diff --git a/DEPS b/DEPS index 8ad005c..c2a3cf2 100644 --- a/DEPS +++ b/DEPS
@@ -291,7 +291,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'src_internal_revision': 'a5073472b181d28117915f910995dccc7a57cac5', + 'src_internal_revision': '466f90ca70623f51b82c63cb869b22ba4fe26de1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. @@ -299,11 +299,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '7d37a54be8c122951b6b553a58c664a38252d8b4', + 'v8_revision': '5c9986d77733643967d10a216bcb594ccfe04b07', # 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': '316c99e166dc22f08c8f8a91433d01a0a509a0a4', + 'angle_revision': 'd3c9719bf06e5664fc544246188ffec8497f0b56', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -311,7 +311,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '3f654284040d971ae0fd1ac7977ee820c1069879', + 'pdfium_revision': 'cc534b45e0aa8becddc6da09732f13aff07a6d6d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -371,7 +371,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling CrossBench # and whatever else without interference from each other. - 'crossbench_revision': 'a4825d77765470c6df91f6c5315407939f4741a0', + 'crossbench_revision': 'd98e13aa6261b85ee3284a87de5ece65e996def9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -387,7 +387,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': '0e29f166e0dd740d1ce15fb24d5edc3c2d87b95a', + 'devtools_frontend_revision': '5e06f392a775081eecd5c33d1c29783728cf8bfb', # 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. @@ -411,11 +411,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '46d76d4aad3b9e3c84dbf0d9565f3b7bdabd3434', + 'dawn_revision': 'c5a1c32fe1664f79c1a6efb3accc15e72af918b7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'quiche_revision': 'ac4ab4297cbdcc10183a2c8d2ab4fd92fbc8fc70', + 'quiche_revision': 'feba5402d20fa4f51c8f7e29ad6f031a650f485a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ink # and whatever else without interference from each other. @@ -519,7 +519,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling llvm-libc # and whatever else without interference from each other. - 'llvm_libc_revision': 'cac770553a6f5e0f607886acfc960a1a68623211', + 'llvm_libc_revision': 'b0d88e0a497deab1607a4b00da2db633bb5af8bc', # If you change this, also update the libc++ revision in # //buildtools/deps_revisions.gni. @@ -1145,7 +1145,7 @@ }, 'src/chrome/release_scripts': { - 'url': Var('chrome_git') + '/chrome/tools/release/scripts' + '@' + 'c980d8c24470ace9a2b0a71952d5ba3d60c6b323', + 'url': Var('chrome_git') + '/chrome/tools/release/scripts' + '@' + '1bce10c60293c2f7e3b3fae1e012ded458d86168', 'condition': 'checkout_chrome_release_scripts', }, @@ -1473,7 +1473,7 @@ 'packages': [ { 'package': 'chromium/chrome/test/data/variations/cipd', - 'version': '35nPWbImP04Anxz4_HokzvKbtelNgH289jMXC1SDHZcC', + 'version': 'Z4Hwx2d7T-VdEOVESX_EYswXbYajoF8HleaamPwLbW0C', }, ], 'dep_type': 'cipd', @@ -1484,7 +1484,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '3caed26bf65373a93272f352981764ff9e3b6209', + 'bbe79ffff6ec262fc09466047ee360fd84f9f675', 'condition': 'checkout_android and checkout_src_internal', }, @@ -1873,7 +1873,7 @@ Var('chromium_git') + '/external/github.com/chromium/content_analysis_sdk.git' + '@' + '9a408736204513e0e95dd2ab3c08de0d95963efc', 'src/third_party/dav1d/libdav1d': - Var('chromium_git') + '/external/github.com/videolan/dav1d.git' + '@' + '7d4b789f55389dad1820d6caf6a650038dad06e2', + Var('chromium_git') + '/external/github.com/videolan/dav1d.git' + '@' + '8d956180934f16244bdb58b39175824775125e55', 'src/third_party/dawn': Var('dawn_git') + '/dawn.git' + '@' + Var('dawn_revision'), @@ -2524,7 +2524,7 @@ Var('pdfium_git') + '/pdfium.git' + '@' + Var('pdfium_revision'), 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '6b56f59b220659e6367b5f8194762ff0b80e9ca2', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '13e3bb887312ff2cc65bfd33f2799149efa00ac9', 'src/base/tracing/test/data': { 'bucket': 'perfetto', @@ -2838,7 +2838,7 @@ 'dep_type': 'cipd', }, - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@548b386bba4eb2cc5a1e4559d23a7345a65cdc6a', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@f87103691a7a5a7313a7b9d77ce2166bd6c16131', 'src/third_party/glslang/src': '{chromium_git}/external/github.com/KhronosGroup/glslang@e57f993cff981c8c3ffd38967e030f04d13781a9', 'src/third_party/spirv-cross/src': '{chromium_git}/external/github.com/KhronosGroup/SPIRV-Cross@b8fcf307f1f347089e3c46eb4451d27f32ebc8d3', 'src/third_party/spirv-headers/src': '{chromium_git}/external/github.com/KhronosGroup/SPIRV-Headers@0e710677989b4326ac974fd80c5308191ed80965', @@ -2847,7 +2847,7 @@ 'src/third_party/vulkan-loader/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-Loader@47404470464709ed5c4b660f9ebc73c717e85a50', 'src/third_party/vulkan-tools/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-Tools@32ee3e6e333a4bc4064fe64cfdfdcf6e71a92743', 'src/third_party/vulkan-utility-libraries/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-Utility-Libraries@ccae111ac678adbc9c74be10c8384cd1af835710', - 'src/third_party/vulkan-validation-layers/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-ValidationLayers@0fd05ea128de73e1b61a60405290f798911ab8ac', + 'src/third_party/vulkan-validation-layers/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-ValidationLayers@d39e6ab0d244d31259b58425b4f76c1862c48f7d', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + '56300b29fbfcc693ee6609ddad3fdd5b7a449a21', @@ -2892,7 +2892,7 @@ Var('chromium_git') + '/webpagereplay.git' + '@' + Var('webpagereplay_revision'), 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'd2534b3914f1b3c6a1aa3683e111fd76b8ff4893', + Var('webrtc_git') + '/src.git' + '@' + '29ead7821ba03d94c43a82fb218cdb1f85dd017b', # Wuffs' canonical repository is at github.com/google/wuffs, but we use # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file. @@ -3000,7 +3000,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/eche_app/app', - 'version': 'Vn4N2atP5LIoXvCFjtuhtaHDqn55owJip8hM6oFfBVgC', + 'version': 'MS1sjyp5yhIO-Ke92rtH-2lv8unbQ7RLnGS8nMpeXnIC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -3011,7 +3011,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/boca_app/app', - 'version': 'PlIiqZbmkMBYZ88AJ1lkuHSMIX45XGcvsWA3SAvn-3sC', + 'version': 'yaDFGmZPjTE3sZrCVlEwx8BRo5YQvewWTrzILVjGXS8C', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -3093,7 +3093,7 @@ 'packages': [ { 'package': 'chromium/third_party/android_deps/autorolled', - 'version': 'tDgulgnm-UGCPQz23HSdOjU9N5iLfhH4Uv-dAE9Tf3sC', + 'version': 'TJzuYmHANgJ9ppyTtvlMFspN9tYUdmunrWDJsNhi5pUC', }, ], 'condition': 'checkout_android and non_git_source', @@ -4615,7 +4615,7 @@ 'src/components/optimization_guide/internal': { 'url': Var('chrome_git') + '/chrome/components/optimization_guide.git' + '@' + - 'be66ee9610e48fcfb3dba8dba2482af49d11f39a', + '70e09ab5396ad41a1fa8996f6b6e9cde542301a1', 'condition': 'checkout_src_internal', }, @@ -5178,6 +5178,16 @@ '-o', 'src/build/util/LASTCHANGE'], }, { + # Update lastchange_commit_position.h (only for CrOS). + 'name': 'lastchange_commit_position_cros', + 'pattern': '.', + 'condition': 'checkout_chromeos', + 'action': ['python3', 'src/build/util/lastchange.py', + '-m', 'CHROMIUM', + '--commit-position-header', + 'src/build/util/LASTCHANGE_commit_position.h'], + }, + { # Update GPU lists version string (for gpu/config). 'name': 'gpu_lists_version', 'pattern': '.',
diff --git a/android_webview/browser/aw_pdf_exporter.cc b/android_webview/browser/aw_pdf_exporter.cc index d28620df..3b84449d 100644 --- a/android_webview/browser/aw_pdf_exporter.cc +++ b/android_webview/browser/aw_pdf_exporter.cc
@@ -86,10 +86,18 @@ } namespace { + // Converts from 1/1000 of inches to device units using DPI. int MilsToDots(int val, int dpi) { - return static_cast<int>(printing::ConvertUnitFloat(val, 1000, dpi)); + return static_cast<int>( + printing::ConvertUnitFloat(val, printing::kMilsPerInch, dpi)); } + +int MilsToDeviceMicrons(int val, int dpi) { + return printing::ConvertUnit(MilsToDots(val, dpi), printing::kPointsPerInch, + printing::kMicronsPerInch); +} + } // namespace std::unique_ptr<printing::PrintSettings> AwPdfExporter::CreatePdfSettings( @@ -99,11 +107,14 @@ auto settings = std::make_unique<printing::PrintSettings>(); int dpi = Java_AwPdfExporter_getDpi(env, obj); printing::PageMargins margins; - margins.left = MilsToDots(Java_AwPdfExporter_getLeftMargin(env, obj), dpi); - margins.right = MilsToDots(Java_AwPdfExporter_getRightMargin(env, obj), dpi); - margins.top = MilsToDots(Java_AwPdfExporter_getTopMargin(env, obj), dpi); + margins.left = + MilsToDeviceMicrons(Java_AwPdfExporter_getLeftMargin(env, obj), dpi); + margins.right = + MilsToDeviceMicrons(Java_AwPdfExporter_getRightMargin(env, obj), dpi); + margins.top = + MilsToDeviceMicrons(Java_AwPdfExporter_getTopMargin(env, obj), dpi); margins.bottom = - MilsToDots(Java_AwPdfExporter_getBottomMargin(env, obj), dpi); + MilsToDeviceMicrons(Java_AwPdfExporter_getBottomMargin(env, obj), dpi); settings->SetCustomMargins(margins); int width = Java_AwPdfExporter_getPageWidth(env, obj);
diff --git a/android_webview/test/data/web_tests/webexposed/global-interface-listing-expected.txt b/android_webview/test/data/web_tests/webexposed/global-interface-listing-expected.txt index d664e248..630991f 100644 --- a/android_webview/test/data/web_tests/webexposed/global-interface-listing-expected.txt +++ b/android_webview/test/data/web_tests/webexposed/global-interface-listing-expected.txt
@@ -28,19 +28,18 @@ method create interface AILanguageModel : EventTarget attribute @@toStringTag - getter maxTokens - getter oncontextoverflow + getter inputQuota + getter inputUsage + getter onquotaoverflow getter temperature - getter tokensLeft - getter tokensSoFar getter topK method clone method constructor - method countPromptTokens method destroy + method measureInputUsage method prompt method promptStreaming - setter oncontextoverflow + setter onquotaoverflow interface AILanguageModelFactory attribute @@toStringTag method availability
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 5c835ad..85cfa48 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -4480,9 +4480,8 @@ <message name="IDS_ASH_ACCELERATOR_DESCRIPTION_TAKE_WINDOW_SCREENSHOT" desc="Label for accelerator action - Take window screenshot or screen recording."> Take window screenshot or screen recording </message> - <!-- TODO: crbug.com/375967525 - Mark this string as translateable once it is confirmed. --> - <message name="IDS_ASH_ACCELERATOR_DESCRIPTION_START_SUNFISH_SESSION" desc="Label for accelerator action - Search my screen." translateable="false"> - Search my screen + <message name="IDS_ASH_ACCELERATOR_DESCRIPTION_START_SUNFISH_SESSION" desc="Label for accelerator action - Search my screen with Google Lens."> + Search my screen with Google Lens </message> <message name="IDS_ASH_ACCELERATOR_DESCRIPTION_TILING_WINDOW_RESIZE_LEFT" desc="Label for accelerator action - Tiled resize window toward the left."> Tiled resize window toward the left
diff --git a/ash/ash_strings_grd/IDS_ASH_ACCELERATOR_DESCRIPTION_START_SUNFISH_SESSION.png.sha1 b/ash/ash_strings_grd/IDS_ASH_ACCELERATOR_DESCRIPTION_START_SUNFISH_SESSION.png.sha1 new file mode 100644 index 0000000..1c98120b --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_ACCELERATOR_DESCRIPTION_START_SUNFISH_SESSION.png.sha1
@@ -0,0 +1 @@ +e4a644f50fbda437d0554dfacfee4cef45832a45 \ No newline at end of file
diff --git a/ash/birch/birch_coral_provider.cc b/ash/birch/birch_coral_provider.cc index 8f610e2..49f29b8 100644 --- a/ash/birch/birch_coral_provider.cc +++ b/ash/birch/birch_coral_provider.cc
@@ -880,6 +880,10 @@ coral::mojom::Entity::NewTab(std::move(tab_mojom))); CoralRequest request; request.set_content(std::move(active_tab_app_data)); + if (!system_language_.has_value()) { + GetAndCheckLanguageAvailability(); + } + request.set_language(*system_language_); Shell::Get()->coral_controller()->CacheEmbeddings(std::move(request)); }
diff --git a/ash/constants/web_app_id_constants.h b/ash/constants/web_app_id_constants.h index 917ac3c0..22749e99 100644 --- a/ash/constants/web_app_id_constants.h +++ b/ash/constants/web_app_id_constants.h
@@ -122,6 +122,10 @@ inline constexpr char kHelpAppId[] = "nbljnnecbjbmifnoehiemkgefbnpoeak"; // Generated as: web_app::GenerateAppId(/*manifest_id=*/std::nullopt, GURL( +// "https://notebooklm.google.com/")) +inline constexpr char kNotebookLmAppId[] = "gjcmcplpgihbecacndmmbaenpfgimlec"; + +// Generated as: web_app::GenerateAppId(/*manifest_id=*/std::nullopt, GURL( // "chrome://media-app/")) inline constexpr char kMediaAppId[] = "jhdjimmaggjajfjphpljagpgkidjilnj";
diff --git a/ash/webui/common/resources/keyboard_diagram.html b/ash/webui/common/resources/keyboard_diagram.html index e03459b3..ae13ddb 100644 --- a/ash/webui/common/resources/keyboard_diagram.html +++ b/ash/webui/common/resources/keyboard_diagram.html
@@ -97,6 +97,7 @@ grid-column: span 4; } + [data-bottom-left-layout='3keys'] #leftAltKey, [data-bottom-left-layout='4keys'] #leftAltKey { grid-column: span 2; } @@ -203,14 +204,22 @@ grid-column: span 6; } + [data-mech-layout='jis'][data-bottom-right-layout='4keys'] #spacebar { + grid-column: span 4; + } + [data-mech-layout='jis'] #rightShiftKey { grid-column: span 3; } - [data-mech-layout='jis'] #arrowKeyCluster { + [data-mech-layout='jis'][data-bottom-right-layout='2keys'] #arrowKeyCluster { grid-column: span 7; } + [data-mech-layout='jis'] #arrowKeyCluster { + grid-column: span 5; + } + /* Modifications for Dell Enterprise keyboards */ [data-show-fn-and-globe-keys] #leftCtrlKey {
diff --git a/ash/webui/media_app_ui/BUILD.gn b/ash/webui/media_app_ui/BUILD.gn index 2e1b04e5..570ce414 100644 --- a/ash/webui/media_app_ui/BUILD.gn +++ b/ash/webui/media_app_ui/BUILD.gn
@@ -113,6 +113,7 @@ public_deps = [ ":mojo_bindings_untrusted_ts__generator", "//chromeos/ash/components/mantis/mojom:mojom_ts__generator", + "//chromeos/services/machine_learning/public/mojom:mojom_ts__generator", ] sources = [] foreach(file, media_app_mojom_sources) {
diff --git a/ash/webui/media_app_ui/media_app_files.gni b/ash/webui/media_app_ui/media_app_files.gni index da88511..b4d41e0 100644 --- a/ash/webui/media_app_ui/media_app_files.gni +++ b/ash/webui/media_app_ui/media_app_files.gni
@@ -25,6 +25,7 @@ "ash/webui/media_app_ui/media_app_ui_untrusted.mojom-webui.ts", "chromeos/ash/components/mantis/mojom/mantis_processor.mojom-webui.ts", "chromeos/ash/components/mantis/mojom/mantis_service.mojom-webui.ts", + "chromeos/services/machine_learning/public/mojom/text_classifier.mojom-webui.ts", ] # Contains only the file name (with extension) part of `media_app_mojom_sources`.
diff --git a/ash/wm/coral/coral_controller.cc b/ash/wm/coral/coral_controller.cc index f1c65bd..98e8893a 100644 --- a/ash/wm/coral/coral_controller.cc +++ b/ash/wm/coral/coral_controller.cc
@@ -129,8 +129,8 @@ CoralController::~CoralController() = default; -void CoralController::Initialize() { - CoralProcessor* coral_processor = EnsureCoralProcessor(); +void CoralController::Initialize(std::string language) { + CoralProcessor* coral_processor = EnsureCoralProcessor(std::move(language)); if (!coral_processor) { LOG(ERROR) << "Failed to connect to coral processor."; } @@ -147,7 +147,7 @@ return; } - CoralProcessor* coral_processor = EnsureCoralProcessor(); + CoralProcessor* coral_processor = EnsureCoralProcessor(request.language()); if (!coral_processor) { LOG(ERROR) << "Failed to connect to coral processor."; std::move(callback).Run(nullptr); @@ -182,7 +182,7 @@ } void CoralController::CacheEmbeddings(const CoralRequest& request) { - CoralProcessor* coral_processor = EnsureCoralProcessor(); + CoralProcessor* coral_processor = EnsureCoralProcessor(request.language()); if (!coral_processor) { LOG(ERROR) << "Failed to connect to coral processor."; return; @@ -303,7 +303,8 @@ weak_factory_.GetWeakPtr())); } -CoralController::CoralProcessor* CoralController::EnsureCoralProcessor() { +CoralController::CoralProcessor* CoralController::EnsureCoralProcessor( + std::string language) { // Generate a fake processor if --force-birch-fake-coral-backend is enabled. if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kForceBirchFakeCoralBackend)) { @@ -333,7 +334,8 @@ ->BindMachineLearningService( ml_service.InitWithNewPipeAndPassReceiver()); coral_service_->Initialize(std::move(ml_service), - coral_processor_.BindNewPipeAndPassReceiver()); + coral_processor_.BindNewPipeAndPassReceiver(), + language); coral_processor_.reset_on_disconnect(); }
diff --git a/ash/wm/coral/coral_controller.h b/ash/wm/coral/coral_controller.h index 86c4e0f..1e766a9 100644 --- a/ash/wm/coral/coral_controller.h +++ b/ash/wm/coral/coral_controller.h
@@ -105,10 +105,10 @@ ~CoralController(); // Claims necessary resources (dlc download / model loading) for processing - // `GenerateContentGroups` and `CacheEmbeddings` requests. It is not necessary - // to call `Initialize` before calling other methods, but in that case - // the first method request might take longer to run. - void Initialize(); + // `GenerateContentGroups` and `CacheEmbeddings` requests. This should be + // run before other methods to ensure models are ready, and set up the + // language. + void Initialize(std::string language); // GenerateContentGroups clusters the input ContentItems (which includes web // tabs, apps, etc.) into suitable groups based on their topics, and gives @@ -147,7 +147,7 @@ // Requests coral processor from service manager and returns the pointer of // the processor instance. - CoralProcessor* EnsureCoralProcessor(); + CoralProcessor* EnsureCoralProcessor(std::string language); // Used as the callback of mojom::CoralProcessor::Group. void HandleGroupResult(CoralSource source,
diff --git a/base/BUILD.gn b/base/BUILD.gn index d38124a0..aa168aa 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -385,6 +385,7 @@ "memory/ref_counted_memory.h", "memory/safe_ref.h", "memory/safe_ref_traits.h", + "memory/safety_checks.cc", "memory/safety_checks.h", "memory/scoped_policy.h", "memory/scoped_refptr.h",
diff --git a/base/allocator/partition_alloc_support.cc b/base/allocator/partition_alloc_support.cc index 70231790..1ca1f0f 100644 --- a/base/allocator/partition_alloc_support.cc +++ b/base/allocator/partition_alloc_support.cc
@@ -1380,4 +1380,10 @@ } #endif +void CheckHeapIntegrity(const void* ptr) { +#if PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) + partition_alloc::PartitionRoot::CheckMetadataIntegrity(ptr); +#endif // PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) +} + } // namespace base::allocator
diff --git a/base/allocator/partition_alloc_support.h b/base/allocator/partition_alloc_support.h index 337511a..6ff139ea 100644 --- a/base/allocator/partition_alloc_support.h +++ b/base/allocator/partition_alloc_support.h
@@ -158,6 +158,13 @@ bool has_pending_task_ = false; }; +// Utility function to detect Double-Free or Out-of-Bounds writes. +// This function can be called to memory assumed to be valid. +// If not, this may crash (not guaranteed). +// This is useful if you want to investigate crashes at `free()`, +// to know which point at execution it goes wrong. +BASE_EXPORT void CheckHeapIntegrity(const void* ptr); + } // namespace base::allocator #endif // BASE_ALLOCATOR_PARTITION_ALLOC_SUPPORT_H_
diff --git a/base/allocator/partition_allocator/src/partition_alloc/gwp_asan_support.cc b/base/allocator/partition_allocator/src/partition_alloc/gwp_asan_support.cc index 90eb7ae..54fa9ce3 100644 --- a/base/allocator/partition_allocator/src/partition_alloc/gwp_asan_support.cc +++ b/base/allocator/partition_allocator/src/partition_alloc/gwp_asan_support.cc
@@ -23,6 +23,9 @@ PartitionOptions GwpAsanPartitionOptions() { PartitionOptions options; options.backup_ref_ptr = PartitionOptions::kEnabled; + + // GWP-ASan does not reserve space for cookies. + options.use_cookie_if_supported = PartitionOptions::kDisabled; return options; }
diff --git a/base/allocator/partition_allocator/src/partition_alloc/in_slot_metadata.h b/base/allocator/partition_allocator/src/partition_alloc/in_slot_metadata.h index f11cd74..c47518ec 100644 --- a/base/allocator/partition_allocator/src/partition_alloc/in_slot_metadata.h +++ b/base/allocator/partition_allocator/src/partition_alloc/in_slot_metadata.h
@@ -301,6 +301,15 @@ return alive; } + // Assertion to allocation which ought to be alive. + PA_ALWAYS_INLINE void EnsureAlive() { + CountType count = count_.load(std::memory_order_relaxed); + if (!(count & kMemoryHeldByAllocatorBit)) { + DoubleFreeOrCorruptionDetected(count); + } + CheckCookieIfSupported(); + } + // Called when a raw_ptr is not banning dangling ptrs, but the user still // wants to ensure the pointer is not currently dangling. This is currently // used in UnretainedWrapper to make sure callbacks are not invoked with
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_unittest.cc b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_unittest.cc index f30ded94..69a7f9d 100644 --- a/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_unittest.cc +++ b/base/allocator/partition_allocator/src/partition_alloc/partition_alloc_unittest.cc
@@ -2659,6 +2659,7 @@ EXPECT_TRUE(ptr); allocator.root()->Free(ptr); EXPECT_DEATH(allocator.root()->Free(ptr), ""); + EXPECT_DEATH(allocator.root()->CheckMetadataIntegrity(ptr), ""); } // As above, but when this isn't the only slot in the span. @@ -2669,6 +2670,7 @@ EXPECT_TRUE(ptr); allocator.root()->Free(ptr); EXPECT_DEATH(allocator.root()->Free(ptr), ""); + EXPECT_DEATH(allocator.root()->CheckMetadataIntegrity(ptr), ""); allocator.root()->Free(ptr0); } @@ -2828,6 +2830,8 @@ // Crash at `free()`, either by cookie check failure or InSlotMetadata // corruption. EXPECT_DEATH(allocator.root()->Free(array), ""); + // It should also crash with `CheckMetadataIntegrity()`. + EXPECT_DEATH(allocator.root()->CheckMetadataIntegrity(array), ""); // Restore integrity, otherwise the process will crash in TearDown(). array[usable_size] = previous_value; allocator.root()->Free(array); @@ -2852,6 +2856,8 @@ // Crash at `free()`, either by cookie check failure or InSlotMetadata // corruption. EXPECT_DEATH(allocator.root()->Free(array), ""); + // It should also crash with `CheckMetadataIntegrity()`. + EXPECT_DEATH(allocator.root()->CheckMetadataIntegrity(array), ""); // Restore integrity, otherwise the process will crash in TearDown(). array[usable_size] = previous_value; allocator.root()->Free(array);
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_cookie.cc b/base/allocator/partition_allocator/src/partition_alloc/partition_cookie.cc index 7a7016d9..72851e3 100644 --- a/base/allocator/partition_allocator/src/partition_alloc/partition_cookie.cc +++ b/base/allocator/partition_allocator/src/partition_alloc/partition_cookie.cc
@@ -12,12 +12,12 @@ #if PA_BUILDFLAG(USE_PARTITION_COOKIE) namespace partition_alloc::internal { [[noreturn]] PA_NOINLINE PA_NOT_TAIL_CALLED void CookieCorruptionDetected( - unsigned char* cookie_ptr, + const unsigned char* cookie_ptr, size_t slot_usable_size) { using CookieValue = std::conditional_t<kCookieSize == 4, uint32_t, uint64_t>; static_assert(sizeof(CookieValue) <= kCookieSize); CookieValue cookie = - *static_cast<CookieValue*>(static_cast<void*>(cookie_ptr)); + *static_cast<const CookieValue*>(static_cast<const void*>(cookie_ptr)); PA_DEBUG_DATA_ON_STACK("slotsize", slot_usable_size); PA_DEBUG_DATA_ON_STACK("cookie", cookie);
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_cookie.h b/base/allocator/partition_allocator/src/partition_alloc/partition_cookie.h index a19bbc5..686b2ab 100644 --- a/base/allocator/partition_allocator/src/partition_alloc/partition_cookie.h +++ b/base/allocator/partition_allocator/src/partition_alloc/partition_cookie.h
@@ -37,11 +37,12 @@ constexpr size_t kPartitionCookieSizeAdjustment = kCookieSize; -[[noreturn]] PA_NOINLINE PA_NOT_TAIL_CALLED PA_COMPONENT_EXPORT( - PARTITION_ALLOC) void CookieCorruptionDetected(unsigned char* cookie_ptr, - size_t slot_usable_size); +[[noreturn]] PA_NOINLINE PA_NOT_TAIL_CALLED + PA_COMPONENT_EXPORT(PARTITION_ALLOC) void CookieCorruptionDetected( + const unsigned char* cookie_ptr, + size_t slot_usable_size); -PA_ALWAYS_INLINE void PartitionCookieCheckValue(unsigned char* cookie_ptr, +PA_ALWAYS_INLINE void PartitionCookieCheckValue(const unsigned char* cookie_ptr, size_t slot_usable_size) { for (size_t i = 0; i < kCookieSize; ++i, ++cookie_ptr) { if (*cookie_ptr != kCookieValue[i]) { @@ -60,7 +61,7 @@ constexpr size_t kPartitionCookieSizeAdjustment = 0; -PA_ALWAYS_INLINE void PartitionCookieCheckValue(unsigned char* address, +PA_ALWAYS_INLINE void PartitionCookieCheckValue(const unsigned char* address, size_t slot_usable_size) {} PA_ALWAYS_INLINE void PartitionCookieWriteValue(unsigned char* cookie_ptr) {}
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_page.h b/base/allocator/partition_allocator/src/partition_alloc/partition_page.h index 1b0061b..2212b80a 100644 --- a/base/allocator/partition_allocator/src/partition_alloc/partition_page.h +++ b/base/allocator/partition_allocator/src/partition_alloc/partition_page.h
@@ -1005,7 +1005,7 @@ } template <bool enforce = PA_CONFIG(ENFORCE_SLOT_STARTS)> - PA_ALWAYS_INLINE static SlotStart FromObject(void* tagged_object) { + PA_ALWAYS_INLINE static SlotStart FromObject(const void* tagged_object) { uintptr_t untagged_slot_start = internal::UntagAddr(reinterpret_cast<uintptr_t>(tagged_object)); return SlotStart::FromUntaggedAddr<enforce>(untagged_slot_start);
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_root.cc b/base/allocator/partition_allocator/src/partition_alloc/partition_root.cc index 2398eaa9..3609433 100644 --- a/base/allocator/partition_allocator/src/partition_alloc/partition_root.cc +++ b/base/allocator/partition_allocator/src/partition_alloc/partition_root.cc
@@ -1212,7 +1212,7 @@ #if PA_CONFIG(EXTRAS_REQUIRED) settings.extras_size = 0; - if (Settings::use_cookie) { + if (settings.use_cookie) { settings.extras_size += internal::kPartitionCookieSizeAdjustment; } @@ -1274,6 +1274,11 @@ } #endif // !PA_CONFIG(THREAD_CACHE_SUPPORTED) +#if PA_BUILDFLAG(USE_PARTITION_COOKIE) + settings.use_cookie = + opts.use_cookie_if_supported == PartitionOptions::kEnabled; +#endif // PA_BUILDFLAG(USE_PARTITION_COOKIE) + #if PA_CONFIG(USE_PARTITION_ROOT_ENUMERATOR) internal::PartitionRootEnumerator::Instance().Register(this); #endif @@ -1481,10 +1486,12 @@ } // Write a new trailing cookie. - if (Settings::use_cookie) { +#if PA_BUILDFLAG(USE_PARTITION_COOKIE) + if (settings.use_cookie) { auto* object = static_cast<unsigned char*>(SlotStartToObject(slot_start)); internal::PartitionCookieWriteValue(object + GetSlotUsableSize(slot_span)); } +#endif // PA_BUILDFLAG(USE_PARTITION_COOKIE) return true; } @@ -1530,10 +1537,12 @@ // PA_BUILDFLAG(DCHECKS_ARE_ON) // Write a new trailing cookie only when it is possible to keep track // raw size (otherwise we wouldn't know where to look for it later). - if (Settings::use_cookie) { +#if PA_BUILDFLAG(USE_PARTITION_COOKIE) + if (settings.use_cookie) { internal::PartitionCookieWriteValue(static_cast<unsigned char*>(object) + GetSlotUsableSize(slot_span)); } +#endif // PA_BUILDFLAG(USE_PARTITION_COOKIE) } // Always record a realloc() as a free() + malloc(), even if it's in @@ -2011,6 +2020,60 @@ } #endif // PA_CONFIG(ENABLE_SHADOW_METADATA) +// static +void PartitionRoot::CheckMetadataIntegrity(const void* ptr) { + uintptr_t address = internal::ObjectInnerPtr2Addr(ptr); + if (!IsManagedByPartitionAlloc(address)) { + // Not managed by PA; cannot help to determine its integrity. + return; + } else if (internal::IsManagedByDirectMap(address)) { + // OOB for direct-mapped allocations is likely immediate crash. + // No extra benefit from additional checks. + return; + } + PA_CHECK(internal::IsManagedByNormalBuckets(address)); + + auto* root = FromAddrInFirstSuperpage(address); + + ReadOnlySlotSpanMetadata* slot_span = + ReadOnlySlotSpanMetadata::FromAddr(address); + PA_CHECK(PartitionRoot::FromSlotSpanMetadata(slot_span) == root); + +#if PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) || \ + PA_BUILDFLAG(USE_PARTITION_COOKIE) + uintptr_t slot_span_start = + ReadOnlySlotSpanMetadata::ToSlotSpanStart(slot_span); + size_t offset_in_slot_span = address - slot_span_start; + + auto* bucket = slot_span->bucket; + uintptr_t untagged_slot_start = + slot_span_start + + bucket->slot_size * bucket->GetSlotNumber(offset_in_slot_span); +#endif // PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) || + // PA_BUILDFLAG(USE_PARTITION_COOKIE) + +#if PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) + if (root->brp_enabled()) { + auto* in_slot_metadata = InSlotMetadataPointerFromSlotStartAndSize( + untagged_slot_start, slot_span->bucket->slot_size); + in_slot_metadata->EnsureAlive(); + } +#endif // PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) + +#if PA_BUILDFLAG(USE_PARTITION_COOKIE) + if (root->settings.use_cookie) { + // Verify the cookie after the allocated region. + // If this assert fires, you probably corrupted memory. + const size_t usable_size = root->GetSlotUsableSize(slot_span); + + uintptr_t cookie_address = untagged_slot_start + usable_size; + internal::PartitionCookieCheckValue( + static_cast<const unsigned char*>(internal::TagAddr(cookie_address)), + usable_size); + } +#endif // PA_BUILDFLAG(USE_PARTITION_COOKIE) +} + // Explicitly define common template instantiations to reduce compile time. #define EXPORT_TEMPLATE \ template PA_EXPORT_TEMPLATE_DEFINE(PA_COMPONENT_EXPORT(PARTITION_ALLOC))
diff --git a/base/allocator/partition_allocator/src/partition_alloc/partition_root.h b/base/allocator/partition_allocator/src/partition_alloc/partition_root.h index fef18b0..02d43fdb 100644 --- a/base/allocator/partition_allocator/src/partition_alloc/partition_root.h +++ b/base/allocator/partition_allocator/src/partition_alloc/partition_root.h
@@ -166,6 +166,7 @@ static constexpr auto kEnabled = EnableToggle::kEnabled; EnableToggle thread_cache = kDisabled; + EnableToggle use_cookie_if_supported = kEnabled; EnableToggle backup_ref_ptr = kDisabled; AllowToggle use_configurable_pool = kDisallowed; @@ -249,7 +250,7 @@ bool with_thread_cache = false; #if PA_BUILDFLAG(USE_PARTITION_COOKIE) - static constexpr bool use_cookie = true; + bool use_cookie = true; #else static constexpr bool use_cookie = false; #endif // PA_BUILDFLAG(USE_PARTITION_COOKIE) @@ -936,6 +937,8 @@ } #endif // PA_CONFIG(ENABLE_SHADOW_METADATA) + PA_NOINLINE static void CheckMetadataIntegrity(const void* object); + private: static inline StraightenLargerSlotSpanFreeListsMode straighten_larger_slot_span_free_lists_ = @@ -1598,13 +1601,15 @@ // For more context, see the other "Layout inside the slot" comment inside // AllocInternalNoHooks(). - if (Settings::use_cookie) { +#if PA_BUILDFLAG(USE_PARTITION_COOKIE) + if (settings.use_cookie) { // Verify the cookie after the allocated region. // If this assert fires, you probably corrupted memory. const size_t usable_size = GetSlotUsableSize(slot_span); internal::PartitionCookieCheckValue( static_cast<unsigned char*>(object) + usable_size, usable_size); } +#endif // PA_BUILDFLAG(USE_PARTITION_COOKIE) #if PA_BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) if (brp_enabled()) [[likely]] { @@ -2311,10 +2316,12 @@ void* object = SlotStartToObject(slot_start); // Add the cookie after the allocation. - if (Settings::use_cookie) { +#if PA_BUILDFLAG(USE_PARTITION_COOKIE) + if (settings.use_cookie) { internal::PartitionCookieWriteValue(static_cast<unsigned char*>(object) + usable_size); } +#endif // PA_BUILDFLAG(USE_PARTITION_COOKIE) // Fill the region kUninitializedByte (on debug builds, if not requested to 0) // or 0 (if requested and not 0 already).
diff --git a/base/memory/safety_checks.cc b/base/memory/safety_checks.cc new file mode 100644 index 0000000..9752f079 --- /dev/null +++ b/base/memory/safety_checks.cc
@@ -0,0 +1,15 @@ +// Copyright 2025 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/memory/safety_checks.h" + +namespace base { + +void CheckHeapIntegrity(const void* ptr) { +#if PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) + partition_alloc::PartitionRoot::CheckMetadataIntegrity(ptr); +#endif // PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) +} + +} // namespace base
diff --git a/base/memory/safety_checks.h b/base/memory/safety_checks.h index fdf8d2ab..f227f1ab 100644 --- a/base/memory/safety_checks.h +++ b/base/memory/safety_checks.h
@@ -8,6 +8,7 @@ #include <new> #include <type_traits> +#include "base/base_export.h" #include "base/compiler_specific.h" #include "base/dcheck_is_on.h" #include "partition_alloc/buildflags.h" @@ -52,10 +53,12 @@ // } // ``` +namespace base { + // We cannot hide things behind anonymous namespace because they are referenced // via macro, which can be defined anywhere. // To avoid tainting ::base namespace, define things inside this namespace. -namespace base::internal { +namespace internal { enum class MemorySafetyCheck : uint32_t { kNone = 0, @@ -194,7 +197,7 @@ ::operator delete(ptr, alignment); } -} // namespace base::internal +} // namespace internal // Macros to annotate class/struct's default memory safety check. // ADVANCED_MEMORY_SAFETY_CHECKS(): Enable Check |kAdvancedChecks| for this @@ -304,4 +307,12 @@ MEMORY_SAFETY_CHECKS_INTERNAL( \ ALWAYS_INLINE, kNone __VA_OPT__(, ) __VA_ARGS__, kNone, kNone) +// Utility function to detect Double-Free or Out-of-Bounds writes. +// This function can be called to memory assumed to be valid. +// If not, this may crash (not guaranteed). +// This is useful if you want to investigate crashes at `free()`, +// to know which point at execution it goes wrong. +BASE_EXPORT void CheckHeapIntegrity(const void* ptr); +} // namespace base + #endif // BASE_MEMORY_SAFETY_CHECKS_H_
diff --git a/base/version_info/version_string.cc b/base/version_info/version_string.cc index 97f8715..96a8f2a 100644 --- a/base/version_info/version_string.cc +++ b/base/version_info/version_string.cc
@@ -5,12 +5,22 @@ #include "base/version_info/version_string.h" #include "base/version_info/version_info.h" +#include "build/build_config.h" + +#if BUILDFLAG(IS_CHROMEOS) +#include "build/util/LASTCHANGE_commit_position.h" +#endif namespace version_info { std::string GetVersionStringWithModifier(const std::string& modifier) { std::string current_version; current_version += GetVersionNumber(); +#if BUILDFLAG(IS_CHROMEOS) && CHROMIUM_COMMIT_POSITION_IS_MAIN + // Adds the revision number as a suffix to the version number if the chrome + // is built from the main branch. + current_version += "-r" CHROMIUM_COMMIT_POSITION_NUMBER; +#endif #if defined(USE_UNOFFICIAL_VERSION_NUMBER) current_version += " (Developer Build "; current_version += GetLastChange();
diff --git a/build/util/lastchange.py b/build/util/lastchange.py index a511f58..3321a3e 100755 --- a/build/util/lastchange.py +++ b/build/util/lastchange.py
@@ -23,9 +23,9 @@ import gclient_utils -VersionInfo = collections.namedtuple("VersionInfo", - ("revision_id", "revision", "timestamp")) -_EMPTY_VERSION_INFO = VersionInfo('0' * 40, '0' * 40, 0) +VersionInfo = collections.namedtuple( + "VersionInfo", ("revision_id", "revision", "commit_position", "timestamp")) +_EMPTY_VERSION_INFO = VersionInfo('0' * 40, '0' * 40, '', 0) class GitError(Exception): pass @@ -142,9 +142,10 @@ output = _RunGitCommand(directory, git_args) hash_, commit_timestamp = output.split() if not hash_: - return VersionInfo('0', '0', 0) + return VersionInfo('0', '0', '', 0) revision = hash_ + pos = '' output = _RunGitCommand(directory, ['cat-file', 'commit', hash_]) for line in reversed(output.splitlines()): if line.startswith('Cr-Commit-Position:'): @@ -152,7 +153,7 @@ logging.debug("Found Cr-Commit-Position '%s'", pos) revision = "{}-{}".format(hash_, pos) break - return VersionInfo(hash_, revision, int(commit_timestamp)) + return VersionInfo(hash_, revision, pos, int(commit_timestamp)) def GetHeaderGuard(path): @@ -171,6 +172,40 @@ return guard.replace('/', '_').replace('.', '_').replace('\\', '_') + '_' +def GetCommitPositionHeaderContents(path, define_prefix, version_info): + """ + Returns what the contents of the header file should be that indicate the + commit position number of given version. + """ + header_guard = GetHeaderGuard(path) + + commit_position_number = '' + commit_position_ref = '' + if version_info.commit_position: + ref_and_number = version_info.commit_position.split('@', 2) + if len(ref_and_number) == 2: + commit_position_ref = ref_and_number[0] + commit_position_number = ref_and_number[1][2:-1] + + header_contents = """/* Generated by lastchange.py, do not edit.*/ + +#ifndef %(header_guard)s +#define %(header_guard)s + +#define %(define)s_COMMIT_POSITION_IS_MAIN %(is_main)s +#define %(define)s_COMMIT_POSITION_NUMBER "%(commit_position_number)s" + +#endif // %(header_guard)s +""" % { + 'header_guard': header_guard, + 'define': define_prefix, + 'is_main': ('1' if commit_position_ref == 'refs/heads/main' else '0'), + 'commit_position_number': commit_position_number, + } + + return header_contents + + def GetHeaderContents(path, define, version): """ Returns what the contents of the header file should be that indicate the given @@ -279,7 +314,7 @@ timestamp = int( os.environ.get('BASE_COMMIT_SUBMISSION_MS', _EMPTY_VERSION_INFO.timestamp)) / 1000 - return VersionInfo(hash, hash, int(timestamp)) + return VersionInfo(hash, hash, '', int(timestamp)) def main(argv=None): @@ -301,6 +336,11 @@ help=("Write last change to FILE as a C/C++ header. " "Can be combined with other file-output-related " "options to write multiple files.")) + parser.add_argument("--commit-position-header", + metavar="FILE", + help=("Write the commit position to FILE as a C/C++ " + "header. Can be combined with other file-output-" + "related options to write multiple files.")) parser.add_argument("--revision", metavar="FILE", help=("Write last change to FILE as a one-line revision. " @@ -332,7 +372,8 @@ out_file = args.output header = args.header revision = args.revision - commit_filter=args.filter + commit_filter = args.filter + commit_position_header = args.commit_position_header while len(extras) and out_file is None: if out_file is None: @@ -360,7 +401,7 @@ "LASTCHANGE_YEAR=%s" % lastchange_year, ] contents = '\n'.join(contents_lines) + '\n' - if not out_file and not header and not revision: + if not (out_file or header or commit_position_header or revision): sys.stdout.write(contents) else: if out_file: @@ -373,6 +414,11 @@ WriteIfChanged(header, GetHeaderContents(header, args.version_macro, revision_string)) + if commit_position_header: + WriteIfChanged( + commit_position_header, + GetCommitPositionHeaderContents(commit_position_header, + args.version_macro, version_info)) if revision: WriteIfChanged(revision, revision_string)
diff --git a/cc/raster/bitmap_raster_buffer_provider.cc b/cc/raster/bitmap_raster_buffer_provider.cc index 407fe1c..a04f794 100644 --- a/cc/raster/bitmap_raster_buffer_provider.cc +++ b/cc/raster/bitmap_raster_buffer_provider.cc
@@ -29,10 +29,8 @@ class BitmapRasterBufferImpl : public RasterBuffer { public: BitmapRasterBufferImpl(ResourcePool::Backing* backing, - uint64_t resource_content_id, - uint64_t previous_content_id) - : resource_has_previous_content_( - resource_content_id && resource_content_id == previous_content_id), + bool resource_has_previous_content) + : resource_has_previous_content_(resource_has_previous_content), backing_(backing) {} BitmapRasterBufferImpl(const BitmapRasterBufferImpl&) = delete; BitmapRasterBufferImpl& operator=(const BitmapRasterBufferImpl&) = delete; @@ -54,11 +52,11 @@ << "Why are we rastering a tile that's not dirty?"; size_t stride = 0u; - viz::SharedImageFormat format = viz::SinglePlaneFormat::kBGRA_8888; auto mapping = backing_->shared_image()->Map(); void* memory = mapping->GetMemoryForPlane(0).data(); RasterBufferProvider::PlaybackToMemory( - memory, format, backing_->shared_image()->size(), stride, raster_source, + memory, backing_->shared_image()->format(), + backing_->shared_image()->size(), stride, raster_source, raster_full_rect, playback_rect, transform, backing_->shared_image()->color_space(), playback_settings); } @@ -92,8 +90,6 @@ bool depends_on_at_raster_decodes, bool depends_on_hardware_accelerated_jpeg_candidates, bool depends_on_hardware_accelerated_webp_candidates) { - DCHECK_EQ(resource.format(), viz::SinglePlaneFormat::kBGRA_8888); - if (!resource.backing()) { resource.InstallSoftwareBacking(shared_image_interface_, "BitmapRasterBufferProvider"); @@ -103,8 +99,10 @@ } ResourcePool::Backing* backing = resource.backing(); - return std::make_unique<BitmapRasterBufferImpl>(backing, resource_content_id, - previous_content_id); + bool resource_has_previous_content = + resource_content_id && resource_content_id == previous_content_id; + return std::make_unique<BitmapRasterBufferImpl>( + backing, resource_has_previous_content); } void BitmapRasterBufferProvider::Flush() {}
diff --git a/chrome/VERSION b/chrome/VERSION index fd87be3..48e5bda 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=136 MINOR=0 -BUILD=7089 +BUILD=7090 PATCH=0
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryViewBinder.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryViewBinder.java index 40ab30d..17eaa4f 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryViewBinder.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryViewBinder.java
@@ -178,9 +178,7 @@ // the following chip. This might give a more consistent user experience and allow wider // windows to show more information in a chip before truncating. if (containsIbanInfo(item.getSuggestion()) - || (ChromeFeatureList.isEnabled( - ChromeFeatureList.AUTOFILL_ENABLE_CARD_PRODUCT_NAME) - && containsCreditCardInfo(item.getSuggestion()))) { + || containsCreditCardInfo(item.getSuggestion())) { int windowWidth = chipView.getContext().getResources().getDisplayMetrics().widthPixels; chipView.setMaxWidth((int) (windowWidth * 0.85));
diff --git a/chrome/android/java/res/values/ids.xml b/chrome/android/java/res/values/ids.xml index 05457c5..65d44f7b 100644 --- a/chrome/android/java/res/values/ids.xml +++ b/chrome/android/java/res/values/ids.xml
@@ -42,6 +42,9 @@ <item type="id" name="password_infobar_accounts_spinner" /> <!-- Context Menu Ids --> + <!-- Page Group --> + <item type="id" name="contextmenu_save_page" /> + <!-- Custom Tab Group --> <item type="id" name="contextmenu_open_in_new_chrome_tab" /> <item type="id" name="contextmenu_open_in_chrome_incognito_tab" />
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java index 8051698..1d672fd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java
@@ -63,7 +63,8 @@ Item.OPEN_IN_NEW_TAB_IN_GROUP, Item.SHARE_HIGHLIGHT, Item.REMOVE_HIGHLIGHT, - Item.LEARN_MORE + Item.LEARN_MORE, + Item.SAVE_PAGE, }) @Retention(RetentionPolicy.SOURCE) public @interface Item { @@ -111,8 +112,10 @@ int SHARE_HIGHLIGHT = 32; int REMOVE_HIGHLIGHT = 33; int LEARN_MORE = 34; + // Page Group + int SAVE_PAGE = 35; // ALWAYS UPDATE! - int NUM_ENTRIES = 35; + int NUM_ENTRIES = 36; } /** Mapping from {@link Item} to the ID found in the ids.xml. */ @@ -152,6 +155,7 @@ R.id.contextmenu_share_highlight, // Item.SHARE_HIGHLIGHT R.id.contextmenu_remove_highlight, // Item.REMOVE_HIGHLIGHT R.id.contextmenu_learn_more, // Item.LEARN_MORE + R.id.contextmenu_save_page, // Item.SAVE_PAGE }; /** Mapping from {@link Item} to the ID of the string that describes the action of the item. */ @@ -191,6 +195,7 @@ R.string.contextmenu_share_highlight, // Item.SHARE_HIGHLIGHT R.string.contextmenu_remove_highlight, // Item.REMOVE_HIGHLIGHT R.string.contextmenu_learn_more, // Item.LEARN_MORE + R.string.contextmenu_save_page, // Item.SAVE_PAGE }; /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java index 4168ffd..69c111f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -173,7 +173,8 @@ Action.SHARE_HIGHLIGHT, Action.REMOVE_HIGHLIGHT, Action.LEARN_MORE, - Action.OPEN_IN_NEW_TAB_IN_GROUP + Action.OPEN_IN_NEW_TAB_IN_GROUP, + Action.SAVE_PAGE, }) @Retention(RetentionPolicy.SOURCE) public @interface Action { @@ -218,7 +219,8 @@ int LEARN_MORE = 38; int OPEN_IN_NEW_TAB_IN_GROUP = 39; int OPEN_IN_NEW_WINDOW = 40; - int NUM_ENTRIES = 41; + int SAVE_PAGE = 41; + int NUM_ENTRIES = 42; } } @@ -275,7 +277,8 @@ return DeviceFormFactor.isNonMultiDisplayContextOnTablet(mContext); } - public static boolean shouldShowEmptySpaceContextMenu() { + @VisibleForTesting + boolean shouldShowEmptySpaceContextMenu() { return DeviceFormFactor.isDesktop() && DeviceInput.supportsAlphabeticKeyboard() && DeviceInput.supportsPrecisionPointer(); @@ -288,7 +291,14 @@ List<Pair<Integer, ModelList>> groupedItems = new ArrayList<>(); if (mParams.isPage() && shouldShowEmptySpaceContextMenu()) { - // TODO (crbug.com/391719844): add new groups and items for page actions. + ModelList pageGroup = new ModelList(); + // TODO(crbug.com/405842034): investigate supporting downloads in incognito mode. + if (!mItemDelegate.isIncognito() + && UrlUtilities.isDownloadableScheme(mParams.getPageUrl())) { + pageGroup.add( + createListItem(Item.SAVE_PAGE, false, !mIsDownloadRestrictedByPolicy)); + } + groupedItems.add(new Pair<>(R.string.contextmenu_page_title, pageGroup)); } if (mParams.isAnchor()) { @@ -616,6 +626,14 @@ } else if (mItemDelegate.startDownload(url, true)) { mNativeDelegate.startDownload(url, false); } + } else if (itemId == R.id.contextmenu_save_page) { + recordContextMenuSelection(ContextMenuUma.Action.SAVE_PAGE); + GURL url = mItemDelegate.getPageUrl(); + if (mIsDownloadRestrictedByPolicy) { + showDownloadRestrictedToast(); + } else if (mItemDelegate.startDownload(url, true)) { + mNativeDelegate.startDownload(url, false); + } } else if (itemId == R.id.contextmenu_share_link) { recordContextMenuSelection(ContextMenuUma.Action.SHARE_LINK); // TODO(crbug.com/40549331): Migrate ShareParams to GURL.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java index 458acc25..ace633f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
@@ -1377,7 +1377,12 @@ mWindowAndroid, tabGroupModelFilter, dataSharingNotificationManager, - mDataSharingTabManager); + mDataSharingTabManager, + () -> { + return MultiWindowUtils.getInstanceCount() <= 1 + || ApplicationStatus.getLastTrackedFocusedActivity() + == mActivity; + }); }); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java index 0f03a5a..b91246e18 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java
@@ -5,7 +5,6 @@ package org.chromium.chrome.browser.contextmenu; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.eq; @@ -146,6 +145,12 @@ doReturn(false).when(mPopulator).shouldTriggerEphemeralTabHelpUi(); doReturn(false).when(mPopulator).shouldTriggerReadLaterHelpUi(); doReturn(true).when(mExternalAuthUtils).isGoogleSigned(IntentHandler.PACKAGE_GSA); + doReturn(false).when(mPopulator).shouldShowEmptySpaceContextMenu(); + } + + private void initializePopulatorOnDesktop(@ContextMenuMode int mode, ContextMenuParams params) { + initializePopulator(mode, params); + doReturn(true).when(mPopulator).shouldShowEmptySpaceContextMenu(); } private void checkMenuOptions(List<Integer> disabled, int[]... groups) { @@ -160,11 +165,10 @@ int[] availableInTab = new int[contextMenuState.get(i).second.size()]; for (int j = 0; j < contextMenuState.get(i).second.size(); j++) { PropertyModel model = contextMenuState.get(i).second.get(j).model; - if (disabled.contains(model.get(MENU_ID))) { - assertFalse(model.get(ENABLED)); - } else { - assertTrue(model.get(ENABLED)); - } + assertEquals( + "'" + model.get(TEXT) + "' has different enablement setting than expected", + !disabled.contains(model.get(MENU_ID)), + model.get(ENABLED)); availableInTab[j] = model.get(MENU_ID); } @@ -187,13 +191,25 @@ } if (!Arrays.equals(expectedItemsInGroup, availableInTab)) { - StringBuilder info = new StringBuilder(); + StringBuilder generated_info = new StringBuilder(); for (int j = 0; j < contextMenuState.get(i).second.size(); j++) { - info.append("'"); - info.append(contextMenuState.get(i).second.get(j).model.get(TEXT)); - info.append("' "); + generated_info.append("'"); + generated_info.append(contextMenuState.get(i).second.get(j).model.get(TEXT)); + generated_info.append("' "); } - fail("Items in group " + i + " don't match, generated: " + info.toString()); + StringBuilder expected_info = new StringBuilder(); + for (int j = 0; j < expectedItemsInGroup.length; j++) { + expected_info.append("'"); + expected_info.append(expectedItemsInGroup[j]); + expected_info.append("' "); + } + fail( + "Items in group " + + i + + " don't match, expecting: " + + expected_info.toString() + + ", generated: " + + generated_info.toString()); } } } @@ -1448,4 +1464,125 @@ }; checkMenuOptions(image2Expected); } + + @Test + @SmallTest + @UiThreadTest + public void testPage() { + FirstRunStatus.setFirstRunFlowComplete(true); + ContextMenuParams params = + new ContextMenuParams( + 0, + ContextMenuDataMediaType.NONE, + new GURL(PAGE_URL), + GURL.emptyGURL(), + "", + GURL.emptyGURL(), + GURL.emptyGURL(), + "", + null, + false, + 0, + 0, + MenuSourceType.TOUCH, + false, + false, + /* additionalNavigationParams= */ null); + + int[] expected = {R.id.contextmenu_save_page}; + + initializePopulatorOnDesktop(ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params); + checkMenuOptions(expected); + + initializePopulatorOnDesktop(ChromeContextMenuPopulator.ContextMenuMode.CUSTOM_TAB, params); + checkMenuOptions(expected); + + initializePopulatorOnDesktop(ChromeContextMenuPopulator.ContextMenuMode.WEB_APP, params); + checkMenuOptions(expected); + + initializePopulatorOnDesktop( + ChromeContextMenuPopulator.ContextMenuMode.NETWORK_BOUND_TAB, params); + checkMenuOptions(expected); + } + + @Test + @SmallTest + @UiThreadTest + public void testPageNotOnDesktop() { + FirstRunStatus.setFirstRunFlowComplete(true); + ContextMenuParams params = + new ContextMenuParams( + 0, + ContextMenuDataMediaType.NONE, + new GURL(PAGE_URL), + GURL.emptyGURL(), + "", + GURL.emptyGURL(), + GURL.emptyGURL(), + "", + null, + false, + 0, + 0, + MenuSourceType.TOUCH, + false, + false, + /* additionalNavigationParams= */ null); + + int[] expected = null; + + initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params); + checkMenuOptions(expected); + + initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.CUSTOM_TAB, params); + checkMenuOptions(expected); + + initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.WEB_APP, params); + checkMenuOptions(expected); + + initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.NETWORK_BOUND_TAB, params); + checkMenuOptions(expected); + } + + @Test + @SmallTest + @UiThreadTest + public void testPageDownloadRestricted() { + FirstRunStatus.setFirstRunFlowComplete(true); + ContextMenuParams params = + new ContextMenuParams( + 0, + ContextMenuDataMediaType.NONE, + new GURL(PAGE_URL), + GURL.emptyGURL(), + "", + GURL.emptyGURL(), + GURL.emptyGURL(), + "", + null, + false, + 0, + 0, + MenuSourceType.TOUCH, + false, + false, + /* additionalNavigationParams= */ null); + DownloadUtils.setIsDownloadRestrictedByPolicyForTesting(true); + + int[] expected = {R.id.contextmenu_save_page}; + List<Integer> expected_disabled = Arrays.asList(R.id.contextmenu_save_page); + + initializePopulatorOnDesktop(ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params); + checkMenuOptions(expected_disabled, expected); + + initializePopulatorOnDesktop(ChromeContextMenuPopulator.ContextMenuMode.CUSTOM_TAB, params); + checkMenuOptions(expected_disabled, expected); + + initializePopulatorOnDesktop(ChromeContextMenuPopulator.ContextMenuMode.WEB_APP, params); + checkMenuOptions(expected_disabled, expected); + + initializePopulatorOnDesktop( + ChromeContextMenuPopulator.ContextMenuMode.NETWORK_BOUND_TAB, params); + checkMenuOptions(expected_disabled, expected); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java index 4994e5b..25c27d9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java
@@ -2255,8 +2255,8 @@ @SmallTest @Feature({"Preferences"}) @EnableFeatures(ChromeFeatureList.PERMISSION_SITE_SETTING_RADIO_BUTTON) - @DisabledTest(message = "crbug.com/402655848") public void testAllowGeolocation() { + LocationSettingsTestUtil.setSystemLocationSettingEnabled(true); new TwoStatePermissionTestCase( "Geolocation", SiteSettingsCategory.Type.DEVICE_LOCATION,
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index c3f033f..b5b629d 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -38,8 +38,8 @@ </if> <!-- About Page --> - <message name="IDS_SETTINGS_ABOUT_PAGE_BROWSER_VERSION" desc="The text label describing the version of the browser, example: Version 57.0.2937.0 (Developer Build) unknown (64-bit)"> - Version <ph name="PRODUCT_VERSION">$1<ex>15.0.865.0</ex></ph> (<ph name="PRODUCT_CHANNEL">$2<ex>Developer Build</ex></ph>) <ph name="PRODUCT_MODIFIER">$3</ph> <ph name="PRODUCT_VERSION_BITS">$4</ph> + <message name="IDS_SETTINGS_ABOUT_PAGE_BROWSER_VERSION" desc="The text label describing the version of the browser, example: Version 57.0.2937.0-r123456 (Developer Build) unknown (64-bit). The suffix of the version (eg. '-r123456') exists only in limited cases.)"> + Version <ph name="PRODUCT_VERSION">$1<ex>15.0.865.0</ex></ph><ph name="PRODUCT_VERSION_SUFFIX">$2<ex>-r123456</ex></ph> (<ph name="PRODUCT_CHANNEL">$3<ex>Developer Build</ex></ph>) <ph name="PRODUCT_MODIFIER">$4</ph> <ph name="PRODUCT_VERSION_BITS">$5</ph> </message> <message name="IDS_SETTINGS_ABOUT_PAGE_LEARN_MORE_UPDATE_ERRORS" desc="The accessibility label for a 'Learn more' link next to an error message about how an update has failed."> Learn more about fixing update errors @@ -482,15 +482,6 @@ <message name="IDS_SETTINGS_ADD_CREDIT_CARD_TITLE" desc="The title for the dialog that's shown when entering the information for a new card. This can be either credit, debit, or prepaid card."> Add card </message> - <message name="IDS_SETTINGS_MIGRATABLE_CARDS_LABEL" desc="Label for the field to migrate the locally cached credit card to Google Payments. Clicking this will upload migratable credit cards to Google Payments."> - Save cards in your Google Account - </message> - <message name="IDS_SETTINGS_SINGLE_MIGRATABLE_CARD_INFO" desc="Display text under the save cards to Google Pay label. This text indicates one of local cards can only be used on this device."> - Right now, you have one card that can only be used on this device - </message> - <message name="IDS_SETTINGS_MULTIPLE_MIGRATABLE_CARDS_INFO" desc="Display text under the save cards to Google Pay label. This text indicates user has multiple migratable cards on this device."> - Right now, you have some cards that can only be used on this device - </message> <message name="IDS_SETTINGS_REMOTE_PAYMENT_METHODS_LINK_LABEL" desc="The title and ARIA (accessibility) label for a link in chrome://settings/payments that opens the payment methods settings on https://pay.google.com. Note that the ARIA role and the link icon already convey that this is a link that will be opened when you click on it. Therefore, the message does not contain a verb."> Your payment methods in Google Pay </message>
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_BROWSER_VERSION.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_BROWSER_VERSION.png.sha1 new file mode 100644 index 0000000..62eea81f --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_ABOUT_PAGE_BROWSER_VERSION.png.sha1
@@ -0,0 +1 @@ +f6157996577a13ddb6aeb454c52e882544d92f1b \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_MIGRATABLE_CARDS_LABEL.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_MIGRATABLE_CARDS_LABEL.png.sha1 deleted file mode 100644 index 59c97cc..0000000 --- a/chrome/app/settings_strings_grdp/IDS_SETTINGS_MIGRATABLE_CARDS_LABEL.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -28cebf10631fde5ff58e13ab25039bfb9c917f43 \ No newline at end of file
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_MULTIPLE_MIGRATABLE_CARDS_INFO.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_MULTIPLE_MIGRATABLE_CARDS_INFO.png.sha1 deleted file mode 100644 index 59c97cc..0000000 --- a/chrome/app/settings_strings_grdp/IDS_SETTINGS_MULTIPLE_MIGRATABLE_CARDS_INFO.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -28cebf10631fde5ff58e13ab25039bfb9c917f43 \ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 7869b14..bf37fa5 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -8338,11 +8338,6 @@ FEATURE_VALUE_TYPE(ash::features::kUseWallpaperStagingUrl)}, #endif // BUILDFLAG(IS_CHROMEOS) - {"autofill-enable-card-product-name", - flag_descriptions::kAutofillEnableCardProductNameName, - flag_descriptions::kAutofillEnableCardProductNameDescription, kOsAll, - FEATURE_VALUE_TYPE(autofill::features::kAutofillEnableCardProductName)}, - #if BUILDFLAG(ENABLE_PAINT_PREVIEW) && BUILDFLAG(IS_ANDROID) {"paint-preview-demo", flag_descriptions::kPaintPreviewDemoName, flag_descriptions::kPaintPreviewDemoDescription, kOsAndroid, @@ -11352,12 +11347,6 @@ FEATURE_VALUE_TYPE( blink::features::kPartitionVisitedLinkDatabaseWithSelfLinks)}, - {"autofill-disable-local-card-migration", - flag_descriptions::kAutofillDisableLocalCardMigrationName, - flag_descriptions::kAutofillDisableLocalCardMigrationDescription, - kOsDesktop, - FEATURE_VALUE_TYPE( - autofill::features::kAutofillDisableLocalCardMigration)}, {"predictable-reported-quota", flag_descriptions::kPredictableReportedQuotaName, flag_descriptions::kPredictableReportedQuotaDescription, kOsAll, @@ -11932,6 +11921,15 @@ #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || // BUILDFLAG(IS_CHROME_OS) +#if BUILDFLAG(IS_CHROMEOS) + {"notebook-lm-app-preinstall", + flag_descriptions::kNotebookLmAppPreinstallName, + flag_descriptions::kNotebookLmAppPreinstallDescription, kOsCrOS, + FEATURE_VALUE_TYPE(chromeos::features::kNotebookLmAppPreinstall)}, +#endif // BUILDFLAG(IS_CHROMEOS) + + // Add new entries above this line. + // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/ai/ai_language_model.cc b/chrome/browser/ai/ai_language_model.cc index 690ce61..b117470 100644 --- a/chrome/browser/ai/ai_language_model.cc +++ b/chrome/browser/ai/ai_language_model.cc
@@ -437,7 +437,7 @@ current_response_)); if (context_->AddContextItem(std::move(copy)) == Context::SpaceReservationResult::kSpaceMadeAvailable) { - responder->OnContextOverflow(); + responder->OnQuotaOverflow(); } } responder->OnCompletion(blink::mojom::ModelExecutionContextInfo::New( @@ -478,7 +478,7 @@ } if (space_reserved == Context::SpaceReservationResult::kSpaceMadeAvailable) { - responder->OnContextOverflow(); + responder->OnQuotaOverflow(); } current_item.tokens = number_of_tokens; @@ -663,9 +663,9 @@ session_sampling_params.top_k, session_sampling_params.temperature)); } -void AILanguageModel::CountPromptTokens( +void AILanguageModel::MeasureInputUsage( const std::string& input, - mojo::PendingRemote<blink::mojom::AILanguageModelCountPromptTokensClient> + mojo::PendingRemote<blink::mojom::AILanguageModelMeasureInputUsageClient> client) { Context::ContextItem item; item.prompts.emplace_back( @@ -677,7 +677,7 @@ session_->GetExecutionInputSizeInTokens( request.read(), base::BindOnce( - [](mojo::Remote<blink::mojom::AILanguageModelCountPromptTokensClient> + [](mojo::Remote<blink::mojom::AILanguageModelMeasureInputUsageClient> client_remote, std::optional<uint32_t> result) { // TODO(crbug.com/351935691): Explicitly return an error. Consider @@ -685,7 +685,7 @@ // for Writing Assistance APIs. client_remote->OnResult(result.value_or(0)); }, - mojo::Remote<blink::mojom::AILanguageModelCountPromptTokensClient>( + mojo::Remote<blink::mojom::AILanguageModelMeasureInputUsageClient>( std::move(client)))); }
diff --git a/chrome/browser/ai/ai_language_model.h b/chrome/browser/ai/ai_language_model.h index 84138d2..9a616e49 100644 --- a/chrome/browser/ai/ai_language_model.h +++ b/chrome/browser/ai/ai_language_model.h
@@ -171,9 +171,9 @@ mojo::PendingRemote<blink::mojom::AIManagerCreateLanguageModelClient> client) override; void Destroy() override; - void CountPromptTokens( + void MeasureInputUsage( const std::string& input, - mojo::PendingRemote<blink::mojom::AILanguageModelCountPromptTokensClient> + mojo::PendingRemote<blink::mojom::AILanguageModelMeasureInputUsageClient> client) override; // Format the initial prompts, gets the token count, updates the session,
diff --git a/chrome/browser/ai/ai_language_model_unittest.cc b/chrome/browser/ai/ai_language_model_unittest.cc index d3f57abd..7d8dbfc8 100644 --- a/chrome/browser/ai/ai_language_model_unittest.cc +++ b/chrome/browser/ai/ai_language_model_unittest.cc
@@ -413,12 +413,12 @@ language_model, blink::mojom::AILanguageModelInstanceInfoPtr info) { EXPECT_TRUE(language_model); - EXPECT_EQ(info->max_tokens, + EXPECT_EQ(info->input_quota, AITestUtils::GetFakeTokenLimits().max_context_tokens); if (is_initial_prompts_or_system_prompt_set) { - EXPECT_GT(info->current_tokens, 0ul); + EXPECT_GT(info->input_usage, 0ul); } else { - EXPECT_EQ(info->current_tokens, 0ul); + EXPECT_EQ(info->input_usage, 0ul); } mock_session = mojo::Remote<blink::mojom::AILanguageModel>( std::move(language_model)); @@ -658,7 +658,7 @@ action); })); - EXPECT_CALL(mock_responder_2, OnContextOverflow()) + EXPECT_CALL(mock_responder_2, OnQuotaOverflow()) .Times(should_overflow_context ? 1 : 0); EXPECT_CALL(mock_responder_1, OnCompletion(_)) @@ -933,7 +933,7 @@ }); } -TEST_P(AILanguageModelTest, PromptSessionWithContextOverflow) { +TEST_P(AILanguageModelTest, PromptSessionWithQuotaOverflow) { RunPromptTest({.prompt_input = kTestPrompt, .expected_prompt = kExpectedFormattedTestPrompt, .should_overflow_context = true}); @@ -969,13 +969,13 @@ // Tests that the session will call `AddContext()` from the second prompt when // there is no context overflow. -TEST_P(AILanguageModelTest, PromptWithHistoryWithoutContextOverflow) { +TEST_P(AILanguageModelTest, PromptWithHistoryWithoutQuotaOverflow) { TestSessionAddContext(/*should_overflow_context=*/false); } // Tests that the session will not call `AddContext()` from the second prompt // when there is context overflow. -TEST_P(AILanguageModelTest, PromptWithHistoryWithContextOverflow) { +TEST_P(AILanguageModelTest, PromptWithHistoryWithQuotaOverflow) { TestSessionAddContext(/*should_overflow_context=*/true); }
diff --git a/chrome/browser/ai/ai_test_utils.h b/chrome/browser/ai/ai_test_utils.h index e275039..9186bd2 100644 --- a/chrome/browser/ai/ai_test_utils.h +++ b/chrome/browser/ai/ai_test_utils.h
@@ -50,7 +50,7 @@ OnCompletion, (blink::mojom::ModelExecutionContextInfoPtr context_info), (override)); - MOCK_METHOD(void, OnContextOverflow, (), (override)); + MOCK_METHOD(void, OnQuotaOverflow, (), (override)); private: mojo::Receiver<blink::mojom::ModelStreamingResponder> receiver_{this};
diff --git a/chrome/browser/ash/arc/intent_helper/arc_settings_service.cc b/chrome/browser/ash/arc/intent_helper/arc_settings_service.cc index 4273ae0..72ee8fe 100644 --- a/chrome/browser/ash/arc/intent_helper/arc_settings_service.cc +++ b/chrome/browser/ash/arc/intent_helper/arc_settings_service.cc
@@ -503,6 +503,12 @@ sync_proxy = true; } + // If the default network change is triggered by establishment of ARC VPN, we + // should not report back the proxy settings. Details: crbug.com/401900912 + if (network->GetVpnProviderType() == shill::kProviderArcVpn) { + sync_proxy = false; + } + if (!sync_proxy) return;
diff --git a/chrome/browser/ash/boca/DEPS b/chrome/browser/ash/boca/DEPS index 4028582..f9ffd37 100644 --- a/chrome/browser/ash/boca/DEPS +++ b/chrome/browser/ash/boca/DEPS
@@ -14,6 +14,7 @@ # Files residing in certain directories (e.g., //chrome/browser) are listed # individually. Other dependencies within //chrome are listed on a per- # directory basis. See //tools/chromeos/gen_deps.sh for details. + "+chrome/app/chrome_command_ids.h", "+chrome/browser/apps/app_service/launch_result_type.h", "+chrome/browser/ash/system_web_apps/system_web_app_manager.h", "+chrome/browser/enterprise/util/affiliation.h",
diff --git a/chrome/browser/ash/boca/on_task/BUILD.gn b/chrome/browser/ash/boca/on_task/BUILD.gn index dab316c..0a5dfce 100644 --- a/chrome/browser/ash/boca/on_task/BUILD.gn +++ b/chrome/browser/ash/boca/on_task/BUILD.gn
@@ -35,6 +35,7 @@ "//ash/webui/boca_ui", "//ash/webui/system_apps/public:system_web_app_type", "//base", + "//chrome/app:command_ids", "//chrome/browser/apps/app_service", # Explicitly depend on boca to get around with circular dependency on
diff --git a/chrome/browser/ash/boca/on_task/on_task_system_web_app_manager_impl.cc b/chrome/browser/ash/boca/on_task/on_task_system_web_app_manager_impl.cc index b405143..373217a 100644 --- a/chrome/browser/ash/boca/on_task/on_task_system_web_app_manager_impl.cc +++ b/chrome/browser/ash/boca/on_task/on_task_system_web_app_manager_impl.cc
@@ -10,6 +10,7 @@ #include "base/functional/callback_helpers.h" #include "base/location.h" #include "base/memory/weak_ptr.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/apps/app_service/launch_result_type.h" #include "chrome/browser/ash/boca/on_task/locked_session_window_tracker_factory.h" #include "chrome/browser/ash/boca/on_task/on_task_locked_session_window_tracker.h" @@ -157,9 +158,28 @@ } else { UnpinWindow(native_window); browser->command_controller()->LockedFullscreenStateChanged(); + DisableCommandsForDevTools(window_id); } } +void OnTaskSystemWebAppManagerImpl::DisableCommandsForDevTools( + SessionID window_id) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + Browser* const browser = GetBrowserWindowWithID(window_id); + if (!browser) { + return; + } + + // TODO(crbug.com/406052710): Allow dev channel to use commands for devtools. + chrome::BrowserCommandController* const command_controller = + browser->command_controller(); + command_controller->UpdateCommandEnabled(IDC_DEV_TOOLS, false); + command_controller->UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE, false); + command_controller->UpdateCommandEnabled(IDC_DEV_TOOLS_DEVICES, false); + command_controller->UpdateCommandEnabled(IDC_DEV_TOOLS_INSPECT, false); + command_controller->UpdateCommandEnabled(IDC_DEV_TOOLS_TOGGLE, false); +} + // TODO(b/367417612): Add unit test for this function. void OnTaskSystemWebAppManagerImpl::SetWindowTrackerForSystemWebAppWindow( SessionID window_id, @@ -236,6 +256,7 @@ if (!browser) { return; } + DisableCommandsForDevTools(window_id); // Configure the browser window for OnTask. This is required to ensure // downstream components (especially UI controls) are setup for locked mode
diff --git a/chrome/browser/ash/boca/on_task/on_task_system_web_app_manager_impl.h b/chrome/browser/ash/boca/on_task/on_task_system_web_app_manager_impl.h index aa4e137..b45f5104 100644 --- a/chrome/browser/ash/boca/on_task/on_task_system_web_app_manager_impl.h +++ b/chrome/browser/ash/boca/on_task/on_task_system_web_app_manager_impl.h
@@ -57,6 +57,8 @@ private: LockedSessionWindowTracker* GetWindowTracker(); + void DisableCommandsForDevTools(SessionID window_id); + raw_ptr<Profile> profile_; raw_ptr<LockedSessionWindowTracker> window_tracker_for_testing_;
diff --git a/chrome/browser/ash/boca/on_task/on_task_system_web_app_manager_impl_browsertest.cc b/chrome/browser/ash/boca/on_task/on_task_system_web_app_manager_impl_browsertest.cc index 98dd21f..33e0023 100644 --- a/chrome/browser/ash/boca/on_task/on_task_system_web_app_manager_impl_browsertest.cc +++ b/chrome/browser/ash/boca/on_task/on_task_system_web_app_manager_impl_browsertest.cc
@@ -8,6 +8,7 @@ #include "ash/webui/system_apps/public/system_web_app_type.h" #include "base/test/scoped_feature_list.h" #include "base/test/test_future.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/ash/boca/boca_manager.h" #include "chrome/browser/ash/boca/boca_manager_factory.h" #include "chrome/browser/ash/boca/on_task/locked_session_window_tracker_factory.h" @@ -16,6 +17,7 @@ #include "chrome/browser/platform_util.h" #include "chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_command_controller.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h" #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" @@ -357,5 +359,56 @@ EXPECT_EQ(boca_app_browser->tab_strip_model()->count(), 2); } +IN_PROC_BROWSER_TEST_F(OnTaskSystemWebAppManagerImplBrowserTest, + PreparingSWAWindowAndDevToolsCommandsDisabled) { + // Launch Boca app for testing purposes. + OnTaskSystemWebAppManagerImpl system_web_app_manager(profile()); + base::test::TestFuture<bool> launch_future; + system_web_app_manager.LaunchSystemWebAppAsync(launch_future.GetCallback()); + ASSERT_TRUE(launch_future.Get()); + Browser* const boca_app_browser = FindBocaSystemWebAppBrowser(); + ASSERT_THAT(boca_app_browser, NotNull()); + + // Verify that dev tools commands are disabled. + system_web_app_manager.PrepareSystemWebAppWindowForOnTask( + boca_app_browser->session_id(), /*close_bundle_content=*/false); + chrome::BrowserCommandController* const command_controller = + boca_app_browser->command_controller(); + EXPECT_FALSE(command_controller->IsCommandEnabled(IDC_DEV_TOOLS)); + EXPECT_FALSE(command_controller->IsCommandEnabled(IDC_DEV_TOOLS_CONSOLE)); + EXPECT_FALSE(command_controller->IsCommandEnabled(IDC_DEV_TOOLS_DEVICES)); + EXPECT_FALSE(command_controller->IsCommandEnabled(IDC_DEV_TOOLS_INSPECT)); + EXPECT_FALSE(command_controller->IsCommandEnabled(IDC_DEV_TOOLS_TOGGLE)); +} + +IN_PROC_BROWSER_TEST_F(OnTaskSystemWebAppManagerImplBrowserTest, + UnpinSystemWebAppWindowAndDevToolsCommandsDisabled) { + // Launch Boca app for testing purposes. + OnTaskSystemWebAppManagerImpl system_web_app_manager(profile()); + base::test::TestFuture<bool> launch_future; + system_web_app_manager.LaunchSystemWebAppAsync(launch_future.GetCallback()); + ASSERT_TRUE(launch_future.Get()); + Browser* const boca_app_browser = FindBocaSystemWebAppBrowser(); + ASSERT_THAT(boca_app_browser, NotNull()); + + system_web_app_manager.SetPinStateForSystemWebAppWindow( + /*pinned=*/true, boca_app_browser->session_id()); + content::RunAllTasksUntilIdle(); + ASSERT_TRUE(platform_util::IsBrowserLockedFullscreen(boca_app_browser)); + + // Unpin the Boca app and verify that dev tools commands are disabled. + system_web_app_manager.SetPinStateForSystemWebAppWindow( + /*pinned=*/false, boca_app_browser->session_id()); + content::RunAllTasksUntilIdle(); + EXPECT_FALSE(platform_util::IsBrowserLockedFullscreen(boca_app_browser)); + chrome::BrowserCommandController* const command_controller = + boca_app_browser->command_controller(); + EXPECT_FALSE(command_controller->IsCommandEnabled(IDC_DEV_TOOLS)); + EXPECT_FALSE(command_controller->IsCommandEnabled(IDC_DEV_TOOLS_CONSOLE)); + EXPECT_FALSE(command_controller->IsCommandEnabled(IDC_DEV_TOOLS_DEVICES)); + EXPECT_FALSE(command_controller->IsCommandEnabled(IDC_DEV_TOOLS_INSPECT)); + EXPECT_FALSE(command_controller->IsCommandEnabled(IDC_DEV_TOOLS_TOGGLE)); +} + } // namespace } // namespace ash::boca
diff --git a/chrome/browser/ash/extensions/default_app_order.cc b/chrome/browser/ash/extensions/default_app_order.cc index 00ea69b..f3e097b 100644 --- a/chrome/browser/ash/extensions/default_app_order.cc +++ b/chrome/browser/ash/extensions/default_app_order.cc
@@ -146,6 +146,8 @@ ash::kMessagesAppId, + ash::kNotebookLmAppId, + arc::kYoutubeAppId, extension_misc::kYoutubeAppId, ash::kYoutubeAppId,
diff --git a/chrome/browser/ash/main_parts/chrome_browser_main_parts_ash.cc b/chrome/browser/ash/main_parts/chrome_browser_main_parts_ash.cc index 60d0cdb6..ffe1d84 100644 --- a/chrome/browser/ash/main_parts/chrome_browser_main_parts_ash.cc +++ b/chrome/browser/ash/main_parts/chrome_browser_main_parts_ash.cc
@@ -287,6 +287,7 @@ #include "ui/base/ime/ash/ime_keyboard.h" #include "ui/base/ime/ash/input_method_manager.h" #include "ui/base/ime/ash/input_method_util.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/base/pointer/pointer_device.h" #include "ui/base/ui_base_features.h" #include "ui/events/ash/pref_names.h" @@ -1055,7 +1056,8 @@ // CoralController depends on machine_learning::ServiceConnection, so needs to // be initialized after it. if (features::IsCoralFeatureEnabled()) { - Shell::Get()->coral_controller()->Initialize(); + Shell::Get()->coral_controller()->Initialize( + l10n_util::GetLanguage(g_browser_process->GetApplicationLocale())); } // Needs to be initialized after crosapi_manager_.
diff --git a/chrome/browser/background/extensions/background_application_list_model.cc b/chrome/browser/background/extensions/background_application_list_model.cc index eff3152..4d9199ff 100644 --- a/chrome/browser/background/extensions/background_application_list_model.cc +++ b/chrome/browser/background/extensions/background_application_list_model.cc
@@ -66,7 +66,7 @@ Application(BackgroundApplicationListModel* model, const Extension* an_extension); - virtual ~Application(); + ~Application(); // Invoked when a request icon is available. void OnImageLoaded(const gfx::Image& image);
diff --git a/chrome/browser/commerce/price_change/android/java/res/drawable/price_change_module_favicon_background.xml b/chrome/browser/commerce/price_change/android/java/res/drawable/price_change_module_favicon_background.xml index 453c10b6..e80b91c6 100644 --- a/chrome/browser/commerce/price_change/android/java/res/drawable/price_change_module_favicon_background.xml +++ b/chrome/browser/commerce/price_change/android/java/res/drawable/price_change_module_favicon_background.xml
@@ -4,12 +4,10 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<org.chromium.components.browser_ui.widget.SurfaceColorDrawable - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools" - tools:ignore="UnusedResources" +<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" - app:surfaceElevation="@dimen/home_surface_ui_background_color_elevation"> + xmlns:tools="http://schemas.android.com/tools" + tools:ignore="UnusedResources"> + <solid android:color="@color/home_surface_ui_background_color"/> <corners android:radius="@dimen/price_change_module_favicon_background_radius"/> -</org.chromium.components.browser_ui.widget.SurfaceColorDrawable> \ No newline at end of file +</shape> \ No newline at end of file
diff --git a/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/InstantMessageDelegateImpl.java b/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/InstantMessageDelegateImpl.java index 52a3030..2d4aaaf5 100644 --- a/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/InstantMessageDelegateImpl.java +++ b/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/InstantMessageDelegateImpl.java
@@ -62,16 +62,19 @@ public final TabGroupModelFilter tabGroupModelFilter; public final DataSharingNotificationManager dataSharingNotificationManager; public final DataSharingTabManager dataSharingTabManager; + public final Supplier<Boolean> isActiveWindowSupplier; public AttachedWindowInfo( WindowAndroid windowAndroid, TabGroupModelFilter tabGroupModelFilter, DataSharingNotificationManager dataSharingNotificationManager, - DataSharingTabManager dataSharingTabManager) { + DataSharingTabManager dataSharingTabManager, + Supplier<Boolean> isActiveWindowSupplier) { this.windowAndroid = windowAndroid; this.tabGroupModelFilter = tabGroupModelFilter; this.dataSharingNotificationManager = dataSharingNotificationManager; this.dataSharingTabManager = dataSharingTabManager; + this.isActiveWindowSupplier = isActiveWindowSupplier; } } @@ -119,12 +122,14 @@ * @param tabGroupModelFilter The tab model and group filter for the given window. * @param dataSharingNotificationManager Used to send notifications for a particular window. * @param dataSharingTabManager Used to display share UI. + * @param isActiveWindowSupplier Used to find out the last focused window as a fallback option. */ public void attachWindow( @NonNull WindowAndroid windowAndroid, @NonNull TabGroupModelFilter tabGroupModelFilter, @NonNull DataSharingNotificationManager dataSharingNotificationManager, - @NonNull DataSharingTabManager dataSharingTabManager) { + @NonNull DataSharingTabManager dataSharingTabManager, + @NonNull Supplier<Boolean> isActiveWindowSupplier) { assert windowAndroid != null; assert tabGroupModelFilter != null; assert !tabGroupModelFilter.getTabModel().isIncognito(); @@ -135,7 +140,8 @@ windowAndroid, tabGroupModelFilter, dataSharingNotificationManager, - dataSharingTabManager)); + dataSharingTabManager, + isActiveWindowSupplier)); } /** @@ -149,7 +155,13 @@ @Override public void displayInstantaneousMessage( InstantMessage message, Callback<Boolean> successCallback) { - @Nullable AttachedWindowInfo attachedWindowInfo = getAttachedWindowInfo(message); + // For TAB_GROUP_REMOVED messages, the group is gone and there is no attached window info. + // Hence using the last focused window is our best bet. + boolean fallbackToLastFocusedWindow = + message.collaborationEvent == CollaborationEvent.TAB_GROUP_REMOVED; + @Nullable + AttachedWindowInfo attachedWindowInfo = + getAttachedWindowInfo(message, fallbackToLastFocusedWindow); if (attachedWindowInfo == null) { successCallback.onResult(false); return; @@ -202,7 +214,8 @@ } } - private AttachedWindowInfo getAttachedWindowInfo(InstantMessage message) { + private AttachedWindowInfo getAttachedWindowInfo( + InstantMessage message, boolean fallbackToLastFocusedWindow) { if (mAttachList.size() == 0) { return null; } @@ -220,6 +233,14 @@ return info; } + if (fallbackToLastFocusedWindow) { + for (AttachedWindowInfo info : mAttachList) { + if (info.isActiveWindowSupplier.get()) { + return info; + } + } + } + // Tab group was deleted or window not active. return null; }
diff --git a/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/InstantMessageDelegateImplUnitTest.java b/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/InstantMessageDelegateImplUnitTest.java index 68b4edd..e2da548 100644 --- a/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/InstantMessageDelegateImplUnitTest.java +++ b/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/InstantMessageDelegateImplUnitTest.java
@@ -105,6 +105,7 @@ @Mock private Callback<Boolean> mSuccessCallback; @Mock private DataSharingNotificationManager mDataSharingNotificationManager; @Mock private DataSharingTabManager mDataSharingTabManager; + @Mock private Supplier<Boolean> mIsActiveWindowSupplier; @Mock private TabGroupSyncService mTabGroupSyncService; @Mock private Bitmap mAvatarBitmap; @Mock private Tab mTab1; @@ -139,6 +140,7 @@ when(mTabGroupModelFilter.tabGroupExists(TAB_GROUP_ID)).thenReturn(true); when(mTabGroupModelFilter.getTabModel()).thenReturn(mTabModel); when(mTabModel.getTabCreator()).thenReturn(mTabCreator); + when(mIsActiveWindowSupplier.get()).thenReturn(false); mSyncedGroupTestHelper = new SyncedGroupTestHelper(mTabGroupSyncService); SavedTabGroup group = mSyncedGroupTestHelper.newTabGroup(SYNC_GROUP_ID1, TAB_GROUP_ID); @@ -152,7 +154,8 @@ mWindowAndroid, mTabGroupModelFilter, mDataSharingNotificationManager, - mDataSharingTabManager); + mDataSharingTabManager, + mIsActiveWindowSupplier); } private InstantMessage newInstantMessage(@CollaborationEvent int collaborationEvent) { @@ -339,6 +342,33 @@ } @Test + public void testCollaborationRemoved_NoLastFocusedWindow() { + when(mTabGroupModelFilter.tabGroupExists(TAB_GROUP_ID)).thenReturn(false); + mDelegate.displayInstantaneousMessage( + newInstantMessage(CollaborationEvent.TAB_GROUP_REMOVED), mSuccessCallback); + + verify(mManagedMessageDispatcher, never()).enqueueWindowScopedMessage(any(), anyBoolean()); + } + + @Test + public void testCollaborationRemoved_LastFocusedWindow() { + when(mTabGroupModelFilter.tabGroupExists(TAB_GROUP_ID)).thenReturn(false); + when(mIsActiveWindowSupplier.get()).thenReturn(true); + mDelegate.displayInstantaneousMessage( + newInstantMessage(CollaborationEvent.TAB_GROUP_REMOVED), mSuccessCallback); + + verify(mManagedMessageDispatcher) + .enqueueWindowScopedMessage(mPropertyModelCaptor.capture(), anyBoolean()); + PropertyModel propertyModel = mPropertyModelCaptor.getValue(); + @MessageIdentifier int messageIdentifier = propertyModel.get(MESSAGE_IDENTIFIER); + assertEquals(MessageIdentifier.COLLABORATION_REMOVED, messageIdentifier); + assertEquals(MESSAGE_CONTENT_1, propertyModel.get(TITLE)); + + propertyModel.get(ON_FULLY_VISIBLE).onResult(true); + verify(mSuccessCallback).onResult(true); + } + + @Test public void testSystemNotification() { InstantMessage message = newInstantMessage(CollaborationEvent.COLLABORATION_MEMBER_ADDED); message.level = InstantNotificationLevel.SYSTEM;
diff --git a/chrome/browser/devtools/BUILD.gn b/chrome/browser/devtools/BUILD.gn index 9fc47257..22055e17 100644 --- a/chrome/browser/devtools/BUILD.gn +++ b/chrome/browser/devtools/BUILD.gn
@@ -143,6 +143,8 @@ sources += [ "aida_client.cc", "aida_client.h", + "devtools_availability_checker.cc", + "devtools_availability_checker.h", "devtools_contents_resizing_strategy.cc", "devtools_contents_resizing_strategy.h", "devtools_embedder_message_dispatcher.cc",
diff --git a/chrome/browser/devtools/chrome_devtools_manager_delegate.cc b/chrome/browser/devtools/chrome_devtools_manager_delegate.cc index b1c91f9..f61d3618 100644 --- a/chrome/browser/devtools/chrome_devtools_manager_delegate.cc +++ b/chrome/browser/devtools/chrome_devtools_manager_delegate.cc
@@ -18,6 +18,7 @@ #include "chrome/browser/devtools/chrome_devtools_session.h" #include "chrome/browser/devtools/device/android_device_manager.h" #include "chrome/browser/devtools/device/tcp_device_provider.h" +#include "chrome/browser/devtools/devtools_availability_checker.h" #include "chrome/browser/devtools/devtools_browser_context_manager.h" #include "chrome/browser/devtools/devtools_window.h" #include "chrome/browser/devtools/protocol/target_handler.h" @@ -62,8 +63,6 @@ #if BUILDFLAG(IS_CHROMEOS) #include "ash/constants/ash_switches.h" #include "chromeos/constants/chromeos_features.h" -#include "chromeos/constants/pref_names.h" -#include "components/prefs/pref_service.h" #endif using content::DevToolsAgentHost; @@ -149,26 +148,6 @@ return true; } -policy::DeveloperToolsPolicyHandler::Availability GetDevToolsAvailability( - Profile* profile) { - using Availability = policy::DeveloperToolsPolicyHandler::Availability; - Availability availability = - policy::DeveloperToolsPolicyHandler::GetEffectiveAvailability(profile); -#if BUILDFLAG(IS_CHROMEOS) - // On ChromeOS disable dev tools for captive portal signin windows to prevent - // them from being used for general navigation. - if (availability != Availability::kDisallowed) { - const PrefService::Preference* const captive_portal_pref = - profile->GetPrefs()->FindPreference( - chromeos::prefs::kCaptivePortalSignin); - if (captive_portal_pref && captive_portal_pref->GetValue()->GetBool()) { - availability = Availability::kDisallowed; - } - } -#endif - return availability; -} - ChromeDevToolsManagerDelegate* g_instance; } // namespace @@ -307,7 +286,7 @@ ? process_manager->GetExtensionForRenderFrameHost(rfh) : nullptr; if (extension || !web_app::AreWebAppsEnabled(profile)) { - return AllowInspection(profile, extension); + return IsInspectionAllowed(profile, extension); } if (auto* web_app_provider = @@ -319,104 +298,11 @@ if (app_id) { const auto* web_app = web_app_provider->registrar_unsafe().GetAppById(app_id.value()); - return AllowInspection(profile, web_app); + return IsInspectionAllowed(profile, web_app); } } // |extension| is always nullptr here. - return AllowInspection(profile, extension); -} - -// static -bool ChromeDevToolsManagerDelegate::AllowInspection( - Profile* profile, - content::WebContents* web_contents) { - const extensions::Extension* extension = nullptr; - if (web_contents) { - if (auto* process_manager = extensions::ProcessManager::Get( - web_contents->GetBrowserContext())) { - extension = process_manager->GetExtensionForWebContents(web_contents); - } - if (extension || !web_app::AreWebAppsEnabled(profile)) { - return AllowInspection(profile, extension); - } - - const webapps::AppId* app_id = - web_app::WebAppTabHelper::GetAppId(web_contents); - auto* web_app_provider = - web_app::WebAppProvider::GetForWebContents(web_contents); - if (app_id && web_app_provider) { - const web_app::WebApp* web_app = - web_app_provider->registrar_unsafe().GetAppById(*app_id); - return AllowInspection(profile, web_app); - } - } - // |extension| is always nullptr here. - return AllowInspection(profile, extension); -} - -// static -bool ChromeDevToolsManagerDelegate::AllowInspection( - Profile* profile, - const extensions::Extension* extension) { - using Availability = policy::DeveloperToolsPolicyHandler::Availability; - Availability availability; - if (extension) { - availability = - policy::DeveloperToolsPolicyHandler::GetEffectiveAvailability(profile); - } else { - // Perform additional checks for browser windows (extension == null). - availability = GetDevToolsAvailability(profile); - } - switch (availability) { - case Availability::kDisallowed: - return false; - case Availability::kAllowed: - return true; - case Availability::kDisallowedForForceInstalledExtensions: - if (!extension) { - return true; - } - if (extensions::Manifest::IsPolicyLocation(extension->location())) { - return false; - } - // We also disallow inspecting component extensions, but only for managed - // profiles. - if (extensions::Manifest::IsComponentLocation(extension->location()) && - profile->GetProfilePolicyConnector()->IsManaged()) { - return false; - } - return true; - default: - NOTREACHED() << "Unknown developer tools policy"; - } -} - -// static -bool ChromeDevToolsManagerDelegate::AllowInspection( - Profile* profile, - const web_app::WebApp* web_app) { - using Availability = policy::DeveloperToolsPolicyHandler::Availability; - Availability availability = - policy::DeveloperToolsPolicyHandler::GetEffectiveAvailability(profile); - switch (availability) { - case Availability::kDisallowed: - return false; - case Availability::kAllowed: - return true; - case Availability::kDisallowedForForceInstalledExtensions: { - if (!web_app) { - return true; - } - // DevTools should be blocked for Kiosk apps and policy-installed IWAs. - if (web_app->IsKioskInstalledApp() || - web_app->IsIwaPolicyInstalledApp()) { - return false; - } - return true; - } - default: - NOTREACHED() << "Unknown developer tools policy"; - } + return IsInspectionAllowed(profile, extension); } void ChromeDevToolsManagerDelegate::ClientAttached(
diff --git a/chrome/browser/devtools/chrome_devtools_manager_delegate.h b/chrome/browser/devtools/chrome_devtools_manager_delegate.h index 9b46c21..5ae87cc 100644 --- a/chrome/browser/devtools/chrome_devtools_manager_delegate.h +++ b/chrome/browser/devtools/chrome_devtools_manager_delegate.h
@@ -19,18 +19,9 @@ #include "net/base/host_port_pair.h" class ChromeDevToolsSession; -class Profile; class ScopedKeepAlive; using RemoteLocations = std::set<net::HostPortPair>; -namespace extensions { -class Extension; -} - -namespace web_app { -class WebApp; -} - class ChromeDevToolsManagerDelegate : public content::DevToolsManagerDelegate { public: static const char kTypeApp[]; @@ -48,20 +39,6 @@ static ChromeDevToolsManagerDelegate* GetInstance(); void UpdateDeviceDiscovery(); - // |web_contents| may be null, in which case this function just checks - // the settings for |profile|. - static bool AllowInspection(Profile* profile, - content::WebContents* web_contents); - - // |extension| may be null, in which case this function just checks - // the settings for |profile|. - static bool AllowInspection(Profile* profile, - const extensions::Extension* extension); - - // |web_app| may be null, in which case this function just checks - // the settings for |profile|. - static bool AllowInspection(Profile* profile, const web_app::WebApp* web_app); - // Resets |device_manager_|. void ResetAndroidDeviceManagerForTesting();
diff --git a/chrome/browser/devtools/device/cast_device_provider.cc b/chrome/browser/devtools/device/cast_device_provider.cc index eb0b6a0..19cab0f9 100644 --- a/chrome/browser/devtools/device/cast_device_provider.cc +++ b/chrome/browser/devtools/device/cast_device_provider.cc
@@ -98,7 +98,7 @@ scoped_refptr<base::SingleThreadTaskRunner> runner) : provider_(provider), runner_(runner) {} - virtual ~DeviceListerDelegate() = default; + ~DeviceListerDelegate() = default; void StartDiscovery() { // This must be called on the UI thread; ServiceDiscoverySharedClient and
diff --git a/chrome/browser/devtools/devtools_availability_checker.cc b/chrome/browser/devtools/devtools_availability_checker.cc new file mode 100644 index 0000000..64a37b4 --- /dev/null +++ b/chrome/browser/devtools/devtools_availability_checker.cc
@@ -0,0 +1,140 @@ +// Copyright 2025 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/devtools/devtools_availability_checker.h" + +#include "chrome/browser/policy/developer_tools_policy_handler.h" +#include "chrome/browser/policy/profile_policy_connector.h" +#include "chrome/browser/profiles/profile.h" +#include "content/public/browser/web_contents.h" +#include "extensions/browser/extension_host.h" +#include "extensions/browser/process_manager.h" + +#if !BUILDFLAG(IS_ANDROID) +#include "chrome/browser/web_applications/web_app.h" +#include "chrome/browser/web_applications/web_app_provider.h" +#include "chrome/browser/web_applications/web_app_registrar.h" +#include "chrome/browser/web_applications/web_app_tab_helper.h" +#include "chrome/browser/web_applications/web_app_utils.h" +#endif + +#if BUILDFLAG(IS_CHROMEOS) +#include "chromeos/constants/pref_names.h" +#include "components/prefs/pref_service.h" +#endif + +namespace { + +policy::DeveloperToolsPolicyHandler::Availability GetDevToolsAvailability( + Profile* profile) { + using Availability = policy::DeveloperToolsPolicyHandler::Availability; + Availability availability = + policy::DeveloperToolsPolicyHandler::GetEffectiveAvailability(profile); +#if BUILDFLAG(IS_CHROMEOS) + // On ChromeOS disable dev tools for captive portal signin windows to prevent + // them from being used for general navigation. + if (availability != Availability::kDisallowed) { + const PrefService::Preference* const captive_portal_pref = + profile->GetPrefs()->FindPreference( + chromeos::prefs::kCaptivePortalSignin); + if (captive_portal_pref && captive_portal_pref->GetValue()->GetBool()) { + availability = Availability::kDisallowed; + } + } +#endif + return availability; +} + +} // namespace + +bool IsInspectionAllowed(Profile* profile, content::WebContents* web_contents) { + const extensions::Extension* extension = nullptr; + if (web_contents) { + if (auto* process_manager = extensions::ProcessManager::Get( + web_contents->GetBrowserContext())) { + extension = process_manager->GetExtensionForWebContents(web_contents); + } + if (extension) { + return IsInspectionAllowed(profile, extension); + } +#if !BUILDFLAG(IS_ANDROID) + if (!web_app::AreWebAppsEnabled(profile)) { + return IsInspectionAllowed(profile, extension); + } + const webapps::AppId* app_id = + web_app::WebAppTabHelper::GetAppId(web_contents); + auto* web_app_provider = + web_app::WebAppProvider::GetForWebContents(web_contents); + if (app_id && web_app_provider) { + const web_app::WebApp* web_app = + web_app_provider->registrar_unsafe().GetAppById(*app_id); + return IsInspectionAllowed(profile, web_app); + } +#endif + } + // |extension| is always nullptr here. + return IsInspectionAllowed(profile, extension); +} + +bool IsInspectionAllowed(Profile* profile, + const extensions::Extension* extension) { + using Availability = policy::DeveloperToolsPolicyHandler::Availability; + Availability availability; + if (extension) { + availability = + policy::DeveloperToolsPolicyHandler::GetEffectiveAvailability(profile); + } else { + // Perform additional checks for browser windows (extension == null). + availability = GetDevToolsAvailability(profile); + } + switch (availability) { + case Availability::kDisallowed: + return false; + case Availability::kAllowed: + return true; + case Availability::kDisallowedForForceInstalledExtensions: + if (!extension) { + return true; + } + if (extensions::Manifest::IsPolicyLocation(extension->location())) { + return false; + } + // We also disallow inspecting component extensions, but only for managed + // profiles. + if (extensions::Manifest::IsComponentLocation(extension->location()) && + profile->GetProfilePolicyConnector()->IsManaged()) { + return false; + } + return true; + default: + NOTREACHED() << "Unknown developer tools policy"; + } +} + +#if !BUILDFLAG(IS_ANDROID) +bool IsInspectionAllowed(Profile* profile, const web_app::WebApp* web_app) { + using Availability = policy::DeveloperToolsPolicyHandler::Availability; + Availability availability = + policy::DeveloperToolsPolicyHandler::GetEffectiveAvailability(profile); + switch (availability) { + case Availability::kDisallowed: + return false; + case Availability::kAllowed: + return true; + case Availability::kDisallowedForForceInstalledExtensions: { + if (!web_app) { + return true; + } + // DevTools should be blocked for Kiosk apps and policy-installed IWAs. + if (web_app->IsKioskInstalledApp() || + web_app->IsIwaPolicyInstalledApp()) { + return false; + } + return true; + } + default: + NOTREACHED() << "Unknown developer tools policy"; + } +} +#endif
diff --git a/chrome/browser/devtools/devtools_availability_checker.h b/chrome/browser/devtools/devtools_availability_checker.h new file mode 100644 index 0000000..de45b25 --- /dev/null +++ b/chrome/browser/devtools/devtools_availability_checker.h
@@ -0,0 +1,35 @@ +// Copyright 2025 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_DEVTOOLS_DEVTOOLS_AVAILABILITY_CHECKER_H_ +#define CHROME_BROWSER_DEVTOOLS_DEVTOOLS_AVAILABILITY_CHECKER_H_ + +class Profile; + +namespace content { +class WebContents; +} + +namespace extensions { +class Extension; +} + +namespace web_app { +class WebApp; +} + +// |web_contents| may be null, in which case this function just checks +// the settings for |profile|. +bool IsInspectionAllowed(Profile* profile, content::WebContents* web_contents); + +// |extension| may be null, in which case this function just checks +// the settings for |profile|. +bool IsInspectionAllowed(Profile* profile, + const extensions::Extension* extension); + +// |web_app| may be null, in which case this function just checks +// the settings for |profile|. +bool IsInspectionAllowed(Profile* profile, const web_app::WebApp* web_app); + +#endif // CHROME_BROWSER_DEVTOOLS_DEVTOOLS_AVAILABILITY_CHECKER_H_
diff --git a/chrome/browser/devtools/devtools_window.cc b/chrome/browser/devtools/devtools_window.cc index efadef22..7148b35 100644 --- a/chrome/browser/devtools/devtools_window.cc +++ b/chrome/browser/devtools/devtools_window.cc
@@ -27,7 +27,7 @@ #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/certificate_viewer.h" -#include "chrome/browser/devtools/chrome_devtools_manager_delegate.h" +#include "chrome/browser/devtools/devtools_availability_checker.h" #include "chrome/browser/devtools/devtools_eye_dropper.h" #include "chrome/browser/devtools/features.h" #include "chrome/browser/devtools/process_sharing_infobar_delegate.h" @@ -1162,12 +1162,7 @@ // broken there. See https://crbug.com/514551 for context. if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode)) return false; -#if BUILDFLAG(IS_ANDROID) - NOTIMPLEMENTED(); - return false; -#else - return ChromeDevToolsManagerDelegate::AllowInspection(profile, web_contents); -#endif + return IsInspectionAllowed(profile, web_contents); } // static
diff --git a/chrome/browser/extensions/BUILD.gn b/chrome/browser/extensions/BUILD.gn index 26a07b6..6ba620b 100644 --- a/chrome/browser/extensions/BUILD.gn +++ b/chrome/browser/extensions/BUILD.gn
@@ -727,6 +727,7 @@ "update_install_gate.h", "updater/extension_updater.cc", "updater/extension_updater.h", + "updater/extension_updater_delegate.h", "warning_badge_service.cc", "warning_badge_service.h", "warning_badge_service_factory.cc",
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 989b531..182bd54 100644 --- a/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc +++ b/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc
@@ -44,12 +44,10 @@ #include "components/autofill/core/browser/data_model/payments/credit_card.h" #include "components/autofill/core/browser/data_model/payments/iban.h" #include "components/autofill/core/browser/field_types.h" -#include "components/autofill/core/browser/form_import/form_data_importer.h" #include "components/autofill/core/browser/foundations/browser_autofill_manager.h" #include "components/autofill/core/browser/metrics/address_save_metrics.h" #include "components/autofill/core/browser/metrics/payments/mandatory_reauth_metrics.h" #include "components/autofill/core/browser/payments/credit_card_access_manager.h" -#include "components/autofill/core/browser/payments/local_card_migration_manager.h" #include "components/autofill/core/browser/payments/mandatory_reauth_manager.h" #include "components/autofill/core/browser/payments/payments_autofill_client.h" #include "components/autofill/core/browser/payments/virtual_card_enrollment_flow.h" @@ -580,54 +578,6 @@ } //////////////////////////////////////////////////////////////////////////////// -// AutofillPrivateMigrateCreditCardsFunction - -ExtensionFunction::ResponseAction -AutofillPrivateMigrateCreditCardsFunction::Run() { - autofill::ContentAutofillClient* client = - autofill::ContentAutofillClient::FromWebContents(GetSenderWebContents()); - if (!client) { - return RespondNow(Error(kErrorDataUnavailable)); - } - - // If `paydm` is not available, then don't do anything since - // `LocalCardMigrationManager` depends on it containing current data. - if (PaymentsDataManager* paydm = payments_data_manager(); - !paydm || !paydm->is_payments_data_loaded()) { - return RespondNow(Error(kErrorDataUnavailable)); - } - - // Get the BrowserAutofillManager from the web contents. - // BrowserAutofillManager has a pointer to its AutofillClient which owns - // FormDataImporter. - autofill::AutofillManager* autofill_manager = - GetBrowserAutofillManager(GetSenderWebContents()); - if (!autofill_manager) { - return RespondNow(Error(kErrorDataUnavailable)); - } - - // Get the FormDataImporter from AutofillClient. FormDataImporter owns - // LocalCardMigrationManager. - autofill::FormDataImporter* form_data_importer = - autofill_manager->client().GetFormDataImporter(); - if (!form_data_importer) - return RespondNow(Error(kErrorDataUnavailable)); - - // Get local card migration manager from form data importer. - autofill::LocalCardMigrationManager* local_card_migration_manager = - form_data_importer->local_card_migration_manager(); - if (!local_card_migration_manager) - return RespondNow(Error(kErrorDataUnavailable)); - - // Since we already check the migration requirements on the settings page, we - // don't check the migration requirements again. - local_card_migration_manager->GetMigratableCreditCards(); - local_card_migration_manager->AttemptToOfferLocalCardMigration( - /*is_from_settings_page=*/true); - return RespondNow(NoArguments()); -} - -//////////////////////////////////////////////////////////////////////////////// // AutofillPrivateLogServerCardLinkClickedFunction ExtensionFunction::ResponseAction
diff --git a/chrome/browser/extensions/api/autofill_private/autofill_private_api.h b/chrome/browser/extensions/api/autofill_private/autofill_private_api.h index f1f9a64..4cfa555a 100644 --- a/chrome/browser/extensions/api/autofill_private/autofill_private_api.h +++ b/chrome/browser/extensions/api/autofill_private/autofill_private_api.h
@@ -196,24 +196,6 @@ ResponseAction Run() override; }; -class AutofillPrivateMigrateCreditCardsFunction - : public AutofillPrivateExtensionFunction { - public: - AutofillPrivateMigrateCreditCardsFunction() = default; - AutofillPrivateMigrateCreditCardsFunction( - const AutofillPrivateMigrateCreditCardsFunction&) = delete; - AutofillPrivateMigrateCreditCardsFunction& operator=( - const AutofillPrivateMigrateCreditCardsFunction&) = delete; - DECLARE_EXTENSION_FUNCTION("autofillPrivate.migrateCreditCards", - AUTOFILLPRIVATE_MIGRATECREDITCARDS) - - protected: - ~AutofillPrivateMigrateCreditCardsFunction() override = default; - - // ExtensionFunction overrides. - ResponseAction Run() override; -}; - class AutofillPrivateLogServerCardLinkClickedFunction : public AutofillPrivateExtensionFunction { public:
diff --git a/chrome/browser/extensions/api/autofill_private/autofill_private_apitest.cc b/chrome/browser/extensions/api/autofill_private/autofill_private_apitest.cc index aaec0a13..3efde81 100644 --- a/chrome/browser/extensions/api/autofill_private/autofill_private_apitest.cc +++ b/chrome/browser/extensions/api/autofill_private/autofill_private_apitest.cc
@@ -392,10 +392,6 @@ << message_; } -IN_PROC_BROWSER_TEST_F(AutofillPrivateApiTest, MigrateCreditCards) { - EXPECT_TRUE(RunAutofillSubtest("migrateCreditCards")) << message_; -} - IN_PROC_BROWSER_TEST_F(AutofillPrivateApiTest, AddVirtualCard) { autofill::TestPersonalDataManager& personal_data_manager = autofill_client()->GetPersonalDataManager();
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc index c97d25d..e7e471c4 100644 --- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc +++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
@@ -11,6 +11,7 @@ #include "extensions/browser/extension_registry_factory.h" #include "extensions/browser/process_manager_factory.h" #include "extensions/browser/warning_service_factory.h" +#include "ui/base/clipboard/file_info.h" #if !BUILDFLAG(IS_ANDROID) #include "chrome/browser/extensions/account_extension_tracker.h" @@ -124,16 +125,16 @@ return path_iter->second; } -void DeveloperPrivateAPI::SetDraggedPath(content::WebContents* web_contents, - const base::FilePath& dragged_path) { +void DeveloperPrivateAPI::SetDraggedFile(content::WebContents* web_contents, + const ui::FileInfo& dragged_file) { WebContentsData* data = GetOrCreateWebContentsData(web_contents); - data->dragged_path = dragged_path; + data->dragged_file = dragged_file; } -base::FilePath DeveloperPrivateAPI::GetDraggedPath( +ui::FileInfo DeveloperPrivateAPI::GetDraggedFile( content::WebContents* web_contents) const { const WebContentsData* data = GetWebContentsData(web_contents); - return data ? data->dragged_path : base::FilePath(); + return data ? data->dragged_file : ui::FileInfo(); } void DeveloperPrivateAPI::RegisterNotifications() {
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.h b/chrome/browser/extensions/api/developer_private/developer_private_api.h index f66df121..7c3753e 100644 --- a/chrome/browser/extensions/api/developer_private/developer_private_api.h +++ b/chrome/browser/extensions/api/developer_private/developer_private_api.h
@@ -9,6 +9,7 @@ #include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/event_router.h" #include "extensions/browser/pref_types.h" +#include "ui/base/clipboard/file_info.h" class Profile; @@ -54,12 +55,12 @@ base::FilePath GetUnpackedPath(content::WebContents* web_contents, const UnpackedRetryId& id) const; - // Sets the dragged path for the given |web_contents|. - void SetDraggedPath(content::WebContents* web_contents, - const base::FilePath& path); + // Sets the dragged file for the given |web_contents|. + void SetDraggedFile(content::WebContents* web_contents, + const ui::FileInfo& file); - // Returns the dragged path for the given |web_contents|, if one exists. - base::FilePath GetDraggedPath(content::WebContents* web_contents) const; + // Returns the dragged file for the given |web_contents|, if one exists. + ui::FileInfo GetDraggedFile(content::WebContents* web_contents) const; // KeyedService implementation void Shutdown() override; @@ -100,8 +101,8 @@ // WebContents B. IdToPathMap allowed_unpacked_paths; - // The last dragged path for the WebContents. - base::FilePath dragged_path; + // The last dragged file for the WebContents. + ui::FileInfo dragged_file; }; friend class BrowserContextKeyedAPIFactory<DeveloperPrivateAPI>;
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc index eebf45c..952856c 100644 --- a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc +++ b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
@@ -1333,8 +1333,9 @@ "manifest_version": 2 })"); base::FilePath path = dir.UnpackedPath(); + ui::FileInfo file(path, path.BaseName()); api::DeveloperPrivateNotifyDragInstallInProgressFunction:: - SetDropPathForTesting(&path); + SetDropFileForTesting(&file); { auto function = base::MakeRefCounted< @@ -1371,8 +1372,9 @@ // was not a directory. In theory, this shouldn't happen (the JS validates the // file), but it could in the case of a compromised renderer, JS bug, etc. base::FilePath invalid_path = path.AppendASCII("manifest.json"); + ui::FileInfo invalid_file(invalid_path, invalid_path.BaseName()); api::DeveloperPrivateNotifyDragInstallInProgressFunction:: - SetDropPathForTesting(&invalid_path); + SetDropFileForTesting(&invalid_file); { auto function = base::MakeRefCounted< api::DeveloperPrivateNotifyDragInstallInProgressFunction>(); @@ -1403,7 +1405,7 @@ // Cleanup. api::DeveloperPrivateNotifyDragInstallInProgressFunction:: - SetDropPathForTesting(nullptr); + SetDropFileForTesting(nullptr); } // Test developerPrivate.requestFileSource. @@ -1733,8 +1735,8 @@ std::unique_ptr<content::WebContents> web_contents( content::WebContentsTester::CreateTestWebContents(profile(), nullptr)); - DeveloperPrivateAPI::Get(profile())->SetDraggedPath(web_contents.get(), - crx_path); + DeveloperPrivateAPI::Get(profile())->SetDraggedFile( + web_contents.get(), ui::FileInfo(crx_path, crx_path.BaseName())); auto function = base::MakeRefCounted<api::DeveloperPrivateInstallDroppedFileFunction>(); @@ -1758,8 +1760,8 @@ std::unique_ptr<content::WebContents> web_contents( content::WebContentsTester::CreateTestWebContents(profile(), nullptr)); - DeveloperPrivateAPI::Get(profile())->SetDraggedPath(web_contents.get(), - script_path); + DeveloperPrivateAPI::Get(profile())->SetDraggedFile( + web_contents.get(), ui::FileInfo(script_path, script_path.BaseName())); auto function = base::MakeRefCounted<api::DeveloperPrivateInstallDroppedFileFunction>(); @@ -2224,8 +2226,8 @@ std::unique_ptr<content::WebContents> web_contents( content::WebContentsTester::CreateTestWebContents(profile(), nullptr)); - DeveloperPrivateAPI::Get(profile())->SetDraggedPath(web_contents.get(), - zip_path); + DeveloperPrivateAPI::Get(profile())->SetDraggedFile( + web_contents.get(), ui::FileInfo(zip_path, zip_path.BaseName())); auto function = base::MakeRefCounted<api::DeveloperPrivateInstallDroppedFileFunction>();
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_functions_desktop.cc b/chrome/browser/extensions/api/developer_private/developer_private_functions_desktop.cc index e47f3cee..305f025 100644 --- a/chrome/browser/extensions/api/developer_private/developer_private_functions_desktop.cc +++ b/chrome/browser/extensions/api/developer_private/developer_private_functions_desktop.cc
@@ -112,6 +112,7 @@ #include "storage/browser/file_system/isolated_context.h" #include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/re2/src/re2/re2.h" +#include "ui/base/clipboard/file_info.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/native_widget_types.h" #include "ui/shell_dialogs/selected_file_info.h" @@ -125,16 +126,10 @@ namespace { constexpr char kUnpackedAppsFolder[] = "apps_target"; -base::FilePath* g_drop_path_for_testing = nullptr; - ExtensionService* GetExtensionService(content::BrowserContext* context) { return ExtensionSystem::Get(context)->extension_service(); } -ExtensionRegistrar* GetExtensionRegistrar(content::BrowserContext* context) { - return ExtensionRegistrar::Get(context); -} - std::string ReadFileToString(const base::FilePath& path) { std::string data; // This call can fail, but it doesn't matter for our purposes. If it fails, @@ -416,13 +411,13 @@ if (params->options && params->options->use_dragged_path && *params->options->use_dragged_path) { DeveloperPrivateAPI* api = DeveloperPrivateAPI::Get(browser_context()); - base::FilePath path = api->GetDraggedPath(web_contents); - if (path.empty()) { + ui::FileInfo file = api->GetDraggedFile(web_contents); + if (file.path.empty()) { return RespondNow(Error("No dragged path")); } AddRef(); // Balanced in Finish. - StartFileLoad(path); + StartFileLoad(file.path); return RespondLater(); } @@ -531,99 +526,6 @@ Release(); // Balanced in Run(). } -DeveloperPrivateInstallDroppedFileFunction:: - DeveloperPrivateInstallDroppedFileFunction() = default; -DeveloperPrivateInstallDroppedFileFunction:: - ~DeveloperPrivateInstallDroppedFileFunction() = default; - -ExtensionFunction::ResponseAction -DeveloperPrivateInstallDroppedFileFunction::Run() { - content::WebContents* web_contents = GetSenderWebContents(); - if (!web_contents) { - return RespondNow(Error(kCouldNotFindWebContentsError)); - } - - DeveloperPrivateAPI* api = DeveloperPrivateAPI::Get(browser_context()); - base::FilePath path = api->GetDraggedPath(web_contents); - if (path.empty()) { - return RespondNow(Error("No dragged path")); - } - - if (path.MatchesExtension(FILE_PATH_LITERAL(".zip"))) { - ExtensionService* service = GetExtensionService(browser_context()); - ExtensionRegistrar* registrar = GetExtensionRegistrar(browser_context()); - ZipFileInstaller::Create(GetExtensionFileTaskRunner(), - MakeRegisterInExtensionServiceCallback(service)) - ->InstallZipFileToUnpackedExtensionsDir( - path, registrar->unpacked_install_directory()); - } else { - auto prompt = std::make_unique<ExtensionInstallPrompt>(web_contents); - scoped_refptr<CrxInstaller> crx_installer = - CrxInstaller::Create(browser_context(), std::move(prompt)); - crx_installer->set_error_on_unsupported_requirements(true); - crx_installer->set_off_store_install_allow_reason( - CrxInstaller::OffStoreInstallAllowedFromSettingsPage); - crx_installer->set_install_immediately(true); - - if (path.MatchesExtension(FILE_PATH_LITERAL(".user.js"))) { - crx_installer->InstallUserScript(path, net::FilePathToFileURL(path)); - } else if (path.MatchesExtension(FILE_PATH_LITERAL(".crx"))) { - crx_installer->InstallCrx(path); - } else { - EXTENSION_FUNCTION_VALIDATE(false); - } - } - - // TODO(devlin): We could optionally wait to return until we validate whether - // the load succeeded or failed. For now, that's unnecessary, and just adds - // complexity. - return RespondNow(NoArguments()); -} - -DeveloperPrivateNotifyDragInstallInProgressFunction:: - DeveloperPrivateNotifyDragInstallInProgressFunction() = default; -DeveloperPrivateNotifyDragInstallInProgressFunction:: - ~DeveloperPrivateNotifyDragInstallInProgressFunction() = default; - -ExtensionFunction::ResponseAction -DeveloperPrivateNotifyDragInstallInProgressFunction::Run() { - content::WebContents* web_contents = GetSenderWebContents(); - if (!web_contents) { - return RespondNow(Error(kCouldNotFindWebContentsError)); - } - - const base::FilePath* file_path = nullptr; - if (g_drop_path_for_testing) { - file_path = g_drop_path_for_testing; - } else { - content::DropData* drop_data = web_contents->GetDropData(); - if (!drop_data) { - return RespondNow(Error("No current drop data.")); - } - - if (drop_data->filenames.empty()) { - return RespondNow(Error("No files being dragged.")); - } - - const ui::FileInfo& file_info = drop_data->filenames.front(); - file_path = &file_info.path; - } - - DCHECK(file_path); - // Note(devlin): we don't do further validation that the file is a directory - // here. This is validated in the JS, but if that fails, then trying to load - // the file as an unpacked extension will also fail (reasonably gracefully). - DeveloperPrivateAPI::Get(browser_context()) - ->SetDraggedPath(web_contents, *file_path); - return RespondNow(NoArguments()); -} - -// static -void DeveloperPrivateNotifyDragInstallInProgressFunction::SetDropPathForTesting( - base::FilePath* file_path) { - g_drop_path_for_testing = file_path; -} - void DeveloperPrivatePackDirectoryFunction::OnPackSuccess( const base::FilePath& crx_file, const base::FilePath& pem_file) {
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_functions_desktop.h b/chrome/browser/extensions/api/developer_private/developer_private_functions_desktop.h index f442273e9..b55e084 100644 --- a/chrome/browser/extensions/api/developer_private/developer_private_functions_desktop.h +++ b/chrome/browser/extensions/api/developer_private/developer_private_functions_desktop.h
@@ -186,46 +186,6 @@ std::optional<ui::SelectedFileInfo> selected_file_for_testing_; }; -class DeveloperPrivateInstallDroppedFileFunction - : public DeveloperPrivateAPIFunction { - public: - DECLARE_EXTENSION_FUNCTION("developerPrivate.installDroppedFile", - DEVELOPERPRIVATE_INSTALLDROPPEDFILE) - DeveloperPrivateInstallDroppedFileFunction(); - - DeveloperPrivateInstallDroppedFileFunction( - const DeveloperPrivateInstallDroppedFileFunction&) = delete; - DeveloperPrivateInstallDroppedFileFunction& operator=( - const DeveloperPrivateInstallDroppedFileFunction&) = delete; - - private: - ~DeveloperPrivateInstallDroppedFileFunction() override; - - // ExtensionFunction: - ResponseAction Run() override; -}; - -class DeveloperPrivateNotifyDragInstallInProgressFunction - : public DeveloperPrivateAPIFunction { - public: - DECLARE_EXTENSION_FUNCTION("developerPrivate.notifyDragInstallInProgress", - DEVELOPERPRIVATE_NOTIFYDRAGINSTALLINPROGRESS) - - DeveloperPrivateNotifyDragInstallInProgressFunction(); - - DeveloperPrivateNotifyDragInstallInProgressFunction( - const DeveloperPrivateNotifyDragInstallInProgressFunction&) = delete; - DeveloperPrivateNotifyDragInstallInProgressFunction& operator=( - const DeveloperPrivateNotifyDragInstallInProgressFunction&) = delete; - - ResponseAction Run() override; - - static void SetDropPathForTesting(base::FilePath* file_path); - - private: - ~DeveloperPrivateNotifyDragInstallInProgressFunction() override; -}; - class DeveloperPrivateChoosePathFunction : public DeveloperPrivateAPIFunction, public ui::SelectFileDialog::Listener {
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_functions_shared.cc b/chrome/browser/extensions/api/developer_private/developer_private_functions_shared.cc index d8ea148..e860980 100644 --- a/chrome/browser/extensions/api/developer_private/developer_private_functions_shared.cc +++ b/chrome/browser/extensions/api/developer_private/developer_private_functions_shared.cc
@@ -9,24 +9,32 @@ #include "chrome/browser/extensions/api/developer_private/developer_private_event_router.h" #include "chrome/browser/extensions/api/developer_private/extension_info_generator.h" #include "chrome/browser/extensions/api/developer_private/profile_info_generator.h" +#include "chrome/browser/extensions/crx_installer.h" #include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/extensions/permissions/permissions_updater.h" #include "chrome/browser/extensions/permissions/scripting_permissions_modifier.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/supervised_user/supervised_user_browser_utils.h" #include "chrome/browser/ui/safety_hub/menu_notification_service_factory.h" +#include "content/public/common/drop_data.h" #include "extensions/browser/extension_prefs.h" +#include "extensions/browser/extension_registrar.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/permissions_manager.h" #include "extensions/browser/ui_util.h" #include "extensions/browser/user_script_manager.h" #include "extensions/common/permissions/permissions_data.h" +#include "net/base/filename_util.h" +#include "ui/base/clipboard/file_info.h" #if !BUILDFLAG(IS_ANDROID) +#include "chrome/browser/extensions/chrome_zipfile_installer.h" +#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/install_verifier.h" #include "chrome/browser/extensions/manifest_v2_experiment_manager.h" #include "chrome/browser/extensions/permissions/site_permissions_helper.h" +#include "extensions/browser/extension_file_task_runner.h" #include "extensions/browser/ui_util.h" #endif // !BUILDFLAG(IS_ANDROID) @@ -38,6 +46,8 @@ const char kCannotUpdateChildAccountProfileSettingsError[] = "Cannot change settings for a child account profile."; +ui::FileInfo* g_drop_file_for_testing = nullptr; + std::optional<URLPattern> ParseRuntimePermissionsPattern( const std::string& pattern_str) { constexpr int kValidRuntimePermissionSchemes = URLPattern::SCHEME_HTTP | @@ -195,6 +205,45 @@ } } +// Sets the dropped path to DeveloperPrivateAPI. +base::expected<void, std::string> SetDroppedPath( + content::WebContents* web_contents, + content::BrowserContext* context) { + const ui::FileInfo* file_info = nullptr; + if (g_drop_file_for_testing) { + file_info = g_drop_file_for_testing; + } else { + content::DropData* drop_data = web_contents->GetDropData(); + if (!drop_data) { + return base::unexpected{"No current drop data."}; + } + + if (drop_data->filenames.empty()) { + return base::unexpected{"No files being dropped."}; + } + + file_info = &drop_data->filenames.front(); + } + + DCHECK(file_info); + // Note(devlin): we don't do further validation that the file is a directory + // here. This is validated in the JS, but if that fails, then trying to load + // the file as an unpacked extension will also fail (reasonably gracefully). + + DeveloperPrivateAPI::Get(context)->SetDraggedFile(web_contents, *file_info); + return base::ok(); +} + +// Returns whether the filename perceived to the user ends with the extension. +// Just using `path` is not enough because it might be a content URI that +// doesn't have the `display_name` as a suffix. +bool MatchesExtension(ui::FileInfo& file_info, + base::FilePath::StringViewType extension) { + return file_info.display_name.empty() + ? file_info.path.MatchesExtension(extension) + : file_info.display_name.MatchesExtension(extension); +} + } // namespace namespace api { @@ -441,6 +490,99 @@ return RespondNow(NoArguments()); } +DeveloperPrivateInstallDroppedFileFunction:: + DeveloperPrivateInstallDroppedFileFunction() = default; +DeveloperPrivateInstallDroppedFileFunction:: + ~DeveloperPrivateInstallDroppedFileFunction() = default; + +ExtensionFunction::ResponseAction +DeveloperPrivateInstallDroppedFileFunction::Run() { + content::WebContents* web_contents = GetSenderWebContents(); + if (!web_contents) { + return RespondNow(Error(kCouldNotFindWebContentsError)); + } + +#if BUILDFLAG(IS_ANDROID) + base::expected<void, std::string> result = + SetDroppedPath(web_contents, browser_context()); + if (!result.has_value()) { + return RespondNow(Error(result.error())); + } +#endif // BUILDFLAG(IS_ANDROID) + + DeveloperPrivateAPI* api = DeveloperPrivateAPI::Get(browser_context()); + ui::FileInfo file = api->GetDraggedFile(web_contents); + if (file.path.empty()) { + return RespondNow(Error("No dragged path")); + } + + if (MatchesExtension(file, FILE_PATH_LITERAL(".zip"))) { +#if BUILDFLAG(IS_ANDROID) + return RespondNow(Error("zip file is not yet supported on android")); +#else + ExtensionService* service = + ExtensionSystem::Get(browser_context())->extension_service(); + ExtensionRegistrar* registrar = ExtensionRegistrar::Get(browser_context()); + ZipFileInstaller::Create(GetExtensionFileTaskRunner(), + MakeRegisterInExtensionServiceCallback(service)) + ->InstallZipFileToUnpackedExtensionsDir( + file.path, registrar->unpacked_install_directory()); +#endif // BUILDFLAG(IS_ANDROID) + } else { + auto prompt = std::make_unique<ExtensionInstallPrompt>(web_contents); + scoped_refptr<CrxInstaller> crx_installer = + CrxInstaller::Create(browser_context(), std::move(prompt)); + crx_installer->set_error_on_unsupported_requirements(true); + crx_installer->set_off_store_install_allow_reason( + CrxInstaller::OffStoreInstallAllowedFromSettingsPage); + crx_installer->set_install_immediately(true); + + if (MatchesExtension(file, FILE_PATH_LITERAL(".user.js"))) { + crx_installer->InstallUserScript(file.path, + net::FilePathToFileURL(file.path)); + } else if (MatchesExtension(file, FILE_PATH_LITERAL(".crx"))) { + crx_installer->InstallCrx(file.path); + } else { + EXTENSION_FUNCTION_VALIDATE(false); + } + } + + // TODO(devlin): We could optionally wait to return until we validate whether + // the load succeeded or failed. For now, that's unnecessary, and just adds + // complexity. + return RespondNow(NoArguments()); +} + +DeveloperPrivateNotifyDragInstallInProgressFunction:: + DeveloperPrivateNotifyDragInstallInProgressFunction() = default; +DeveloperPrivateNotifyDragInstallInProgressFunction:: + ~DeveloperPrivateNotifyDragInstallInProgressFunction() = default; + +ExtensionFunction::ResponseAction +DeveloperPrivateNotifyDragInstallInProgressFunction::Run() { +// Drop data is available only on drop on android. +#if !BUILDFLAG(IS_ANDROID) + content::WebContents* web_contents = GetSenderWebContents(); + if (!web_contents) { + return RespondNow(Error(kCouldNotFindWebContentsError)); + } + + const base::expected<void, std::string> result = + SetDroppedPath(web_contents, browser_context()); + if (!result.has_value()) { + return RespondNow(Error(result.error())); + } +#endif // !BUILDFLAG(IS_ANDROID) + + return RespondNow(NoArguments()); +} + +// static +void DeveloperPrivateNotifyDragInstallInProgressFunction::SetDropFileForTesting( + ui::FileInfo* file_info) { + g_drop_file_for_testing = file_info; +} + DeveloperPrivateDeleteExtensionErrorsFunction:: ~DeveloperPrivateDeleteExtensionErrorsFunction() = default;
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_functions_shared.h b/chrome/browser/extensions/api/developer_private/developer_private_functions_shared.h index 6433eb2..91177c2 100644 --- a/chrome/browser/extensions/api/developer_private/developer_private_functions_shared.h +++ b/chrome/browser/extensions/api/developer_private/developer_private_functions_shared.h
@@ -9,6 +9,7 @@ #include "chrome/common/extensions/api/developer_private.h" #include "extensions/browser/extension_function.h" #include "extensions/common/extension.h" +#include "ui/base/clipboard/file_info.h" namespace extensions::api { @@ -159,6 +160,46 @@ ResponseAction Run() override; }; +class DeveloperPrivateInstallDroppedFileFunction + : public DeveloperPrivateAPIFunction { + public: + DECLARE_EXTENSION_FUNCTION("developerPrivate.installDroppedFile", + DEVELOPERPRIVATE_INSTALLDROPPEDFILE) + DeveloperPrivateInstallDroppedFileFunction(); + + DeveloperPrivateInstallDroppedFileFunction( + const DeveloperPrivateInstallDroppedFileFunction&) = delete; + DeveloperPrivateInstallDroppedFileFunction& operator=( + const DeveloperPrivateInstallDroppedFileFunction&) = delete; + + private: + ~DeveloperPrivateInstallDroppedFileFunction() override; + + // ExtensionFunction: + ResponseAction Run() override; +}; + +class DeveloperPrivateNotifyDragInstallInProgressFunction + : public DeveloperPrivateAPIFunction { + public: + DECLARE_EXTENSION_FUNCTION("developerPrivate.notifyDragInstallInProgress", + DEVELOPERPRIVATE_NOTIFYDRAGINSTALLINPROGRESS) + + DeveloperPrivateNotifyDragInstallInProgressFunction(); + + DeveloperPrivateNotifyDragInstallInProgressFunction( + const DeveloperPrivateNotifyDragInstallInProgressFunction&) = delete; + DeveloperPrivateNotifyDragInstallInProgressFunction& operator=( + const DeveloperPrivateNotifyDragInstallInProgressFunction&) = delete; + + ResponseAction Run() override; + + static void SetDropFileForTesting(ui::FileInfo* file_info); + + private: + ~DeveloperPrivateNotifyDragInstallInProgressFunction() override; +}; + class DeveloperPrivateDeleteExtensionErrorsFunction : public DeveloperPrivateAPIFunction { public:
diff --git a/chrome/browser/extensions/api/developer_private/inspectable_views_finder.cc b/chrome/browser/extensions/api/developer_private/inspectable_views_finder.cc index b8f859e3..461441b 100644 --- a/chrome/browser/extensions/api/developer_private/inspectable_views_finder.cc +++ b/chrome/browser/extensions/api/developer_private/inspectable_views_finder.cc
@@ -6,7 +6,7 @@ #include <set> -#include "chrome/browser/devtools/chrome_devtools_manager_delegate.h" +#include "chrome/browser/devtools/devtools_availability_checker.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/extensions/api/developer_private.h" #include "content/public/browser/render_frame_host.h" @@ -105,8 +105,9 @@ const Extension& extension, bool is_enabled) { ViewList result; - if (!ChromeDevToolsManagerDelegate::AllowInspection(profile_, &extension)) + if (!IsInspectionAllowed(profile_, &extension)) { return result; + } GetViewsForExtensionForProfile( extension, profile_, is_enabled, false, &result); if (profile_->HasPrimaryOTRProfile()) {
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index e4469235..54e5f0f 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -952,8 +952,6 @@ settings_api::PrefType::kBoolean; (*s_allowlist)[ash::prefs::kLobsterEnterprisePolicySettings] = settings_api::PrefType::kNumber; - (*s_allowlist)[ash::prefs::kSunfishEnabled] = - settings_api::PrefType::kBoolean; (*s_allowlist)[ash::prefs::kScannerEnabled] = settings_api::PrefType::kBoolean; (*s_allowlist)[ash::prefs::kScannerEnterprisePolicyAllowed] =
diff --git a/chrome/browser/extensions/api/storage/sync_storage_backend.h b/chrome/browser/extensions/api/storage/sync_storage_backend.h index 4c446457..2f725040 100644 --- a/chrome/browser/extensions/api/storage/sync_storage_backend.h +++ b/chrome/browser/extensions/api/storage/sync_storage_backend.h
@@ -47,8 +47,8 @@ ~SyncStorageBackend() override; - virtual value_store::ValueStore* GetStorage(const ExtensionId& extension_id); - virtual void DeleteStorage(const ExtensionId& extension_id); + value_store::ValueStore* GetStorage(const ExtensionId& extension_id); + void DeleteStorage(const ExtensionId& extension_id); // syncer::SyncableService implementation. void WaitUntilReadyToSync(base::OnceClosure done) override;
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index 55c3fb4..4b2fd6f 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc
@@ -401,6 +401,8 @@ extension_registrar_->EnabledReloadableExtensions(); } +// TODO(crbug.com/404943906): Migrate CreateUpdateInstaller() out of +// ExtensionService. scoped_refptr<CrxInstaller> ExtensionService::CreateUpdateInstaller( const CRXFileInfo& file, bool file_ownership_passed) {
diff --git a/chrome/browser/extensions/extension_service.h b/chrome/browser/extensions/extension_service.h index 49e1fbd..ae5c93d 100644 --- a/chrome/browser/extensions/extension_service.h +++ b/chrome/browser/extensions/extension_service.h
@@ -30,6 +30,7 @@ #include "chrome/browser/extensions/forced_extensions/force_installed_tracker.h" #include "chrome/browser/extensions/omaha_attributes_handler.h" #include "chrome/browser/extensions/safe_browsing_verdict_handler.h" +#include "chrome/browser/extensions/updater/extension_updater_delegate.h" #include "chrome/browser/profiles/profile_manager_observer.h" #include "chrome/browser/upgrade_detector/upgrade_observer.h" #include "components/sync/model/string_ordinal.h" @@ -87,13 +88,6 @@ public: virtual ~ExtensionServiceInterface() = default; - // Creates an CrxInstaller to update an extension. - // Returns null if an update is not possible. Eg: system shutdown or extension - // doesn't exist. - virtual scoped_refptr<CrxInstaller> CreateUpdateInstaller( - const CRXFileInfo& file, - bool file_ownership_passed) = 0; - // Returns an update for an extension with the specified id, if installation // of that update was previously delayed because the extension was in use. If // no updates are pending for the extension returns NULL. @@ -145,6 +139,7 @@ // Manages installed and running Chromium extensions. An instance is shared // between normal and incognito profiles. class ExtensionService : public ExtensionServiceInterface, + public ExtensionUpdaterDelegate, public content::RenderProcessHostCreationObserver, public content::RenderProcessHostObserver, public Blocklist::Observer, @@ -174,9 +169,6 @@ // ExtensionServiceInterface implementation. // - scoped_refptr<CrxInstaller> CreateUpdateInstaller( - const CRXFileInfo& file, - bool file_ownership_passed) override; void UnloadExtension(const std::string& extension_id, UnloadedExtensionReason reason) override; void RemoveComponentExtension(const std::string& extension_id) override; @@ -190,6 +182,11 @@ void CheckForUpdatesSoon() override; base::WeakPtr<ExtensionServiceInterface> AsWeakPtr() override; + // ExtensionUpdaterDelegate: + scoped_refptr<CrxInstaller> CreateUpdateInstaller( + const CRXFileInfo& file, + bool file_ownership_passed) override; + // ExtensionManagement::Observer implementation: void OnExtensionManagementSettingsChanged() override;
diff --git a/chrome/browser/extensions/keyed_services/chrome_browser_context_keyed_service_factories.cc b/chrome/browser/extensions/keyed_services/chrome_browser_context_keyed_service_factories.cc index c719271b..db5f567 100644 --- a/chrome/browser/extensions/keyed_services/chrome_browser_context_keyed_service_factories.cc +++ b/chrome/browser/extensions/keyed_services/chrome_browser_context_keyed_service_factories.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/extensions/keyed_services/chrome_browser_context_keyed_service_factories.h" #include "build/build_config.h" +#include "chrome/browser/extensions/blocklist_factory.h" #include "chrome/browser/extensions/delayed_install_manager_factory.h" #include "chrome/browser/extensions/error_console/error_console_factory.h" #include "chrome/browser/extensions/extension_allowlist_factory.h" @@ -47,6 +48,7 @@ namespace chrome_extensions { void EnsureChromeBrowserContextKeyedServiceFactoriesBuilt() { + extensions::BlocklistFactory::GetInstance(); extensions::DelayedInstallManagerFactory::GetInstance(); extensions::ErrorConsoleFactory::GetInstance(); extensions::ExtensionAllowlistFactory::GetInstance();
diff --git a/chrome/browser/extensions/test_extension_service.cc b/chrome/browser/extensions/test_extension_service.cc index bb6dd90..4e4ce53 100644 --- a/chrome/browser/extensions/test_extension_service.cc +++ b/chrome/browser/extensions/test_extension_service.cc
@@ -13,13 +13,6 @@ TestExtensionService::~TestExtensionService() = default; -scoped_refptr<extensions::CrxInstaller> -TestExtensionService::CreateUpdateInstaller(const extensions::CRXFileInfo& file, - bool file_ownership_passed) { - ADD_FAILURE(); - return nullptr; -} - const Extension* TestExtensionService::GetPendingExtensionUpdate( const std::string& id) const { ADD_FAILURE();
diff --git a/chrome/browser/extensions/test_extension_service.h b/chrome/browser/extensions/test_extension_service.h index ee1f80a..d54f6e8 100644 --- a/chrome/browser/extensions/test_extension_service.h +++ b/chrome/browser/extensions/test_extension_service.h
@@ -13,7 +13,6 @@ namespace extensions { class CWSInfoServiceInterface; -class CrxInstaller; class Extension; } // namespace extensions @@ -26,9 +25,6 @@ ~TestExtensionService() override; // ExtensionServiceInterface implementation. - scoped_refptr<extensions::CrxInstaller> CreateUpdateInstaller( - const extensions::CRXFileInfo& file, - bool file_ownership_passed) override; const extensions::Extension* GetPendingExtensionUpdate( const std::string& extension_id) const override; bool FinishDelayedInstallationIfReady(const std::string& extension_id,
diff --git a/chrome/browser/extensions/updater/extension_updater.cc b/chrome/browser/extensions/updater/extension_updater.cc index a36bd883..8a3daf1 100644 --- a/chrome/browser/extensions/updater/extension_updater.cc +++ b/chrome/browser/extensions/updater/extension_updater.cc
@@ -29,9 +29,9 @@ #include "chrome/browser/extensions/crx_installer.h" #include "chrome/browser/extensions/delayed_install_manager.h" #include "chrome/browser/extensions/extension_management.h" -#include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/forced_extensions/install_stage_tracker.h" #include "chrome/browser/extensions/pending_extension_manager.h" +#include "chrome/browser/extensions/updater/extension_updater_delegate.h" #include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h" #include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h" #include "chrome/browser/profiles/profile.h" @@ -158,14 +158,14 @@ ExtensionUpdater::InProgressCheck::~InProgressCheck() = default; ExtensionUpdater::ExtensionUpdater( - ExtensionServiceInterface* service, + ExtensionUpdaterDelegate* delegate, ExtensionPrefs* extension_prefs, PrefService* prefs, Profile* profile, int frequency_seconds, ExtensionCache* cache, const ExtensionDownloader::Factory& downloader_factory) - : service_(service), + : delegate_(delegate), downloader_factory_(downloader_factory), frequency_(base::Seconds(frequency_seconds)), extension_prefs_(extension_prefs), @@ -201,7 +201,7 @@ DCHECK(!alive_); // If these are NULL, then that means we've been called after Stop() // has been called. - DCHECK(service_); + DCHECK(delegate_); DCHECK(extension_prefs_); DCHECK(prefs_); DCHECK(profile_); @@ -221,7 +221,7 @@ void ExtensionUpdater::Stop() { weak_ptr_factory_.InvalidateWeakPtrs(); alive_ = false; - service_ = nullptr; + delegate_ = nullptr; extension_prefs_ = nullptr; prefs_ = nullptr; profile_ = nullptr; @@ -807,11 +807,9 @@ VLOG(2) << "updating " << crx_file.info.extension_id << " with " << crx_file.info.path.value(); - // The ExtensionService is now responsible for cleaning up the temp file - // at |crx_file.info.path|. - // TODO(crbug.com/404943906): Migrate CreateUpdateInstaller() out of - // ExtensionService and call the new location here. - scoped_refptr<CrxInstaller> installer = service_->CreateUpdateInstaller( + // The delegate is now responsible for cleaning up the temp file at + // `crx_file.info.path`. + scoped_refptr<CrxInstaller> installer = delegate_->CreateUpdateInstaller( crx_file.info, crx_file.file_ownership_passed); if (installer) { // If the crx file passes the expectations from the update manifest, this
diff --git a/chrome/browser/extensions/updater/extension_updater.h b/chrome/browser/extensions/updater/extension_updater.h index 4068187..c76b396 100644 --- a/chrome/browser/extensions/updater/extension_updater.h +++ b/chrome/browser/extensions/updater/extension_updater.h
@@ -43,9 +43,9 @@ class ExtensionPrefs; class ExtensionRegistrar; class ExtensionRegistry; -class ExtensionServiceInterface; class ExtensionSet; struct ExtensionUpdateCheckParams; +class ExtensionUpdaterDelegate; class ExtensionUpdaterTest; // A class for doing auto-updates of installed Extensions. Used like this: @@ -113,10 +113,10 @@ ~ScopedSkipScheduledCheckForTest(); }; - // Holds a pointer to the passed |service|, using it for querying installed - // extensions and installing updated ones. The |frequency_seconds| parameter - // controls how often update checks are scheduled. - ExtensionUpdater(ExtensionServiceInterface* service, + // Holds a pointer to the passed `delegate`, using it for installing updated + // extensions. The `frequency_seconds` parameter controls how often update + // checks are scheduled. + ExtensionUpdater(ExtensionUpdaterDelegate* delegate, ExtensionPrefs* extension_prefs, PrefService* prefs, Profile* profile, @@ -315,8 +315,8 @@ // Whether Start() has been called but not Stop(). bool alive_ = false; - // Pointer back to the service that owns this ExtensionUpdater. - raw_ptr<ExtensionServiceInterface> service_ = nullptr; + // Delegate used for extension installs. + raw_ptr<ExtensionUpdaterDelegate> delegate_ = nullptr; // A closure passed into the ExtensionUpdater to teach it how to construct // new ExtensionDownloader instances.
diff --git a/chrome/browser/extensions/updater/extension_updater_delegate.h b/chrome/browser/extensions/updater/extension_updater_delegate.h new file mode 100644 index 0000000..f856d43 --- /dev/null +++ b/chrome/browser/extensions/updater/extension_updater_delegate.h
@@ -0,0 +1,31 @@ +// Copyright 2025 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_EXTENSIONS_UPDATER_EXTENSION_UPDATER_DELEGATE_H_ +#define CHROME_BROWSER_EXTENSIONS_UPDATER_EXTENSION_UPDATER_DELEGATE_H_ + +#include "base/memory/scoped_refptr.h" + +namespace extensions { + +struct CRXFileInfo; +class CrxInstaller; + +// Delegate for ExtensionUpdater. Exists to break circular dependencies with +// ExtensionService. Has its own header file to avoid increasing the number of +// transitive includes from extension_service.h. +class ExtensionUpdaterDelegate { + public: + // Creates an CrxInstaller to update an extension. Returns null if an update + // is not possible. Eg: system shutdown or extension doesn't exist. + virtual scoped_refptr<CrxInstaller> CreateUpdateInstaller( + const CRXFileInfo& file, + bool file_ownership_passed) = 0; + + virtual ~ExtensionUpdaterDelegate() = default; +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_UPDATER_EXTENSION_UPDATER_DELEGATE_H_
diff --git a/chrome/browser/extensions/updater/extension_updater_unittest.cc b/chrome/browser/extensions/updater/extension_updater_unittest.cc index 23cc5a15..12817e6b 100644 --- a/chrome/browser/extensions/updater/extension_updater_unittest.cc +++ b/chrome/browser/extensions/updater/extension_updater_unittest.cc
@@ -51,6 +51,7 @@ #include "chrome/browser/extensions/test_extension_service.h" #include "chrome/browser/extensions/test_extension_system.h" #include "chrome/browser/extensions/updater/chrome_extension_downloader_factory.h" +#include "chrome/browser/extensions/updater/extension_updater_delegate.h" #include "chrome/browser/google/google_brand.h" #include "chrome/test/base/scoped_testing_local_state.h" #include "chrome/test/base/testing_browser_process.h" @@ -242,13 +243,12 @@ } // namespace -// Base class for further specialized test classes. -class MockService : public TestExtensionService { +class MockDelegate : public ExtensionUpdaterDelegate { public: - MockService() = default; - MockService(const MockService&) = delete; - MockService& operator=(const MockService&) = delete; - ~MockService() override = default; + MockDelegate() = default; + MockDelegate(const MockDelegate&) = delete; + MockDelegate& operator=(const MockDelegate&) = delete; + ~MockDelegate() override = default; const ExtensionId& crx_extension_id() const { return crx_extension_id_; } @@ -261,6 +261,7 @@ fake_crx_installers_[id] = crx_installer; } + // ExtensionUpdaterDelegate: scoped_refptr<CrxInstaller> CreateUpdateInstaller( const CRXFileInfo& file, bool file_ownership_passed) override { @@ -620,7 +621,7 @@ // Create an extension with an update_url. ExtensionDownloaderTestHelper helper; TestDownloaderFactory factory(helper.url_loader_factory()); - MockService service; + MockDelegate delegate; std::string update_url("http://foo.com/bar"); ExtensionList extensions; PendingExtensionManager* pending_extension_manager = @@ -635,7 +636,7 @@ } // Set up and start the updater. - ExtensionUpdater updater(&service, extension_prefs(), pref_service(), + ExtensionUpdater updater(&delegate, extension_prefs(), pref_service(), profile(), 60 * 60 * 24, nullptr, factory.GetDownloaderFactory()); updater.Start(); @@ -735,7 +736,7 @@ bool should_include_traffic_management_headers) { ExtensionDownloaderTestHelper helper; TestDownloaderFactory factory(helper.url_loader_factory()); - MockService service; + MockDelegate delegate; ExtensionList extensions; CreateTestExtensions(1, num_extensions, &extensions, &update_url, @@ -994,7 +995,6 @@ // Create a set of test extensions ExtensionDownloaderTestHelper helper; TestDownloaderFactory factory(helper.url_loader_factory()); - MockService service; PendingExtensionManager* pending_extension_manager = PendingExtensionManager::Get(profile()); SetupPendingExtensionManagerForTest(3, GURL(), pending_extension_manager); @@ -1429,13 +1429,13 @@ ExtensionUpdater::ScopedSkipScheduledCheckForTest skip_scheduled_checks; ExtensionDownloaderTestHelper helper; TestDownloaderFactory factory(helper.url_loader_factory()); - std::unique_ptr<MockService> service = std::make_unique<MockService>(); - ExtensionUpdater updater(service.get(), extension_prefs(), pref_service(), + MockDelegate delegate; + ExtensionUpdater updater(&delegate, extension_prefs(), pref_service(), profile(), kUpdateFrequencySecs, nullptr, factory.GetDownloaderFactory()); - MockExtensionDownloaderDelegate delegate; - delegate.DelegateTo(&updater); - factory.OverrideDownloaderDelegate(&delegate); + MockExtensionDownloaderDelegate downloader_delegate; + downloader_delegate.DelegateTo(&updater); + factory.OverrideDownloaderDelegate(&downloader_delegate); updater.Start(); updater.EnsureDownloaderCreated(); updater.downloader_->extensions_queue_.set_backoff_policy(kNoBackoffPolicy); @@ -1466,13 +1466,13 @@ ExtensionUpdater::ScopedSkipScheduledCheckForTest skip_scheduled_checks; ExtensionDownloaderTestHelper helper; TestDownloaderFactory factory(helper.url_loader_factory()); - std::unique_ptr<MockService> service = std::make_unique<MockService>(); - ExtensionUpdater updater(service.get(), extension_prefs(), pref_service(), + MockDelegate delegate; + ExtensionUpdater updater(&delegate, extension_prefs(), pref_service(), profile(), kUpdateFrequencySecs, nullptr, factory.GetDownloaderFactory()); - MockExtensionDownloaderDelegate delegate; - delegate.DelegateTo(&updater); - factory.OverrideDownloaderDelegate(&delegate); + MockExtensionDownloaderDelegate downloader_delegate; + downloader_delegate.DelegateTo(&updater); + factory.OverrideDownloaderDelegate(&downloader_delegate); updater.Start(); updater.EnsureDownloaderCreated(); updater.downloader_->extensions_queue_.set_backoff_policy(kNoBackoffPolicy); @@ -1504,46 +1504,47 @@ } if (retry) { - EXPECT_CALL(delegate, OnExtensionDownloadRetryForTests()) + EXPECT_CALL(downloader_delegate, OnExtensionDownloadRetryForTests()) .WillOnce(DoAll( - InvokeWithoutArgs(&delegate, + InvokeWithoutArgs(&downloader_delegate, &MockExtensionDownloaderDelegate::Quit), InvokeWithoutArgs(&helper, &ExtensionDownloaderTestHelper:: ClearURLLoaderFactoryResponses))); helper.test_url_loader_factory().AddResponse( test_url.spec(), "", net::HTTP_INTERNAL_SERVER_ERROR); - delegate.Wait(); + downloader_delegate.Wait(); EXPECT_TRUE(updater.downloader_->extension_loader_); } if (fail) { - EXPECT_CALL(delegate, OnExtensionDownloadFailed(id, _, _, requests, _)) + EXPECT_CALL(downloader_delegate, + OnExtensionDownloadFailed(id, _, _, requests, _)) .WillOnce(DoAll( - InvokeWithoutArgs(&delegate, + InvokeWithoutArgs(&downloader_delegate, &MockExtensionDownloaderDelegate::Quit), InvokeWithoutArgs(&helper, &ExtensionDownloaderTestHelper:: ClearURLLoaderFactoryResponses))); helper.test_url_loader_factory().AddResponse( test_url.spec(), "Any content. It is irrelevant.", net::HTTP_NOT_FOUND); - delegate.Wait(); + downloader_delegate.Wait(); } else { EXPECT_TRUE(updater.downloader_->extension_loader_); - EXPECT_CALL(delegate, + EXPECT_CALL(downloader_delegate, OnExtensionDownloadFinished_(_, _, _, _, requests, _)) .WillOnce( DoAll(testing::SaveArg<0>(&crx_file_info), - InvokeWithoutArgs(&delegate, + InvokeWithoutArgs(&downloader_delegate, &MockExtensionDownloaderDelegate::Quit))); helper.test_url_loader_factory().AddResponse( test_url.spec(), "Any content. It is irrelevant."); - delegate.Wait(); + downloader_delegate.Wait(); EXPECT_EQ(version, crx_file_info.expected_version); } if (fail) { // Don't expect any extension to have been installed. - EXPECT_TRUE(service->crx_extension_id().empty()); + EXPECT_TRUE(delegate.crx_extension_id().empty()); } else { // Expect that ExtensionUpdater asked the mock extensions service to // install a file with the test data for the right id. @@ -1623,15 +1624,15 @@ // Create mock extension service for test. We need this mock service so that // the extension updater process can be intercepted before the installer // which is then called explicitly. - std::unique_ptr<MockService> service = std::make_unique<MockService>(); - service->AddFakeCrxInstaller(kTestExtensionId, mock_installer); + MockDelegate delegate; + delegate.AddFakeCrxInstaller(kTestExtensionId, mock_installer); - ExtensionUpdater updater(service.get(), extension_prefs(), pref_service(), + ExtensionUpdater updater(&delegate, extension_prefs(), pref_service(), prefs_->profile(), kUpdateFrequencySecs, nullptr, factory.GetDownloaderFactory()); - MockExtensionDownloaderDelegate& delegate = helper.delegate(); - delegate.DelegateTo(&updater); - factory.OverrideDownloaderDelegate(&delegate); + MockExtensionDownloaderDelegate& downloader_delegate = helper.delegate(); + downloader_delegate.DelegateTo(&updater); + factory.OverrideDownloaderDelegate(&downloader_delegate); updater.Start(); // Create and initialize local cache. @@ -1673,43 +1674,44 @@ // Set cache in extension downloader. helper.downloader().StartAllPending(&test_extension_cache); - EXPECT_CALL(delegate, IsExtensionPending(kTestExtensionId)) + EXPECT_CALL(downloader_delegate, IsExtensionPending(kTestExtensionId)) .WillOnce(Return(true)); // Download the update manifest for the extension, find the same extension // version in the cache, start installing the cached crx file which fails // due to unpacker error and is hence, removed from the cache and // re-downlaoded for installation. testing::Sequence sequence; - EXPECT_CALL(delegate, + EXPECT_CALL(downloader_delegate, OnExtensionDownloadStageChanged( kTestExtensionId, ExtensionDownloaderDelegate::Stage::QUEUED_FOR_MANIFEST)) .Times(testing::AnyNumber()); - EXPECT_CALL(delegate, + EXPECT_CALL(downloader_delegate, OnExtensionDownloadStageChanged( kTestExtensionId, ExtensionDownloaderDelegate::Stage::DOWNLOADING_MANIFEST)) .InSequence(sequence); - EXPECT_CALL(delegate, + EXPECT_CALL(downloader_delegate, OnExtensionDownloadStageChanged( kTestExtensionId, ExtensionDownloaderDelegate::Stage::PARSING_MANIFEST)) .InSequence(sequence); - EXPECT_CALL(delegate, + EXPECT_CALL(downloader_delegate, OnExtensionDownloadStageChanged( kTestExtensionId, ExtensionDownloaderDelegate::Stage::MANIFEST_LOADED)) .InSequence(sequence); - EXPECT_CALL(delegate, + EXPECT_CALL(downloader_delegate, OnExtensionDownloadCacheStatusRetrieved( kTestExtensionId, ExtensionDownloaderDelegate::CacheStatus::CACHE_HIT)) .InSequence(sequence); - EXPECT_CALL(delegate, OnExtensionDownloadStageChanged( - kTestExtensionId, - ExtensionDownloaderDelegate::Stage::FINISHED)) + EXPECT_CALL( + downloader_delegate, + OnExtensionDownloadStageChanged( + kTestExtensionId, ExtensionDownloaderDelegate::Stage::FINISHED)) .InSequence(sequence); - EXPECT_CALL(delegate, + EXPECT_CALL(downloader_delegate, OnExtensionDownloadStageChanged( kTestExtensionId, ExtensionDownloaderDelegate::Stage::DOWNLOADING_CRX)) @@ -1749,17 +1751,17 @@ int max_authuser) { ExtensionDownloaderTestHelper helper; TestDownloaderFactory factory(helper.url_loader_factory()); - MockService service; + MockDelegate delegate; const ExtensionDownloader::Factory& downloader_factory = enable_oauth2 ? factory.GetAuthenticatedDownloaderFactory() : factory.GetDownloaderFactory(); - ExtensionUpdater updater(&service, extension_prefs(), pref_service(), + ExtensionUpdater updater(&delegate, extension_prefs(), pref_service(), profile(), kUpdateFrequencySecs, nullptr, downloader_factory); - MockExtensionDownloaderDelegate delegate; - delegate.DelegateTo(&updater); - factory.OverrideDownloaderDelegate(&delegate); + MockExtensionDownloaderDelegate downloader_delegate; + downloader_delegate.DelegateTo(&updater); + factory.OverrideDownloaderDelegate(&downloader_delegate); updater.Start(); updater.EnsureDownloaderCreated(); @@ -1782,15 +1784,15 @@ updater.downloader_->last_extension_loader_load_flags_for_testing_); // Fake a 403 response. - EXPECT_CALL(delegate, OnExtensionDownloadRetryForTests()) + EXPECT_CALL(downloader_delegate, OnExtensionDownloadRetryForTests()) .WillOnce(DoAll( - InvokeWithoutArgs(&delegate, + InvokeWithoutArgs(&downloader_delegate, &MockExtensionDownloaderDelegate::Quit), InvokeWithoutArgs(&helper, &ExtensionDownloaderTestHelper:: ClearURLLoaderFactoryResponses))); helper.test_url_loader_factory().AddResponse(test_url.spec(), "", net::HTTP_FORBIDDEN); - delegate.Wait(); + downloader_delegate.Wait(); // Only call out to WaitForAccessTokenRequest(...) method below if // HTTPS is in use in a google domain and oauth is explicitly enabled. @@ -1858,16 +1860,16 @@ success = true; } else { // Simulate OAuth2 failure and ensure that we fall back on cookies. - EXPECT_CALL(delegate, OnExtensionDownloadRetryForTests()) + EXPECT_CALL(downloader_delegate, OnExtensionDownloadRetryForTests()) .WillOnce( - DoAll(InvokeWithoutArgs(&delegate, + DoAll(InvokeWithoutArgs(&downloader_delegate, &MockExtensionDownloaderDelegate::Quit), InvokeWithoutArgs(&helper, &ExtensionDownloaderTestHelper:: ClearURLLoaderFactoryResponses))); helper.test_url_loader_factory().AddResponse(test_url.spec(), "", net::HTTP_FORBIDDEN); - delegate.Wait(); + downloader_delegate.Wait(); const ExtensionDownloader::ExtensionFetch& fetch = *updater.downloader_->extensions_queue_.active_request(); @@ -1907,16 +1909,16 @@ EXPECT_EQ( expected_load_flags, updater.downloader_->last_extension_loader_load_flags_for_testing_); - EXPECT_CALL(delegate, OnExtensionDownloadRetryForTests()) + EXPECT_CALL(downloader_delegate, OnExtensionDownloadRetryForTests()) .WillOnce( - DoAll(InvokeWithoutArgs(&delegate, + DoAll(InvokeWithoutArgs(&downloader_delegate, &MockExtensionDownloaderDelegate::Quit), InvokeWithoutArgs(&helper, &ExtensionDownloaderTestHelper:: ClearURLLoaderFactoryResponses))); helper.test_url_loader_factory().AddResponse( fetch.url.spec(), "whatever", net::HTTP_FORBIDDEN); - delegate.Wait(); + downloader_delegate.Wait(); } // Simulate exhaustion of all available authusers. @@ -1926,10 +1928,11 @@ EXPECT_TRUE(updater.downloader_->extension_loader_); helper.test_url_loader_factory().AddResponse( fetch.url.spec(), std::string(), net::HTTP_UNAUTHORIZED); - EXPECT_CALL(delegate, OnExtensionDownloadFailed(_, _, _, _, _)) + EXPECT_CALL(downloader_delegate, + OnExtensionDownloadFailed(_, _, _, _, _)) .WillOnce(InvokeWithoutArgs( - &delegate, &MockExtensionDownloaderDelegate::Quit)); - delegate.Wait(); + &downloader_delegate, &MockExtensionDownloaderDelegate::Quit)); + downloader_delegate.Wait(); } } @@ -1940,14 +1943,15 @@ *updater.downloader_->extensions_queue_.active_request(); CRXFileInfo crx_file_info; - EXPECT_CALL(delegate, OnExtensionDownloadFinished_(_, _, _, _, _, _)) + EXPECT_CALL(downloader_delegate, + OnExtensionDownloadFinished_(_, _, _, _, _, _)) .WillOnce( DoAll(testing::SaveArg<0>(&crx_file_info), - InvokeWithoutArgs(&delegate, + InvokeWithoutArgs(&downloader_delegate, &MockExtensionDownloaderDelegate::Quit))); helper.test_url_loader_factory().AddResponse(fetch.url.spec(), "whatever"); - delegate.Wait(); + downloader_delegate.Wait(); // Verify installation would proceed as normal. EXPECT_EQ(id, crx_file_info.extension_id); @@ -1963,8 +1967,8 @@ void TestMultipleExtensionDownloading(bool updates_start_running) { ExtensionDownloaderTestHelper helper; TestDownloaderFactory factory(helper.url_loader_factory()); - MockService service; - ExtensionUpdater updater(&service, extension_prefs(), pref_service(), + MockDelegate delegate; + ExtensionUpdater updater(&delegate, extension_prefs(), pref_service(), profile(), kUpdateFrequencySecs, nullptr, factory.GetDownloaderFactory()); updater.Start(); @@ -2024,11 +2028,11 @@ if (updates_start_running) { // Add mock CrxInstaller to be returned by - // service.CreateUpdateInstaller(). - service.AddFakeCrxInstaller(id1, fake_crx1); - service.AddFakeCrxInstaller(id2, fake_crx2); + // delegate.CreateUpdateInstaller(). + delegate.AddFakeCrxInstaller(id1, fake_crx1); + delegate.AddFakeCrxInstaller(id2, fake_crx2); } else { - // If we don't add mock CRX installers, the mock service will just return + // If we don't add mock CRX installers, the mock delegate will just return // nullptr, meaning a failure. } @@ -2036,10 +2040,10 @@ url1.spec(), "Any content. This is irrelevant.", net::HTTP_OK); content::RunAllTasksUntilIdle(); - // Expect that the service was asked to do an install with the right data. - base::FilePath tmpfile_path = service.crx_install_path(); + // Expect that the delegate was asked to do an install with the right data. + base::FilePath tmpfile_path = delegate.crx_install_path(); EXPECT_FALSE(tmpfile_path.empty()); - EXPECT_EQ(id1, service.crx_extension_id()); + EXPECT_EQ(id1, delegate.crx_extension_id()); RunUntilIdle(); // Make sure the second fetch finished and asked the service to do an @@ -2126,7 +2130,7 @@ base::SingleThreadTaskRunner::GetCurrentDefault()); ExtensionDownloaderTestHelper helper; TestDownloaderFactory factory(helper.url_loader_factory()); - MockService service; + MockDelegate delegate; ExtensionList tmp; GURL url1("http://clients2.google.com/service/update2/crx"); GURL url2("http://www.somewebsite.com"); @@ -2159,7 +2163,7 @@ if (active_bit) prefs->SetActiveBit(id, true); - ExtensionUpdater updater(&service, extension_prefs(), pref_service(), + ExtensionUpdater updater(&delegate, extension_prefs(), pref_service(), profile(), kUpdateFrequencySecs, nullptr, factory.GetDownloaderFactory()); updater.Start(); @@ -2254,14 +2258,14 @@ void TestHandleManifestResults() { ExtensionDownloaderTestHelper helper; TestDownloaderFactory factory(helper.url_loader_factory()); - MockService service; + MockDelegate delegate; GURL update_url("http://www.google.com/manifest"); ExtensionList tmp; CreateTestExtensions(1, 1, &tmp, &update_url.spec(), ManifestLocation::kInternal); SetExtensions(tmp, ExtensionList()); - ExtensionUpdater updater(&service, extension_prefs(), pref_service(), + ExtensionUpdater updater(&delegate, extension_prefs(), pref_service(), profile(), kUpdateFrequencySecs, nullptr, factory.GetDownloaderFactory()); updater.Start(); @@ -2518,12 +2522,12 @@ TEST_F(ExtensionUpdaterTest, TestNonAutoUpdateableLocations) { ExtensionDownloaderTestHelper helper; TestDownloaderFactory factory(helper.url_loader_factory()); - MockService service; - ExtensionUpdater updater(&service, extension_prefs(), pref_service(), + MockDelegate delegate; + ExtensionUpdater updater(&delegate, extension_prefs(), pref_service(), profile(), kUpdateFrequencySecs, nullptr, factory.GetDownloaderFactory()); - MockExtensionDownloaderDelegate delegate; - factory.OverrideDownloaderDelegate(&delegate); + MockExtensionDownloaderDelegate downloader_delegate; + factory.OverrideDownloaderDelegate(&downloader_delegate); // Non-internal non-external extensions should be rejected. ExtensionList extensions; @@ -2540,8 +2544,8 @@ TEST_F(ExtensionUpdaterTest, TestUpdatingDisabledExtensions) { ExtensionDownloaderTestHelper helper; TestDownloaderFactory factory(helper.url_loader_factory()); - MockService service; - ExtensionUpdater updater(&service, extension_prefs(), pref_service(), + MockDelegate delegate; + ExtensionUpdater updater(&delegate, extension_prefs(), pref_service(), profile(), kUpdateFrequencySecs, nullptr, factory.GetDownloaderFactory()); NiceMock<MockUpdateService> update_service; @@ -2574,8 +2578,8 @@ TEST_F(ExtensionUpdaterTest, TestUpdatingRemotelyDisabledExtensions) { ExtensionDownloaderTestHelper helper; TestDownloaderFactory factory(helper.url_loader_factory()); - MockService service; - ExtensionUpdater updater(&service, extension_prefs(), pref_service(), + MockDelegate delegate; + ExtensionUpdater updater(&delegate, extension_prefs(), pref_service(), profile(), kUpdateFrequencySecs, nullptr, factory.GetDownloaderFactory()); NiceMock<MockUpdateService> update_service; @@ -2626,8 +2630,8 @@ ExtensionDownloaderTestHelper helper; TestDownloaderFactory factory(helper.url_loader_factory()); - MockService service; - ExtensionUpdater updater(&service, extension_prefs(), pref_service(), + MockDelegate delegate; + ExtensionUpdater updater(&delegate, extension_prefs(), pref_service(), profile(), kUpdateFrequencySecs, nullptr, factory.GetDownloaderFactory()); NiceMock<MockUpdateService> update_service; @@ -2791,8 +2795,8 @@ TEST_F(ExtensionUpdaterTest, TestCheckSoon) { ExtensionDownloaderTestHelper helper; TestDownloaderFactory factory(helper.url_loader_factory()); - MockService service; - ExtensionUpdater updater(&service, extension_prefs(), pref_service(), + MockDelegate delegate; + ExtensionUpdater updater(&delegate, extension_prefs(), pref_service(), profile(), kUpdateFrequencySecs, nullptr, factory.GetDownloaderFactory()); EXPECT_FALSE(updater.WillCheckSoon()); @@ -2815,7 +2819,7 @@ TEST_F(ExtensionUpdaterTest, TestUninstallWhileUpdateCheck) { ExtensionDownloaderTestHelper helper; TestDownloaderFactory factory(helper.url_loader_factory()); - MockService service; + MockDelegate delegate; ExtensionList tmp; CreateTestExtensions(1, 1, &tmp, nullptr, ManifestLocation::kInternal); SetExtensions(tmp, ExtensionList()); @@ -2825,7 +2829,7 @@ ExtensionRegistry* registry = ExtensionRegistry::Get(profile()); ASSERT_TRUE(registry->enabled_extensions().GetByID(id)); - ExtensionUpdater updater(&service, extension_prefs(), pref_service(), + ExtensionUpdater updater(&delegate, extension_prefs(), pref_service(), profile(), kUpdateFrequencySecs, nullptr, factory.GetDownloaderFactory()); ExtensionUpdater::CheckParams params; @@ -2903,9 +2907,9 @@ factory_ = std::make_unique<TestDownloaderFactory>( downloader_test_helper_.url_loader_factory()); - service_ = std::make_unique<MockService>(); + delegate_ = std::make_unique<MockDelegate>(); updater_ = std::make_unique<ExtensionUpdater>( - service_.get(), extension_prefs(), pref_service(), profile(), + delegate_.get(), extension_prefs(), pref_service(), profile(), kUpdateFrequencySecs, nullptr, factory_->GetDownloaderFactory()); store_extension_ = @@ -2938,7 +2942,7 @@ void TearDown() override { // Avoid dangling pointers. updater_.reset(); - service_.reset(); + delegate_.reset(); factory_.reset(); ExtensionUpdaterTest::TearDown(); } @@ -2949,7 +2953,7 @@ ExtensionUpdater::ScopedSkipScheduledCheckForTest skip_scheduled_checks_; ExtensionDownloaderTestHelper downloader_test_helper_; std::unique_ptr<TestDownloaderFactory> factory_; - std::unique_ptr<MockService> service_; + std::unique_ptr<MockDelegate> delegate_; std::unique_ptr<ExtensionUpdater> updater_; scoped_refptr<const Extension> store_extension_;
diff --git a/chrome/browser/feed/android/java/res/drawable/header_title_section_tab_background_v2.xml b/chrome/browser/feed/android/java/res/drawable/header_title_section_tab_background_v2.xml index f62c15a..07b5304f 100644 --- a/chrome/browser/feed/android/java/res/drawable/header_title_section_tab_background_v2.xml +++ b/chrome/browser/feed/android/java/res/drawable/header_title_section_tab_background_v2.xml
@@ -7,10 +7,10 @@ <selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:state_enabled="true"> - <org.chromium.components.browser_ui.widget.SurfaceColorDrawable - android:shape="rectangle" - app:surfaceElevation="@dimen/home_surface_ui_background_color_elevation"> + <shape + android:shape="rectangle"> + <solid android:color="@color/home_surface_ui_background_color"/> <corners android:radius="@dimen/feed_header_background_outer_corner_radius"/> - </org.chromium.components.browser_ui.widget.SurfaceColorDrawable> + </shape> </item> </selector> \ No newline at end of file
diff --git a/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_bottom_rounded.xml b/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_bottom_rounded.xml index c8c217a..1a3e10cd 100644 --- a/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_bottom_rounded.xml +++ b/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_bottom_rounded.xml
@@ -4,14 +4,12 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<org.chromium.components.browser_ui.widget.SurfaceColorDrawable - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:shape="rectangle" - app:surfaceElevation="@dimen/home_surface_ui_background_color_elevation"> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <solid android:color="@color/home_surface_ui_background_color"/> <corners - android:topLeftRadius="0dp" - android:topRightRadius="0dp" - android:bottomLeftRadius="@dimen/home_surface_ui_background_radius" - android:bottomRightRadius="@dimen/home_surface_ui_background_radius" /> -</org.chromium.components.browser_ui.widget.SurfaceColorDrawable> + android:topLeftRadius="0dp" + android:topRightRadius="0dp" + android:bottomLeftRadius="@dimen/home_surface_ui_background_radius" + android:bottomRightRadius="@dimen/home_surface_ui_background_radius" /> +</shape>
diff --git a/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_bottomleft_rounded.xml b/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_bottomleft_rounded.xml index 794d8687..821d003 100644 --- a/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_bottomleft_rounded.xml +++ b/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_bottomleft_rounded.xml
@@ -4,14 +4,13 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<org.chromium.components.browser_ui.widget.SurfaceColorDrawable - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:shape="rectangle" - app:surfaceElevation="@dimen/home_surface_ui_background_color_elevation"> + +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <solid android:color="@color/home_surface_ui_background_color"/> <corners - android:topLeftRadius="0dp" - android:topRightRadius="0dp" - android:bottomLeftRadius="@dimen/home_surface_ui_background_radius" - android:bottomRightRadius="0dp" /> -</org.chromium.components.browser_ui.widget.SurfaceColorDrawable> + android:topLeftRadius="0dp" + android:topRightRadius="0dp" + android:bottomLeftRadius="@dimen/home_surface_ui_background_radius" + android:bottomRightRadius="0dp" /> +</shape>
diff --git a/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_bottomright_rounded.xml b/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_bottomright_rounded.xml index c7763c8..9fc0798 100644 --- a/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_bottomright_rounded.xml +++ b/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_bottomright_rounded.xml
@@ -4,14 +4,13 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<org.chromium.components.browser_ui.widget.SurfaceColorDrawable - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:shape="rectangle" - app:surfaceElevation="@dimen/home_surface_ui_background_color_elevation"> + +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <solid android:color="@color/home_surface_ui_background_color"/> <corners - android:topLeftRadius="0dp" - android:topRightRadius="0dp" - android:bottomLeftRadius="0dp" - android:bottomRightRadius="@dimen/home_surface_ui_background_radius" /> -</org.chromium.components.browser_ui.widget.SurfaceColorDrawable> + android:topLeftRadius="0dp" + android:topRightRadius="0dp" + android:bottomLeftRadius="0dp" + android:bottomRightRadius="@dimen/home_surface_ui_background_radius" /> +</shape> \ No newline at end of file
diff --git a/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_not_rounded.xml b/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_not_rounded.xml index 44015622..54ec9e8 100644 --- a/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_not_rounded.xml +++ b/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_not_rounded.xml
@@ -4,8 +4,7 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<org.chromium.components.browser_ui.widget.SurfaceColorDrawable - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:shape="rectangle" - app:surfaceElevation="@dimen/home_surface_ui_background_color_elevation" /> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <solid android:color="@color/home_surface_ui_background_color"/> +</shape>
diff --git a/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_top_rounded.xml b/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_top_rounded.xml index 733bb67..6f7d5ff9 100644 --- a/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_top_rounded.xml +++ b/chrome/browser/feed/android/java/res/drawable/home_surface_ui_background_top_rounded.xml
@@ -4,14 +4,12 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<org.chromium.components.browser_ui.widget.SurfaceColorDrawable - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:shape="rectangle" - app:surfaceElevation="@dimen/home_surface_ui_background_color_elevation"> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <solid android:color="@color/home_surface_ui_background_color"/> <corners - android:topLeftRadius="@dimen/home_surface_ui_background_radius" - android:topRightRadius="@dimen/home_surface_ui_background_radius" - android:bottomLeftRadius="0dp" - android:bottomRightRadius="0dp" /> -</org.chromium.components.browser_ui.widget.SurfaceColorDrawable> + android:topLeftRadius="@dimen/home_surface_ui_background_radius" + android:topRightRadius="@dimen/home_surface_ui_background_radius" + android:bottomLeftRadius="0dp" + android:bottomRightRadius="0dp" /> +</shape> \ No newline at end of file
diff --git a/chrome/browser/feedback/android/java/src/org/chromium/chrome/browser/feedback/DeviceInfoFeedbackSource.java b/chrome/browser/feedback/android/java/src/org/chromium/chrome/browser/feedback/DeviceInfoFeedbackSource.java index c1cdd30..7b61e2b 100644 --- a/chrome/browser/feedback/android/java/src/org/chromium/chrome/browser/feedback/DeviceInfoFeedbackSource.java +++ b/chrome/browser/feedback/android/java/src/org/chromium/chrome/browser/feedback/DeviceInfoFeedbackSource.java
@@ -8,6 +8,7 @@ import org.chromium.base.BuildInfo; import org.chromium.base.ContextUtils; +import org.chromium.base.DeviceInfo; import org.chromium.build.annotations.NullMarked; import org.chromium.ui.base.DeviceFormFactor; @@ -21,6 +22,7 @@ private static final String TYPE_PHONE = "phone"; private static final String TYPE_TABLET = "tablet"; private static final String TYPE_AUTO = "automotive"; + private static final String TYPE_DESKTOP = "desktop"; @Override public Map<String, String> getFeedback() { @@ -32,6 +34,8 @@ String type; if (BuildInfo.getInstance().isAutomotive) { type = TYPE_AUTO; + } else if (DeviceInfo.isDesktop()) { + type = TYPE_DESKTOP; } else if (DeviceFormFactor.isNonMultiDisplayContextOnTablet( ContextUtils.getApplicationContext())) { type = TYPE_TABLET;
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 9d118412..6ef15555a 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -592,11 +592,6 @@ "expiry_milestone": 140 }, { - "name": "autofill-disable-local-card-migration", - "owners": [ "jsaul@google.com", "payments-autofill-team@google.com" ], - "expiry_milestone": 140 - }, - { "name": "autofill-enable-allowlist-for-bmo-card-category-benefits", "owners": [ "ferny@google.com", "payments-autofill-team@google.com" ], "expiry_milestone": 145 @@ -652,11 +647,6 @@ "expiry_milestone": 145 }, { - "name": "autofill-enable-card-product-name", - "owners": [ "vishwasuppoor@chromium.org", "siyua@chromium.org"], - "expiry_milestone": 130 - }, - { "name": "autofill-enable-cvc-storage-and-filling", "owners": [ "koulvipul@google.com", "payments-autofill-team@google.com"], "expiry_milestone": 140 @@ -6265,6 +6255,11 @@ "expiry_milestone": 145 }, { + "name": "notebook-lm-app-preinstall", + "owners": [ "alancutter@google.com", "crosdev-commerce-eng@google.com" ], + "expiry_milestone": 146 + }, + { "name": "notification-collision-management", "owners": [ "thegreenfrog@chromium.org", "bling-gsu-pod@google.com" ], "expiry_milestone": 145 @@ -6810,7 +6805,7 @@ { "name": "omnibox-zero-suggest-prefetching", "owners": [ "mahmadi@chromium.org", "chrome-omnibox-team@google.com" ], - "expiry_milestone": 130 + "expiry_milestone": 140 }, { "name": "omnibox-zero-suggest-prefetching-on-srp", @@ -6820,7 +6815,7 @@ { "name": "omnibox-zero-suggest-prefetching-on-web", "owners": [ "khalidpeer@chromium.org", "mahmadi@chromium.org", "chrome-omnibox-team@google.com" ], - "expiry_milestone": 130 + "expiry_milestone": 140 }, { "name": "on-device-app-controls",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 342df5db..7e932769 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -591,12 +591,6 @@ " other Autofill services, enable #enable-autofill-virtual-view-structure."; #endif // BUILDFLAG(IS_ANDROID) -const char kAutofillDisableLocalCardMigrationName[] = - "Disable bulk local credit card migration flows"; -const char kAutofillDisableLocalCardMigrationDescription[] = - "When enabled, local credit card migration flows will not be offered, both " - "from checkout flows and from the payment methods settings page."; - const char kAutofillEnableAllowlistForBmoCardCategoryBenefitsName[] = "Enable allowlist for showing category benefits for BMO cards"; const char kAutofillEnableAllowlistForBmoCardCategoryBenefitsDescription[] = @@ -704,12 +698,6 @@ "When enabled, runtime retrieval of CVC along with card number and expiry " "from issuer for enrolled cards will be enabled during form fill."; -const char kAutofillEnableCardProductNameName[] = - "Enable showing card product name"; -const char kAutofillEnableCardProductNameDescription[] = - "When enabled, card product name (instead of issuer network) will be shown " - "in Payments Autofill UI."; - const char kAutofillEnableLogFormEventsToAllParsedFormTypesName[] = "Enable logging form events to all parsed form on a web page."; const char kAutofillEnableLogFormEventsToAllParsedFormTypesDescription[] = @@ -2599,6 +2587,10 @@ "thumbnails."; #endif +const char kNotebookLmAppPreinstallName[] = "NotebookLM app preload"; +const char kNotebookLmAppPreinstallDescription[] = + "Preloads the NotebookLM app."; + const char kNotificationSchedulerName[] = "Notification scheduler"; const char kNotificationSchedulerDescription[] = "Enable notification scheduler feature.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 1e2b7ab..dbe19774 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -368,9 +368,6 @@ extern const char kAutofillDeprecateAccessibilityApiDescription[]; #endif // BUILDFLAG(IS_ANDROID) -extern const char kAutofillDisableLocalCardMigrationName[]; -extern const char kAutofillDisableLocalCardMigrationDescription[]; - extern const char kAutofillEnableAllowlistForBmoCardCategoryBenefitsName[]; extern const char kAutofillEnableAllowlistForBmoCardCategoryBenefitsDescription[]; @@ -427,9 +424,6 @@ extern const char kAutofillEnableCardInfoRuntimeRetrievalName[]; extern const char kAutofillEnableCardInfoRuntimeRetrievalDescription[]; -extern const char kAutofillEnableCardProductNameName[]; -extern const char kAutofillEnableCardProductNameDescription[]; - extern const char kAutofillEnableLogFormEventsToAllParsedFormTypesName[]; extern const char kAutofillEnableLogFormEventsToAllParsedFormTypesDescription[]; @@ -1492,6 +1486,9 @@ extern const char kNewEtc1EncoderDescription[]; #endif +extern const char kNotebookLmAppPreinstallName[]; +extern const char kNotebookLmAppPreinstallDescription[]; + extern const char kNotificationSchedulerName[]; extern const char kNotificationSchedulerDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 890aa36..b16128e 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -94,7 +94,6 @@ &autofill::features::kAutofillEnableRankingFormulaCreditCards, &autofill::features::kAutofillEnableCardBenefitsForAmericanExpress, &autofill::features::kAutofillEnableCardBenefitsForBmo, - &autofill::features::kAutofillEnableCardProductName, &autofill::features::kAutofillEnablePaymentSettingsCardPromoAndScanCard, &autofill::features::kAutofillEnablePaymentSettingsCardPromoAndScanCard, &autofill::features::kAutofillThirdPartyModeContentProvider,
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 e89c24b..7acba21 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
@@ -206,7 +206,6 @@ "AutofillEnableCardBenefitsForAmericanExpress"; public static final String AUTOFILL_ENABLE_CARD_BENEFITS_FOR_BMO = "AutofillEnableCardBenefitsForBmo"; - 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_SERVER_IBAN = "AutofillEnableServerIban"; public static final String AUTOFILL_ENABLE_CVC_STORAGE = "AutofillEnableCvcStorageAndFilling";
diff --git a/chrome/browser/glic/fre/glic_fre.mojom b/chrome/browser/glic/fre/glic_fre.mojom index 557c020..6556a27c 100644 --- a/chrome/browser/glic/fre/glic_fre.mojom +++ b/chrome/browser/glic/fre/glic_fre.mojom
@@ -17,11 +17,19 @@ // Closes the glic FRE modal dialog and opens the widget hosting the main // glic WebUI. AcceptFre(); + // Closes the glic FRE modal dialog. DismissFre(); + + // Prepare the webview for loading the client. Sync Google account sign-in + // cookies to the webview, if necessary, so that it can sign-in automatically. + // If this returns false, the web client cannot be created due to an error. + PrepareForClient() => (bool success); + // Opens `url` in a new backgrounded tab when a link is clicked in the FRE // modal dialog if `url` uses the Google domain. ValidateAndOpenLinkInNewTab(url.mojom.Url url); + // Notifies the PageHandler that the state of the WebUI has changed. WebUiStateChanged(FreWebUiState new_state); };
diff --git a/chrome/browser/glic/fre/glic_fre_controller.cc b/chrome/browser/glic/fre/glic_fre_controller.cc index b13bb8a..e1c7870 100644 --- a/chrome/browser/glic/fre/glic_fre_controller.cc +++ b/chrome/browser/glic/fre/glic_fre_controller.cc
@@ -6,6 +6,7 @@ #include "base/feature_list.h" #include "base/functional/bind.h" +#include "base/functional/callback_forward.h" #include "base/memory/scoped_refptr.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/user_metrics.h" @@ -77,8 +78,8 @@ if (!browser) { return false; } - // If there is a browser, the FRE can only be shown if no - // other modal is currently being shown on the same tab. + // If there is a browser, the FRE can only be shown if no other modal is + // currently being shown on the same tab. tabs::TabInterface* tab = browser->GetActiveTabInterface(); return tab && tab->CanShowModalUI(); } @@ -182,6 +183,11 @@ } } +void GlicFreController::PrepareForClient( + base::OnceCallback<void(bool)> callback) { + auth_controller_.CheckAuthBeforeLoad(std::move(callback)); +} + void GlicFreController::OnLinkClicked(const GURL& url) { if (url.DomainIs("support.google.com")) { if (url.path().find("13594961") != std::string::npos) {
diff --git a/chrome/browser/glic/fre/glic_fre_controller.h b/chrome/browser/glic/fre/glic_fre_controller.h index 7228d81..91f2e9f 100644 --- a/chrome/browser/glic/fre/glic_fre_controller.h +++ b/chrome/browser/glic/fre/glic_fre_controller.h
@@ -76,6 +76,9 @@ // Closes the FRE dialog. void DismissFre(); + // Re-sync cookies to FRE webview. + void PrepareForClient(base::OnceCallback<void(bool)> callback); + // Notify FRE controller that the user clicked on a link. void OnLinkClicked(const GURL& url);
diff --git a/chrome/browser/glic/fre/glic_fre_page_handler.cc b/chrome/browser/glic/fre/glic_fre_page_handler.cc index c952864..8e3e306 100644 --- a/chrome/browser/glic/fre/glic_fre_page_handler.cc +++ b/chrome/browser/glic/fre/glic_fre_page_handler.cc
@@ -40,6 +40,12 @@ GetGlicService()->window_controller().fre_controller()->OnNoThanksClicked(); } +void GlicFrePageHandler::PrepareForClient( + base::OnceCallback<void(bool)> callback) { + GetGlicService()->window_controller().fre_controller()->PrepareForClient( + std::move(callback)); +} + void GlicFrePageHandler::ValidateAndOpenLinkInNewTab(const GURL& url) { if (url.DomainIs("google.com")) { GetGlicService()->CreateTab(url, /*open_in_background=*/true, std::nullopt,
diff --git a/chrome/browser/glic/fre/glic_fre_page_handler.h b/chrome/browser/glic/fre/glic_fre_page_handler.h index 02703cb2..9045ce2 100644 --- a/chrome/browser/glic/fre/glic_fre_page_handler.h +++ b/chrome/browser/glic/fre/glic_fre_page_handler.h
@@ -34,6 +34,7 @@ // glic::mojom::FrePageHandler implementation. void AcceptFre() override; void DismissFre() override; + void PrepareForClient(base::OnceCallback<void(bool)> callback) override; void ValidateAndOpenLinkInNewTab(const GURL& url) override; void WebUiStateChanged(mojom::FreWebUiState new_state) override;
diff --git a/chrome/browser/glic/fre/glic_fre_ui.cc b/chrome/browser/glic/fre/glic_fre_ui.cc index ac4cce7..2485712 100644 --- a/chrome/browser/glic/fre/glic_fre_ui.cc +++ b/chrome/browser/glic/fre/glic_fre_ui.cc
@@ -41,6 +41,9 @@ {"errorNotice", IDS_GLIC_ERROR_NOTICE}, {"errorNoticeActionButton", IDS_GLIC_ERROR_NOTICE_ACTION_BUTTON}, {"errorNoticeHeader", IDS_GLIC_ERROR_NOTICE_HEADER}, + {"offlineNoticeAction", IDS_GLIC_OFFLINE_NOTICE_ACTION}, + {"offlineNoticeActionButton", IDS_GLIC_OFFLINE_NOTICE_ACTION_BUTTON}, + {"offlineNoticeHeader", IDS_GLIC_OFFLINE_NOTICE_HEADER}, }; content::BrowserContext* browser_context =
diff --git a/chrome/browser/glic/host/glic.mojom b/chrome/browser/glic/host/glic.mojom index 895c038a..b614841 100644 --- a/chrome/browser/glic/host/glic.mojom +++ b/chrome/browser/glic/host/glic.mojom
@@ -161,6 +161,9 @@ bool panel_is_active; WebClientSizingMode sizing_mode; bool browser_is_open; + // Whether to enable the OpenOsPermissionSettingsMenu API for the client. + // Depends on platform. Currently only allowed for Mac. + bool open_os_settings_api_is_allowed; }; // Options for getting tab context.
diff --git a/chrome/browser/glic/host/glic_page_handler.cc b/chrome/browser/glic/host/glic_page_handler.cc index 7cef4c8d..c6616fe 100644 --- a/chrome/browser/glic/host/glic_page_handler.cc +++ b/chrome/browser/glic/host/glic_page_handler.cc
@@ -317,6 +317,12 @@ state->browser_is_open = browser_is_open_calculator_.IsOpen(); +#if BUILDFLAG(IS_MAC) + state->open_os_settings_api_is_allowed = true; +#else + state->open_os_settings_api_is_allowed = false; +#endif + local_state_pref_change_registrar_.Init(g_browser_process->local_state()); local_state_pref_change_registrar_.Add( prefs::kGlicLauncherHotkey, @@ -557,6 +563,7 @@ } void OpenOsPermissionSettingsMenu(ContentSettingsType type) override { +#if BUILDFLAG(IS_MAC) if (type != ContentSettingsType::MEDIASTREAM_MIC && type != ContentSettingsType::GEOLOCATION) { // This will terminate the render process. @@ -567,6 +574,10 @@ } system_permission_settings::OpenSystemSettings( page_handler_->webui_contents(), type); +#else + mojo::ReportBadMessage( + "OpenOsPermissionSettingsMenu not supported on this platform."); +#endif } void GetOsMicrophonePermissionStatus(
diff --git a/chrome/browser/headless/headless_mode_protocol_browsertest.cc b/chrome/browser/headless/headless_mode_protocol_browsertest.cc index 4f4840a..e5eef8d 100644 --- a/chrome/browser/headless/headless_mode_protocol_browsertest.cc +++ b/chrome/browser/headless/headless_mode_protocol_browsertest.cc
@@ -341,8 +341,8 @@ "--ozone-override-screen-size=1234,5678") #endif -// --screen-info switch is only supported on Linux at this time. -#if BUILDFLAG(IS_LINUX) +// --screen-info switch is only supported on Linux and Windows at this time. +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) // This currently results in an unexpected screen orientation type, // see http://crbug.com/398150465. HEADLESS_MODE_PROTOCOL_TEST_WITH_COMMAND_LINE_EXTRAS( @@ -350,10 +350,13 @@ "sanity/multiple-screen-details.js", "--screen-info={label=#1}{600x800 label='#2'}") +// This fails on Windows, see http://crbug.com/401294443. +#if !BUILDFLAG(IS_WIN) HEADLESS_MODE_PROTOCOL_TEST_WITH_COMMAND_LINE_EXTRAS( MoveWindowBetweenScreens, "sanity/move-window-between-screens.js", "--screen-info={label='#1'}{label='#2'}{0,600 label='#3'}{label='#4'}") +#endif HEADLESS_MODE_PROTOCOL_TEST_WITH_COMMAND_LINE_EXTRAS( WindowOpenOnSecondaryScreen,
diff --git a/chrome/browser/net/stub_resolver_config_reader.cc b/chrome/browser/net/stub_resolver_config_reader.cc index 4e41ece..cb7b91b 100644 --- a/chrome/browser/net/stub_resolver_config_reader.cc +++ b/chrome/browser/net/stub_resolver_config_reader.cc
@@ -124,6 +124,7 @@ pref_change_registrar_.Add(prefs::kBuiltInDnsClientEnabled, pref_callback); pref_change_registrar_.Add(prefs::kAdditionalDnsQueryTypesEnabled, pref_callback); + pref_change_registrar_.Add(prefs::kHappyEyeballsV3Enabled, pref_callback); parental_controls_delay_timer_.Start( FROM_HERE, kParentalControlsCheckDelay, @@ -150,6 +151,7 @@ // for SystemNetworkContextManager, at which point the feature list is ready. registry->RegisterBooleanPref(prefs::kBuiltInDnsClientEnabled, false); registry->RegisterBooleanPref(prefs::kAdditionalDnsQueryTypesEnabled, true); + registry->RegisterBooleanPref(prefs::kHappyEyeballsV3Enabled, false); } SecureDnsConfig StubResolverConfigReader::GetSecureDnsConfiguration( @@ -225,7 +227,9 @@ } bool StubResolverConfigReader::GetHappyEyeballsV3Enabled() const { - // TODO(crbug.com/401410305): Add a policy and check the policy here. + if (local_state_->IsManagedPreference(prefs::kHappyEyeballsV3Enabled)) { + return local_state_->GetBoolean(prefs::kHappyEyeballsV3Enabled); + } return base::FeatureList::IsEnabled(net::features::kHappyEyeballsV3); }
diff --git a/chrome/browser/page_load_metrics/observers/gws_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/gws_page_load_metrics_observer_unittest.cc index 8d8c93f..9c975e2 100644 --- a/chrome/browser/page_load_metrics/observers/gws_page_load_metrics_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/gws_page_load_metrics_observer_unittest.cc
@@ -79,6 +79,12 @@ TEST_F(GWSPageLoadMetricsObserverTest, Search) { page_load_metrics::mojom::PageLoadTiming timing; page_load_metrics::InitPageLoadTimingForTest(&timing); + + // TODO(crbug.com/393980912): Add a test for the histogram related to + // LoadTimingInternalInfo. To do this, we need to add it to PageLoadTiming for + // testing purposes. However, we shouldn't expose LoadTimingInternalInfo to + // untrustworthy processes. + timing.navigation_start = base::Time::FromSecondsSinceUnixEpoch(1); timing.parse_timing->parse_start = base::Milliseconds(1); timing.connect_start = base::Milliseconds(1);
diff --git a/chrome/browser/password_manager/android/pwm_disabled/BUILD.gn b/chrome/browser/password_manager/android/pwm_disabled/BUILD.gn index 0a1cab3..8026854f 100644 --- a/chrome/browser/password_manager/android/pwm_disabled/BUILD.gn +++ b/chrome/browser/password_manager/android/pwm_disabled/BUILD.gn
@@ -17,6 +17,7 @@ "java/src/org/chromium/chrome/browser/pwm_disabled/PasswordCsvDownloadFlowControllerFactory.java", "java/src/org/chromium/chrome/browser/pwm_disabled/PasswordManagerUnavailableDialogCoordinator.java", "java/src/org/chromium/chrome/browser/pwm_disabled/PasswordManagerUnavailableDialogMediator.java", + "java/src/org/chromium/chrome/browser/pwm_disabled/PwmDeprecationDialogsMetricsRecorder.java", ] deps = [
diff --git a/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/PasswordManagerUnavailableDialogMediator.java b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/PasswordManagerUnavailableDialogMediator.java index 455f798..78ed64f 100644 --- a/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/PasswordManagerUnavailableDialogMediator.java +++ b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/PasswordManagerUnavailableDialogMediator.java
@@ -28,6 +28,9 @@ mModalDialogManager = modalDialogManager; mLaunchGmsUpdate = launchGmsUpdate; mIsUpdateDialog = isUpdateDialog; + if (!isUpdateDialog) { + PwmDeprecationDialogsMetricsRecorder.recordNoGmsNoPasswordsDialogShown(); + } } private void runPositiveButtonCallback() {
diff --git a/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/PasswordManagerUnavailableDialogTest.java b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/PasswordManagerUnavailableDialogTest.java index 74f29716..fde414f2 100644 --- a/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/PasswordManagerUnavailableDialogTest.java +++ b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/PasswordManagerUnavailableDialogTest.java
@@ -26,6 +26,7 @@ import org.chromium.base.Callback; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.Batch; +import org.chromium.base.test.util.HistogramWatcher; import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modaldialog.ModalDialogProperties; import org.chromium.ui.modelutil.PropertyModel; @@ -127,4 +128,15 @@ ModalDialogProperties.ButtonStyles.PRIMARY_OUTLINE_NEGATIVE_OUTLINE, mDialogModel.get(ModalDialogProperties.BUTTON_STYLES)); } + + @Test + public void recordsNoGmsDialogShownHistogram() { + HistogramWatcher histogramWatcher = + HistogramWatcher.newSingleRecordWatcher( + PwmDeprecationDialogsMetricsRecorder + .NO_GMS_NO_PASSWORDS_DIALOG_SHOWN_HISTOGRAM, + true); + mCoordinator.showDialog(mActivity, mModalDialogManager, null); + histogramWatcher.assertExpected(); + } }
diff --git a/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/PwmDeprecationDialogsMetricsRecorder.java b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/PwmDeprecationDialogsMetricsRecorder.java new file mode 100644 index 0000000..040b093 --- /dev/null +++ b/chrome/browser/password_manager/android/pwm_disabled/java/src/org/chromium/chrome/browser/pwm_disabled/PwmDeprecationDialogsMetricsRecorder.java
@@ -0,0 +1,20 @@ +// Copyright 2025 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.pwm_disabled; + +import org.chromium.base.metrics.RecordHistogram; + +/** + * Util class to be used when recording metrics for one of the password manager dialogs shown as + * part of the login database deprecation process. + */ +class PwmDeprecationDialogsMetricsRecorder { + static final String NO_GMS_NO_PASSWORDS_DIALOG_SHOWN_HISTOGRAM = + "PasswordManager.UPM.NoGmsNoPasswordsDialogShown"; + + static void recordNoGmsNoPasswordsDialogShown() { + RecordHistogram.recordBooleanHistogram(NO_GMS_NO_PASSWORDS_DIALOG_SHOWN_HISTOGRAM, true); + } +}
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index 13e8001..ebe39bc 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -70,6 +70,7 @@ #include "components/zoom/zoom_controller.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/download_manager.h" +#include "content/public/browser/host_zoom_map.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/plugin_service.h" @@ -110,6 +111,7 @@ #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/common/input/web_mouse_event.h" #include "third_party/blink/public/common/messaging/transferable_message.h" +#include "third_party/blink/public/common/page/page_zoom.h" #include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/clipboard_monitor.h" #include "ui/base/clipboard/clipboard_observer.h" @@ -285,6 +287,40 @@ EXPECT_EQ(extension_url, extension_host->GetLastCommittedURL()); } +// A test to verify that the presence of a pending NavigationEntry on the +// NavigationController of a WebContents hosting a PDF does not affect the +// value returned by WebContentsImpl::GetPendingZoomLevel() when called on +// the PDF extension frame's RenderWidgetHost. +IN_PROC_BROWSER_TEST_P(PDFExtensionTest, + ZoomNotAffectedByPendingNavigationEntry) { + // Set default zoom factor to 200%. + auto* web_contents = GetActiveWebContents(); + content::HostZoomMap::GetForWebContents(web_contents) + ->SetDefaultZoomLevel(blink::ZoomFactorToZoomLevel(2.0)); + + // Load PDF. + const GURL main_url(embedded_test_server()->GetURL("/pdf/test.pdf")); + content::RenderFrameHost* extension_host = LoadPdfGetExtensionHost(main_url); + ASSERT_TRUE(extension_host); + + // Verify PDF extension frame has zoom factor 100%. + EXPECT_EQ( + blink::ZoomFactorToZoomLevel(1.0), + content::GetPendingZoomLevel(extension_host->GetRenderWidgetHost())); + + // Navigate and immediately check GetPendingZoomLevel stays at factor 100%. + auto& controller = web_contents->GetController(); + controller.LoadURLWithParams(content::NavigationController::LoadURLParams( + embedded_test_server()->GetURL("/title1.html"))); + EXPECT_EQ( + blink::ZoomFactorToZoomLevel(1.0), + content::GetPendingZoomLevel(extension_host->GetRenderWidgetHost())); + // Verify the navigation is still pending. This gives assurance that the + // preceding call to GetPendingZoomLevel did encounter the condition being + // tested. + EXPECT_NE(nullptr, controller.GetPendingEntry()); +} + // Helper class to allow pausing the asynchronous attachment of an inner // WebContents between MimeHandlerViewAttachHelper's AttachToOuterWebContents() // and ResumeAttachOrDestroy(). This corresponds to the point where the inner
diff --git a/chrome/browser/policy/BUILD.gn b/chrome/browser/policy/BUILD.gn index 86e41be..25c10a02 100644 --- a/chrome/browser/policy/BUILD.gn +++ b/chrome/browser/policy/BUILD.gn
@@ -289,6 +289,7 @@ "test/data_url_policy_browsertest.cc", "test/developer_tools_policy_browsertest.cc", "test/download_directory_browsertest.cc", + "test/happy_eyeballs_v3_enabled_policy_browsertest.cc", "test/ipv6_reachability_override_policy_browsertest.cc", "test/local_fonts_policy_browsertest.cc", "test/media_stream_policy_browsertest.cc",
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index 75f431d3..419629de 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -2283,6 +2283,9 @@ { key::kStandardizedBrowserZoomEnabled, policy_prefs::kStandardizedBrowserZoomEnabled, base::Value::Type::BOOLEAN}, + { key::kHappyEyeballsV3Enabled, + prefs::kHappyEyeballsV3Enabled, + base::Value::Type::BOOLEAN }, { key::kIPv6ReachabilityOverrideEnabled, prefs::kIPv6ReachabilityOverrideEnabled, base::Value::Type::BOOLEAN },
diff --git a/chrome/browser/policy/test/happy_eyeballs_v3_enabled_policy_browsertest.cc b/chrome/browser/policy/test/happy_eyeballs_v3_enabled_policy_browsertest.cc new file mode 100644 index 0000000..ca1b433e --- /dev/null +++ b/chrome/browser/policy/test/happy_eyeballs_v3_enabled_policy_browsertest.cc
@@ -0,0 +1,134 @@ +// Copyright 2025 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/bind.h" +#include "base/test/metrics/histogram_tester.h" +#include "chrome/browser/policy/policy_test_utils.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/ui_test_utils.h" +#include "components/policy/core/common/policy_map.h" +#include "components/policy/core/common/policy_types.h" +#include "components/policy/policy_constants.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/network_service_instance.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "net/base/features.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "services/network/public/mojom/network_service.mojom.h" +#include "services/network/public/mojom/network_service_test.mojom.h" +#include "url/gurl.h" + +namespace policy { + +class HappyEyeballsV3EnabledPolicyTest + : public PolicyTest, + public ::testing::WithParamInterface< + /*policy::key::kHappyEyeballsV3Enabled=*/std::optional<bool>> { + public: + HappyEyeballsV3EnabledPolicyTest() = default; + + ~HappyEyeballsV3EnabledPolicyTest() override = default; + + void SetUp() override { + if (GetParam().has_value()) { + PolicyMap policies; + policies.Set(policy::key::kHappyEyeballsV3Enabled, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, + base::Value(*GetParam()), + /*external_data_fetcher=*/nullptr); + UpdateProviderPolicy(policies); + } + + embedded_test_server()->ServeFilesFromSourceDirectory("content/test/data"); + ASSERT_TRUE(embedded_test_server()->Start()); + PolicyTest::SetUp(); + } + + protected: + bool IsHappyEyeballsV3EnabledInNetworkService() { + mojo::Remote<network::mojom::NetworkServiceTest> network_service_test; + content::GetNetworkService()->BindTestInterfaceForTesting( + network_service_test.BindNewPipeAndPassReceiver()); + + base::RunLoop loop; + std::optional<bool> enabled; + network_service_test->IsHappyEyeballsV3Enabled( + base::BindLambdaForTesting([&](bool result) { + enabled = result; + loop.Quit(); + })); + loop.Run(); + + return *enabled; + } + + void TestDynamicRefresh(bool enabled) { + if (GetParam().value_or( + base::FeatureList::IsEnabled(net::features::kHappyEyeballsV3))) { + ASSERT_TRUE(IsHappyEyeballsV3EnabledInNetworkService()); + } else { + ASSERT_FALSE(IsHappyEyeballsV3EnabledInNetworkService()); + } + + PolicyMap policies; + policies.Set(policy::key::kHappyEyeballsV3Enabled, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::Value(enabled), + /*external_data_fetcher=*/nullptr); + UpdateProviderPolicy(policies); + ASSERT_EQ(IsHappyEyeballsV3EnabledInNetworkService(), enabled); + + // Ensure a loading request succeeds. + GURL url = embedded_test_server()->GetURL("/empty.html"); + int rv = content::LoadBasicRequest( + browser()->profile()->GetDefaultStoragePartition()->GetNetworkContext(), + url); + ASSERT_EQ(rv, net::OK); + } +}; + +IN_PROC_BROWSER_TEST_P(HappyEyeballsV3EnabledPolicyTest, RespectPolicy) { + if (GetParam().value_or( + base::FeatureList::IsEnabled(net::features::kHappyEyeballsV3))) { + ASSERT_TRUE(IsHappyEyeballsV3EnabledInNetworkService()); + } else { + ASSERT_FALSE(IsHappyEyeballsV3EnabledInNetworkService()); + } + + // Ensure a loading request succeeds. + GURL url = embedded_test_server()->GetURL("/empty.html"); + int rv = content::LoadBasicRequest( + browser()->profile()->GetDefaultStoragePartition()->GetNetworkContext(), + url); + ASSERT_EQ(rv, net::OK); +} + +IN_PROC_BROWSER_TEST_P(HappyEyeballsV3EnabledPolicyTest, DynamicRefreshEnable) { + TestDynamicRefresh(true); +} + +IN_PROC_BROWSER_TEST_P(HappyEyeballsV3EnabledPolicyTest, + DynamicRefreshDisable) { + TestDynamicRefresh(false); +} + +INSTANTIATE_TEST_SUITE_P( + Enabled, + HappyEyeballsV3EnabledPolicyTest, + ::testing::Values(/*policy::key::kHappyEyeballsV3Enabled=*/true)); + +INSTANTIATE_TEST_SUITE_P( + Disabled, + HappyEyeballsV3EnabledPolicyTest, + ::testing::Values(/*policy::key::kHappyEyeballsV3Enabled=*/false)); + +INSTANTIATE_TEST_SUITE_P( + NotSet, + HappyEyeballsV3EnabledPolicyTest, + ::testing::Values( + /*policy::key::kHappyEyeballsV3Enabled=*/std::nullopt)); + +} // namespace policy
diff --git a/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util.cc b/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util.cc index 7f03170..0d5d34a 100644 --- a/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util.cc +++ b/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util.cc
@@ -317,19 +317,25 @@ // If there is no room to add a `new_entry` (the capacity is // the same as the sliding window size), create a room by discounting the // existing histogram frequency. - if (1 + SumOfFrequency(histogram_, other_bucket_frequency_) > - sliding_window_size_) { - double discount = 1.0 / sliding_window_size_; - for (auto it = histogram_.begin(); it != histogram_.end();) { - it->second -= it->second * discount; - // Remove item that has too small frequency. - if (it->second < 1e-7) { - it = histogram_.erase(it); - } else { - ++it; + { + double sum_of_frequency = + SumOfFrequency(histogram_, other_bucket_frequency_); + if (1.0 + sum_of_frequency > sliding_window_size_) { + // The following `discount` has to be a value such that: + // 1 + sum_of_frequency == sliding_window_size_. + double discount = + (1.0 + sum_of_frequency - sliding_window_size_) / sum_of_frequency; + for (auto it = histogram_.begin(); it != histogram_.end();) { + it->second -= it->second * discount; + // Remove item that has too small frequency. + if (it->second < 1e-7) { + it = histogram_.erase(it); + } else { + ++it; + } } + other_bucket_frequency_ -= other_bucket_frequency_ * discount; } - other_bucket_frequency_ -= other_bucket_frequency_ * discount; } // Now we have one free space to store a new lcp_script_url. @@ -768,6 +774,15 @@ } // namespace +bool RecordLcpElementLocatorHistogramForTesting( // IN-TEST + int sliding_window_size, + int max_histogram_buckets, + const std::string& lcp_element_locator, + LcppStat& stat) { + return RecordLcpElementLocatorHistogram( + sliding_window_size, max_histogram_buckets, lcp_element_locator, stat); +} + std::optional<blink::mojom::LCPCriticalPathPredictorNavigationTimeHint> ConvertLcppStatToLCPCriticalPathPredictorNavigationTimeHint( const LcppStat& lcpp_stat) {
diff --git a/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util.h b/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util.h index de425a9..d98baf4 100644 --- a/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util.h +++ b/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util.h
@@ -30,6 +30,12 @@ } // namespace lcpp struct PreconnectPrediction; +bool RecordLcpElementLocatorHistogramForTesting( + int sliding_window_size, + int max_histogram_buckets, + const std::string& lcp_element_locator, + LcppStat& stat); + // Converts LcppStat to LCPCriticalPathPredictorNavigationTimeHint // so that it can be passed to the renderer via the navigation handle. std::optional<blink::mojom::LCPCriticalPathPredictorNavigationTimeHint>
diff --git a/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util_unittest.cc b/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util_unittest.cc index 081c0e0..491c7b16 100644 --- a/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util_unittest.cc +++ b/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util_unittest.cc
@@ -23,7 +23,9 @@ using testing::StrictMock; namespace predictors { + namespace { + class Updater { public: Updater(size_t sliding_window_size, size_t max_histogram_buckets) @@ -152,6 +154,19 @@ } } +LcpElementLocatorStat CreateLcpElementLocatorStat( + std::vector<std::pair<std::string, double>> lcp_element_locator_buckets, + double other_bucket_frequency) { + LcpElementLocatorStat lcp_element_locator_stat; + for (auto [lcp_element_locator, frequency] : lcp_element_locator_buckets) { + auto* bucket = lcp_element_locator_stat.add_lcp_element_locator_buckets(); + bucket->set_lcp_element_locator(lcp_element_locator); + bucket->set_frequency(frequency); + } + lcp_element_locator_stat.set_other_bucket_frequency(other_bucket_frequency); + return lcp_element_locator_stat; +} + } // namespace TEST(UpdateLcppStringFrequencyStatDataTest, Base) { @@ -1264,6 +1279,26 @@ } } +TEST(RecordLcpElementLocatorHistogramTest, ReduceSlidingWindowSize) { + LcppStat lcpp_stat; + *lcpp_stat.mutable_lcp_element_locator_stat() = + CreateLcpElementLocatorStat({{"#a", 3.0}, {"#b", 2.0}, {"#c", 1.0}}, 4.0); + + // Reduce sliding_window_size from 10 to 5. + RecordLcpElementLocatorHistogramForTesting( + /*sliding_window_size=*/5, /*max_histogram_buckets=*/3, "#d", lcpp_stat); + EXPECT_EQ(lcpp_stat.lcp_element_locator_stat(), + CreateLcpElementLocatorStat({{"#a", 1.2}, {"#b", 0.8}, {"#d", 1.0}}, + /*other_bucket_frequency=*/2.0)); + + // Reduce sliding_window_size from 5 to 1. + RecordLcpElementLocatorHistogramForTesting( + /*sliding_window_size=*/1, /*max_histogram_buckets=*/3, "#e", lcpp_stat); + EXPECT_EQ(lcpp_stat.lcp_element_locator_stat(), + CreateLcpElementLocatorStat({{"#e", 1.0}}, + /*other_bucket_frequency=*/0.0)); +} + class LcppDataMapTest : public testing::Test { public: void InitializeDB(const LoadingPredictorConfig& config) {
diff --git a/chrome/browser/resources/app_service_internals/BUILD.gn b/chrome/browser/resources/app_service_internals/BUILD.gn index fa9e392e..be412a6 100644 --- a/chrome/browser/resources/app_service_internals/BUILD.gn +++ b/chrome/browser/resources/app_service_internals/BUILD.gn
@@ -14,6 +14,7 @@ mojo_files_deps = [ "//chrome/browser/ui/webui/app_service_internals:mojo_bindings_ts__generator" ] mojo_files = [ "$root_gen_dir/chrome/browser/ui/webui/app_service_internals/app_service_internals.mojom-webui.ts" ] + ts_tsconfig_base = "//tools/typescript/tsconfig_base_polymer_389737066.json" ts_deps = [ "//third_party/polymer/v3_0:library", "//ui/webui/resources/mojo:build_ts",
diff --git a/chrome/browser/resources/app_service_internals/app_service_internals.ts b/chrome/browser/resources/app_service_internals/app_service_internals.ts index 7a3d9a7..c15da80 100644 --- a/chrome/browser/resources/app_service_internals/app_service_internals.ts +++ b/chrome/browser/resources/app_service_internals/app_service_internals.ts
@@ -19,22 +19,37 @@ static get properties() { return { - appList_: Array, - preferredAppList_: Array, - promiseAppList_: Array, - appCapabilityList_: Array, + appList_: { + type: Array, + value: () => [], + }, + + preferredAppList_: { + type: Array, + value: () => [], + }, + + promiseAppList_: { + type: Array, + value: () => [], + }, + + appCapabilityList_: { + type: Array, + value: () => [], + }, }; } /** List containing debug information for all installed apps. */ - private appList_: AppInfo[] = []; + declare private appList_: AppInfo[]; private hashChangeListener_ = () => this.onHashChanged_(); /** List containing preferred app debug information for installed apps. */ - private preferredAppList_: PreferredAppInfo[] = []; + declare private preferredAppList_: PreferredAppInfo[]; /** List containing debug information for all promise apps. */ - private promiseAppList_: PromiseAppInfo[] = []; + declare private promiseAppList_: PromiseAppInfo[]; /** List containing app capability access information. */ - private appCapabilityList_: AppCapabilityInfo[] = []; + declare private appCapabilityList_: AppCapabilityInfo[]; override ready() { super.ready();
diff --git a/chrome/browser/resources/app_settings/BUILD.gn b/chrome/browser/resources/app_settings/BUILD.gn index 1031363..9b9890b3 100644 --- a/chrome/browser/resources/app_settings/BUILD.gn +++ b/chrome/browser/resources/app_settings/BUILD.gn
@@ -64,6 +64,7 @@ html_to_wrapper_template = "detect" ts_composite = true + ts_tsconfig_base = "//tools/typescript/tsconfig_base_lit_389737066.json" ts_deps = [ "//third_party/lit/v3_0:build_ts", "//ui/webui/resources/cr_components/app_management:build_ts",
diff --git a/chrome/browser/resources/app_settings/app.ts b/chrome/browser/resources/app_settings/app.ts index fa4806f..883b332 100644 --- a/chrome/browser/resources/app_settings/app.ts +++ b/chrome/browser/resources/app_settings/app.ts
@@ -57,10 +57,10 @@ }; } - protected app_: App = createDummyApp(); - protected apps_: AppMap = {}; - protected iconUrl_: string = ''; - protected showSearch_: boolean = false; + protected accessor app_: App = createDummyApp(); + protected accessor apps_: AppMap = {}; + protected accessor iconUrl_: string = ''; + protected accessor showSearch_: boolean = false; override willUpdate(changedProperties: PropertyValues<this>) { super.willUpdate(changedProperties);
diff --git a/chrome/browser/resources/app_settings/app_content_dialog.ts b/chrome/browser/resources/app_settings/app_content_dialog.ts index def41193..adc9708 100644 --- a/chrome/browser/resources/app_settings/app_content_dialog.ts +++ b/chrome/browser/resources/app_settings/app_content_dialog.ts
@@ -31,7 +31,7 @@ }; } - app: App = createDummyApp(); + accessor app: App = createDummyApp(); override firstUpdated() { this.addEventListener('keydown', e => this.trapFocus_(e));
diff --git a/chrome/browser/resources/app_settings/app_content_item.ts b/chrome/browser/resources/app_settings/app_content_item.ts index 103f43b..4b0c0cc4 100644 --- a/chrome/browser/resources/app_settings/app_content_item.ts +++ b/chrome/browser/resources/app_settings/app_content_item.ts
@@ -37,11 +37,11 @@ }; } - app: App = createDummyApp(); + accessor app: App = createDummyApp(); appContentLabel: string = ''; appContentSublabel: string = ''; - showAppContentDialog: boolean = false; - override hidden: boolean = false; + accessor showAppContentDialog: boolean = false; + override accessor hidden: boolean = false; override willUpdate(changedProperties: PropertyValues<this>) { super.willUpdate(changedProperties);
diff --git a/chrome/browser/resources/app_settings/file_handling_item.ts b/chrome/browser/resources/app_settings/file_handling_item.ts index b984a57..17f3761 100644 --- a/chrome/browser/resources/app_settings/file_handling_item.ts +++ b/chrome/browser/resources/app_settings/file_handling_item.ts
@@ -48,9 +48,9 @@ }; } - app: App = createDummyApp(); - showOverflowDialog: boolean = false; - override hidden: boolean = false; + accessor app: App = createDummyApp(); + accessor showOverflowDialog: boolean = false; + override accessor hidden: boolean = false; override willUpdate(changedProperties: PropertyValues<this>) { super.willUpdate(changedProperties);
diff --git a/chrome/browser/resources/app_settings/more_permissions_item.ts b/chrome/browser/resources/app_settings/more_permissions_item.ts index 0ae0450a..d8f5c96 100644 --- a/chrome/browser/resources/app_settings/more_permissions_item.ts +++ b/chrome/browser/resources/app_settings/more_permissions_item.ts
@@ -34,8 +34,8 @@ }; } - app: App = createDummyApp(); - morePermissionsLabel: string = ''; + accessor app: App = createDummyApp(); + accessor morePermissionsLabel: string = ''; override firstUpdated() { this.addEventListener('click', this.onClick_);
diff --git a/chrome/browser/resources/app_settings/permission_item.ts b/chrome/browser/resources/app_settings/permission_item.ts index eec84a1..bcba94e 100644 --- a/chrome/browser/resources/app_settings/permission_item.ts +++ b/chrome/browser/resources/app_settings/permission_item.ts
@@ -69,12 +69,12 @@ }; } - app: App = createDummyApp(); - permissionLabel: string = ''; - permissionType: PermissionTypeIndex = 'kUnknown'; - icon: string = ''; - private syncPermissionManually: boolean = false; - protected available_: boolean = false; + accessor app: App = createDummyApp(); + accessor permissionLabel: string = ''; + accessor permissionType: PermissionTypeIndex = 'kUnknown'; + accessor icon: string = ''; + private accessor syncPermissionManually: boolean = false; + protected accessor available_: boolean = false; override willUpdate(changedProperties: PropertyValues<this>) { super.willUpdate(changedProperties);
diff --git a/chrome/browser/resources/app_settings/run_on_os_login_item.ts b/chrome/browser/resources/app_settings/run_on_os_login_item.ts index 8cba976..215f184 100644 --- a/chrome/browser/resources/app_settings/run_on_os_login_item.ts +++ b/chrome/browser/resources/app_settings/run_on_os_login_item.ts
@@ -56,8 +56,8 @@ }; } - loginModeLabel: string = ''; - app: App = createDummyApp(); + accessor loginModeLabel: string = ''; + accessor app: App = createDummyApp(); override firstUpdated() { this.addEventListener('click', this.onClick_);
diff --git a/chrome/browser/resources/app_settings/supported_links_dialog.ts b/chrome/browser/resources/app_settings/supported_links_dialog.ts index 3b38b41..47cf4202 100644 --- a/chrome/browser/resources/app_settings/supported_links_dialog.ts +++ b/chrome/browser/resources/app_settings/supported_links_dialog.ts
@@ -31,7 +31,7 @@ }; } - app: App = createDummyApp(); + accessor app: App = createDummyApp(); override firstUpdated() { this.addEventListener('keydown', e => this.trapDialogFocus_(e));
diff --git a/chrome/browser/resources/app_settings/supported_links_item.ts b/chrome/browser/resources/app_settings/supported_links_item.ts index c6d8e7e..2a33899 100644 --- a/chrome/browser/resources/app_settings/supported_links_item.ts +++ b/chrome/browser/resources/app_settings/supported_links_item.ts
@@ -83,15 +83,15 @@ }; } - app: App = createDummyApp(); - apps: AppMap = {}; - override hidden: boolean = false; - protected disabled_: boolean = false; - protected overlappingAppsWarning_: string = ''; - protected overlappingAppIds_: string[] = []; - protected showOverlappingAppsDialog_: boolean = false; - protected showOverlappingAppsWarning_: boolean = false; - protected showSupportedLinksDialog_: boolean = false; + accessor app: App = createDummyApp(); + accessor apps: AppMap = {}; + override accessor hidden: boolean = false; + protected accessor disabled_: boolean = false; + protected accessor overlappingAppsWarning_: string = ''; + protected accessor overlappingAppIds_: string[] = []; + protected accessor showOverlappingAppsDialog_: boolean = false; + protected accessor showOverlappingAppsWarning_: boolean = false; + protected accessor showSupportedLinksDialog_: boolean = false; override willUpdate(changedProperties: PropertyValues<this>) { super.willUpdate(changedProperties);
diff --git a/chrome/browser/resources/app_settings/supported_links_overlapping_apps_dialog.ts b/chrome/browser/resources/app_settings/supported_links_overlapping_apps_dialog.ts index e7a60af..e445d7a 100644 --- a/chrome/browser/resources/app_settings/supported_links_overlapping_apps_dialog.ts +++ b/chrome/browser/resources/app_settings/supported_links_overlapping_apps_dialog.ts
@@ -48,9 +48,9 @@ }; } - app: App = createDummyApp(); - overlappingAppIds: string[] = []; - apps: AppMap = {}; + accessor app: App = createDummyApp(); + accessor overlappingAppIds: string[] = []; + accessor apps: AppMap = {}; protected getBodyText_(): string { const appNames: string[] = this.overlappingAppIds.map(appId => {
diff --git a/chrome/browser/resources/app_settings/toggle_row.ts b/chrome/browser/resources/app_settings/toggle_row.ts index 2b129aca3..9c1aa28 100644 --- a/chrome/browser/resources/app_settings/toggle_row.ts +++ b/chrome/browser/resources/app_settings/toggle_row.ts
@@ -49,12 +49,12 @@ }; } - icon: string = ''; - label: string = ''; - managed: boolean = false; - disabled: boolean = false; - value: boolean = false; - description: string = ''; + accessor icon: string = ''; + accessor label: string = ''; + accessor managed: boolean = false; + accessor disabled: boolean = false; + accessor value: boolean = false; + accessor description: string = ''; override firstUpdated() { this.addEventListener('click', this.onClick_);
diff --git a/chrome/browser/resources/app_settings/uninstall_button.ts b/chrome/browser/resources/app_settings/uninstall_button.ts index 9fba3fa9..6fb478fb 100644 --- a/chrome/browser/resources/app_settings/uninstall_button.ts +++ b/chrome/browser/resources/app_settings/uninstall_button.ts
@@ -37,9 +37,9 @@ }; } - app: App = createDummyApp(); - uninstallLabel: string = ''; - policyLabel: string = ''; + accessor app: App = createDummyApp(); + accessor uninstallLabel: string = ''; + accessor policyLabel: string = ''; /** * Returns true if the button should be disabled due to app install type.
diff --git a/chrome/browser/resources/app_settings/window_mode_item.ts b/chrome/browser/resources/app_settings/window_mode_item.ts index e3dc79b4..052dd92 100644 --- a/chrome/browser/resources/app_settings/window_mode_item.ts +++ b/chrome/browser/resources/app_settings/window_mode_item.ts
@@ -58,9 +58,9 @@ }; } - windowModeLabel: string = ''; - app: App = createDummyApp(); - override hidden: boolean = false; + accessor windowModeLabel: string = ''; + accessor app: App = createDummyApp(); + override accessor hidden: boolean = false; override willUpdate(changedProperties: PropertyValues<this>) { super.willUpdate(changedProperties);
diff --git a/chrome/browser/resources/ash/settings/common/load_time_booleans.ts b/chrome/browser/resources/ash/settings/common/load_time_booleans.ts index 65d34711..79cd511 100644 --- a/chrome/browser/resources/ash/settings/common/load_time_booleans.ts +++ b/chrome/browser/resources/ash/settings/common/load_time_booleans.ts
@@ -111,10 +111,6 @@ return loadTimeData.getBoolean('isLobsterSettingsToggleVisible'); } -export function isSunfishSettingsToggleVisible(): boolean { - return loadTimeData.getBoolean('isSunfishSettingsToggleVisible'); -} - export function isScannerSettingsToggleVisible(): boolean { return loadTimeData.getBoolean('isScannerSettingsToggleVisible'); }
diff --git a/chrome/browser/resources/ash/settings/metrics_utils.ts b/chrome/browser/resources/ash/settings/metrics_utils.ts index 2a960ad8..5ac882f 100644 --- a/chrome/browser/resources/ash/settings/metrics_utils.ts +++ b/chrome/browser/resources/ash/settings/metrics_utils.ts
@@ -266,10 +266,6 @@ setting: Setting.kLobsterOnOff, type: PrefType.BOOLEAN, }, - 'ash.capture_mode.sunfish_enabled': { - setting: Setting.kSunfishOnOff, - type: PrefType.BOOLEAN, - }, 'ash.scanner.enabled': { setting: Setting.kScannerOnOff, type: PrefType.BOOLEAN,
diff --git a/chrome/browser/resources/ash/settings/os_languages_page/os_japanese_dictionary_expand.html b/chrome/browser/resources/ash/settings/os_languages_page/os_japanese_dictionary_expand.html index c4fe971..3451b4e 100644 --- a/chrome/browser/resources/ash/settings/os_languages_page/os_japanese_dictionary_expand.html +++ b/chrome/browser/resources/ash/settings/os_languages_page/os_japanese_dictionary_expand.html
@@ -8,6 +8,11 @@ display: flex; justify-content: space-between; } + + .button-container { + display: flex; + gap: 8px; + } </style> <cr-expand-button expanded="{{expanded_}}" class="cr-row"> @@ -19,7 +24,7 @@ label="Dictionary name" type="text" on-change="saveName_"></cr-input> - <div> + <div class="button-container"> <cr-icon-button class="delete-icon" iron-icon="cr:delete" on-click="deleteDictionary_"
diff --git a/chrome/browser/resources/ash/settings/os_search_page/search_and_assistant_settings_card.html b/chrome/browser/resources/ash/settings/os_search_page/search_and_assistant_settings_card.html index 14a427a..a7aa7ced 100644 --- a/chrome/browser/resources/ash/settings/os_search_page/search_and_assistant_settings_card.html +++ b/chrome/browser/resources/ash/settings/os_search_page/search_and_assistant_settings_card.html
@@ -180,17 +180,6 @@ </iron-collapse> </template> - <template is="dom-if" if="[[isSunfishSettingsToggleVisible_]]"> - <!-- TODO: b/395736972 - Localise the label and add an icon, sublabel and - learn more link. --> - <settings-toggle-button - id="sunfishToggle" - class="hr" - pref="{{prefs.ash.capture_mode.sunfish_enabled}}" - label="Enable Sunfish" - deep-link-focus-id$="[[Setting.kSunfishOnOff]]"> - </settings-toggle-button> - </template> <template is="dom-if" if="[[isScannerSettingsToggleVisible_]]"> <!-- TODO: crbug.com/404069127 - Add a learn more link. --> <!-- \`restamp\` is needed to ensure that deep links work correctly if
diff --git a/chrome/browser/resources/ash/settings/os_search_page/search_and_assistant_settings_card.ts b/chrome/browser/resources/ash/settings/os_search_page/search_and_assistant_settings_card.ts index b7b843b9..3ea739b 100644 --- a/chrome/browser/resources/ash/settings/os_search_page/search_and_assistant_settings_card.ts +++ b/chrome/browser/resources/ash/settings/os_search_page/search_and_assistant_settings_card.ts
@@ -23,7 +23,7 @@ import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {DeepLinkingMixin} from '../common/deep_linking_mixin.js'; -import {isAssistantAllowed, isLobsterSettingsToggleVisible, isMagicBoostFeatureEnabled, isMagicBoostNoticeBannerVisible, isQuickAnswersSupported, isScannerSettingsToggleVisible, isSunfishSettingsToggleVisible} from '../common/load_time_booleans.js'; +import {isAssistantAllowed, isLobsterSettingsToggleVisible, isMagicBoostFeatureEnabled, isMagicBoostNoticeBannerVisible, isQuickAnswersSupported, isScannerSettingsToggleVisible} from '../common/load_time_booleans.js'; import {RouteOriginMixin} from '../common/route_origin_mixin.js'; import type {PrefsState} from '../common/types.js'; import {Setting} from '../mojom-webui/setting.mojom-webui.js'; @@ -82,14 +82,6 @@ }, }, - isSunfishSettingsToggleVisible_: { - type: Boolean, - readOnly: true, - value: () => { - return isSunfishSettingsToggleVisible(); - }, - }, - isScannerSettingsToggleVisible_: { type: Boolean, readOnly: true, @@ -158,7 +150,6 @@ private isAssistantAllowed_: boolean; private isQuickAnswersSupported_: boolean; private isMagicBoostFeatureEnabled_: boolean; - private readonly isSunfishSettingsToggleVisible_: boolean; private readonly isScannerSettingsToggleVisible_: boolean; constructor() {
diff --git a/chrome/browser/resources/bookmarks/BUILD.gn b/chrome/browser/resources/bookmarks/BUILD.gn index ae69738..41f91ae 100644 --- a/chrome/browser/resources/bookmarks/BUILD.gn +++ b/chrome/browser/resources/bookmarks/BUILD.gn
@@ -54,7 +54,7 @@ ] ts_composite = true - + ts_tsconfig_base = "//tools/typescript/tsconfig_base_lit_389737066.json" ts_definitions = [ "//tools/typescript/definitions/bookmark_manager_private.d.ts", "//tools/typescript/definitions/bookmarks.d.ts",
diff --git a/chrome/browser/resources/bookmarks/app.ts b/chrome/browser/resources/bookmarks/app.ts index e5c691d5..968bcee8 100644 --- a/chrome/browser/resources/bookmarks/app.ts +++ b/chrome/browser/resources/bookmarks/app.ts
@@ -72,10 +72,10 @@ }; } - private folderOpenState_?: FolderOpenState; - private searchTerm_?: string; - protected sidebarWidth_: string = ''; - protected toolbarShadow_: boolean = false; + private accessor folderOpenState_: FolderOpenState|undefined; + private accessor searchTerm_: string|undefined; + protected accessor sidebarWidth_: string = ''; + protected accessor toolbarShadow_: boolean = false; private eventTracker_: EventTracker = new EventTracker(); private dndManager_: DndManager|null = null; private router_: BookmarksRouter = new BookmarksRouter();
diff --git a/chrome/browser/resources/bookmarks/command_manager.ts b/chrome/browser/resources/bookmarks/command_manager.ts index 175054e..3e922831 100644 --- a/chrome/browser/resources/bookmarks/command_manager.ts +++ b/chrome/browser/resources/bookmarks/command_manager.ts
@@ -80,13 +80,13 @@ * menu is not open, indicating that commands are from keyboard shortcuts * or elsewhere in the UI. */ - private menuSource_: MenuSource = MenuSource.NONE; + private accessor menuSource_: MenuSource = MenuSource.NONE; private confirmOpenCallback_: (() => void)|null = null; - private canPaste_: boolean = false; - private globalCanEdit_: boolean = false; - protected menuIds_: Set<string> = new Set<string>(); - protected showEditDialog_: boolean = false; - protected showOpenDialog_: boolean = false; + private accessor canPaste_: boolean = false; + private accessor globalCanEdit_: boolean = false; + protected accessor menuIds_: Set<string> = new Set<string>(); + protected accessor showEditDialog_: boolean = false; + protected accessor showOpenDialog_: boolean = false; private browserProxy_: BrowserProxy = BrowserProxyImpl.getInstance(); private shortcuts_: Map<Command, KeyboardShortcutList> = new Map(); private eventTracker_: EventTracker = new EventTracker();
diff --git a/chrome/browser/resources/bookmarks/edit_dialog.ts b/chrome/browser/resources/bookmarks/edit_dialog.ts index 5f44f45..08b4b4b 100644 --- a/chrome/browser/resources/bookmarks/edit_dialog.ts +++ b/chrome/browser/resources/bookmarks/edit_dialog.ts
@@ -61,12 +61,12 @@ }; } - protected isFolder_: boolean = false; - private isEdit_: boolean = false; - private editItem_: BookmarkNode|null = null; - private parentId_: string|null = null; - protected titleValue_: string = ''; - protected urlValue_: string = ''; + protected accessor isFolder_: boolean = false; + private accessor isEdit_: boolean = false; + private accessor editItem_: BookmarkNode|null = null; + private accessor parentId_: string|null = null; + protected accessor titleValue_: string = ''; + protected accessor urlValue_: string = ''; /** * Show the dialog to add a new folder (if |isFolder|) or item, which will be
diff --git a/chrome/browser/resources/bookmarks/folder_node.ts b/chrome/browser/resources/bookmarks/folder_node.ts index 1a24459..7a7b4db7 100644 --- a/chrome/browser/resources/bookmarks/folder_node.ts +++ b/chrome/browser/resources/bookmarks/folder_node.ts
@@ -62,15 +62,15 @@ }; } - depth: number = -1; - isOpen: boolean = false; - itemId: string = ''; - protected item_?: BookmarkNode; - private openState_: boolean|null = null; - private selectedFolder_: string = ''; - private searchActive_: boolean = false; - protected isSelectedFolder_: boolean = false; - protected hasChildFolder_: boolean = false; + accessor depth: number = -1; + accessor isOpen: boolean = false; + accessor itemId: string = ''; + protected accessor item_: BookmarkNode|undefined; + private accessor openState_: boolean|null = null; + private accessor selectedFolder_: string = ''; + private accessor searchActive_: boolean = false; + protected accessor isSelectedFolder_: boolean = false; + protected accessor hasChildFolder_: boolean = false; override firstUpdated(changedProperties: PropertyValues<this>) { super.firstUpdated(changedProperties);
diff --git a/chrome/browser/resources/bookmarks/item.ts b/chrome/browser/resources/bookmarks/item.ts index 7930f471..cb36e591 100644 --- a/chrome/browser/resources/bookmarks/item.ts +++ b/chrome/browser/resources/bookmarks/item.ts
@@ -58,13 +58,13 @@ }; } - itemId: string = ''; - ironListTabIndex?: number; - protected item_?: BookmarkNode; - private isSelectedItem_: boolean = false; - private isMultiSelect_: boolean = false; - private isFolder_: boolean = false; - private lastTouchPoints_: number = -1; + accessor itemId: string = ''; + accessor ironListTabIndex: number|undefined; + protected accessor item_: BookmarkNode|undefined; + private accessor isSelectedItem_: boolean = false; + private accessor isMultiSelect_: boolean = false; + private accessor isFolder_: boolean = false; + private accessor lastTouchPoints_: number = -1; override firstUpdated(changedProperties: PropertyValues<this>) { super.firstUpdated(changedProperties);
diff --git a/chrome/browser/resources/bookmarks/list.ts b/chrome/browser/resources/bookmarks/list.ts index 71a0e6c..a50a8a14 100644 --- a/chrome/browser/resources/bookmarks/list.ts +++ b/chrome/browser/resources/bookmarks/list.ts
@@ -58,12 +58,12 @@ }; } - protected displayedIds_: string[] = []; - private focusedIndex_: number = 0; + protected accessor displayedIds_: string[] = []; + private accessor focusedIndex_: number = 0; private eventTracker_: EventTracker = new EventTracker(); - private searchTerm_: string = ''; - protected selectedFolder_: string = ''; - private selectedItems_: Set<string> = new Set(); + private accessor searchTerm_: string = ''; + protected accessor selectedFolder_: string = ''; + private accessor selectedItems_: Set<string> = new Set(); override firstUpdated() { this.addEventListener('click', () => this.deselectItems_());
diff --git a/chrome/browser/resources/bookmarks/toolbar.ts b/chrome/browser/resources/bookmarks/toolbar.ts index 8c8c1f1..e3bee2b 100644 --- a/chrome/browser/resources/bookmarks/toolbar.ts +++ b/chrome/browser/resources/bookmarks/toolbar.ts
@@ -55,12 +55,12 @@ }; } - sidebarWidth: string = ''; - showSelectionOverlay: boolean = false; - protected narrow_: boolean = false; - private searchTerm_: string = ''; - private selectedItems_: Set<string> = new Set(); - private globalCanEdit_: boolean = false; + accessor sidebarWidth: string = ''; + accessor showSelectionOverlay: boolean = false; + protected accessor narrow_: boolean = false; + private accessor searchTerm_: string = ''; + private accessor selectedItems_: Set<string> = new Set(); + private accessor globalCanEdit_: boolean = false; override connectedCallback() { super.connectedCallback();
diff --git a/chrome/browser/resources/compose/app.ts b/chrome/browser/resources/compose/app.ts index 041504e..a01454c 100644 --- a/chrome/browser/resources/compose/app.ts +++ b/chrome/browser/resources/compose/app.ts
@@ -49,6 +49,12 @@ isEditingSubmittedInput?: boolean; } +interface ModifierOption { + value: StyleModifier; + label: string; + isDefault: boolean; +} + export interface ComposeAppElement { $: { firstRunDialog: HTMLElement, @@ -295,8 +301,10 @@ private isEditSubmitEnabled_: boolean; private isSubmitEnabled_: boolean; private loading_: boolean; + private loadingIndicatorShown_: boolean; private response_: ComposeResponse|null; private partialResponse_: PartialComposeResponse|undefined; + private showInputModes_: boolean; private saveAppStateDebouncer_: Debouncer; private scrollCheckDebouncer_: Debouncer; private updateResultCompleteDebouncer_: Debouncer; @@ -314,6 +322,7 @@ private outputComplete_: boolean = true; private hasOutput_: boolean = false; private displayedText_: string; + private modifierOptions_: ModifierOption[]; private responseText_: string; private userResponseText_: string|undefined;
diff --git a/chrome/browser/resources/compose/result_text.ts b/chrome/browser/resources/compose/result_text.ts index 9a706403..249a5b8 100644 --- a/chrome/browser/resources/compose/result_text.ts +++ b/chrome/browser/resources/compose/result_text.ts
@@ -90,6 +90,7 @@ // Private regular properties. private wordStreamer_: WordStreamer; + private hasPartialOutput_: boolean; private displayedChunks_: StreamChunk[] = []; private displayedFullText_: string = ''; private initialText_: string = '';
diff --git a/chrome/browser/resources/glic/fre/fre.css b/chrome/browser/resources/glic/fre/fre.css index 27c5bcf..2a75001 100644 --- a/chrome/browser/resources/glic/fre/fre.css +++ b/chrome/browser/resources/glic/fre/fre.css
@@ -77,6 +77,11 @@ border: 0; } +#webviewContainer { + width: 100%; + height: 100%; +} + .tonal-button { margin-top: 8px; background-color: var(--cr-fallback-color-tonal-container);
diff --git a/chrome/browser/resources/glic/fre/fre.html b/chrome/browser/resources/glic/fre/fre.html index aa289bd..f76935a 100644 --- a/chrome/browser/resources/glic/fre/fre.html +++ b/chrome/browser/resources/glic/fre/fre.html
@@ -27,9 +27,21 @@ </div> </div> </section> + <section hidden class="dialog panel" id="offlinePanel"> + <div class="header"> + <cr-icon-button class="close-button" iron-icon="cr:close"> + </cr-icon-button> + </div> + <div class="container"> + <div class="notice"> + <div class="icon"><cr-icon icon="glic:offline"></cr-icon></div> + <p class="headline">$i18n{offlineNoticeHeader}</p> + <p>$i18n{offlineNoticeAction}</p> + </div> + </div> + </section> <section hidden class="panel" id="guestPanel"> - <webview id="fre-guest-frame" partition="glicfrepart"> - </webview> + <div id="webviewContainer"></div> </section> </body> </html> \ No newline at end of file
diff --git a/chrome/browser/resources/glic/fre/fre_app_controller.ts b/chrome/browser/resources/glic/fre/fre_app_controller.ts index e775e27..9dc0476 100644 --- a/chrome/browser/resources/glic/fre/fre_app_controller.ts +++ b/chrome/browser/resources/glic/fre/fre_app_controller.ts
@@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {EventTracker} from '//resources/js/event_tracker.js'; import {loadTimeData} from '//resources/js/load_time_data.js'; +import {getRequiredElement} from 'chrome://resources/js/util.js'; import {FrePageHandlerFactory, FrePageHandlerRemote, FreWebUiState} from './glic_fre.mojom-webui.js'; @@ -11,6 +13,16 @@ onExit?: () => void; } +interface PageElementTypes { + webviewContainer: HTMLDivElement; +} + +const $: PageElementTypes = new Proxy({}, { + get(_target: any, prop: string) { + return getRequiredElement(prop); + }, +}); + type PanelId = 'guestPanel'|'offlinePanel'|'errorPanel'; // Maximum time to wait for load before showing error panel. @@ -26,15 +38,22 @@ // Created from constructor and never null since the destructor replaces it // with an empty <webview>. - webview: chrome.webviewTag.WebView; + private webview: chrome.webviewTag.WebView; + private webviewEventTracker = new EventTracker(); constructor() { this.onLoadCommit = this.onLoadCommit.bind(this); - this.contentLoaded = this.contentLoaded.bind(this); + this.onContentLoad = this.onContentLoad.bind(this); this.onNewWindow = this.onNewWindow.bind(this); - this.webview = this.createWebView(); + this.webview = this.createWebview(); + window.addEventListener('online', () => { + this.online(); + }); + window.addEventListener('offline', () => { + this.offline(); + }); window.addEventListener('load', () => { // Allow WebUI close button to close the window. This close button is // present on all UI states except for `FreWebUiState.kReady`. @@ -43,17 +62,11 @@ }); }); - this.setState(FreWebUiState.kBeginLoading); - } - - createWebView(): chrome.webviewTag.WebView { - const webview = - document.getElementById('fre-guest-frame') as chrome.webviewTag.WebView; - webview.addEventListener('loadcommit', this.onLoadCommit); - webview.addEventListener('contentload', this.contentLoaded); - webview.addEventListener('newwindow', this.onNewWindow); - - return webview; + if (navigator.onLine) { + this.setState(FreWebUiState.kBeginLoading); + } else { + this.setState(FreWebUiState.kOffline); + } } onLoadCommit(e: any) { @@ -74,7 +87,7 @@ } } - contentLoaded() { + onContentLoad() { this.setState(FreWebUiState.kReady); } @@ -86,6 +99,25 @@ e.stopPropagation(); } + online(): void { + if (this.state !== FreWebUiState.kOffline) { + return; + } + this.setState(FreWebUiState.kBeginLoading); + } + + offline(): void { + const allowedStates = [ + FreWebUiState.kBeginLoading, + FreWebUiState.kShowLoading, + FreWebUiState.kFinishLoading, + FreWebUiState.kReady, + ]; + if (allowedStates.includes(this.state)) { + this.setState(FreWebUiState.kOffline); + } + } + private showPanel(id: PanelId): void { for (const panel of document.querySelectorAll<HTMLElement>('.panel')) { panel.hidden = panel.id !== id; @@ -157,14 +189,40 @@ } } - beginLoading(): void { - // TODO crbug.com/393417356. Check cookies and load the web client after - // cookie sync. Set up the timer to transition to show loading after a - // determined prehold loading time. + async beginLoading(): Promise<void> { + // Attempt to re-sync cookies before continuing. + const {success} = await freHandler.prepareForClient(); + if (!success) { + this.setState(FreWebUiState.kError); + return; + } + + // Load the web client now that cookie sync is complete. + this.destroyWebview(); + + // TODO(crbug.com/393417356): Set up a timer to transition to showLoading + // state after a determined prehold loading time. this.webview.src = loadTimeData.getString('glicFreURL'); this.setState(FreWebUiState.kShowLoading); } + private createWebview(): chrome.webviewTag.WebView { + const webview = + document.createElement('webview') as chrome.webviewTag.WebView; + webview.id = 'freGuestFrame'; + webview.setAttribute('partition', 'glicfrepart'); + $.webviewContainer.appendChild(webview); + + this.webviewEventTracker.add( + webview, 'loadcommit', this.onLoadCommit.bind(this)); + this.webviewEventTracker.add( + webview, 'contentload', this.onContentLoad.bind(this)); + this.webviewEventTracker.add( + webview, 'newwindow', this.onNewWindow.bind(this)); + + return webview; + } + showLoading(): void { // TODO crbug.com/393417356. Show a loading panel and transition to finish // loading after a minimum hold loading time. @@ -184,7 +242,7 @@ finishLoading(): void { // The web client is not yet ready, so wait for the remainder of // `kMaxWaitTimeMs`. Switch to error state at that time unless interrupted - // by `contentLoaded`. + // by `onContentLoad`. this.loadingTimer = setTimeout(() => { this.setState(FreWebUiState.kError); }, kMaxWaitTimeMs); @@ -193,10 +251,10 @@ // Destroy the current webview and create a new one. This is necessary because // webview does not support unloading content by setting src="" destroyWebview(): void { - this.webview.removeEventListener('loadcommit', this.onLoadCommit); - this.webview.removeEventListener('contentload', this.contentLoaded); - this.webview.removeEventListener('newwindow', this.onNewWindow); + this.webviewEventTracker.removeAll(); - this.webview = this.createWebView(); + $.webviewContainer.removeChild(this.webview); + + this.webview = this.createWebview(); } }
diff --git a/chrome/browser/resources/glic/fre/icons.html.ts b/chrome/browser/resources/glic/fre/icons.html.ts index 3af7512..7b91372ca 100644 --- a/chrome/browser/resources/glic/fre/icons.html.ts +++ b/chrome/browser/resources/glic/fre/icons.html.ts
@@ -34,6 +34,25 @@ 4.325 5.075C2.775 6.625 2 8.51667 2 10.75C2 12.9833 2.775 14.875 4.325 16.425C5.875 17.975 7.76667 18.75 10 18.75Z"/> </g> + <g id="offline"> + <path d="M20.25 20.1L10.85 10.65C10.0667 10.8333 9.33333 11.1083 8.65 +11.475C7.98333 11.8417 7.38333 12.3 6.85 12.85L4.75 10.7C5.28333 10.1667 5.85833 +9.7 6.475 9.3C7.09167 8.9 7.75 8.55 8.45 8.25L6.2 6C5.51667 6.35 4.875 6.74167 +4.275 7.175C3.69167 7.59167 3.13333 8.06667 2.6 8.6L0.5 6.45C1.03333 5.91667 +1.58333 5.44167 2.15 5.025C2.73333 4.59167 3.35 4.18333 4 3.8L1.9 1.7L3.3 +0.299999L21.7 18.7L20.25 20.1ZM12.5 18.5C11.8 18.5 11.2083 18.2583 10.725 +17.775C10.2417 17.275 10 16.6833 10 16C10 15.3 10.2417 14.7083 10.725 +14.225C11.2083 13.7417 11.8 13.5 12.5 13.5C13.2 13.5 13.7917 13.7417 14.275 +14.225C14.7583 14.7083 15 15.3 15 16C15 16.6833 14.7583 17.275 14.275 +17.775C13.7917 18.2583 13.2 18.5 12.5 18.5ZM18.4 12.55C18.1167 12.2667 17.875 +12.025 17.675 11.825C17.475 11.625 17.2333 11.3833 16.95 11.1L13.35 7.5C14.7 +7.63333 15.9583 7.975 17.125 8.525C18.3083 9.075 19.35 9.8 20.25 10.7L18.4 +12.55ZM22.4 8.6C21.1167 7.31667 19.625 6.31667 17.925 5.6C16.2417 4.86667 +14.4333 4.5 12.5 4.5C12.15 4.5 11.8083 4.51667 11.475 4.55C11.1583 4.56667 +10.8333 4.6 10.5 4.65L7.95 2.1C8.68333 1.9 9.425 1.75 10.175 1.65C10.9417 1.55 +11.7167 1.5 12.5 1.5C14.8667 1.5 17.075 1.94167 19.125 2.825C21.175 3.70833 +22.9667 4.91667 24.5 6.45L22.4 8.6Z"/> + </g> </defs> </svg> </cr-iconset>`;
diff --git a/chrome/browser/resources/glic/glic_api/glic_api.ts b/chrome/browser/resources/glic/glic_api/glic_api.ts index c87508c3..cb68f6d 100644 --- a/chrome/browser/resources/glic/glic_api/glic_api.ts +++ b/chrome/browser/resources/glic/glic_api/glic_api.ts
@@ -407,7 +407,8 @@ /** * Opens the OS permission settings menu for the given permission type. - * Supports `media` for microphone ad `geolocation` for location. + * Supports `media` for microphone ad `geolocation` for location. This + * function is available when running on Mac. */ openOsPermissionSettingsMenu?(permission: string): void;
diff --git a/chrome/browser/resources/glic/glic_api_impl/glic_api_client.ts b/chrome/browser/resources/glic/glic_api_impl/glic_api_client.ts index f6846735..8df1c65 100644 --- a/chrome/browser/resources/glic/glic_api_impl/glic_api_client.ts +++ b/chrome/browser/resources/glic/glic_api_impl/glic_api_client.ts
@@ -246,6 +246,10 @@ if (!state.dragResizeEnabled) { (this as GlicBrowserHost).enableDragResize = undefined; } + + if (!state.openOsSettingsApiIsAllowed) { + (this as GlicBrowserHost).openOsPermissionSettingsMenu = undefined; + } } webClientInitialized(
diff --git a/chrome/browser/resources/lens/overlay/lens_overlay_app.ts b/chrome/browser/resources/lens/overlay/lens_overlay_app.ts index 4a868b1..88f9aedd 100644 --- a/chrome/browser/resources/lens/overlay/lens_overlay_app.ts +++ b/chrome/browser/resources/lens/overlay/lens_overlay_app.ts
@@ -199,6 +199,7 @@ private isPointerDown: boolean = false; // Whether the button containers should be faded out. private shouldFadeOutButtons: boolean = false; + private darkMode: boolean; // The overlay theme. private theme: OverlayTheme; // Whether the contextual searchbox feature is enabled.
diff --git a/chrome/browser/resources/lens/overlay/object_layer.ts b/chrome/browser/resources/lens/overlay/object_layer.ts index b95b1aa..9deaf686f 100644 --- a/chrome/browser/resources/lens/overlay/object_layer.ts +++ b/chrome/browser/resources/lens/overlay/object_layer.ts
@@ -205,6 +205,7 @@ // The last post selection made. Updated by events from the post selection // layer. private lastPostSelection: PostSelectionBoundingBox|null = null; + private debugMode: boolean; // The overlay theme. private theme: OverlayTheme; private fadeOutAnimations: Animation[] = [];
diff --git a/chrome/browser/resources/lens/overlay/selection_overlay.ts b/chrome/browser/resources/lens/overlay/selection_overlay.ts index 9f1b28a..e1825e7 100644 --- a/chrome/browser/resources/lens/overlay/selection_overlay.ts +++ b/chrome/browser/resources/lens/overlay/selection_overlay.ts
@@ -24,6 +24,7 @@ import {type CursorTooltipData, CursorTooltipType} from './cursor_tooltip.js'; import type {CenterRotatedBox} from './geometry.mojom-webui.js'; import {UserAction} from './lens.mojom-webui.js'; +import type {OverlayTheme} from './lens.mojom-webui.js'; import {INVOCATION_SOURCE} from './lens_overlay_app.js'; import {ContextMenuOption, recordContextMenuOptionShown, recordLensOverlayInteraction} from './metrics_utils.js'; import type {ObjectLayerElement} from './object_layer.js'; @@ -296,6 +297,8 @@ private onPointerMoveRequestId?: number; private handleResizeRequestId?: number; + private theme: OverlayTheme; + // Whether or not translate mode is enabled. If true, only text should // be selectable, and it should be selectable from any point in the // overlay.
diff --git a/chrome/browser/resources/lens/overlay/side_panel/side_panel_app.ts b/chrome/browser/resources/lens/overlay/side_panel/side_panel_app.ts index 3d95a5a..8b9a603d3 100644 --- a/chrome/browser/resources/lens/overlay/side_panel/side_panel_app.ts +++ b/chrome/browser/resources/lens/overlay/side_panel/side_panel_app.ts
@@ -145,12 +145,15 @@ isBackArrowVisible: boolean; // Whether the user is currently focused into the searchbox. isSearchboxFocused: boolean; + private showGhostLoader: boolean; // Whether to purposely suppress the ghost loader. Done when escaping from // the searchbox when there's text or when page bytes aren't successfully // uploaded. suppressGhostLoader: boolean; + placeholderText: string; // Whether the ghost loader should show its error state. showErrorState: boolean; + private showUploadProgress: boolean; // The current progress of the page content upload. uploadProgressPercentage: number; // The placeholder text to show in the searchbox.
diff --git a/chrome/browser/resources/lens/overlay/side_panel/side_panel_ghost_loader.ts b/chrome/browser/resources/lens/overlay/side_panel/side_panel_ghost_loader.ts index 3fcb9dda..e73e0eb 100644 --- a/chrome/browser/resources/lens/overlay/side_panel/side_panel_ghost_loader.ts +++ b/chrome/browser/resources/lens/overlay/side_panel/side_panel_ghost_loader.ts
@@ -21,7 +21,6 @@ static get properties() { return { - squares: Array, darkMode: { type: Boolean, value: () => loadTimeData.getBoolean('darkMode'),
diff --git a/chrome/browser/resources/lens/overlay/text_layer.ts b/chrome/browser/resources/lens/overlay/text_layer.ts index e0e95c4b..70e840c 100644 --- a/chrome/browser/resources/lens/overlay/text_layer.ts +++ b/chrome/browser/resources/lens/overlay/text_layer.ts
@@ -181,6 +181,7 @@ // The index of the word in renderedWords at the end of the current selection. // -1 if no current selection. private selectionEndIndex: number; + private debugMode: boolean; // Whether the user is currently selecting text. private isSelectingText: boolean; // The bounds of the parent element. This is updated by the parent to avoid
diff --git a/chrome/browser/resources/lens/overlay/translate_button.ts b/chrome/browser/resources/lens/overlay/translate_button.ts index e870c4b..607b97f 100644 --- a/chrome/browser/resources/lens/overlay/translate_button.ts +++ b/chrome/browser/resources/lens/overlay/translate_button.ts
@@ -194,9 +194,11 @@ private searchedLanguageList: SearchedLanguage[] = []; // Whether the stars icon is visible on the source language button. private shouldShowStarsIcon: boolean; + private sourceLanguageList: Language[]; // The currently selected source language to translate to. If null, we should // auto detect the language. private sourceLanguage: Language|null = null; + private targetLanguageList: Language[]; // The currently selected target language to translate to. private targetLanguage: Language|null = null; // Whether the source language menu picker is visible.
diff --git a/chrome/browser/resources/lens/shared/searchbox_ghost_loader.ts b/chrome/browser/resources/lens/shared/searchbox_ghost_loader.ts index 4833d1ff..afc0a7a 100644 --- a/chrome/browser/resources/lens/shared/searchbox_ghost_loader.ts +++ b/chrome/browser/resources/lens/shared/searchbox_ghost_loader.ts
@@ -63,6 +63,7 @@ private pageContentType: PageContentType; private browserProxy: BrowserProxy = BrowserProxyImpl.getInstance(); private listenerIds: number[]; + private ghostLoaderPrimaryMessage: string; override connectedCallback() { super.connectedCallback();
diff --git a/chrome/browser/resources/pdf/elements/ink_color_selector.html.ts b/chrome/browser/resources/pdf/elements/ink_color_selector.html.ts index cd487c0..831ca341 100644 --- a/chrome/browser/resources/pdf/elements/ink_color_selector.html.ts +++ b/chrome/browser/resources/pdf/elements/ink_color_selector.html.ts
@@ -18,6 +18,7 @@ name="${this.getColorName_()}" .value="${item.color}" .style="--item-color: ${this.getVisibleColor_(item.color)}" aria-label="${this.i18n(item.label)}" + tabindex="${this.getTabIndex_(item.color)}" title="${this.i18n(item.label)}" @click="${this.onColorClick_}" ?checked="${this.isCurrentColor_(item.color)}">
diff --git a/chrome/browser/resources/pdf/elements/ink_color_selector.ts b/chrome/browser/resources/pdf/elements/ink_color_selector.ts index c92bc8d9..fae4d62 100644 --- a/chrome/browser/resources/pdf/elements/ink_color_selector.ts +++ b/chrome/browser/resources/pdf/elements/ink_color_selector.ts
@@ -114,6 +114,10 @@ selectedButton.focus(); } + protected getTabIndex_(color: string): number { + return this.isCurrentColor_(color) ? 0 : -1; + } + protected isCurrentColor_(hex: string): boolean { return areColorsEqual(this.currentColor, hexToColor(hex)); }
diff --git a/chrome/browser/resources/pdf/elements/selectable_icon_button.css b/chrome/browser/resources/pdf/elements/selectable_icon_button.css index 17240b8d..46e83e4 100644 --- a/chrome/browser/resources/pdf/elements/selectable_icon_button.css +++ b/chrome/browser/resources/pdf/elements/selectable_icon_button.css
@@ -5,6 +5,8 @@ /* #css_wrapper_metadata_start * #type=style-lit * #import=./shared_vars.css.js + * #import=./pdf_shared.css.js + * #include=pdf-shared * #css_wrapper_metadata_end */ cr-icon-button {
diff --git a/chrome/browser/resources/pdf/pdf_viewer.ts b/chrome/browser/resources/pdf/pdf_viewer.ts index 9365f658..673088b 100644 --- a/chrome/browser/resources/pdf/pdf_viewer.ts +++ b/chrome/browser/resources/pdf/pdf_viewer.ts
@@ -606,7 +606,7 @@ // <if expr="enable_ink"> /** Exits annotation mode if active. */ private async exitAnnotationMode_(): Promise<void> { - if (!this.$.toolbar.annotationMode) { + if (this.$.toolbar.annotationMode === AnnotationMode.NONE) { return; } this.$.toolbar.setAnnotationMode(AnnotationMode.NONE);
diff --git a/chrome/browser/resources/settings/a11y_page/captions_subpage.ts b/chrome/browser/resources/settings/a11y_page/captions_subpage.ts index 6625b7c..c4014cbc 100644 --- a/chrome/browser/resources/settings/a11y_page/captions_subpage.ts +++ b/chrome/browser/resources/settings/a11y_page/captions_subpage.ts
@@ -37,12 +37,6 @@ static get properties() { return { - prefs: { - type: Object, - notify: true, - }, - - /** * Read-only reference to the languages model provided by the * 'settings-languages' instance.
diff --git a/chrome/browser/resources/settings/a11y_page/live_caption_section.ts b/chrome/browser/resources/settings/a11y_page/live_caption_section.ts index bbc8dab..66e600c 100644 --- a/chrome/browser/resources/settings/a11y_page/live_caption_section.ts +++ b/chrome/browser/resources/settings/a11y_page/live_caption_section.ts
@@ -74,11 +74,6 @@ static get properties() { return { - prefs: { - type: Object, - notify: true, - }, - /** * The subtitle to display under the Live Caption heading. Generally, this * is a generic subtitle describing the feature. While the SODA model is
diff --git a/chrome/browser/resources/settings/a11y_page/live_translate_section.ts b/chrome/browser/resources/settings/a11y_page/live_translate_section.ts index c966277..c75f941 100644 --- a/chrome/browser/resources/settings/a11y_page/live_translate_section.ts +++ b/chrome/browser/resources/settings/a11y_page/live_translate_section.ts
@@ -48,11 +48,6 @@ static get properties() { return { - prefs: { - type: Object, - notify: true, - }, - /** * Read-only reference to the languages model provided by the * 'settings-languages' instance.
diff --git a/chrome/browser/resources/settings/autofill_page/payments_manager_proxy.ts b/chrome/browser/resources/settings/autofill_page/payments_manager_proxy.ts index 8becf6d..63a729b 100644 --- a/chrome/browser/resources/settings/autofill_page/payments_manager_proxy.ts +++ b/chrome/browser/resources/settings/autofill_page/payments_manager_proxy.ts
@@ -49,11 +49,6 @@ saveIban(iban: chrome.autofillPrivate.IbanEntry): void; /** - * Migrate the local credit cards. - */ - migrateCreditCards(): void; - - /** * Logs that the server cards edit link was clicked. */ logServerCardLinkClicked(): void; @@ -154,10 +149,6 @@ chrome.autofillPrivate.removePaymentsEntity(guid); } - migrateCreditCards() { - chrome.autofillPrivate.migrateCreditCards(); - } - logServerCardLinkClicked() { chrome.autofillPrivate.logServerCardLinkClicked(); }
diff --git a/chrome/browser/resources/settings/autofill_page/payments_section.html b/chrome/browser/resources/settings/autofill_page/payments_section.html index a0126b9..4ef03648 100644 --- a/chrome/browser/resources/settings/autofill_page/payments_section.html +++ b/chrome/browser/resources/settings/autofill_page/payments_section.html
@@ -17,14 +17,6 @@ padding-inline-start: 20px; } - #migrateCreditCards { - border-bottom: var(--cr-separator-line); - border-top: none; - } - - #migrateCreditCardsButton { - margin: 0 auto; - } </style> <settings-toggle-button id="autofillCreditCardToggle" no-extension-indicator label="$i18n{enableCreditCardsLabel}" @@ -129,12 +121,6 @@ </cr-lazy-render> </template> </div> -<cr-link-row id="migrateCreditCards" - hidden$="[[!checkIfMigratable_(creditCards, - prefs.autofill.credit_card_enabled.value)]]" - on-click="onMigrateCreditCardsClick_" - label="$i18n{migrateCreditCardsLabel}" - sub-label="[[migratableCreditCardsInfo_]]"></cr-link-row> <settings-payments-list id="paymentsList" class="list-frame payment-list-margin-start" credit-cards="[[creditCards]]"
diff --git a/chrome/browser/resources/settings/autofill_page/payments_section.ts b/chrome/browser/resources/settings/autofill_page/payments_section.ts index b0be04da..bd4e33a 100644 --- a/chrome/browser/resources/settings/autofill_page/payments_section.ts +++ b/chrome/browser/resources/settings/autofill_page/payments_section.ts
@@ -10,7 +10,6 @@ import '/shared/settings/prefs/prefs.js'; import 'chrome://resources/cr_elements/cr_action_menu/cr_action_menu.js'; import 'chrome://resources/cr_elements/cr_button/cr_button.js'; -import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js'; import 'chrome://resources/cr_elements/cr_shared_style.css.js'; import 'chrome://resources/cr_elements/cr_shared_vars.css.js'; import '../settings_shared.css.js'; @@ -71,7 +70,6 @@ menuRemoveCreditCard: HTMLElement, menuAddVirtualCard: HTMLElement, menuRemoveVirtualCard: HTMLElement, - migrateCreditCards: HTMLElement, paymentsList: SettingsPaymentsListElement, }; } @@ -142,21 +140,9 @@ showLocalCreditCardRemoveConfirmationDialog_: Boolean, showLocalIbanRemoveConfirmationDialog_: Boolean, showVirtualCardUnenrollDialog_: Boolean, - migratableCreditCardsInfo_: String, showBulkRemoveCvcConfirmationDialog_: Boolean, /** - * Whether migration local card on settings page is enabled. - */ - migrationEnabled_: { - type: Boolean, - value() { - return loadTimeData.getBoolean('migrationEnabled'); - }, - readOnly: true, - }, - - /** * Checks if we can use device authentication to authenticate the user. */ // <if expr="is_win or is_macosx"> @@ -235,8 +221,6 @@ private showLocalCreditCardRemoveConfirmationDialog_: boolean; private showLocalIbanRemoveConfirmationDialog_: boolean; private showVirtualCardUnenrollDialog_: boolean; - private migratableCreditCardsInfo_: string; - private migrationEnabled_: boolean; // <if expr="is_win or is_macosx"> private deviceAuthAvailable_: boolean; // </if> @@ -527,14 +511,6 @@ } /** - * Handles clicking on the "Migrate" button for migrate local credit - * cards. - */ - private onMigrateCreditCardsClick_() { - this.paymentsManager_.migrateCreditCards(); - } - - /** * Records changes made to the "Allow sites to check if you have payment * methods saved" setting to a histogram. */ @@ -555,38 +531,6 @@ this.paymentsManager_.saveIban(event.detail); } - /** - * @return Whether to show the migration button. - */ - private checkIfMigratable_( - creditCards: chrome.autofillPrivate.CreditCardEntry[], - creditCardEnabled: boolean): boolean { - // If migration prerequisites are not met, return false. - if (!this.migrationEnabled_) { - return false; - } - - // If credit card enabled pref is false, return false. - if (!creditCardEnabled) { - return false; - } - - const numberOfMigratableCreditCard = - creditCards.filter(card => card.metadata!.isMigratable).length; - // Check whether exist at least one local valid card for migration. - if (numberOfMigratableCreditCard === 0) { - return false; - } - - // Update the display text depends on the number of migratable credit - // cards. - this.migratableCreditCardsInfo_ = numberOfMigratableCreditCard === 1 ? - this.i18n('migratableCardsInfoSingle') : - this.i18n('migratableCardsInfoMultiple'); - - return true; - } - private getMenuEditCardText_(isLocalCard: boolean): string { return this.i18n(isLocalCard ? 'edit' : 'editServerCard'); }
diff --git a/chrome/browser/resources/settings/people_page/sync_account_control.ts b/chrome/browser/resources/settings/people_page/sync_account_control.ts index 58fd6787..90fa7bd 100644 --- a/chrome/browser/resources/settings/people_page/sync_account_control.ts +++ b/chrome/browser/resources/settings/people_page/sync_account_control.ts
@@ -55,14 +55,6 @@ static get properties() { return { /** - * Preferences state. - */ - prefs: { - type: Object, - notify: true, - }, - - /** * The current sync status, supplied by parent element. */ syncStatus: Object,
diff --git a/chrome/browser/resources/settings/people_page/sync_page.ts b/chrome/browser/resources/settings/people_page/sync_page.ts index 308e7880..d9fe4d9 100644 --- a/chrome/browser/resources/settings/people_page/sync_page.ts +++ b/chrome/browser/resources/settings/people_page/sync_page.ts
@@ -42,6 +42,7 @@ import {loadTimeData} from '../i18n_setup.js'; import type {MetricsBrowserProxy} from '../metrics_browser_proxy.js'; import {MetricsBrowserProxyImpl} from '../metrics_browser_proxy.js'; +import type {PageVisibility} from '../page_visibility.js'; // <if expr="chromeos_ash"> import type {SettingsPersonalizationOptionsElement} from '../privacy_page/personalization_options.js'; // </if> @@ -228,12 +229,14 @@ prefs: {[key: string]: any}; focusConfig: FocusConfig; private pageStatus_: PageStatus; + pageVisibility: PageVisibility; syncPrefs?: SyncPrefs; syncStatus: SyncStatus; private dataEncrypted_: boolean; private encryptionExpanded_: boolean; forceEncryptionExpanded: boolean; private existingPassphrase_: string; + private showExistingPassphraseBelowAccount_: boolean; private signedIn_: boolean; private syncDisabledByAdmin_: boolean; private syncSectionDisabled_: boolean;
diff --git a/chrome/browser/resources/settings/privacy_page/personalization_options.ts b/chrome/browser/resources/settings/privacy_page/personalization_options.ts index 67bb71d..94286e33 100644 --- a/chrome/browser/resources/settings/privacy_page/personalization_options.ts +++ b/chrome/browser/resources/settings/privacy_page/personalization_options.ts
@@ -77,11 +77,6 @@ static get properties() { return { - prefs: { - type: Object, - notify: true, - }, - focusConfig: { type: Object, observer: 'onFocusConfigChange_',
diff --git a/chrome/browser/sync_file_system/local/local_file_sync_service.h b/chrome/browser/sync_file_system/local/local_file_sync_service.h index f41103f9..b679306 100644 --- a/chrome/browser/sync_file_system/local/local_file_sync_service.h +++ b/chrome/browser/sync_file_system/local/local_file_sync_service.h
@@ -130,8 +130,8 @@ void PromoteDemotedChanges(base::RepeatingClosure callback); // Returns the metadata of a remote file pointed by |url|. - virtual void GetLocalFileMetadata(const storage::FileSystemURL& url, - SyncFileMetadataCallback callback); + void GetLocalFileMetadata(const storage::FileSystemURL& url, + SyncFileMetadataCallback callback); // RemoteChangeProcessor overrides. void PrepareForProcessRemoteChange(const storage::FileSystemURL& url,
diff --git a/chrome/browser/tab_resumption/java/res/drawable/tab_resumption_module_ripple.xml b/chrome/browser/tab_resumption/java/res/drawable/tab_resumption_module_ripple.xml index f9a0563..24d69d5 100644 --- a/chrome/browser/tab_resumption/java/res/drawable/tab_resumption_module_ripple.xml +++ b/chrome/browser/tab_resumption/java/res/drawable/tab_resumption_module_ripple.xml
@@ -8,11 +8,10 @@ <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="?android:attr/colorControlHighlight"> <item android:id="@android:id/mask"> - <org.chromium.components.browser_ui.widget.SurfaceColorDrawable - xmlns:app="http://schemas.android.com/apk/res-auto" - android:shape="rectangle" - app:surfaceElevation="@dimen/home_surface_ui_background_color_elevation"> + <shape + android:shape="rectangle"> + <solid android:color="@color/home_surface_ui_background_color"/> <corners android:radius="@dimen/tab_resumption_module_tile_rounded_corner_radius"/> - </org.chromium.components.browser_ui.widget.SurfaceColorDrawable> + </shape> </item> </ripple>
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index e0ce0ab..d9d1d04b 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -3738,14 +3738,6 @@ "views/autofill/payments/filled_card_information_bubble_views.h", "views/autofill/payments/filled_card_information_icon_view.cc", "views/autofill/payments/filled_card_information_icon_view.h", - "views/autofill/payments/local_card_migration_bubble_views.cc", - "views/autofill/payments/local_card_migration_bubble_views.h", - "views/autofill/payments/local_card_migration_dialog_view.cc", - "views/autofill/payments/local_card_migration_dialog_view.h", - "views/autofill/payments/local_card_migration_error_dialog_view.cc", - "views/autofill/payments/local_card_migration_error_dialog_view.h", - "views/autofill/payments/local_card_migration_icon_view.cc", - "views/autofill/payments/local_card_migration_icon_view.h", "views/autofill/payments/manage_saved_iban_bubble_view.cc", "views/autofill/payments/manage_saved_iban_bubble_view.h", "views/autofill/payments/mandatory_reauth_confirmation_bubble_view.cc", @@ -3754,8 +3746,6 @@ "views/autofill/payments/mandatory_reauth_icon_view.h", "views/autofill/payments/mandatory_reauth_opt_in_bubble_view.cc", "views/autofill/payments/mandatory_reauth_opt_in_bubble_view.h", - "views/autofill/payments/migratable_card_view.cc", - "views/autofill/payments/migratable_card_view.h", "views/autofill/payments/offer_notification_bubble_views.cc", "views/autofill/payments/offer_notification_bubble_views.h", "views/autofill/payments/offer_notification_icon_view.cc",
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index b303ffb..16d9c328 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -3095,6 +3095,9 @@ </message> <!-- ContextMenu --> + <message name="IDS_CONTEXTMENU_SAVE_PAGE" desc="This string is shown in the context menu for saving the current page."> + Download + </message> <message name="IDS_CONTEXTMENU_OPEN_IN_OTHER_WINDOW" desc="Context sensitive menu item to open the selected link in the other window. [CHAR_LIMIT=30]"> Open in other window </message> @@ -5538,6 +5541,9 @@ </message> <!-- Custom Context Menu Informations --> + <message name="IDS_CONTEXTMENU_PAGE_TITLE" desc="The title of a context menu tab when the item pressed contains more than one type. This indicates that all the actions are related to the page."> + PAGE + </message> <message name="IDS_CONTEXTMENU_IMAGE_TITLE" desc="The title of a context menu tab when the item pressed contains more than one type. This indicates that all the actions are related to the image."> IMAGE </message>
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_CONTEXTMENU_SAVE_PAGE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_CONTEXTMENU_SAVE_PAGE.png.sha1 new file mode 100644 index 0000000..9ff3d4f --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_CONTEXTMENU_SAVE_PAGE.png.sha1
@@ -0,0 +1 @@ +b3564117e33bd2b1be95fde0eb074d1caf7597e5 \ No newline at end of file
diff --git a/chrome/browser/ui/autofill/autofill_bubble_handler.h b/chrome/browser/ui/autofill/autofill_bubble_handler.h index 6fc68cb2..57b51601 100644 --- a/chrome/browser/ui/autofill/autofill_bubble_handler.h +++ b/chrome/browser/ui/autofill/autofill_bubble_handler.h
@@ -21,7 +21,6 @@ namespace autofill { class AutofillProfile; class AutofillBubbleBase; -class LocalCardMigrationBubbleController; class OfferNotificationBubbleController; class SaveAddressBubbleController; class UpdateAddressBubbleController; @@ -53,11 +52,6 @@ SaveCardBubbleController* controller, bool is_user_gesture) = 0; - virtual AutofillBubbleBase* ShowLocalCardMigrationBubble( - content::WebContents* web_contents, - LocalCardMigrationBubbleController* controller, - bool is_user_gesture) = 0; - virtual AutofillBubbleBase* ShowIbanBubble(content::WebContents* web_contents, IbanBubbleController* controller, bool is_user_gesture,
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h index a088172f..4f59541 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.h +++ b/chrome/browser/ui/autofill/chrome_autofill_client.h
@@ -44,8 +44,6 @@ #if BUILDFLAG(IS_ANDROID) #include "chrome/browser/ui/autofill/autofill_snackbar_controller_impl.h" #include "components/autofill/core/browser/integrators/fast_checkout_client.h" -#else -#include "chrome/browser/ui/autofill/payments/manage_migration_ui_controller.h" #endif // BUILDFLAG(IS_ANDROID) namespace autofill {
diff --git a/chrome/browser/ui/autofill/payments/BUILD.gn b/chrome/browser/ui/autofill/payments/BUILD.gn index 581b9691..1ee31e96 100644 --- a/chrome/browser/ui/autofill/payments/BUILD.gn +++ b/chrome/browser/ui/autofill/payments/BUILD.gn
@@ -65,13 +65,6 @@ "filled_card_information_bubble_controller_impl.h", "iban_bubble_controller.h", "iban_bubble_controller_impl.h", - "local_card_migration_bubble_controller_impl.h", - "local_card_migration_controller_observer.h", - "local_card_migration_dialog.h", - "local_card_migration_dialog_controller_impl.h", - "local_card_migration_dialog_factory.h", - "local_card_migration_dialog_state.h", - "manage_migration_ui_controller.h", "mandatory_reauth_ui.h", "offer_notification_bubble_controller.h", "offer_notification_bubble_controller_impl.h", @@ -158,9 +151,6 @@ sources += [ "filled_card_information_bubble_controller_impl.cc", "iban_bubble_controller_impl.cc", - "local_card_migration_bubble_controller_impl.cc", - "local_card_migration_dialog_controller_impl.cc", - "manage_migration_ui_controller.cc", "offer_notification_bubble_controller_impl.cc", "save_card_bubble_controller_impl.cc", "save_payment_icon_controller.cc", @@ -277,7 +267,6 @@ sources += [ "autofill_dialog_models_unittest.cc", "iban_bubble_controller_impl_unittest.cc", - "local_card_migration_bubble_controller_impl_unittest.cc", "mandatory_reauth_bubble_controller_impl_unittest.cc", "offer_notification_bubble_controller_impl_unittest.cc", "save_card_bubble_controller_impl_unittest.cc",
diff --git a/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.cc b/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.cc index b6ef565..8bf8e53 100644 --- a/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.cc +++ b/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.cc
@@ -91,7 +91,6 @@ #else // !BUILDFLAG(IS_ANDROID) #include "chrome/browser/ui/autofill/payments/desktop_payments_window_manager.h" #include "chrome/browser/ui/autofill/payments/filled_card_information_bubble_controller_impl.h" -#include "chrome/browser/ui/autofill/payments/manage_migration_ui_controller.h" #include "chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl.h" #include "chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.h" #include "chrome/browser/ui/autofill/payments/webauthn_dialog_controller_impl.h" @@ -99,7 +98,6 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/promos/ios_promos_utils.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "components/autofill/core/browser/payments/local_card_migration_manager.h" #include "components/autofill/core/common/autofill_payments_features.h" #include "components/webauthn/content/browser/internal_authenticator_impl.h" #endif // BUILDFLAG(IS_ANDROID) @@ -192,40 +190,6 @@ /*upload_save_card_callback=*/std::move(callback)); } #else // !BUILDFLAG(IS_ANDROID) -void ChromePaymentsAutofillClient::ShowLocalCardMigrationDialog( - base::OnceClosure show_migration_dialog_closure) { - ManageMigrationUiController::CreateForWebContents(web_contents()); - ManageMigrationUiController* controller = - ManageMigrationUiController::FromWebContents(web_contents()); - controller->ShowBubble(std::move(show_migration_dialog_closure)); -} - -void ChromePaymentsAutofillClient::ConfirmMigrateLocalCardToCloud( - const LegalMessageLines& legal_message_lines, - const std::string& user_email, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - LocalCardMigrationCallback start_migrating_cards_callback) { - ManageMigrationUiController::CreateForWebContents(web_contents()); - ManageMigrationUiController* controller = - ManageMigrationUiController::FromWebContents(web_contents()); - controller->ShowOfferDialog(legal_message_lines, user_email, - migratable_credit_cards, - std::move(start_migrating_cards_callback)); -} - -void ChromePaymentsAutofillClient::ShowLocalCardMigrationResults( - bool has_server_error, - const std::u16string& tip_message, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - MigrationDeleteCardCallback delete_local_card_callback) { - ManageMigrationUiController::CreateForWebContents(web_contents()); - ManageMigrationUiController* controller = - ManageMigrationUiController::FromWebContents(web_contents()); - controller->UpdateCreditCardIcon(has_server_error, tip_message, - migratable_credit_cards, - delete_local_card_callback); -} - void ChromePaymentsAutofillClient::ShowWebauthnOfferDialog( WebauthnDialogCallback offer_dialog_callback) { WebauthnDialogControllerImpl::GetOrCreateForPage(
diff --git a/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.h b/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.h index baaebd39..bfee219f 100644 --- a/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.h +++ b/chrome/browser/ui/autofill/payments/chrome_payments_autofill_client.h
@@ -24,8 +24,6 @@ #include "chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_controller.h" #include "components/autofill/core/browser/ui/payments/card_expiration_date_fix_flow_controller_impl.h" #include "components/autofill/core/browser/ui/payments/card_name_fix_flow_controller_impl.h" -#else // !BUILDFLAG(IS_ANDROID) -#include "chrome/browser/ui/autofill/payments/manage_migration_ui_controller.h" #endif // BUILDFLAG(IS_ANDROID) class GURL; @@ -109,18 +107,6 @@ base::OnceCallback<void(const std::u16string&, const std::u16string&)> callback) override; #else // !BUILDFLAG(IS_ANDROID) - void ShowLocalCardMigrationDialog( - base::OnceClosure show_migration_dialog_closure) override; - void ConfirmMigrateLocalCardToCloud( - const LegalMessageLines& legal_message_lines, - const std::string& user_email, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - LocalCardMigrationCallback start_migrating_cards_callback) override; - void ShowLocalCardMigrationResults( - bool has_server_error, - const std::u16string& tip_message, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - MigrationDeleteCardCallback delete_local_card_callback) override; void ShowWebauthnOfferDialog( WebauthnDialogCallback offer_dialog_callback) override; void ShowWebauthnVerifyPendingDialog(
diff --git a/chrome/browser/ui/autofill/payments/local_card_migration_bubble_controller_impl.cc b/chrome/browser/ui/autofill/payments/local_card_migration_bubble_controller_impl.cc deleted file mode 100644 index 6c188f02..0000000 --- a/chrome/browser/ui/autofill/payments/local_card_migration_bubble_controller_impl.cc +++ /dev/null
@@ -1,165 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/autofill/payments/local_card_migration_bubble_controller_impl.h" - -#include <stddef.h> - -#include "base/observer_list.h" -#include "chrome/browser/autofill/strike_database_factory.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/autofill/autofill_bubble_base.h" -#include "chrome/browser/ui/autofill/autofill_bubble_handler.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_controller_observer.h" -#include "chrome/browser/ui/autofill/payments/payments_ui_constants.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/browser_window.h" -#include "components/autofill/core/browser/metrics/autofill_metrics.h" -#include "components/autofill/core/browser/metrics/payments/local_card_migration_metrics.h" -#include "components/autofill/core/browser/strike_databases/payments/local_card_migration_strike_database.h" -#include "components/autofill/core/browser/strike_databases/strike_database.h" -#include "components/autofill/core/common/autofill_clock.h" -#include "components/autofill/core/common/autofill_features.h" -#include "components/autofill/core/common/autofill_payments_features.h" -#include "components/strings/grit/components_strings.h" -#include "content/public/browser/navigation_handle.h" -#include "ui/base/l10n/l10n_util.h" - -namespace autofill { - -LocalCardMigrationBubbleControllerImpl::LocalCardMigrationBubbleControllerImpl( - content::WebContents* web_contents) - : AutofillBubbleControllerBase(web_contents), - content::WebContentsUserData<LocalCardMigrationBubbleControllerImpl>( - *web_contents) {} - -LocalCardMigrationBubbleControllerImpl:: - ~LocalCardMigrationBubbleControllerImpl() { - observer_list_.Notify( - &LocalCardMigrationControllerObserver::OnSourceDestruction, - LocalCardMigrationControllerObserver::LocalCardMigrationControllerSource:: - kBubbleController); -} - -void LocalCardMigrationBubbleControllerImpl::ShowBubble( - base::OnceClosure local_card_migration_bubble_closure) { - // Don't show the bubble if it's already visible. - if (bubble_view()) { - return; - } - - is_reshow_ = false; - should_add_strikes_on_bubble_close_ = true; - local_card_migration_bubble_closure_ = - std::move(local_card_migration_bubble_closure); - - autofill_metrics::LogLocalCardMigrationBubbleOfferMetric( - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_REQUESTED, is_reshow_); - - Show(); -} - -void LocalCardMigrationBubbleControllerImpl::ReshowBubble() { - if (bubble_view()) { - return; - } - - is_reshow_ = true; - autofill_metrics::LogLocalCardMigrationBubbleOfferMetric( - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_REQUESTED, is_reshow_); - - Show(); -} - -void LocalCardMigrationBubbleControllerImpl::AddObserver( - LocalCardMigrationControllerObserver* observer) { - observer_list_.AddObserver(observer); -} - -void LocalCardMigrationBubbleControllerImpl::RemoveObserver( - LocalCardMigrationControllerObserver* observer) { - observer_list_.RemoveObserver(observer); -} - -AutofillBubbleBase* -LocalCardMigrationBubbleControllerImpl::local_card_migration_bubble_view() - const { - return bubble_view(); -} - -void LocalCardMigrationBubbleControllerImpl::OnConfirmButtonClicked() { - DCHECK(local_card_migration_bubble_closure_); - std::move(local_card_migration_bubble_closure_).Run(); - should_add_strikes_on_bubble_close_ = false; -} - -void LocalCardMigrationBubbleControllerImpl::OnCancelButtonClicked() { - local_card_migration_bubble_closure_.Reset(); -} - -void LocalCardMigrationBubbleControllerImpl::OnBubbleClosed( - PaymentsUiClosedReason closed_reason) { - set_bubble_view(nullptr); - UpdatePageActionIcon(); - if (should_add_strikes_on_bubble_close_) { - should_add_strikes_on_bubble_close_ = false; - AddStrikesForBubbleClose(); - } - - // Log local card migration bubble result according to the closed reason. - autofill_metrics::LocalCardMigrationBubbleResultMetric metric; - switch (closed_reason) { - case PaymentsUiClosedReason::kAccepted: - metric = autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_ACCEPTED; - break; - case PaymentsUiClosedReason::kClosed: - metric = autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_CLOSED; - break; - case PaymentsUiClosedReason::kNotInteracted: - metric = autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_NOT_INTERACTED; - break; - case PaymentsUiClosedReason::kLostFocus: - metric = autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_LOST_FOCUS; - break; - case PaymentsUiClosedReason::kUnknown: - metric = autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_RESULT_UNKNOWN; - break; - case PaymentsUiClosedReason::kCancelled: - NOTREACHED(); - } - autofill_metrics::LogLocalCardMigrationBubbleResultMetric(metric, is_reshow_); -} - -PageActionIconType -LocalCardMigrationBubbleControllerImpl::GetPageActionIconType() { - return PageActionIconType::kLocalCardMigration; -} - -void LocalCardMigrationBubbleControllerImpl::DoShowBubble() { - DCHECK(local_card_migration_bubble_closure_); - DCHECK(!bubble_view()); - - Browser* browser = chrome::FindBrowserWithTab(web_contents()); - set_bubble_view( - browser->window() - ->GetAutofillBubbleHandler() - ->ShowLocalCardMigrationBubble(web_contents(), this, is_reshow_)); - DCHECK(bubble_view()); - - autofill_metrics::LogLocalCardMigrationBubbleOfferMetric( - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_SHOWN, is_reshow_); -} - -void LocalCardMigrationBubbleControllerImpl::AddStrikesForBubbleClose() { - LocalCardMigrationStrikeDatabase local_card_migration_strike_database( - StrikeDatabaseFactory::GetForProfile( - Profile::FromBrowserContext(web_contents()->GetBrowserContext()))); - local_card_migration_strike_database.AddStrikes( - LocalCardMigrationStrikeDatabase::kStrikesToAddWhenBubbleClosed); -} - -WEB_CONTENTS_USER_DATA_KEY_IMPL(LocalCardMigrationBubbleControllerImpl); - -} // namespace autofill
diff --git a/chrome/browser/ui/autofill/payments/local_card_migration_bubble_controller_impl.h b/chrome/browser/ui/autofill/payments/local_card_migration_bubble_controller_impl.h deleted file mode 100644 index b4b12f1..0000000 --- a/chrome/browser/ui/autofill/payments/local_card_migration_bubble_controller_impl.h +++ /dev/null
@@ -1,86 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_BUBBLE_CONTROLLER_IMPL_H_ -#define CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_BUBBLE_CONTROLLER_IMPL_H_ - -#include "base/observer_list.h" -#include "chrome/browser/ui/autofill/autofill_bubble_controller_base.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_controller_observer.h" -#include "components/autofill/core/browser/ui/payments/local_card_migration_bubble_controller.h" -#include "content/public/browser/web_contents_user_data.h" - -namespace autofill { - -// Implementation of per-tab class to control the local card migration bubble -// and Omnibox icon. -class LocalCardMigrationBubbleControllerImpl - : public AutofillBubbleControllerBase, - public LocalCardMigrationBubbleController, - public content::WebContentsUserData< - LocalCardMigrationBubbleControllerImpl> { - public: - LocalCardMigrationBubbleControllerImpl( - const LocalCardMigrationBubbleControllerImpl&) = delete; - LocalCardMigrationBubbleControllerImpl& operator=( - const LocalCardMigrationBubbleControllerImpl&) = delete; - ~LocalCardMigrationBubbleControllerImpl() override; - - // Shows the prompt that offers local credit card migration. - // |local_card_migration_bubble_closure| is run upon acceptance. - void ShowBubble(base::OnceClosure local_card_migration_bubble_closure); - - // Invoked when local card migration icon is clicked. - void ReshowBubble(); - - void AddObserver(LocalCardMigrationControllerObserver* observer); - void RemoveObserver(LocalCardMigrationControllerObserver* observer); - - // Returns nullptr if no bubble is currently shown. - AutofillBubbleBase* local_card_migration_bubble_view() const; - - // LocalCardMigrationBubbleController: - void OnConfirmButtonClicked() override; - void OnCancelButtonClicked() override; - void OnBubbleClosed(PaymentsUiClosedReason closed_reason) override; - - protected: - explicit LocalCardMigrationBubbleControllerImpl( - content::WebContents* web_contents); - - // AutofillBubbleControllerBase:: - PageActionIconType GetPageActionIconType() override; - void DoShowBubble() override; - - private: - friend class content::WebContentsUserData< - LocalCardMigrationBubbleControllerImpl>; - - friend class LocalCardMigrationBrowserTest; - - void UpdateLocalCardMigrationIcon(); - - // Add strikes for local card migration, to be called on user closing the - // promo bubble. - void AddStrikesForBubbleClose(); - - // Callback to run if user presses Save button in the offer-to-migrate bubble. - base::OnceClosure local_card_migration_bubble_closure_; - - // Boolean to determine if bubble is called from ReshowBubble(). - bool is_reshow_ = false; - - // Boolean to determine if strikes should be added when bubble is closed. They - // should be added only once and only if the bubble isn't closed due to - // clicking the Continue button. - bool should_add_strikes_on_bubble_close_ = true; - - base::ObserverList<LocalCardMigrationControllerObserver> observer_list_; - - WEB_CONTENTS_USER_DATA_KEY_DECL(); -}; - -} // namespace autofill - -#endif // CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_BUBBLE_CONTROLLER_IMPL_H_
diff --git a/chrome/browser/ui/autofill/payments/local_card_migration_bubble_controller_impl_unittest.cc b/chrome/browser/ui/autofill/payments/local_card_migration_bubble_controller_impl_unittest.cc deleted file mode 100644 index 725a36cf..0000000 --- a/chrome/browser/ui/autofill/payments/local_card_migration_bubble_controller_impl_unittest.cc +++ /dev/null
@@ -1,281 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/autofill/payments/local_card_migration_bubble_controller_impl.h" - -#include <stddef.h> - -#include <utility> - -#include "base/functional/bind.h" -#include "base/strings/utf_string_conversions.h" -#include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" -#include "base/values.h" -#include "chrome/browser/ui/autofill/autofill_bubble_base.h" -#include "chrome/browser/ui/autofill/test/test_autofill_bubble_handler.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/test/base/browser_with_test_window_test.h" -#include "chrome/test/base/chrome_render_view_host_test_harness.h" -#include "components/autofill/core/browser/metrics/autofill_metrics.h" -#include "components/autofill/core/browser/metrics/payments/local_card_migration_metrics.h" -#include "components/autofill/core/browser/test_utils/autofill_test_utils.h" -#include "components/autofill/core/common/autofill_payments_features.h" -#include "content/public/test/mock_navigation_handle.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using base::Bucket; -using testing::ElementsAre; - -namespace autofill { -namespace { - -class TestLocalCardMigrationBubbleControllerImpl - : public LocalCardMigrationBubbleControllerImpl { - public: - static void CreateForTesting(content::WebContents* web_contents) { - web_contents->SetUserData( - UserDataKey(), - std::make_unique<TestLocalCardMigrationBubbleControllerImpl>( - web_contents)); - } - - explicit TestLocalCardMigrationBubbleControllerImpl( - content::WebContents* web_contents) - : LocalCardMigrationBubbleControllerImpl(web_contents) {} - - void SimulateNavigation() { - content::RenderFrameHost* rfh = web_contents()->GetPrimaryMainFrame(); - content::MockNavigationHandle navigation_handle(GURL(), rfh); - navigation_handle.set_has_committed(true); - DidFinishNavigation(&navigation_handle); - } -}; - -class LocalCardMigrationBubbleControllerImplTest - : public BrowserWithTestWindowTest { - public: - LocalCardMigrationBubbleControllerImplTest() - : BrowserWithTestWindowTest( - base::test::TaskEnvironment::TimeSource::MOCK_TIME) {} - LocalCardMigrationBubbleControllerImplTest( - const LocalCardMigrationBubbleControllerImplTest&) = delete; - LocalCardMigrationBubbleControllerImplTest& operator=( - const LocalCardMigrationBubbleControllerImplTest&) = delete; - - void SetUp() override { - BrowserWithTestWindowTest::SetUp(); - AddTab(browser(), GURL("about:blank")); - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - TestLocalCardMigrationBubbleControllerImpl::CreateForTesting(web_contents); - } - - protected: - void ShowBubble() { - controller()->ShowBubble(base::BindOnce(&LocalCardMigrationCallback)); - } - - void CloseBubble(PaymentsUiClosedReason closed_reason = - PaymentsUiClosedReason::kNotInteracted) { - controller()->OnBubbleClosed(closed_reason); - } - - void CloseAndReshowBubble() { - CloseBubble(); - controller()->ReshowBubble(); - } - - TestLocalCardMigrationBubbleControllerImpl* controller() { - return static_cast<TestLocalCardMigrationBubbleControllerImpl*>( - TestLocalCardMigrationBubbleControllerImpl::FromWebContents( - browser()->tab_strip_model()->GetActiveWebContents())); - } - - private: - static void LocalCardMigrationCallback() {} -}; - -TEST_F(LocalCardMigrationBubbleControllerImplTest, - Metrics_FirstShow_ShowBubble) { - base::HistogramTester histogram_tester; - ShowBubble(); - - EXPECT_THAT( - histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationBubbleOffer.FirstShow"), - ElementsAre( - Bucket(autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_REQUESTED, 1), - Bucket(autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_SHOWN, 1))); -} - -TEST_F(LocalCardMigrationBubbleControllerImplTest, Metrics_Reshows_ShowBubble) { - base::HistogramTester histogram_tester; - ShowBubble(); - CloseAndReshowBubble(); - - EXPECT_THAT( - histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationBubbleOffer.Reshows"), - ElementsAre( - Bucket(autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_REQUESTED, 1), - Bucket(autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_SHOWN, 1))); -} - -TEST_F(LocalCardMigrationBubbleControllerImplTest, - OnlyOneActiveBubble_Repeated) { - base::HistogramTester histogram_tester; - ShowBubble(); - ShowBubble(); - ShowBubble(); - EXPECT_THAT( - histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationBubbleOffer.FirstShow"), - ElementsAre( - Bucket(autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_REQUESTED, 1), - Bucket(autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_SHOWN, 1))); -} - -// Ensures the bubble should still stick around even if the time since bubble -// showing is longer than kCardBubbleSurviveNavigationTime (5 seconds) when the -// feature is enabled. -TEST_F(LocalCardMigrationBubbleControllerImplTest, - StickyBubble_ShouldNotDismissUponNavigation) { - ShowBubble(); - base::HistogramTester histogram_tester; - task_environment()->FastForwardBy(base::Seconds(10)); - controller()->SimulateNavigation(); - - histogram_tester.ExpectTotalCount( - "Autofill.LocalCardMigrationBubbleOffer.FirstShow", 0); - EXPECT_NE(nullptr, controller()->local_card_migration_bubble_view()); -} - -// Test class to ensure the local card migration bubble result is logged -// correctly. -TEST_F(LocalCardMigrationBubbleControllerImplTest, FirstShow_BubbleAccepted) { - base::HistogramTester histogram_tester; - ShowBubble(); - CloseBubble(PaymentsUiClosedReason::kAccepted); - - histogram_tester.ExpectUniqueSample( - "Autofill.LocalCardMigrationBubbleResult.FirstShow", - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_ACCEPTED, 1); -} - -TEST_F(LocalCardMigrationBubbleControllerImplTest, FirstShow_BubbleClosed) { - base::HistogramTester histogram_tester; - ShowBubble(); - CloseBubble(PaymentsUiClosedReason::kClosed); - - histogram_tester.ExpectUniqueSample( - "Autofill.LocalCardMigrationBubbleResult.FirstShow", - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_CLOSED, 1); -} - -TEST_F(LocalCardMigrationBubbleControllerImplTest, - FirstShow_BubbleNotInteracted) { - base::HistogramTester histogram_tester; - ShowBubble(); - CloseBubble(PaymentsUiClosedReason::kNotInteracted); - - histogram_tester.ExpectUniqueSample( - "Autofill.LocalCardMigrationBubbleResult.FirstShow", - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_NOT_INTERACTED, 1); -} - -TEST_F(LocalCardMigrationBubbleControllerImplTest, FirstShow_BubbleLostFocus) { - base::HistogramTester histogram_tester; - ShowBubble(); - CloseBubble(PaymentsUiClosedReason::kLostFocus); - - histogram_tester.ExpectUniqueSample( - "Autofill.LocalCardMigrationBubbleResult.FirstShow", - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_LOST_FOCUS, 1); -} - -TEST_F(LocalCardMigrationBubbleControllerImplTest, FirstShow_Unknown) { - base::HistogramTester histogram_tester; - ShowBubble(); - CloseBubble(PaymentsUiClosedReason::kUnknown); - - histogram_tester.ExpectUniqueSample( - "Autofill.LocalCardMigrationBubbleResult.FirstShow", - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_RESULT_UNKNOWN, 1); -} - -TEST_F(LocalCardMigrationBubbleControllerImplTest, Reshows_BubbleAccepted) { - base::HistogramTester histogram_tester; - ShowBubble(); - CloseAndReshowBubble(); - CloseBubble(PaymentsUiClosedReason::kAccepted); - - histogram_tester.ExpectUniqueSample( - "Autofill.LocalCardMigrationBubbleResult.FirstShow", - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_NOT_INTERACTED, 1); - histogram_tester.ExpectUniqueSample( - "Autofill.LocalCardMigrationBubbleResult.Reshows", - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_ACCEPTED, 1); -} - -TEST_F(LocalCardMigrationBubbleControllerImplTest, Reshows_BubbleClosed) { - base::HistogramTester histogram_tester; - ShowBubble(); - CloseAndReshowBubble(); - CloseBubble(PaymentsUiClosedReason::kClosed); - - histogram_tester.ExpectUniqueSample( - "Autofill.LocalCardMigrationBubbleResult.FirstShow", - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_NOT_INTERACTED, 1); - histogram_tester.ExpectUniqueSample( - "Autofill.LocalCardMigrationBubbleResult.Reshows", - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_CLOSED, 1); -} - -TEST_F(LocalCardMigrationBubbleControllerImplTest, - Reshows_BubbleNotInteracted) { - base::HistogramTester histogram_tester; - ShowBubble(); - CloseAndReshowBubble(); - CloseBubble(PaymentsUiClosedReason::kNotInteracted); - - histogram_tester.ExpectUniqueSample( - "Autofill.LocalCardMigrationBubbleResult.FirstShow", - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_NOT_INTERACTED, 1); - histogram_tester.ExpectUniqueSample( - "Autofill.LocalCardMigrationBubbleResult.Reshows", - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_NOT_INTERACTED, 1); -} - -TEST_F(LocalCardMigrationBubbleControllerImplTest, Reshows_BubbleLostFocus) { - base::HistogramTester histogram_tester; - ShowBubble(); - CloseAndReshowBubble(); - CloseBubble(PaymentsUiClosedReason::kLostFocus); - - histogram_tester.ExpectUniqueSample( - "Autofill.LocalCardMigrationBubbleResult.FirstShow", - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_NOT_INTERACTED, 1); - histogram_tester.ExpectUniqueSample( - "Autofill.LocalCardMigrationBubbleResult.Reshows", - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_LOST_FOCUS, 1); -} - -TEST_F(LocalCardMigrationBubbleControllerImplTest, Reshows_Unknown) { - base::HistogramTester histogram_tester; - ShowBubble(); - CloseAndReshowBubble(); - CloseBubble(PaymentsUiClosedReason::kUnknown); - - histogram_tester.ExpectUniqueSample( - "Autofill.LocalCardMigrationBubbleResult.FirstShow", - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_NOT_INTERACTED, 1); - histogram_tester.ExpectUniqueSample( - "Autofill.LocalCardMigrationBubbleResult.Reshows", - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_RESULT_UNKNOWN, 1); -} - -} // namespace -} // namespace autofill
diff --git a/chrome/browser/ui/autofill/payments/local_card_migration_controller_observer.h b/chrome/browser/ui/autofill/payments/local_card_migration_controller_observer.h deleted file mode 100644 index 180f7d1..0000000 --- a/chrome/browser/ui/autofill/payments/local_card_migration_controller_observer.h +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_CONTROLLER_OBSERVER_H_ -#define CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_CONTROLLER_OBSERVER_H_ - -#include "base/observer_list_types.h" - -// The observer interface that listens for events in local card migration -// related controllers. -class LocalCardMigrationControllerObserver : public base::CheckedObserver { - public: - // Called when the user declined the offer dialog, navigated away with - // feedback credit card icon or finished with the feedback dialog. - virtual void OnMigrationNoLongerAvailable() = 0; - // Called after the user clicked the save button. Will trigger the - // credit card icon animation. - virtual void OnMigrationStarted() = 0; - - enum class LocalCardMigrationControllerSource { - kBubbleController, - kDialogContoller, - }; - // Called during source destruction to reset scoped observation stored in the - // observer. - virtual void OnSourceDestruction( - LocalCardMigrationControllerSource source) = 0; - - protected: - ~LocalCardMigrationControllerObserver() override = default; -}; - -#endif // CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_CONTROLLER_OBSERVER_H_
diff --git a/chrome/browser/ui/autofill/payments/local_card_migration_dialog.h b/chrome/browser/ui/autofill/payments/local_card_migration_dialog.h deleted file mode 100644 index 5db7766..0000000 --- a/chrome/browser/ui/autofill/payments/local_card_migration_dialog.h +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_H_ -#define CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_H_ - -#include "base/functional/callback.h" - -namespace content { -class WebContents; -} // namespace content - -namespace autofill { - -// The cross-platform UI interface which displays all the local card migration -// dialogs. -class LocalCardMigrationDialog { - public: - LocalCardMigrationDialog(const LocalCardMigrationDialog&) = delete; - LocalCardMigrationDialog& operator=(const LocalCardMigrationDialog&) = delete; - virtual void ShowDialog(content::WebContents& web_contents) = 0; - virtual void CloseDialog() = 0; - - protected: - LocalCardMigrationDialog() = default; - virtual ~LocalCardMigrationDialog() = default; -}; - -} // namespace autofill - -#endif // CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_H_
diff --git a/chrome/browser/ui/autofill/payments/local_card_migration_dialog_controller_impl.cc b/chrome/browser/ui/autofill/payments/local_card_migration_dialog_controller_impl.cc deleted file mode 100644 index 17d245ba..0000000 --- a/chrome/browser/ui/autofill/payments/local_card_migration_dialog_controller_impl.cc +++ /dev/null
@@ -1,320 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/autofill/payments/local_card_migration_dialog_controller_impl.h" - -#include <stddef.h> - -#include <string> -#include <utility> -#include <vector> - -#include "base/containers/contains.h" -#include "base/functional/bind.h" -#include "base/logging.h" -#include "base/observer_list.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "base/time/time.h" -#include "build/build_config.h" -#include "chrome/browser/autofill/strike_database_factory.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_controller_observer.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_dialog.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_dialog_factory.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_dialog_state.h" -#include "chrome/browser/ui/autofill/payments/manage_migration_ui_controller.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/browser_window.h" -#include "components/autofill/core/browser/data_quality/validation.h" -#include "components/autofill/core/browser/metrics/autofill_metrics.h" -#include "components/autofill/core/browser/metrics/payments/local_card_migration_metrics.h" -#include "components/autofill/core/browser/payments/local_card_migration_manager.h" -#include "components/autofill/core/browser/payments/payments_service_url.h" -#include "components/autofill/core/browser/strike_databases/payments/local_card_migration_strike_database.h" -#include "components/autofill/core/browser/strike_databases/strike_database.h" -#include "components/autofill/core/common/autofill_clock.h" -#include "components/autofill/core/common/autofill_features.h" -#include "components/autofill/core/common/autofill_payments_features.h" -#include "components/autofill/core/common/autofill_prefs.h" -#include "components/prefs/pref_service.h" -#include "components/user_prefs/user_prefs.h" -#include "content/public/browser/browser_context.h" - -namespace autofill { - -LocalCardMigrationDialogControllerImpl::LocalCardMigrationDialogControllerImpl( - content::WebContents* web_contents) - : content::WebContentsUserData<LocalCardMigrationDialogControllerImpl>( - *web_contents), - pref_service_( - user_prefs::UserPrefs::Get(web_contents->GetBrowserContext())) {} - -LocalCardMigrationDialogControllerImpl:: - ~LocalCardMigrationDialogControllerImpl() { - if (local_card_migration_dialog_) { - local_card_migration_dialog_->CloseDialog(); - } - observer_list_.Notify( - &LocalCardMigrationControllerObserver::OnSourceDestruction, - LocalCardMigrationControllerObserver::LocalCardMigrationControllerSource:: - kDialogContoller); -} - -void LocalCardMigrationDialogControllerImpl::ShowOfferDialog( - const LegalMessageLines& legal_message_lines, - const std::string& user_email, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - payments::PaymentsAutofillClient::LocalCardMigrationCallback - start_migrating_cards_callback) { - if (local_card_migration_dialog_) { - local_card_migration_dialog_->CloseDialog(); - } - - legal_message_lines_ = legal_message_lines; - view_state_ = LocalCardMigrationDialogState::kOffered; - // Need to create the icon first otherwise the dialog will not be shown. - UpdateLocalCardMigrationIcon(); - local_card_migration_dialog_ = CreateLocalCardMigrationDialogView(this); - start_migrating_cards_callback_ = std::move(start_migrating_cards_callback); - migratable_credit_cards_ = migratable_credit_cards; - user_email_ = user_email; - local_card_migration_dialog_->ShowDialog(GetWebContents()); - UpdateLocalCardMigrationIcon(); - dialog_is_visible_duration_timer_ = base::ElapsedTimer(); - - autofill_metrics::LogLocalCardMigrationDialogOfferMetric( - autofill_metrics::LOCAL_CARD_MIGRATION_DIALOG_SHOWN); -} - -void LocalCardMigrationDialogControllerImpl::UpdateCreditCardIcon( - const std::u16string& tip_message, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - payments::PaymentsAutofillClient::MigrationDeleteCardCallback - delete_local_card_callback) { - if (local_card_migration_dialog_) { - local_card_migration_dialog_->CloseDialog(); - } - - migratable_credit_cards_ = migratable_credit_cards; - tip_message_ = tip_message; - delete_local_card_callback_ = delete_local_card_callback; - - view_state_ = LocalCardMigrationDialogState::kFinished; - for (const auto& cc : migratable_credit_cards) { - if (cc.migration_status() == - MigratableCreditCard::MigrationStatus::FAILURE_ON_UPLOAD) { - view_state_ = LocalCardMigrationDialogState::kActionRequired; - break; - } - } - UpdateLocalCardMigrationIcon(); -} - -void LocalCardMigrationDialogControllerImpl::ShowFeedbackDialog() { - autofill_metrics::LogLocalCardMigrationDialogOfferMetric( - autofill_metrics::LOCAL_CARD_MIGRATION_DIALOG_FEEDBACK_SHOWN); - - local_card_migration_dialog_ = CreateLocalCardMigrationDialogView(this); - local_card_migration_dialog_->ShowDialog(GetWebContents()); - UpdateLocalCardMigrationIcon(); - dialog_is_visible_duration_timer_ = base::ElapsedTimer(); -} - -void LocalCardMigrationDialogControllerImpl::ShowErrorDialog() { - autofill_metrics::LogLocalCardMigrationDialogOfferMetric( - autofill_metrics:: - LOCAL_CARD_MIGRATION_DIALOG_FEEDBACK_SERVER_ERROR_SHOWN); - - local_card_migration_dialog_ = CreateLocalCardMigrationErrorDialogView(this); - UpdateLocalCardMigrationIcon(); - local_card_migration_dialog_->ShowDialog(GetWebContents()); - dialog_is_visible_duration_timer_ = base::ElapsedTimer(); -} - -void LocalCardMigrationDialogControllerImpl::AddObserver( - LocalCardMigrationControllerObserver* observer) { - observer_list_.AddObserver(observer); -} - -void LocalCardMigrationDialogControllerImpl::RemoveObserver( - LocalCardMigrationControllerObserver* observer) { - observer_list_.RemoveObserver(observer); -} - -LocalCardMigrationDialogState -LocalCardMigrationDialogControllerImpl::GetViewState() const { - return view_state_; -} - -const std::vector<MigratableCreditCard>& -LocalCardMigrationDialogControllerImpl::GetCardList() const { - return migratable_credit_cards_; -} - -const LegalMessageLines& -LocalCardMigrationDialogControllerImpl::GetLegalMessageLines() const { - return legal_message_lines_; -} - -const std::u16string& LocalCardMigrationDialogControllerImpl::GetTipMessage() - const { - return tip_message_; -} - -const std::string& LocalCardMigrationDialogControllerImpl::GetUserEmail() - const { - return user_email_; -} - -void LocalCardMigrationDialogControllerImpl::OnSaveButtonClicked( - const std::vector<std::string>& selected_cards_guids) { - // Add maximum strikes for local card migration due to user closing the main - // dialog. Even though the user accepted, we should not prompt migration again - // if there are other eligible cards, since they would have been intentionally - // deselected in this round. - LocalCardMigrationStrikeDatabase local_card_migration_strike_database( - StrikeDatabaseFactory::GetForProfile( - Profile::FromBrowserContext(GetWebContents().GetBrowserContext()))); - local_card_migration_strike_database.AddStrikes( - LocalCardMigrationStrikeDatabase::kStrikesToAddWhenDialogClosed); - - autofill_metrics::LogLocalCardMigrationDialogUserSelectionPercentageMetric( - selected_cards_guids.size(), migratable_credit_cards_.size()); - autofill_metrics::LogLocalCardMigrationDialogUserInteractionMetric( - dialog_is_visible_duration_timer_.Elapsed(), - autofill_metrics::LOCAL_CARD_MIGRATION_DIALOG_CLOSED_SAVE_BUTTON_CLICKED); - - std::move(start_migrating_cards_callback_).Run(selected_cards_guids); - NotifyMigrationStarted(); -} - -void LocalCardMigrationDialogControllerImpl::OnCancelButtonClicked() { - // Add maximum strikes for local card migration due to user closing the main - // dialog. - LocalCardMigrationStrikeDatabase local_card_migration_strike_database( - StrikeDatabaseFactory::GetForProfile( - Profile::FromBrowserContext(GetWebContents().GetBrowserContext()))); - local_card_migration_strike_database.AddStrikes( - LocalCardMigrationStrikeDatabase::kStrikesToAddWhenDialogClosed); - - autofill_metrics::LogLocalCardMigrationDialogUserInteractionMetric( - dialog_is_visible_duration_timer_.Elapsed(), - autofill_metrics:: - LOCAL_CARD_MIGRATION_DIALOG_CLOSED_CANCEL_BUTTON_CLICKED); - - start_migrating_cards_callback_.Reset(); - NotifyMigrationNoLongerAvailable(); -} - -void LocalCardMigrationDialogControllerImpl::OnDoneButtonClicked() { - autofill_metrics::LogLocalCardMigrationDialogUserInteractionMetric( - dialog_is_visible_duration_timer_.Elapsed(), - autofill_metrics::LOCAL_CARD_MIGRATION_DIALOG_CLOSED_DONE_BUTTON_CLICKED); - NotifyMigrationNoLongerAvailable(); -} - -void LocalCardMigrationDialogControllerImpl::OnViewCardsButtonClicked() { - autofill_metrics::LogLocalCardMigrationDialogUserInteractionMetric( - dialog_is_visible_duration_timer_.Elapsed(), - autofill_metrics:: - LOCAL_CARD_MIGRATION_DIALOG_CLOSED_VIEW_CARDS_BUTTON_CLICKED); - - OpenUrl(payments::GetManageInstrumentsUrl()); - NotifyMigrationNoLongerAvailable(); -} - -void LocalCardMigrationDialogControllerImpl::OnLegalMessageLinkClicked( - const GURL& url) { - OpenUrl(url); - autofill_metrics::LogLocalCardMigrationDialogUserInteractionMetric( - dialog_is_visible_duration_timer_.Elapsed(), - autofill_metrics::LOCAL_CARD_MIGRATION_DIALOG_LEGAL_MESSAGE_CLICKED); -} - -void LocalCardMigrationDialogControllerImpl::DeleteCard( - const std::string& deleted_card_guid) { - DCHECK(delete_local_card_callback_); - delete_local_card_callback_.Run(deleted_card_guid); - - std::erase_if(migratable_credit_cards_, [&](const auto& card) { - return card.credit_card().guid() == deleted_card_guid; - }); - - if (!HasFailedCard()) { - view_state_ = LocalCardMigrationDialogState::kFinished; - delete_local_card_callback_.Reset(); - } - - autofill_metrics::LogLocalCardMigrationDialogUserInteractionMetric( - dialog_is_visible_duration_timer_.Elapsed(), - autofill_metrics::LOCAL_CARD_MIGRATION_DIALOG_DELETE_CARD_ICON_CLICKED); -} - -void LocalCardMigrationDialogControllerImpl::OnDialogClosed() { - if (local_card_migration_dialog_) { - local_card_migration_dialog_ = nullptr; - } - - UpdateLocalCardMigrationIcon(); -} - -bool LocalCardMigrationDialogControllerImpl::AllCardsInvalid() const { - // For kOffered state, the migration status of all cards are UNKNOWN, - // so this function will return true as well. Need an early exit to avoid - // it. - return (view_state_ != LocalCardMigrationDialogState::kOffered) && - !base::Contains( - migratable_credit_cards_, - MigratableCreditCard::MigrationStatus::SUCCESS_ON_UPLOAD, - &MigratableCreditCard::migration_status); -} - -LocalCardMigrationDialog* -LocalCardMigrationDialogControllerImpl::local_card_migration_dialog_view() - const { - return local_card_migration_dialog_; -} - -void LocalCardMigrationDialogControllerImpl::OpenUrl(const GURL& url) { - GetWebContents().OpenURL( - content::OpenURLParams(url, content::Referrer(), - WindowOpenDisposition::NEW_POPUP, - ui::PAGE_TRANSITION_LINK, false), - /*navigation_handle_callback=*/{}); -} - -void LocalCardMigrationDialogControllerImpl::UpdateLocalCardMigrationIcon() { - Browser* browser = chrome::FindBrowserWithTab(&GetWebContents()); - if (browser) { - browser->window()->UpdatePageActionIcon( - PageActionIconType::kLocalCardMigration); - } -} - -bool LocalCardMigrationDialogControllerImpl::HasFailedCard() const { - return base::Contains( - migratable_credit_cards_, - MigratableCreditCard::MigrationStatus::FAILURE_ON_UPLOAD, - &MigratableCreditCard::migration_status); -} - -void LocalCardMigrationDialogControllerImpl:: - NotifyMigrationNoLongerAvailable() { - for (LocalCardMigrationControllerObserver& observer : observer_list_) { - observer.OnMigrationNoLongerAvailable(); - } -} - -void LocalCardMigrationDialogControllerImpl::NotifyMigrationStarted() { - for (LocalCardMigrationControllerObserver& observer : observer_list_) { - observer.OnMigrationStarted(); - } -} - -WEB_CONTENTS_USER_DATA_KEY_IMPL(LocalCardMigrationDialogControllerImpl); - -} // namespace autofill
diff --git a/chrome/browser/ui/autofill/payments/local_card_migration_dialog_controller_impl.h b/chrome/browser/ui/autofill/payments/local_card_migration_dialog_controller_impl.h deleted file mode 100644 index e56a053..0000000 --- a/chrome/browser/ui/autofill/payments/local_card_migration_dialog_controller_impl.h +++ /dev/null
@@ -1,150 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_CONTROLLER_IMPL_H_ -#define CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_CONTROLLER_IMPL_H_ - -#include <memory> -#include <string> -#include <vector> - -#include "base/memory/raw_ptr.h" -#include "base/observer_list.h" -#include "base/timer/elapsed_timer.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_controller_observer.h" -#include "components/autofill/core/browser/foundations/autofill_client.h" -#include "components/autofill/core/browser/payments/legal_message_line.h" -#include "components/autofill/core/browser/payments/payments_autofill_client.h" -#include "components/autofill/core/browser/ui/payments/local_card_migration_dialog_controller.h" -#include "content/public/browser/web_contents_user_data.h" - -namespace autofill { - -class LocalCardMigrationDialog; - -// This per-tab controller is lazily initialized and owns a -// LocalCardMigrationDialog. It's also responsible for reshowing the original -// dialog that the migration dialog interrupted. -class LocalCardMigrationDialogControllerImpl - : public LocalCardMigrationDialogController, - public content::WebContentsUserData< - LocalCardMigrationDialogControllerImpl> { - public: - LocalCardMigrationDialogControllerImpl( - const LocalCardMigrationDialogControllerImpl&) = delete; - LocalCardMigrationDialogControllerImpl& operator=( - const LocalCardMigrationDialogControllerImpl&) = delete; - ~LocalCardMigrationDialogControllerImpl() override; - - void ShowOfferDialog( - const LegalMessageLines& legal_message_lines, - const std::string& user_email, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - payments::PaymentsAutofillClient::LocalCardMigrationCallback - start_migrating_cards_callback); - - // When migration is finished, update the credit card icon. Also passes - // |tip_message|, and |migratable_credit_cards| to controller. - void UpdateCreditCardIcon( - const std::u16string& tip_message, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - payments::PaymentsAutofillClient::MigrationDeleteCardCallback - delete_local_card_callback); - - // If the user clicks on the credit card icon in the omnibox, we show the - // feedback dialog containing the uploading results of the cards that the - // user selected to upload. - void ShowFeedbackDialog(); - - // If the user clicks on the credit card icon in the omnibox after the - // migration request failed due to some internal server errors, we show the - // error dialog containing an error message. - void ShowErrorDialog(); - - void AddObserver(LocalCardMigrationControllerObserver* observer); - void RemoveObserver(LocalCardMigrationControllerObserver* observer); - - // LocalCardMigrationDialogController: - LocalCardMigrationDialogState GetViewState() const override; - const std::vector<MigratableCreditCard>& GetCardList() const override; - const LegalMessageLines& GetLegalMessageLines() const override; - const std::u16string& GetTipMessage() const override; - const std::string& GetUserEmail() const override; - void OnSaveButtonClicked( - const std::vector<std::string>& selected_cards_guids) override; - void OnCancelButtonClicked() override; - void OnDoneButtonClicked() override; - void OnViewCardsButtonClicked() override; - void OnLegalMessageLinkClicked(const GURL& url) override; - void DeleteCard(const std::string& deleted_card_guid) override; - void OnDialogClosed() override; - bool AllCardsInvalid() const override; - - // Returns nullptr if no dialog is currently shown. - LocalCardMigrationDialog* local_card_migration_dialog_view() const; - - protected: - explicit LocalCardMigrationDialogControllerImpl( - content::WebContents* web_contents); - - private: - friend class content::WebContentsUserData< - LocalCardMigrationDialogControllerImpl>; - - void OpenUrl(const GURL& url); - - void UpdateLocalCardMigrationIcon(); - - // The dialog is showing cards of which the migration failed. We will show - // the "Almost done" dialog in this case. - bool HasFailedCard() const; - - void NotifyMigrationNoLongerAvailable(); - void NotifyMigrationStarted(); - - raw_ptr<LocalCardMigrationDialog> local_card_migration_dialog_ = nullptr; - - raw_ptr<PrefService> pref_service_; - - LocalCardMigrationDialogState view_state_; - - LegalMessageLines legal_message_lines_; - - // Invoked when the save button is clicked. Will return a vector containing - // GUIDs of cards that the user selected to upload. - payments::PaymentsAutofillClient::LocalCardMigrationCallback - start_migrating_cards_callback_; - - // Invoked when the trash can button in the action-requied dialog is clicked. - // Will pass a string of GUID of the card the user selected to delete from - // local storage to LocalCardMigrationManager. - payments::PaymentsAutofillClient::MigrationDeleteCardCallback - delete_local_card_callback_; - - // Local copy of the MigratableCreditCards vector passed from - // LocalCardMigrationManager. Used in constructing the - // LocalCardMigrationDialogView. - std::vector<MigratableCreditCard> migratable_credit_cards_; - - // Timer used to measure the amount of time that the local card migration - // dialog is visible to users. - base::ElapsedTimer dialog_is_visible_duration_timer_; - - // The message containing information from Google Payments. Shown in the - // feedback dialogs after migration process is finished. - std::u16string tip_message_; - - // The user email shown in the dialogs. - std::string user_email_; - - // Contains observer listening to user's interactions with the dialog. The - // observer is responsible for setting flow step upon these interactions. - base::ObserverList<LocalCardMigrationControllerObserver> observer_list_; - - WEB_CONTENTS_USER_DATA_KEY_DECL(); -}; - -} // namespace autofill - -#endif // CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_CONTROLLER_IMPL_H_
diff --git a/chrome/browser/ui/autofill/payments/local_card_migration_dialog_factory.h b/chrome/browser/ui/autofill/payments/local_card_migration_dialog_factory.h deleted file mode 100644 index 755b44d..0000000 --- a/chrome/browser/ui/autofill/payments/local_card_migration_dialog_factory.h +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_FACTORY_H_ -#define CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_FACTORY_H_ - -namespace autofill { - -class LocalCardMigrationDialogController; -class LocalCardMigrationDialog; - -LocalCardMigrationDialog* CreateLocalCardMigrationDialogView( - LocalCardMigrationDialogController* controller); - -LocalCardMigrationDialog* CreateLocalCardMigrationErrorDialogView( - LocalCardMigrationDialogController* controller); - -} // namespace autofill - -#endif // CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_FACTORY_H_
diff --git a/chrome/browser/ui/autofill/payments/local_card_migration_dialog_state.h b/chrome/browser/ui/autofill/payments/local_card_migration_dialog_state.h deleted file mode 100644 index 3fb7a44..0000000 --- a/chrome/browser/ui/autofill/payments/local_card_migration_dialog_state.h +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_STATE_H_ -#define CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_STATE_H_ - -namespace autofill { - -// The current view state of the local card migration dialog. -enum class LocalCardMigrationDialogState { - // Dialog that offers users to migrate browser-saved local cards. - kOffered, - // Dialog that shows to users migration is done. - kFinished, - // Dialog that notifies users there are errors in the process of - // migration, and requires further actions from users. - kActionRequired, -}; - -} // namespace autofill - -#endif // CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_STATE_H_
diff --git a/chrome/browser/ui/autofill/payments/manage_migration_ui_controller.cc b/chrome/browser/ui/autofill/payments/manage_migration_ui_controller.cc deleted file mode 100644 index 547069de..0000000 --- a/chrome/browser/ui/autofill/payments/manage_migration_ui_controller.cc +++ /dev/null
@@ -1,184 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/autofill/payments/manage_migration_ui_controller.h" - -#include "chrome/browser/ui/autofill/autofill_bubble_base.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_controller_observer.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_dialog.h" -#include "components/autofill/core/browser/payments/local_card_migration_manager.h" -#include "components/autofill/core/browser/ui/payments/local_card_migration_dialog_controller.h" - -namespace autofill { - -ManageMigrationUiController::ManageMigrationUiController( - content::WebContents* web_contents) - : content::WebContentsUserData<ManageMigrationUiController>(*web_contents) { - LocalCardMigrationBubbleControllerImpl::CreateForWebContents(web_contents); - bubble_controller_observation_.Observe(GetBubbleController()); - - LocalCardMigrationDialogControllerImpl::CreateForWebContents(web_contents); - dialog_controller_observation_.Observe(GetDialogController()); -} - -ManageMigrationUiController::~ManageMigrationUiController() = default; - -LocalCardMigrationBubbleControllerImpl* -ManageMigrationUiController::GetBubbleController() { - return LocalCardMigrationBubbleControllerImpl::FromWebContents( - &GetWebContents()); -} - -LocalCardMigrationDialogControllerImpl* -ManageMigrationUiController::GetDialogController() { - return LocalCardMigrationDialogControllerImpl::FromWebContents( - &GetWebContents()); -} - -void ManageMigrationUiController::OnSourceDestruction( - LocalCardMigrationControllerSource source) { - switch (source) { - case LocalCardMigrationControllerSource::kBubbleController: - CHECK(bubble_controller_observation_.IsObserving()); - bubble_controller_observation_.Reset(); - return; - case LocalCardMigrationControllerSource::kDialogContoller: - CHECK(dialog_controller_observation_.IsObserving()); - dialog_controller_observation_.Reset(); - return; - } - NOTREACHED(); -} - -void ManageMigrationUiController::ShowBubble( - base::OnceClosure show_migration_dialog_closure) { - flow_step_ = LocalCardMigrationFlowStep::PROMO_BUBBLE; - DCHECK(GetBubbleController()); - GetBubbleController()->ShowBubble(std::move(show_migration_dialog_closure)); -} - -void ManageMigrationUiController::ShowOfferDialog( - const LegalMessageLines& legal_message_lines, - const std::string& user_email, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - payments::PaymentsAutofillClient::LocalCardMigrationCallback - start_migrating_cards_callback) { - flow_step_ = LocalCardMigrationFlowStep::OFFER_DIALOG; - DCHECK(GetDialogController()); - GetDialogController()->ShowOfferDialog( - legal_message_lines, user_email, migratable_credit_cards, - std::move(start_migrating_cards_callback)); -} - -void ManageMigrationUiController::UpdateCreditCardIcon( - const bool has_server_error, - const std::u16string& tip_message, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - payments::PaymentsAutofillClient::MigrationDeleteCardCallback - delete_local_card_callback) { - if (!GetDialogController()) { - return; - } - - DCHECK_EQ(flow_step_, LocalCardMigrationFlowStep::MIGRATION_RESULT_PENDING); - flow_step_ = LocalCardMigrationFlowStep::MIGRATION_FINISHED; - for (const auto& cc : migratable_credit_cards) { - if (cc.migration_status() == - MigratableCreditCard::MigrationStatus::FAILURE_ON_UPLOAD) { - flow_step_ = LocalCardMigrationFlowStep::MIGRATION_FAILED; - break; - } - } - if (has_server_error) { - flow_step_ = LocalCardMigrationFlowStep::MIGRATION_FAILED; - } - - // Show error dialog when |has_server_error| is true, which indicates - // Payments Rpc failure. - show_error_dialog_ = has_server_error; - - GetDialogController()->UpdateCreditCardIcon( - tip_message, migratable_credit_cards, delete_local_card_callback); -} - -void ManageMigrationUiController::OnUserClickedCreditCardIcon() { - switch (flow_step_) { - case LocalCardMigrationFlowStep::PROMO_BUBBLE: { - ReshowBubble(); - break; - } - case LocalCardMigrationFlowStep::MIGRATION_FINISHED: { - ShowFeedbackDialog(); - break; - } - case LocalCardMigrationFlowStep::MIGRATION_FAILED: { - show_error_dialog_ ? ShowErrorDialog() : ShowFeedbackDialog(); - break; - } - default: { - break; - } - } -} - -LocalCardMigrationFlowStep ManageMigrationUiController::GetFlowStep() const { - return flow_step_; -} - -bool ManageMigrationUiController::IsIconVisible() const { - DCHECK_NE(flow_step_, LocalCardMigrationFlowStep::UNKNOWN); - return flow_step_ != LocalCardMigrationFlowStep::NOT_SHOWN; -} - -AutofillBubbleBase* ManageMigrationUiController::GetBubbleView() { - LocalCardMigrationBubbleControllerImpl* controller = GetBubbleController(); - return controller ? controller->local_card_migration_bubble_view() : nullptr; -} - -LocalCardMigrationDialog* ManageMigrationUiController::GetDialogView() { - LocalCardMigrationDialogControllerImpl* controller = GetDialogController(); - return controller ? controller->local_card_migration_dialog_view() : nullptr; -} - -void ManageMigrationUiController::OnMigrationNoLongerAvailable() { - flow_step_ = LocalCardMigrationFlowStep::NOT_SHOWN; -} - -void ManageMigrationUiController::OnMigrationStarted() { - flow_step_ = LocalCardMigrationFlowStep::MIGRATION_RESULT_PENDING; -} - -void ManageMigrationUiController::ReshowBubble() { - if (!GetBubbleController()) { - return; - } - - DCHECK_EQ(flow_step_, LocalCardMigrationFlowStep::PROMO_BUBBLE); - GetBubbleController()->ReshowBubble(); -} - -void ManageMigrationUiController::ShowErrorDialog() { - if (!GetDialogController()) { - return; - } - - DCHECK_EQ(flow_step_, LocalCardMigrationFlowStep::MIGRATION_FINISHED); - flow_step_ = LocalCardMigrationFlowStep::ERROR_DIALOG; - GetDialogController()->ShowErrorDialog(); -} - -void ManageMigrationUiController::ShowFeedbackDialog() { - if (!GetDialogController()) { - return; - } - - DCHECK(flow_step_ == LocalCardMigrationFlowStep::MIGRATION_FINISHED || - flow_step_ == LocalCardMigrationFlowStep::MIGRATION_FAILED); - flow_step_ = LocalCardMigrationFlowStep::FEEDBACK_DIALOG; - GetDialogController()->ShowFeedbackDialog(); -} - -WEB_CONTENTS_USER_DATA_KEY_IMPL(ManageMigrationUiController); - -} // namespace autofill
diff --git a/chrome/browser/ui/autofill/payments/manage_migration_ui_controller.h b/chrome/browser/ui/autofill/payments/manage_migration_ui_controller.h deleted file mode 100644 index 4093898..0000000 --- a/chrome/browser/ui/autofill/payments/manage_migration_ui_controller.h +++ /dev/null
@@ -1,131 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_MANAGE_MIGRATION_UI_CONTROLLER_H_ -#define CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_MANAGE_MIGRATION_UI_CONTROLLER_H_ - -#include <string> -#include <vector> - -#include "base/memory/raw_ptr.h" -#include "base/scoped_observation.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_bubble_controller_impl.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_controller_observer.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_dialog_controller_impl.h" -#include "components/autofill/core/browser/payments/legal_message_line.h" -#include "content/public/browser/web_contents_user_data.h" - -namespace autofill { - -// Possible steps the migration flow could be in. -enum class LocalCardMigrationFlowStep { - // Migration flow step unknown. - UNKNOWN, - // No migration flow bubble or dialog is shown. - NOT_SHOWN, - // Should show the bubble that offers users to continue with the migration - // flow. - PROMO_BUBBLE, - // Should show the dialog that offers users to migrate credit cards to - // Payments server. - OFFER_DIALOG, - // Migration is in process and result is pending after users click the save - // button. - // Should show credit card icon and the animation. - MIGRATION_RESULT_PENDING, - // Migration is finished. Should show the credit card icon when migration - // is finished and the feedback dialog is ready. - MIGRATION_FINISHED, - // Migration is finished and there are some cards save fails, or payments - // server error. - MIGRATION_FAILED, - // Should show the feedback dialog containing the migration results of cards - // that the user selected to upload after the user clicking the credit card - // icon. - FEEDBACK_DIALOG, - // Should show the error dialog if the Payments Rpc request failed after the - // user clicks the credit card icon. - ERROR_DIALOG, -}; - -// Controller controls the step of migration flow and is responsible -// for interacting with LocalCardMigrationIconView. -class ManageMigrationUiController - : public LocalCardMigrationControllerObserver, - public content::WebContentsUserData<ManageMigrationUiController> { - public: - ManageMigrationUiController(const ManageMigrationUiController&) = delete; - ManageMigrationUiController& operator=(const ManageMigrationUiController&) = - delete; - ~ManageMigrationUiController() override; - - void ShowBubble(base::OnceClosure show_migration_dialog_closure); - - void ShowOfferDialog( - const LegalMessageLines& legal_message_lines, - const std::string& user_email, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - payments::PaymentsAutofillClient::LocalCardMigrationCallback - start_migrating_cards_callback); - - void UpdateCreditCardIcon( - const bool has_server_error, - const std::u16string& tip_message, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - payments::PaymentsAutofillClient::MigrationDeleteCardCallback - delete_local_card_callback); - - void OnUserClickedCreditCardIcon(); - - LocalCardMigrationFlowStep GetFlowStep() const; - - bool IsIconVisible() const; - - // Returns the bubble or the dialog view, respectively. - AutofillBubbleBase* GetBubbleView(); - LocalCardMigrationDialog* GetDialogView(); - - // LocalCardMigrationControllerObserver: - void OnMigrationNoLongerAvailable() override; - void OnMigrationStarted() override; - void OnSourceDestruction(LocalCardMigrationControllerSource source) override; - - protected: - explicit ManageMigrationUiController(content::WebContents* web_contents); - - private: - friend class content::WebContentsUserData<ManageMigrationUiController>; - - // Gets the card migration bubble controller for this `WebContents`. - LocalCardMigrationBubbleControllerImpl* GetBubbleController(); - // Gets the card migration dialog controller for this `WebContents`. - LocalCardMigrationDialogControllerImpl* GetDialogController(); - - void ReshowBubble(); - - void ShowErrorDialog(); - - void ShowFeedbackDialog(); - - // This indicates what step the migration flow is currently in and - // what should be shown next. - LocalCardMigrationFlowStep flow_step_ = LocalCardMigrationFlowStep::NOT_SHOWN; - - // This indicates if we should show error dialog or normal feedback dialog - // after users click the credit card icon. - bool show_error_dialog_ = false; - - base::ScopedObservation<LocalCardMigrationBubbleControllerImpl, - ManageMigrationUiController> - bubble_controller_observation_{this}; - base::ScopedObservation<LocalCardMigrationDialogControllerImpl, - ManageMigrationUiController> - dialog_controller_observation_{this}; - - WEB_CONTENTS_USER_DATA_KEY_DECL(); -}; - -} // namespace autofill - -#endif // CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_MANAGE_MIGRATION_UI_CONTROLLER_H_
diff --git a/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.cc b/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.cc index 5305f2c..62f14a6e 100644 --- a/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.cc +++ b/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.cc
@@ -36,16 +36,6 @@ return iban_bubble_view_.get(); } -AutofillBubbleBase* TestAutofillBubbleHandler::ShowLocalCardMigrationBubble( - content::WebContents* web_contents, - LocalCardMigrationBubbleController* controller, - bool is_user_gesture) { - if (!local_card_migration_bubble_view_) { - local_card_migration_bubble_view_ = std::make_unique<TestAutofillBubble>(); - } - return local_card_migration_bubble_view_.get(); -} - AutofillBubbleBase* TestAutofillBubbleHandler::ShowOfferNotificationBubble( content::WebContents* web_contents, OfferNotificationBubbleController* controller,
diff --git a/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.h b/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.h index 4834acd..8c69c81 100644 --- a/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.h +++ b/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.h
@@ -39,10 +39,6 @@ IbanBubbleController* controller, bool is_user_gesture, IbanBubbleType bubble_type) override; - AutofillBubbleBase* ShowLocalCardMigrationBubble( - content::WebContents* web_contents, - LocalCardMigrationBubbleController* controller, - bool is_user_gesture) override; AutofillBubbleBase* ShowOfferNotificationBubble( content::WebContents* contents, OfferNotificationBubbleController* controller,
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc index 37b2430..150c50a 100644 --- a/chrome/browser/ui/browser_command_controller.cc +++ b/chrome/browser/ui/browser_command_controller.cc
@@ -661,9 +661,6 @@ case IDC_AUTOFILL_MANDATORY_REAUTH: ShowMandatoryReauthOptInPrompt(browser_); break; - case IDC_MIGRATE_LOCAL_CREDIT_CARD_FOR_PAGE: - MigrateLocalCards(browser_); - break; case IDC_SAVE_AUTOFILL_ADDRESS: SaveAutofillAddress(browser_); break;
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index 834bef3f..bf25708 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc
@@ -57,7 +57,6 @@ #include "chrome/browser/ui/autofill/address_bubbles_controller.h" #include "chrome/browser/ui/autofill/payments/filled_card_information_bubble_controller_impl.h" #include "chrome/browser/ui/autofill/payments/iban_bubble_controller_impl.h" -#include "chrome/browser/ui/autofill/payments/manage_migration_ui_controller.h" #include "chrome/browser/ui/autofill/payments/mandatory_reauth_bubble_controller_impl.h" #include "chrome/browser/ui/autofill/payments/offer_notification_bubble_controller_impl.h" #include "chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.h" @@ -1520,15 +1519,6 @@ controller->ReshowBubble(); } -void MigrateLocalCards(Browser* browser) { - WebContents* web_contents = - browser->tab_strip_model()->GetActiveWebContents(); - autofill::ManageMigrationUiController* controller = - autofill::ManageMigrationUiController::FromWebContents(web_contents); - // Show migration-related Ui when the user clicks the credit card icon. - controller->OnUserClickedCreditCardIcon(); -} - void SaveAutofillAddress(Browser* browser) { WebContents* web_contents = browser->tab_strip_model()->GetActiveWebContents();
diff --git a/chrome/browser/ui/browser_commands.h b/chrome/browser/ui/browser_commands.h index dd7689d..b4a56b42 100644 --- a/chrome/browser/ui/browser_commands.h +++ b/chrome/browser/ui/browser_commands.h
@@ -171,7 +171,6 @@ void SaveCreditCard(Browser* browser); void SaveIban(Browser* browser); void ShowMandatoryReauthOptInPrompt(Browser* browser); -void MigrateLocalCards(Browser* browser); void SaveAutofillAddress(Browser* browser); void ShowFilledCardInformationBubble(Browser* browser); void ShowVirtualCardEnrollBubble(Browser* browser);
diff --git a/chrome/browser/ui/global_media_controls/cast_media_notification_producer.cc b/chrome/browser/ui/global_media_controls/cast_media_notification_producer.cc index 467cfec1..d4087679 100644 --- a/chrome/browser/ui/global_media_controls/cast_media_notification_producer.cc +++ b/chrome/browser/ui/global_media_controls/cast_media_notification_producer.cc
@@ -33,8 +33,6 @@ } // If the user changes the pref to show all Cast sessions, they won't be shown // until `OnRoutesUpdated()` is called again. - // TODO(crbug.com/41321719): Ash currently considers Lacros routes non-local - // and hides them if the pref is set to false. if (!route.is_local() && !profile->GetPrefs()->GetBoolean( media_router::prefs::
diff --git a/chrome/browser/ui/global_media_controls/supplemental_device_picker_producer.h b/chrome/browser/ui/global_media_controls/supplemental_device_picker_producer.h index e0b2888b..98ddecc 100644 --- a/chrome/browser/ui/global_media_controls/supplemental_device_picker_producer.h +++ b/chrome/browser/ui/global_media_controls/supplemental_device_picker_producer.h
@@ -34,8 +34,6 @@ // // This object is not the only producer of items containing device pickers. // MediaSessionItemProducer produces items containing pickers for active media. -// -// On Chrome OS, this object lives on the Ash side of the Ash-Lacros split. class SupplementalDevicePickerProducer final : public global_media_controls::MediaItemProducer, public global_media_controls::MediaItemManagerObserver,
diff --git a/chrome/browser/ui/page_action/page_action_icon_type.h b/chrome/browser/ui/page_action/page_action_icon_type.h index f55e9e6..6c29fa4 100644 --- a/chrome/browser/ui/page_action/page_action_icon_type.h +++ b/chrome/browser/ui/page_action/page_action_icon_type.h
@@ -18,7 +18,7 @@ kFind = 4, kMemorySaver = 5, kIntentPicker = 6, - kLocalCardMigration = 7, + // DEPRECATED: kLocalCardMigration = 7, kManagePasswords = 8, kPaymentsOfferNotification = 9, kPriceTracking = 10, @@ -55,7 +55,6 @@ static_assert(static_cast<int>(PageActionIconType::kFind) == 4); static_assert(static_cast<int>(PageActionIconType::kMemorySaver) == 5); static_assert(static_cast<int>(PageActionIconType::kIntentPicker) == 6); -static_assert(static_cast<int>(PageActionIconType::kLocalCardMigration) == 7); static_assert(static_cast<int>(PageActionIconType::kManagePasswords) == 8); static_assert( static_cast<int>(PageActionIconType::kPaymentsOfferNotification) == 9);
diff --git a/chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt_helper.cc b/chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt_helper.cc index 5fa197b..6ee451f 100644 --- a/chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt_helper.cc +++ b/chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt_helper.cc
@@ -109,8 +109,7 @@ #if BUILDFLAG(IS_CHROMEOS) // TODO(crbug.com/1315580, crbug.com/1315579): When navigating to a NTP that // isn't Chrome-controlled on ChromeOS, open an about blank tab to display the - // prompt. On other platforms, it's being handled during the startup. This - // logic can be removed when Lacros is ready. + // prompt. On other platforms, it's being handled during the startup. if (web_contents()->GetLastCommittedURL() == chrome::kChromeUINewTabURL) { const bool has_extention_override = HasExtensionNtpOverride(extensions::ExtensionRegistry::Get(profile()));
diff --git a/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager.cc b/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager.cc index fce7d02..545d0a1 100644 --- a/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager.cc +++ b/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager.cc
@@ -135,6 +135,13 @@ if (!recorded_score.has_value()) { continue; } + const std::string* revoked_status = + dict.FindString(safety_hub::kRevokedStatusDictKeyStr); + if (revoked_status && *revoked_status == safety_hub::kFalsePositiveStr) { + base::UmaHistogramEnumeration(kRevocationResultHistogram, + RevocationResult::kAlreadyFalsePositive); + continue; + } const double new_score = site_engagement_service_->GetScore(url); if (recorded_score.value() < new_score) { dict.Set(safety_hub::kRevokedStatusDictKeyStr,
diff --git a/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager.h b/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager.h index 1c2eef9..5ab0ade3 100644 --- a/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager.h +++ b/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager.h
@@ -35,7 +35,8 @@ kNotDisruptive = 6, kRevoke = 7, kNoRevokeDefaultBlock = 8, - kMaxValue = kNoRevokeDefaultBlock, + kAlreadyFalsePositive = 9, + kMaxValue = kAlreadyFalsePositive, }; // LINT.ThenChange(//tools/metrics/histograms/metadata/settings/enums.xml:DisruptiveNotificationRevocationResult)
diff --git a/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager_unittest.cc b/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager_unittest.cc index 16b7981..db54665 100644 --- a/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager_unittest.cc +++ b/chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager_unittest.cc
@@ -336,6 +336,12 @@ t.ExpectBucketCount(kRevocationResultHistogram, RevocationResult::kFalsePositive, 1); t.ExpectBucketCount(kFalsePositiveSiteEngagementHistogram, 5, 1); + + // Verify that future calls will report `kAlreadyFalsePositive` instead of + // `kFalsePositive`. + manager()->RevokeDisruptiveNotifications(); + t.ExpectBucketCount(kRevocationResultHistogram, + RevocationResult::kAlreadyFalsePositive, 1); } TEST_F(DisruptiveNotificationPermissionsManagerTest, ProposedMetrics) {
diff --git a/chrome/browser/ui/tabs/pinned_tab_service_browsertest.cc b/chrome/browser/ui/tabs/pinned_tab_service_browsertest.cc index 479e331..2ba7925 100644 --- a/chrome/browser/ui/tabs/pinned_tab_service_browsertest.cc +++ b/chrome/browser/ui/tabs/pinned_tab_service_browsertest.cc
@@ -86,7 +86,7 @@ EXPECT_TRUE(PinnedTabServiceFactory::GetForProfile(profile)); EXPECT_TRUE(profile->GetPrefs()); - GURL url("http://www.google.com"); + GURL url("https://www.google.com"); NavigateParams params(browser(), url, ui::PAGE_TRANSITION_TYPED); ui_test_utils::NavigateToURL(¶ms);
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.cc b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.cc index fbc205a..e123427 100644 --- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.cc +++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.cc
@@ -248,10 +248,6 @@ // static void SavedTabGroupUtils::LeaveSharedGroup(const Browser* browser, const base::Uuid& saved_group_guid) { - if (!tab_groups::SavedTabGroupUtils::SupportsSharedTabGroups()) { - return; - } - TabGroupSyncService* tab_group_service = SavedTabGroupUtils::GetServiceForProfile(browser->profile()); if (!tab_group_service) { @@ -268,14 +264,53 @@ return; } - collaboration::CollaborationService* collaboration_service = - collaboration::CollaborationServiceFactory::GetForProfile( - browser->profile()); - auto delegate = std::make_unique<CollaborationControllerDelegateDesktop>( - const_cast<Browser*>(browser), data_sharing::FlowType::kLeave); - collaboration_service->StartShareOrManageFlow( - std::move(delegate), saved_group->saved_guid(), - collaboration::CollaborationServiceShareOrManageEntryPoint::kUnknown); + base::OnceCallback<void()> leave_callback = base::BindOnce( + [](const Browser* browser, const base::Uuid& saved_group_guid) { + TabGroupSyncService* tab_group_service = + SavedTabGroupUtils::GetServiceForProfile(browser->profile()); + if (!tab_group_service) { + return; + } + + const std::optional<SavedTabGroup> saved_group = + tab_group_service->GetGroup(saved_group_guid); + if (!saved_group) { + return; + } + + if (!saved_group->is_shared_tab_group()) { + return; + } + + collaboration::CollaborationService* collaboration_service = + collaboration::CollaborationServiceFactory::GetForProfile( + browser->profile()); + if (!collaboration_service) { + return; + } + + collaboration_service->LeaveGroup( + data_sharing::GroupId(saved_group->collaboration_id()->value()), + base::BindOnce( + [](std::optional<TabGroupId> local_group, bool successful) { + if (successful && local_group) { + SavedTabGroupUtils::RemoveGroupFromTabstrip( + nullptr, local_group.value()); + } + }, + saved_group->local_group_id())); + }, + browser, saved_group_guid); + + DeletionDialogController::DialogMetadata dialog_metadata( + DeletionDialogController::DialogType::LeaveGroup, + /*closing_group_count=*/1, + /*closing_multiple_tabs=*/saved_group->saved_tabs().size() > 1); + dialog_metadata.title_of_closing_group = saved_group->title(); + browser->tab_group_deletion_dialog_controller()->MaybeShowDialog( + dialog_metadata, + base::IgnoreArgs<DeletionDialogController::DeletionDialogTiming>( + std::move(leave_callback))); } // static
diff --git a/chrome/browser/ui/test/test_browser_ui.cc b/chrome/browser/ui/test/test_browser_ui.cc index e37a9eb..85e2e04 100644 --- a/chrome/browser/ui/test/test_browser_ui.cc +++ b/chrome/browser/ui/test/test_browser_ui.cc
@@ -91,8 +91,6 @@ } // namespace TestBrowserUi::TestBrowserUi() { -// TODO(crbug.com/40118868): Revisit the macro expression once build flag switch -// of lacros-chrome is complete. #if BUILDFLAG(IS_WIN) && defined(ARCH_CPU_ARM64) // TODO(crbug.com/40262522): Make these pass with x64 win magic numbers. SetPixelMatchAlgorithm(
diff --git a/chrome/browser/ui/toolbar/app_menu_model.h b/chrome/browser/ui/toolbar/app_menu_model.h index f5f5d8c..559ff92 100644 --- a/chrome/browser/ui/toolbar/app_menu_model.h +++ b/chrome/browser/ui/toolbar/app_menu_model.h
@@ -76,7 +76,6 @@ MENU_ACTION_UNINSTALL_APP = 51, MENU_ACTION_CHROME_TIPS = 53, MENU_ACTION_CHROME_WHATS_NEW = 54, - MENU_ACTION_LACROS_DATA_MIGRATION = 55, MENU_ACTION_MENU_OPENED = 56, MENU_ACTION_VISIT_CHROME_WEB_STORE = 57, MENU_ACTION_PASSWORD_MANAGER = 58,
diff --git a/chrome/browser/ui/views/autofill/autofill_ai/save_or_update_autofill_ai_data_bubble_view.cc b/chrome/browser/ui/views/autofill/autofill_ai/save_or_update_autofill_ai_data_bubble_view.cc index 1eba1d52..6af2c94 100644 --- a/chrome/browser/ui/views/autofill/autofill_ai/save_or_update_autofill_ai_data_bubble_view.cc +++ b/chrome/browser/ui/views/autofill/autofill_ai/save_or_update_autofill_ai_data_bubble_view.cc
@@ -239,57 +239,19 @@ auto* attributes_wrapper = main_content_wrapper->AddChildView( views::Builder<views::BoxLayoutView>() .SetOrientation(views::BoxLayout::Orientation::kVertical) - .SetAccessibleRole(ax::mojom::Role::kDescriptionList) - .SetBetweenChildSpacing(GetVerticaSpaceBetweenDialogSections()) + .SetBetweenChildSpacing( + ChromeLayoutProvider::Get()->GetDistanceMetric( + DISTANCE_CONTROL_LIST_VERTICAL)) + .SetCrossAxisAlignment(views::LayoutAlignment::kStart) .Build()); - auto* new_entity_added_or_updated_attributes_container = - attributes_wrapper->AddChildView( - views::Builder<views::BoxLayoutView>() - .SetOrientation(views::BoxLayout::Orientation::kVertical) - .SetBetweenChildSpacing( - ChromeLayoutProvider::Get()->GetDistanceMetric( - DISTANCE_CONTROL_LIST_VERTICAL)) - .SetCrossAxisAlignment(views::LayoutAlignment::kStart) - .Build()); - new_entity_added_or_updated_attributes_container->SetID( - kNewEntityAddedOrUpdatedAttributesContainer); - - // Only present in the update case. - views::View* new_entity_unchanged_attributes_container = nullptr; - if (!is_save_prompt) { - new_entity_unchanged_attributes_container = - attributes_wrapper->AddChildView( - views::Builder<views::BoxLayoutView>() - .SetOrientation(views::BoxLayout::Orientation::kVertical) - .SetBetweenChildSpacing( - ChromeLayoutProvider::Get()->GetDistanceMetric( - DISTANCE_CONTROL_LIST_VERTICAL)) - .SetCrossAxisAlignment(views::LayoutAlignment::kStart) - .Build()); - new_entity_unchanged_attributes_container->SetID( - kNewEntityUnchagedAttributesContainer); - } const std::vector< SaveOrUpdateAutofillAiDataController::EntityAttributeUpdateDetails> attributes_details = controller_->GetUpdatedAttributesDetails(); for (const SaveOrUpdateAutofillAiDataController::EntityAttributeUpdateDetails& detail : attributes_details) { - const bool new_entity_added_or_updated_attibute = - (detail.update_type == - SaveOrUpdateAutofillAiDataController::EntityAttributeUpdateType:: - kNewEntityAttributeUpdated) || - (detail.update_type == - SaveOrUpdateAutofillAiDataController::EntityAttributeUpdateType:: - kNewEntityAttributeAdded); - if (new_entity_added_or_updated_attibute) { - new_entity_added_or_updated_attributes_container->AddChildView( - BuildEntityAttributeRow(detail, is_save_prompt)); - } else { - CHECK(!is_save_prompt); - new_entity_unchanged_attributes_container->AddChildView( - BuildEntityAttributeRow(detail, is_save_prompt)); - } + attributes_wrapper->AddChildView( + BuildEntityAttributeRow(detail, is_save_prompt)); } DialogDelegate::SetButtonLabel(
diff --git a/chrome/browser/ui/views/autofill/autofill_ai/save_or_update_autofill_ai_data_bubble_view.h b/chrome/browser/ui/views/autofill/autofill_ai/save_or_update_autofill_ai_data_bubble_view.h index 9b94d07a..4fc21c3 100644 --- a/chrome/browser/ui/views/autofill/autofill_ai/save_or_update_autofill_ai_data_bubble_view.h +++ b/chrome/browser/ui/views/autofill/autofill_ai/save_or_update_autofill_ai_data_bubble_view.h
@@ -21,9 +21,6 @@ METADATA_HEADER(SaveOrUpdateAutofillAiDataBubbleView, views::View) public: - static constexpr int kNewEntityAddedOrUpdatedAttributesContainer = 437; - static constexpr int kNewEntityUnchagedAttributesContainer = 438; - SaveOrUpdateAutofillAiDataBubbleView( views::View* anchor_view, content::WebContents* web_contents,
diff --git a/chrome/browser/ui/views/autofill/autofill_ai/save_or_update_autofill_ai_data_bubble_view_unittest.cc b/chrome/browser/ui/views/autofill/autofill_ai/save_or_update_autofill_ai_data_bubble_view_unittest.cc index ccadf46..12f47f13 100644 --- a/chrome/browser/ui/views/autofill/autofill_ai/save_or_update_autofill_ai_data_bubble_view_unittest.cc +++ b/chrome/browser/ui/views/autofill/autofill_ai/save_or_update_autofill_ai_data_bubble_view_unittest.cc
@@ -169,21 +169,6 @@ view().CancelDialog(); } -TEST_F(SaveOrUpdateAutofillAiDataBubbleViewTest, ViewHasExpectedSections) { - CreateViewAndShow(); - views::View* new_entity_added_or_updated_attributes_container = - view().GetViewByID(SaveOrUpdateAutofillAiDataBubbleView:: - kNewEntityAddedOrUpdatedAttributesContainer); - EXPECT_EQ(new_entity_added_or_updated_attributes_container->children().size(), - 2u); - - // Test that there 2 row in the container that stores unchanged values. - views::View* new_entity_unchanged_attributes_container = - view().GetViewByID(SaveOrUpdateAutofillAiDataBubbleView:: - kNewEntityUnchagedAttributesContainer); - EXPECT_EQ(new_entity_unchanged_attributes_container->children().size(), 2u); -} - } // namespace } // namespace autofill_ai
diff --git a/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.cc b/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.cc index 66d80ce..86fec0fb 100644 --- a/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.cc +++ b/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.cc
@@ -22,8 +22,6 @@ #include "chrome/browser/ui/views/autofill/autofill_ai/save_or_update_autofill_ai_data_bubble_view.h" #include "chrome/browser/ui/views/autofill/payments/filled_card_information_bubble_views.h" #include "chrome/browser/ui/views/autofill/payments/filled_card_information_icon_view.h" -#include "chrome/browser/ui/views/autofill/payments/local_card_migration_bubble_views.h" -#include "chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.h" #include "chrome/browser/ui/views/autofill/payments/manage_saved_iban_bubble_view.h" #include "chrome/browser/ui/views/autofill/payments/mandatory_reauth_confirmation_bubble_view.h" #include "chrome/browser/ui/views/autofill/payments/mandatory_reauth_opt_in_bubble_view.h" @@ -166,18 +164,6 @@ NOTREACHED(); } -AutofillBubbleBase* AutofillBubbleHandlerImpl::ShowLocalCardMigrationBubble( - content::WebContents* web_contents, - LocalCardMigrationBubbleController* controller, - bool is_user_gesture) { - // TODO(crbug.com/376284016): An action ID should be created and used here - // when Local Card Migration is migrated to the new page actions framework. - return ShowBubble<LocalCardMigrationBubbleViews>( - toolbar_button_provider_, std::nullopt, - PageActionIconType::kLocalCardMigration, is_user_gesture, web_contents, - controller); -} - AutofillBubbleBase* AutofillBubbleHandlerImpl::ShowOfferNotificationBubble( content::WebContents* web_contents, OfferNotificationBubbleController* controller,
diff --git a/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.h b/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.h index 8dbf253..5bf654c5 100644 --- a/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.h +++ b/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.h
@@ -27,7 +27,6 @@ namespace autofill { class AutofillBubbleBase; class FilledCardInformationBubbleController; -class LocalCardMigrationBubbleController; class SaveCardBubbleController; class IbanBubbleController; enum class IbanBubbleType; @@ -53,10 +52,6 @@ bool is_user_gesture, IbanBubbleType bubble_type) override; - AutofillBubbleBase* ShowLocalCardMigrationBubble( - content::WebContents* web_contents, - LocalCardMigrationBubbleController* controller, - bool is_user_gesture) override; AutofillBubbleBase* ShowOfferNotificationBubble( content::WebContents* contents, OfferNotificationBubbleController* controller,
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_bubble_views.cc b/chrome/browser/ui/views/autofill/payments/local_card_migration_bubble_views.cc deleted file mode 100644 index 2c22859..0000000 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_bubble_views.cc +++ /dev/null
@@ -1,185 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/views/autofill/payments/local_card_migration_bubble_views.h" - -#include <stddef.h> - -#include <memory> -#include <utility> - -#include "base/strings/utf_string_conversions.h" -#include "build/branding_buildflags.h" -#include "build/build_config.h" -#include "chrome/app/vector_icons/vector_icons.h" -#include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/color/chrome_color_id.h" -#include "chrome/browser/ui/views/autofill/payments/dialog_view_ids.h" -#include "chrome/browser/ui/views/autofill/payments/payments_view_util.h" -#include "chrome/browser/ui/views/chrome_layout_provider.h" -#include "chrome/browser/ui/views/chrome_typography.h" -#include "components/autofill/core/browser/ui/payments/local_card_migration_bubble_controller.h" -#include "components/strings/grit/components_strings.h" -#include "components/vector_icons/vector_icons.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/metadata/metadata_impl_macros.h" -#include "ui/base/mojom/dialog_button.mojom.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/color/color_id.h" -#include "ui/color/color_provider.h" -#include "ui/gfx/color_palette.h" -#include "ui/gfx/geometry/insets.h" -#include "ui/gfx/image/image_skia_operations.h" -#include "ui/gfx/paint_vector_icon.h" -#include "ui/views/accessibility/view_accessibility.h" -#include "ui/views/border.h" -#include "ui/views/bubble/bubble_frame_view.h" -#include "ui/views/controls/button/label_button.h" -#include "ui/views/controls/label.h" -#include "ui/views/layout/box_layout.h" -#include "ui/views/layout/fill_layout.h" -#include "ui/views/style/typography.h" - -namespace autofill { - -namespace { -#if BUILDFLAG(GOOGLE_CHROME_BRANDING) -const int kMigrationBubbleGooglePayLogoWidth = 40; -#endif -const int kMigrationBubbleGooglePayLogoHeight = 16; -} // namespace - -LocalCardMigrationBubbleViews::LocalCardMigrationBubbleViews( - views::View* anchor_view, - content::WebContents* web_contents, - LocalCardMigrationBubbleController* controller) - : AutofillLocationBarBubble(anchor_view, web_contents), - controller_(controller) { - DCHECK(controller); - SetButtons(static_cast<int>(ui::mojom::DialogButton::kOk)); - SetButtonLabel(ui::mojom::DialogButton::kOk, - l10n_util::GetStringUTF16( - IDS_AUTOFILL_LOCAL_CARD_MIGRATION_BUBBLE_BUTTON_LABEL)); - SetCancelCallback( - base::BindOnce(&LocalCardMigrationBubbleViews::OnDialogCancelled, - base::Unretained(this))); - SetAcceptCallback( - base::BindOnce(&LocalCardMigrationBubbleViews::OnDialogAccepted, - base::Unretained(this))); - - SetShowCloseButton(true); - set_fixed_width(views::LayoutProvider::Get()->GetDistanceMetric( - views::DISTANCE_BUBBLE_PREFERRED_WIDTH)); -} - -void LocalCardMigrationBubbleViews::Show(DisplayReason reason) { - ShowForReason(reason); -} - -void LocalCardMigrationBubbleViews::Hide() { - // If |controller_| is null, WindowClosing() won't invoke OnBubbleClosed(), so - // do that here. This will clear out |controller_|'s reference to |this|. Note - // that WindowClosing() happens only after the _asynchronous_ Close() task - // posted in CloseBubble() completes, but we need to fix references sooner. - CloseBubble(); - - if (controller_) { - controller_->OnBubbleClosed( - GetPaymentsUiClosedReasonFromWidget(GetWidget())); - } - controller_ = nullptr; -} - -void LocalCardMigrationBubbleViews::OnDialogAccepted() { - if (controller_) { - controller_->OnConfirmButtonClicked(); - } -} - -void LocalCardMigrationBubbleViews::OnDialogCancelled() { - if (controller_) { - controller_->OnCancelButtonClicked(); - } -} - -void LocalCardMigrationBubbleViews::AddedToWidget() { - auto title_container = std::make_unique<views::View>(); - title_container->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kVertical, gfx::Insets(), - ChromeLayoutProvider::Get()->GetDistanceMetric( - DISTANCE_RELATED_CONTROL_VERTICAL_SMALL))); -#if BUILDFLAG(GOOGLE_CHROME_BRANDING) - // kGooglePayLogoIcon is square, and CreateTiledImage() will clip it whereas - // setting the icon size would rescale it incorrectly. - gfx::ImageSkia image = gfx::ImageSkiaOperations::CreateTiledImage( - gfx::CreateVectorIcon( - vector_icons::kGooglePayLogoIcon, - GetColorProvider()->GetColor(kColorPaymentsGooglePayLogo)), - /*x=*/0, /*y=*/0, kMigrationBubbleGooglePayLogoWidth, - kMigrationBubbleGooglePayLogoHeight); -#else - gfx::ImageSkia image = gfx::CreateVectorIcon( - kCreditCardIcon, kMigrationBubbleGooglePayLogoHeight, - GetColorProvider()->GetColor(ui::kColorIcon)); -#endif - views::ImageView* icon_view = new views::ImageView(); - icon_view->SetImage(ui::ImageModel::FromImageSkia(image)); - icon_view->SetHorizontalAlignment(views::ImageView::Alignment::kLeading); - icon_view->GetViewAccessibility().SetName( - l10n_util::GetStringUTF16(IDS_AUTOFILL_GOOGLE_PAY_LOGO_ACCESSIBLE_NAME)); - title_container->AddChildViewRaw(icon_view); - - auto* title = - new views::Label(GetWindowTitle(), views::style::CONTEXT_DIALOG_TITLE); - title->SetHorizontalAlignment(gfx::ALIGN_LEFT); - // Need to set title's preferred size otherwise the long title - // would not be two-lined but would change the width of bubble. - title->SetPreferredSize(gfx::Size(0, 0)); - title->SetMultiLine(true); - title_container->AddChildViewRaw(title); - - GetBubbleFrameView()->SetTitleView(std::move(title_container)); -} - -std::u16string LocalCardMigrationBubbleViews::GetWindowTitle() const { - return controller_ ? l10n_util::GetStringUTF16( - IDS_AUTOFILL_LOCAL_CARD_MIGRATION_BUBBLE_TITLE) - : std::u16string(); -} - -void LocalCardMigrationBubbleViews::WindowClosing() { - if (controller_) { - controller_->OnBubbleClosed( - GetPaymentsUiClosedReasonFromWidget(GetWidget())); - controller_ = nullptr; - } -} - -void LocalCardMigrationBubbleViews::OnWidgetDestroying(views::Widget* widget) { - LocationBarBubbleDelegateView::OnWidgetDestroying(widget); - if (!widget->IsClosed()) { - return; - } - DCHECK_NE(widget->closed_reason(), - views::Widget::ClosedReason::kCancelButtonClicked); -} - -LocalCardMigrationBubbleViews::~LocalCardMigrationBubbleViews() = default; - -void LocalCardMigrationBubbleViews::Init() { - SetLayoutManager(std::make_unique<views::FillLayout>()); - auto* explanatory_message = new views::Label( - l10n_util::GetStringUTF16( - IDS_AUTOFILL_LOCAL_CARD_MIGRATION_BUBBLE_BODY_TEXT), - views::style::CONTEXT_DIALOG_BODY_TEXT, views::style::STYLE_SECONDARY); - explanatory_message->SetHorizontalAlignment(gfx::ALIGN_LEFT); - explanatory_message->SetMultiLine(true); - AddChildViewRaw(explanatory_message); - SetID(DialogViewId::MAIN_CONTENT_VIEW_MIGRATION_BUBBLE); -} - -BEGIN_METADATA(LocalCardMigrationBubbleViews) -END_METADATA - -} // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_bubble_views.h b/chrome/browser/ui/views/autofill/payments/local_card_migration_bubble_views.h deleted file mode 100644 index c4daba7..0000000 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_bubble_views.h +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_BUBBLE_VIEWS_H_ -#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_BUBBLE_VIEWS_H_ - -#include "base/memory/raw_ptr.h" -#include "chrome/browser/ui/autofill/autofill_bubble_base.h" -#include "chrome/browser/ui/views/autofill/autofill_location_bar_bubble.h" -#include "components/autofill/core/browser/ui/payments/local_card_migration_bubble_controller.h" -#include "components/autofill/core/browser/ui/payments/payments_ui_closed_reasons.h" -#include "ui/base/metadata/metadata_header_macros.h" - -namespace content { -class WebContents; -} - -namespace autofill { - -// Class responsible for showing the local card migration bubble which is -// the entry point of the entire migration flow. -class LocalCardMigrationBubbleViews : public AutofillLocationBarBubble { - METADATA_HEADER(LocalCardMigrationBubbleViews, AutofillLocationBarBubble) - public: - // The |controller| is lazily initialized in ChromeAutofillClient and there - // should be only one controller per tab after the initialization. It should - // live even when bubble is gone. - LocalCardMigrationBubbleViews(views::View* anchor_view, - content::WebContents* web_contents, - LocalCardMigrationBubbleController* controller); - - LocalCardMigrationBubbleViews(const LocalCardMigrationBubbleViews&) = delete; - LocalCardMigrationBubbleViews& operator=( - const LocalCardMigrationBubbleViews&) = delete; - ~LocalCardMigrationBubbleViews() override; - - void Show(DisplayReason reason); - - // AutofillBubbleBase: - void Hide() override; - - // LocationBarBubbleDelegateView: - void AddedToWidget() override; - std::u16string GetWindowTitle() const override; - void WindowClosing() override; - void OnWidgetDestroying(views::Widget* widget) override; - - private: - friend class LocalCardMigrationBrowserTest; - - void OnDialogAccepted(); - void OnDialogCancelled(); - - // views::BubbleDialogDelegateView: - void Init() override; - - raw_ptr<LocalCardMigrationBubbleController> controller_; -}; - -} // namespace autofill - -#endif // CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_BUBBLE_VIEWS_H_
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.cc b/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.cc deleted file mode 100644 index 2c6b014..0000000 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.cc +++ /dev/null
@@ -1,538 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.h" - -#include <memory> -#include <string> -#include <vector> - -#include "base/functional/bind.h" -#include "base/i18n/message_formatter.h" -#include "base/location.h" -#include "base/memory/raw_ptr.h" -#include "base/strings/utf_string_conversions.h" -#include "build/branding_buildflags.h" -#include "chrome/app/vector_icons/vector_icons.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_dialog_factory.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_dialog_state.h" -#include "chrome/browser/ui/autofill/payments/payments_ui_constants.h" -#include "chrome/browser/ui/color/chrome_color_id.h" -#include "chrome/browser/ui/views/autofill/payments/migratable_card_view.h" -#include "chrome/browser/ui/views/autofill/payments/payments_view_util.h" -#include "chrome/browser/ui/views/chrome_typography.h" -#include "components/autofill/core/browser/payments/local_card_migration_manager.h" -#include "components/constrained_window/constrained_window_views.h" -#include "components/grit/components_scaled_resources.h" -#include "components/strings/grit/components_strings.h" -#include "components/vector_icons/vector_icons.h" -#include "components/web_modal/web_contents_modal_dialog_host.h" -#include "components/web_modal/web_contents_modal_dialog_manager.h" -#include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/metadata/metadata_header_macros.h" -#include "ui/base/metadata/metadata_impl_macros.h" -#include "ui/base/models/image_model.h" -#include "ui/base/mojom/dialog_button.mojom.h" -#include "ui/base/mojom/ui_base_types.mojom-shared.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/color/color_id.h" -#include "ui/gfx/color_palette.h" -#include "ui/gfx/geometry/insets.h" -#include "ui/gfx/paint_vector_icon.h" -#include "ui/views/background.h" -#include "ui/views/border.h" -#include "ui/views/controls/button/button.h" -#include "ui/views/controls/button/checkbox.h" -#include "ui/views/controls/button/image_button.h" -#include "ui/views/controls/image_view.h" -#include "ui/views/controls/label.h" -#include "ui/views/controls/scroll_view.h" -#include "ui/views/controls/separator.h" -#include "ui/views/controls/styled_label.h" -#include "ui/views/layout/box_layout.h" -#include "ui/views/layout/box_layout_view.h" -#include "ui/views/layout/layout_provider.h" -#include "ui/views/style/typography.h" -#include "ui/views/view_utils.h" -#include "ui/views/widget/widget.h" - -namespace autofill { - -namespace { - -#if BUILDFLAG(GOOGLE_CHROME_BRANDING) -class AutofillMigrationHeaderView : public views::ImageView { - METADATA_HEADER(AutofillMigrationHeaderView, views::ImageView) - - public: - AutofillMigrationHeaderView() { - constexpr int kImageBorderBottom = 8; - SetBorder(views::CreateEmptyBorder( - gfx::Insets::TLBR(0, 0, kImageBorderBottom, 0))); - SetAccessibleName(l10n_util::GetStringUTF16( - IDS_AUTOFILL_GOOGLE_PAY_LOGO_ACCESSIBLE_NAME)); - } - - // views::Label: - void OnThemeChanged() override { - ImageView::OnThemeChanged(); - SetImage(ui::ImageModel::FromResourceId( - GetNativeTheme()->ShouldUseDarkColors() - ? IDR_AUTOFILL_MIGRATION_DIALOG_HEADER_DARK - : IDR_AUTOFILL_MIGRATION_DIALOG_HEADER)); - } -}; - -BEGIN_METADATA(AutofillMigrationHeaderView) -END_METADATA -#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) - -// Create the view containing the `tip_message` shown to the user. -std::unique_ptr<views::BoxLayoutView> CreateTipTextContainer( - const std::u16string& tip_message) { - views::LayoutProvider* provider = views::LayoutProvider::Get(); - const gfx::Insets kContainerInsets = - provider->GetInsetsMetric(views::INSETS_DIALOG_SUBSECTION); - const int kContainerChildSpace = - provider->GetDistanceMetric(views::DISTANCE_RELATED_LABEL_HORIZONTAL); - constexpr int kTipValuePromptBorderThickness = 1; - constexpr int kTipImageSize = 16; - - auto container = - views::Builder<views::BoxLayoutView>() - .SetOrientation(views::BoxLayout::Orientation::kHorizontal) - .SetInsideBorderInsets(gfx::Insets(kContainerInsets)) - .SetBetweenChildSpacing(kContainerChildSpace) - .SetBackground( - views::CreateSolidBackground(kColorPaymentsFeedbackTipBackground)) - .SetBorder(views::CreateSolidBorder(kTipValuePromptBorderThickness, - kColorPaymentsFeedbackTipBorder)) - .Build(); - - container->AddChildView( - views::Builder<views::ImageView>() - .SetImage(ui::ImageModel::FromVectorIcon( - vector_icons::kLightbulbOutlineIcon, - kColorPaymentsFeedbackTipIcon, kTipImageSize)) - .SetVerticalAlignment(views::ImageView::Alignment::kLeading) - .Build()); - - container->AddChildView( - views::Builder<views::Label>() - .SetText(tip_message) - .SetTextContext(CONTEXT_DIALOG_BODY_TEXT_SMALL) - .SetTextStyle(views::style::STYLE_SECONDARY) - .SetEnabledColor(kColorPaymentsFeedbackTipForeground) - .SetMultiLine(true) - .SetHorizontalAlignment(gfx::ALIGN_LEFT) - .SizeToFit(provider->GetDistanceMetric( - views::DISTANCE_LARGE_MODAL_DIALOG_PREFERRED_WIDTH) - - kMigrationDialogInsets.width() - kContainerInsets.width() - - kTipImageSize - kContainerChildSpace) - .Build()); - - return container; -} - -// Create the title label container for the migration dialogs. The title -// text depends on the |view_state| of the dialog. -std::unique_ptr<views::Label> CreateTitle( - LocalCardMigrationDialogState view_state, - int card_list_size) { - int message_id; - switch (view_state) { - case LocalCardMigrationDialogState::kOffered: - message_id = IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TITLE_OFFER; - break; - case LocalCardMigrationDialogState::kFinished: - message_id = IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TITLE_DONE; - break; - case LocalCardMigrationDialogState::kActionRequired: - message_id = IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TITLE_FIX; - break; - } - - auto title = std::make_unique<views::Label>( - l10n_util::GetPluralStringFUTF16(message_id, card_list_size)); - constexpr int kMigrationDialogTitleFontSize = 8; -#if BUILDFLAG(GOOGLE_CHROME_BRANDING) - constexpr int kMigrationDialogTitleMarginTop = 0; -#else - constexpr int kMigrationDialogTitleMarginTop = 12; -#endif - title->SetBorder(views::CreateEmptyBorder(gfx::Insets::TLBR( - kMigrationDialogTitleMarginTop, kMigrationDialogInsets.left(), 0, - kMigrationDialogInsets.right()))); - title->SetFontList(gfx::FontList().Derive(kMigrationDialogTitleFontSize, - gfx::Font::NORMAL, - gfx::Font::Weight::NORMAL)); - constexpr int kMigrationDialogTitleLineHeight = 20; - title->SetMultiLine(true); - title->SetLineHeight(kMigrationDialogTitleLineHeight); - return title; -} - -// Create the explanation text label with |user_email| for the migration -// dialogs. The text content depends on the |view_state| of the dialog and the -// |card_list_size|. -std::unique_ptr<views::Label> CreateExplanationText( - LocalCardMigrationDialogState view_state, - int card_list_size, - const std::u16string& user_email) { - auto explanation_text = std::make_unique<views::Label>( - std::u16string(), views::style::CONTEXT_DIALOG_BODY_TEXT, - views::style::STYLE_SECONDARY); - switch (view_state) { - case LocalCardMigrationDialogState::kOffered: - DCHECK(!user_email.empty()); - explanation_text->SetText( - base::i18n::MessageFormatter::FormatWithNumberedArgs( - l10n_util::GetStringFUTF16( - IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_OFFER, - user_email), - card_list_size)); - break; - case LocalCardMigrationDialogState::kFinished: - explanation_text->SetText(l10n_util::GetPluralStringFUTF16( - card_list_size == 0 - ? IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_INVALID_CARD_REMOVED - : IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_DONE, - card_list_size)); - break; - case LocalCardMigrationDialogState::kActionRequired: - explanation_text->SetText(l10n_util::GetStringUTF16( - IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_FIX)); - break; - } - explanation_text->SetMultiLine(true); - explanation_text->SetHorizontalAlignment(gfx::ALIGN_LEFT); - return explanation_text; -} - -// Create the scroll view of cards in |migratable_credit_cards|, and each -// row in the scroll view is a MigratableCardView. |dialog_view| -// will be notified whenever the checkbox or the trash can button -// (if any) in any row is clicked. The content and the layout of the -// scroll view depends on |should_show_checkbox|. -std::unique_ptr<views::ScrollView> CreateCardList( - const std::vector<MigratableCreditCard>& migratable_credit_cards, - LocalCardMigrationDialogView* dialog_view, - bool should_show_checkbox) { - views::LayoutProvider* provider = views::LayoutProvider::Get(); - auto card_list_view = std::make_unique<views::View>(); - constexpr int kCardListSmallVerticalDistance = 8; - auto* card_list_view_layout = - card_list_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kVertical, gfx::Insets(), - should_show_checkbox - ? kCardListSmallVerticalDistance - : provider->GetDistanceMetric( - views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); - card_list_view_layout->set_main_axis_alignment( - views::BoxLayout::MainAxisAlignment::kStart); - for (const auto& migratable_credit_card : migratable_credit_cards) { - card_list_view->AddChildView(std::make_unique<MigratableCardView>( - migratable_credit_card, dialog_view, should_show_checkbox)); - } - - auto card_list_scroll_view = std::make_unique<views::ScrollView>(); - card_list_scroll_view->SetHorizontalScrollBarMode( - views::ScrollView::ScrollBarMode::kDisabled); - card_list_scroll_view->SetContents(std::move(card_list_view)); - card_list_scroll_view->SetDrawOverflowIndicator(false); - constexpr int kCardListScrollViewHeight = 140; - card_list_scroll_view->ClipHeightTo(0, kCardListScrollViewHeight); - return card_list_scroll_view; -} - -// Create the feedback main content view composed of -// title, explanation text, card list, and the tip (if present). -std::unique_ptr<views::View> CreateFeedbackContentView( - LocalCardMigrationDialogController* controller, - LocalCardMigrationDialogView* dialog_view) { - DCHECK(controller->GetViewState() != LocalCardMigrationDialogState::kOffered); - - auto feedback_view = std::make_unique<views::View>(); - views::LayoutProvider* provider = views::LayoutProvider::Get(); - feedback_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kVertical, gfx::Insets(), - provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); - feedback_view->SetBorder(views::CreateEmptyBorder(kMigrationDialogInsets)); - - LocalCardMigrationDialogState view_state = controller->GetViewState(); - const std::vector<MigratableCreditCard>& card_list = - controller->GetCardList(); - const int card_list_size = card_list.size(); - - feedback_view->AddChildView( - CreateExplanationText(view_state, card_list_size, std::u16string())); - - if (card_list_size > 0) { - feedback_view->AddChildView(CreateCardList(card_list, dialog_view, false)); - - // If there are no more than two cards in the finished dialog, show the tip. - constexpr int kShowTipMessageCardNumberLimit = 2; - if (view_state == LocalCardMigrationDialogState::kFinished && - card_list_size <= kShowTipMessageCardNumberLimit) { - feedback_view->AddChildView( - CreateTipTextContainer(controller->GetTipMessage())); - } - } - - return feedback_view; -} - -// The height of the bounded legal message ScrollView. -constexpr int kLegalMessageScrollViewHeight = 140; - -} // namespace - -// A view composed of the main contents for local card migration dialog -// including title, explanatory message, migratable credit card list, -// horizontal separator, and legal message. It is used by -// LocalCardMigrationDialogView class when it offers the user the -// option to upload all browser-saved credit cards. -class LocalCardMigrationOfferView : public views::View { - METADATA_HEADER(LocalCardMigrationOfferView, views::View) - - public: - LocalCardMigrationOfferView(LocalCardMigrationDialogController* controller, - LocalCardMigrationDialogView* dialog_view) { - DCHECK(controller); - views::LayoutProvider* provider = views::LayoutProvider::Get(); - SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kVertical, gfx::Insets(), - kMigrationDialogMainContainerChildSpacing)); - - auto* contents_container = AddChildView(std::make_unique<views::View>()); - contents_container->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kVertical, gfx::Insets(), - provider->GetDistanceMetric( - views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); - // Don't set bottom since there is a legal message view in the offer dialog. - contents_container->SetBorder(views::CreateEmptyBorder(gfx::Insets::TLBR( - 0, kMigrationDialogInsets.left(), 0, kMigrationDialogInsets.right()))); - - const std::vector<MigratableCreditCard>& card_list = - controller->GetCardList(); - int card_list_size = card_list.size(); - - contents_container->AddChildView( - CreateExplanationText(controller->GetViewState(), card_list_size, - base::UTF8ToUTF16(controller->GetUserEmail()))); - - auto* scroll_view = contents_container->AddChildView( - CreateCardList(card_list, dialog_view, card_list_size != 1)); - card_list_view_ = scroll_view->contents(); - - AddChildView(std::make_unique<views::Separator>()); - - auto* legal_message_container = - AddChildView(std::make_unique<views::ScrollView>()); - legal_message_container->SetHorizontalScrollBarMode( - views::ScrollView::ScrollBarMode::kDisabled); - legal_message_container->SetContents(CreateLegalMessageView( - controller->GetLegalMessageLines(), /*user_email=*/std::u16string(), - /*user_avatar=*/ui::ImageModel(), - base::BindRepeating( - &LocalCardMigrationDialogController::OnLegalMessageLinkClicked, - base::Unretained(controller)))); - legal_message_container->ClipHeightTo(0, kLegalMessageScrollViewHeight); - legal_message_container->SetBorder( - views::CreateEmptyBorder(kMigrationDialogInsets)); - } - - LocalCardMigrationOfferView(const LocalCardMigrationOfferView&) = delete; - LocalCardMigrationOfferView& operator=(const LocalCardMigrationOfferView&) = - delete; - ~LocalCardMigrationOfferView() override = default; - - const std::vector<std::string> GetSelectedCardGuids() const { - std::vector<std::string> selected_cards; - for (views::View* child : card_list_view_->children()) { - DCHECK(views::IsViewClass<MigratableCardView>(child)); - auto* card = static_cast<MigratableCardView*>(child); - if (card->GetSelected()) { - selected_cards.push_back(card->GetGuid()); - } - } - return selected_cards; - } - - private: - friend class LocalCardMigrationDialogView; - - raw_ptr<views::View> card_list_view_ = nullptr; -}; - -BEGIN_METADATA(LocalCardMigrationOfferView) -ADD_READONLY_PROPERTY_METADATA(std::vector<std::string>, SelectedCardGuids) -END_METADATA - -LocalCardMigrationDialogView::LocalCardMigrationDialogView( - LocalCardMigrationDialogController* controller) - : controller_(controller) { - SetButtons(controller_->AllCardsInvalid() - ? static_cast<int>(ui::mojom::DialogButton::kOk) - : static_cast<int>(ui::mojom::DialogButton::kOk) | - static_cast<int>(ui::mojom::DialogButton::kCancel)); - SetButtonLabel(ui::mojom::DialogButton::kOk, GetOkButtonLabel()); - SetButtonLabel(ui::mojom::DialogButton::kCancel, GetCancelButtonLabel()); - SetCancelCallback( - base::BindOnce(&LocalCardMigrationDialogView::OnDialogCancelled, - base::Unretained(this))); - SetAcceptCallback(base::BindOnce( - &LocalCardMigrationDialogView::OnDialogAccepted, base::Unretained(this))); - // This should be a modal dialog blocking the browser since we don't want - // users to lose progress in the migration workflow until they are done. - SetModalType(ui::mojom::ModalType::kWindow); - set_close_on_deactivate(false); - set_margins(gfx::Insets()); - set_fixed_width(views::LayoutProvider::Get()->GetDistanceMetric( - views::DISTANCE_LARGE_MODAL_DIALOG_PREFERRED_WIDTH)); - SetShowCloseButton(false); -} - -LocalCardMigrationDialogView::~LocalCardMigrationDialogView() { - if (controller_) { - controller_->OnDialogClosed(); - controller_ = nullptr; - } -} - -void LocalCardMigrationDialogView::ShowDialog( - content::WebContents& web_contents) { - ConstructView(); - constrained_window::CreateBrowserModalDialogViews( - this, web_contents.GetTopLevelNativeWindow()) - ->Show(); -} - -void LocalCardMigrationDialogView::CloseDialog() { - GetWidget()->Close(); - if (controller_) { - controller_->OnDialogClosed(); - controller_ = nullptr; - } -} - -void LocalCardMigrationDialogView::OnDialogAccepted() { - switch (controller_->GetViewState()) { - case LocalCardMigrationDialogState::kOffered: - DCHECK(offer_view_); - controller_->OnSaveButtonClicked(offer_view_->GetSelectedCardGuids()); - break; - case LocalCardMigrationDialogState::kFinished: - case LocalCardMigrationDialogState::kActionRequired: - controller_->OnDoneButtonClicked(); - break; - } -} - -void LocalCardMigrationDialogView::OnDialogCancelled() { - switch (controller_->GetViewState()) { - case LocalCardMigrationDialogState::kOffered: - controller_->OnCancelButtonClicked(); - break; - case LocalCardMigrationDialogState::kFinished: - case LocalCardMigrationDialogState::kActionRequired: - controller_->OnViewCardsButtonClicked(); - break; - } -} - -bool LocalCardMigrationDialogView::GetEnableOkButton() const { - if (controller_->GetViewState() == LocalCardMigrationDialogState::kOffered) { - DCHECK(offer_view_) << "This method can't be called before ConstructView"; - return !offer_view_->GetSelectedCardGuids().empty(); - } - return true; -} - -void LocalCardMigrationDialogView::DeleteCard(const std::string& guid) { - controller_->DeleteCard(guid); - ConstructView(); - UpdateLayout(); -} - -void LocalCardMigrationDialogView::OnCardCheckboxToggled() { - SetButtonEnabled(ui::mojom::DialogButton::kOk, GetEnableOkButton()); -} - -// TODO(crbug.com/41430966): Figure out a way to avoid two consecutive layouts. -void LocalCardMigrationDialogView::UpdateLayout() { - DeprecatedLayoutImmediately(); - // Since the dialog does not have anchor view or arrow, cannot use - // SizeToContents() for now. TODO(crbug.com/40586517): Try to fix the - // BubbleDialogDelegateView::GetBubbleBounds() when there is no anchor - // view or arrow. - GetWidget()->SetSize(GetWidget()->non_client_view()->GetPreferredSize()); -} - -void LocalCardMigrationDialogView::ConstructView() { - DCHECK(controller_->GetViewState() != - LocalCardMigrationDialogState::kOffered || - children().empty()); - card_list_view_ = nullptr; - RemoveAllChildViews(); - - SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kVertical, gfx::Insets(), - kMigrationDialogMainContainerChildSpacing)); - -#if BUILDFLAG(GOOGLE_CHROME_BRANDING) - AddChildView(std::make_unique<AutofillMigrationHeaderView>()); -#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) - - LocalCardMigrationDialogState view_state = controller_->GetViewState(); - AddChildView(CreateTitle(view_state, controller_->GetCardList().size())); - - if (view_state == LocalCardMigrationDialogState::kOffered) { - offer_view_ = AddChildView( - std::make_unique<LocalCardMigrationOfferView>(controller_, this)); - offer_view_->SetID(DialogViewId::MAIN_CONTENT_VIEW_MIGRATION_OFFER_DIALOG); - card_list_view_ = offer_view_->card_list_view_; - SetButtonEnabled(ui::mojom::DialogButton::kOk, GetEnableOkButton()); - } else { - AddChildView(CreateFeedbackContentView(controller_, this)); - } -} - -std::u16string LocalCardMigrationDialogView::GetOkButtonLabel() const { - switch (controller_->GetViewState()) { - case LocalCardMigrationDialogState::kOffered: - return l10n_util::GetStringUTF16( - IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_BUTTON_LABEL_SAVE); - case LocalCardMigrationDialogState::kFinished: - case LocalCardMigrationDialogState::kActionRequired: - return l10n_util::GetStringUTF16( - IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_BUTTON_LABEL_DONE); - } -} - -std::u16string LocalCardMigrationDialogView::GetCancelButtonLabel() const { - switch (controller_->GetViewState()) { - case LocalCardMigrationDialogState::kOffered: - return l10n_util::GetStringUTF16( - IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_BUTTON_LABEL_CANCEL); - case LocalCardMigrationDialogState::kFinished: - case LocalCardMigrationDialogState::kActionRequired: - return l10n_util::GetStringUTF16( - IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_BUTTON_LABEL_VIEW_CARDS); - } -} - -LocalCardMigrationDialog* CreateLocalCardMigrationDialogView( - LocalCardMigrationDialogController* controller) { - return new LocalCardMigrationDialogView(controller); -} - -BEGIN_METADATA(LocalCardMigrationDialogView) -ADD_READONLY_PROPERTY_METADATA(bool, EnableOkButton) -ADD_READONLY_PROPERTY_METADATA(std::u16string, OkButtonLabel) -ADD_READONLY_PROPERTY_METADATA(std::u16string, CancelButtonLabel) -END_METADATA - -} // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.h b/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.h deleted file mode 100644 index b70c4a5..0000000 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.h +++ /dev/null
@@ -1,72 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_VIEW_H_ -#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_VIEW_H_ - -#include "base/memory/raw_ptr.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_dialog.h" -#include "chrome/browser/ui/views/autofill/payments/dialog_view_ids.h" -#include "components/autofill/core/browser/ui/payments/local_card_migration_dialog_controller.h" -#include "ui/base/metadata/metadata_header_macros.h" -#include "ui/views/bubble/bubble_dialog_delegate_view.h" -#include "ui/views/view.h" -#include "ui/views/window/dialog_delegate.h" - -namespace content { -class WebContents; -} // namespace content - -namespace autofill { - -enum class LocalCardMigrationDialogState; -class LocalCardMigrationOfferView; - -class LocalCardMigrationDialogView : public LocalCardMigrationDialog, - public views::BubbleDialogDelegateView { - METADATA_HEADER(LocalCardMigrationDialogView, views::BubbleDialogDelegateView) - - public: - explicit LocalCardMigrationDialogView( - LocalCardMigrationDialogController* controller); - LocalCardMigrationDialogView(const LocalCardMigrationDialogView&) = delete; - LocalCardMigrationDialogView& operator=(const LocalCardMigrationDialogView&) = - delete; - ~LocalCardMigrationDialogView() override; - - // LocalCardMigrationDialog: - void ShowDialog(content::WebContents& web_contents) override; - void CloseDialog() override; - - // Called by MigratableCardView when the user clicks the trash can button. - // |guid| is the GUID of the credit card to be deleted. - void OnCardCheckboxToggled(); - void DeleteCard(const std::string& guid); - void UpdateLayout(); - - private: - friend class LocalCardMigrationBrowserTest; - - void ConstructView(); - void OnDialogAccepted(); - void OnDialogCancelled(); - bool GetEnableOkButton() const; - - std::u16string GetOkButtonLabel() const; - std::u16string GetCancelButtonLabel() const; - - raw_ptr<LocalCardMigrationDialogController> controller_; - - // Pointer points to the LocalCardMigrationOfferView. Can be null when the - // dialog is not in the 'offer' state. - raw_ptr<LocalCardMigrationOfferView> offer_view_ = nullptr; - - // The view containing a list of cards. It is the content of the scroll bar. - // Owned by the LocalCardMigrationOfferView. - raw_ptr<views::View> card_list_view_ = nullptr; -}; - -} // namespace autofill - -#endif // CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_VIEW_H_
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_error_dialog_view.cc b/chrome/browser/ui/views/autofill/payments/local_card_migration_error_dialog_view.cc deleted file mode 100644 index 509f76d8..0000000 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_error_dialog_view.cc +++ /dev/null
@@ -1,135 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/views/autofill/payments/local_card_migration_error_dialog_view.h" - -#include "build/branding_buildflags.h" -#include "chrome/app/vector_icons/vector_icons.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_dialog_factory.h" -#include "chrome/browser/ui/autofill/payments/payments_ui_constants.h" -#include "chrome/browser/ui/views/chrome_typography.h" -#include "components/autofill/core/browser/payments/local_card_migration_manager.h" -#include "components/constrained_window/constrained_window_views.h" -#include "components/grit/components_scaled_resources.h" -#include "components/strings/grit/components_strings.h" -#include "components/web_modal/web_contents_modal_dialog_host.h" -#include "components/web_modal/web_contents_modal_dialog_manager.h" -#include "components/web_modal/web_contents_modal_dialog_manager_delegate.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/metadata/metadata_impl_macros.h" -#include "ui/base/mojom/dialog_button.mojom.h" -#include "ui/base/mojom/ui_base_types.mojom-shared.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/color/color_id.h" -#include "ui/color/color_provider.h" -#include "ui/gfx/geometry/insets.h" -#include "ui/gfx/paint_vector_icon.h" -#include "ui/native_theme/native_theme.h" -#include "ui/views/border.h" -#include "ui/views/controls/image_view.h" -#include "ui/views/controls/label.h" -#include "ui/views/layout/box_layout.h" -#include "ui/views/layout/layout_provider.h" -#include "ui/views/style/typography.h" -#include "ui/views/widget/widget.h" - -namespace autofill { - -LocalCardMigrationErrorDialogView::LocalCardMigrationErrorDialogView( - LocalCardMigrationDialogController* controller) - : controller_(controller) { - SetButtons(static_cast<int>(ui::mojom::DialogButton::kCancel)); - SetCancelCallback( - base::BindOnce(&LocalCardMigrationDialogController::OnDoneButtonClicked, - base::Unretained(controller_))); - - // The error dialog should be a modal dialog blocking the whole browser - // which is consistent with other dialogs. It should make sure that the - // user can see the error message. - SetModalType(ui::mojom::ModalType::kWindow); - SetShowCloseButton(false); - set_fixed_width(views::LayoutProvider::Get()->GetDistanceMetric( - views::DISTANCE_LARGE_MODAL_DIALOG_PREFERRED_WIDTH)); - - set_close_on_deactivate(false); - set_margins(gfx::Insets()); -} - -LocalCardMigrationErrorDialogView::~LocalCardMigrationErrorDialogView() { - if (controller_) { - controller_->OnDialogClosed(); - controller_ = nullptr; - } -} - -void LocalCardMigrationErrorDialogView::ShowDialog( - content::WebContents& web_contents) { - Init(); - constrained_window::CreateBrowserModalDialogViews( - this, web_contents.GetTopLevelNativeWindow()) - ->Show(); -} - -void LocalCardMigrationErrorDialogView::CloseDialog() { - GetWidget()->Close(); - if (controller_) { - controller_->OnDialogClosed(); - controller_ = nullptr; - } -} - -void LocalCardMigrationErrorDialogView::Init() { - if (!children().empty()) { - return; - } - - views::LayoutProvider* provider = views::LayoutProvider::Get(); - SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kVertical, gfx::Insets(), - kMigrationDialogMainContainerChildSpacing)); - -#if BUILDFLAG(GOOGLE_CHROME_BRANDING) - auto* image = new views::ImageView(); - image->SetImage(ui::ImageModel::FromResourceId( - GetNativeTheme()->ShouldUseDarkColors() - ? IDR_AUTOFILL_MIGRATION_DIALOG_HEADER_DARK - : IDR_AUTOFILL_MIGRATION_DIALOG_HEADER)); - image->SetAccessibleName( - l10n_util::GetStringUTF16(IDS_AUTOFILL_GOOGLE_PAY_LOGO_ACCESSIBLE_NAME)); - AddChildViewRaw(image); -#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) - - auto* error_view = new views::View(); - auto* horizontal_layout = - error_view->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), - provider->GetDistanceMetric( - views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); - horizontal_layout->set_main_axis_alignment( - views::BoxLayout::MainAxisAlignment::kCenter); - error_view->SetBorder(views::CreateEmptyBorder(kMigrationDialogInsets)); - auto* error_image = new views::ImageView(); - error_image->SetImage(ui::ImageModel::FromVectorIcon( - kBrowserToolsErrorIcon, ui::kColorAlertHighSeverity)); - error_view->AddChildViewRaw(error_image); - - auto* error_message = new views::Label( - l10n_util::GetPluralStringFUTF16( - IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_ERROR, - controller_->GetCardList().size()), - views::style::CONTEXT_DIALOG_BODY_TEXT, ChromeTextStyle::STYLE_RED); - error_view->AddChildViewRaw(error_message); - - AddChildViewRaw(error_view); -} - -LocalCardMigrationDialog* CreateLocalCardMigrationErrorDialogView( - LocalCardMigrationDialogController* controller) { - return new LocalCardMigrationErrorDialogView(controller); -} - -BEGIN_METADATA(LocalCardMigrationErrorDialogView) -END_METADATA - -} // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_error_dialog_view.h b/chrome/browser/ui/views/autofill/payments/local_card_migration_error_dialog_view.h deleted file mode 100644 index e0414b1..0000000 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_error_dialog_view.h +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_ERROR_DIALOG_VIEW_H_ -#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_ERROR_DIALOG_VIEW_H_ - -#include "base/memory/raw_ptr.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_dialog.h" -#include "chrome/browser/ui/views/autofill/payments/dialog_view_ids.h" -#include "components/autofill/core/browser/ui/payments/local_card_migration_dialog_controller.h" -#include "ui/base/metadata/metadata_header_macros.h" -#include "ui/views/bubble/bubble_dialog_delegate_view.h" -#include "ui/views/controls/button/button.h" -#include "ui/views/view.h" -#include "ui/views/window/dialog_delegate.h" - -namespace content { -class WebContents; -} // namespace content - -namespace autofill { - -class LocalCardMigrationErrorDialogView - : public LocalCardMigrationDialog, - public views::BubbleDialogDelegateView { - METADATA_HEADER(LocalCardMigrationErrorDialogView, - views::BubbleDialogDelegateView) - - public: - explicit LocalCardMigrationErrorDialogView( - LocalCardMigrationDialogController* controller); - LocalCardMigrationErrorDialogView(const LocalCardMigrationErrorDialogView&) = - delete; - LocalCardMigrationErrorDialogView& operator=( - const LocalCardMigrationErrorDialogView&) = delete; - ~LocalCardMigrationErrorDialogView() override; - - // LocalCardMigrationDialog: - void ShowDialog(content::WebContents& web_contents) override; - void CloseDialog() override; - - // views::BubbleDialogDelegateView: - void Init() override; - - private: - raw_ptr<LocalCardMigrationDialogController> controller_; -}; - -} // namespace autofill - -#endif // CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_ERROR_DIALOG_VIEW_H_
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.cc b/chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.cc deleted file mode 100644 index f10e7333..0000000 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.cc +++ /dev/null
@@ -1,172 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.h" - -#include "chrome/app/chrome_command_ids.h" -#include "chrome/app/vector_icons/vector_icons.h" -#include "chrome/browser/ui/autofill/payments/manage_migration_ui_controller.h" -#include "chrome/browser/ui/browser_command_controller.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/ui/view_ids.h" -#include "chrome/browser/ui/views/autofill/payments/local_card_migration_bubble_views.h" -#include "chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.h" -#include "chrome/grit/generated_resources.h" -#include "components/autofill/core/common/autofill_payments_features.h" -#include "components/strings/grit/components_strings.h" -#include "components/vector_icons/vector_icons.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/metadata/metadata_impl_macros.h" -#include "ui/gfx/vector_icon_types.h" -#include "ui/views/accessibility/view_accessibility.h" -#include "ui/views/animation/ink_drop.h" - -namespace autofill { - -LocalCardMigrationIconView::LocalCardMigrationIconView( - CommandUpdater* command_updater, - IconLabelBubbleView::Delegate* icon_label_bubble_delegate, - PageActionIconView::Delegate* page_action_icon_delegate) - : PageActionIconView(command_updater, - IDC_MIGRATE_LOCAL_CREDIT_CARD_FOR_PAGE, - icon_label_bubble_delegate, - page_action_icon_delegate, - "LocalCardMigration") { - SetID(VIEW_ID_MIGRATE_LOCAL_CREDIT_CARD_BUTTON); - SetUpForInOutAnimation(); - GetViewAccessibility().SetName( - l10n_util::GetStringUTF16(IDS_TOOLTIP_MIGRATE_LOCAL_CARD)); -} - -LocalCardMigrationIconView::~LocalCardMigrationIconView() = default; - -views::BubbleDialogDelegate* LocalCardMigrationIconView::GetBubble() const { - ManageMigrationUiController* controller = GetController(); - if (!controller) { - return nullptr; - } - - LocalCardMigrationFlowStep step = controller->GetFlowStep(); - DCHECK_NE(step, LocalCardMigrationFlowStep::UNKNOWN); - switch (step) { - case LocalCardMigrationFlowStep::PROMO_BUBBLE: - return static_cast<LocalCardMigrationBubbleViews*>( - controller->GetBubbleView()); - case LocalCardMigrationFlowStep::NOT_SHOWN: - case LocalCardMigrationFlowStep::MIGRATION_RESULT_PENDING: - return nullptr; - default: - return static_cast<LocalCardMigrationDialogView*>( - controller->GetDialogView()); - } -} - -void LocalCardMigrationIconView::UpdateImpl() { - if (!GetWebContents()) { - return; - } - - // |controller| may be nullptr due to lazy initialization. - ManageMigrationUiController* controller = GetController(); - bool enabled = controller && controller->IsIconVisible(); - enabled &= SetCommandEnabled(enabled); - SetVisible(enabled); - - if (GetVisible()) { - switch (controller->GetFlowStep()) { - // When the dialog is about to show, trigger the ink drop animation - // so that the credit card icon in "selected" state by default. This needs - // to be manually set since the migration dialog is not anchored at the - // credit card icon. - case LocalCardMigrationFlowStep::OFFER_DIALOG: { - UpdateIconImage(); - SetHighlighted(true); - break; - } - case LocalCardMigrationFlowStep::MIGRATION_RESULT_PENDING: { - SetHighlighted(false); - // Disable the credit card icon so it does not update if user clicks - // on it. - SetEnabled(false); - AnimateIn(IDS_AUTOFILL_LOCAL_CARD_MIGRATION_ANIMATION_LABEL); - break; - } - case LocalCardMigrationFlowStep::MIGRATION_FINISHED: { - UnpauseAnimation(); - SetEnabled(true); - break; - } - case LocalCardMigrationFlowStep::MIGRATION_FAILED: { - UnpauseAnimation(); - SetEnabled(true); - break; - } - default: - break; - } - } else { - // Fade out inkdrop but only if icon was actually highlighted. Calling - // SetHighlighted() can result in a spurious fade-out animation and visual - // glitches. - // TODO(pbos): Fix this and remove check. Calling SetHighlighted(false) with - // !GetHighighted() should be a no-op. - if (views::InkDrop::Get(this)->GetHighlighted()) { - SetHighlighted(false); - } - // Handle corner cases where users navigate away or close the tab. - UnpauseAnimation(); - } -} - -void LocalCardMigrationIconView::OnExecuting( - PageActionIconView::ExecuteSource execute_source) {} - -const gfx::VectorIcon& LocalCardMigrationIconView::GetVectorIcon() const { - return kCreditCardChromeRefreshIcon; -} - -const gfx::VectorIcon& LocalCardMigrationIconView::GetVectorIconBadge() const { - ManageMigrationUiController* controller = GetController(); - if (controller && controller->GetFlowStep() == - LocalCardMigrationFlowStep::MIGRATION_FAILED) { - return vector_icons::kBlockedBadgeIcon; - } - return gfx::VectorIcon::EmptyIcon(); -} - -ManageMigrationUiController* LocalCardMigrationIconView::GetController() const { - content::WebContents* web_contents = GetWebContents(); - if (!web_contents) { - return nullptr; - } - - return autofill::ManageMigrationUiController::FromWebContents(web_contents); -} - -void LocalCardMigrationIconView::AnimationProgressed( - const gfx::Animation* animation) { - IconLabelBubbleView::AnimationProgressed(animation); - - // Pause the animation when the animation text is completely shown. If the - // user navigates to other tab when the animation is in progress, don't pause - // the animation. - constexpr double animation_text_full_length_shown_state = 0.5; - if (GetController() && - GetController()->GetFlowStep() == - LocalCardMigrationFlowStep::MIGRATION_RESULT_PENDING && - GetAnimationValue() >= animation_text_full_length_shown_state) { - PauseAnimation(); - } -} - -void LocalCardMigrationIconView::AnimationEnded( - const gfx::Animation* animation) { - IconLabelBubbleView::AnimationEnded(animation); - UpdateIconImage(); -} - -BEGIN_METADATA(LocalCardMigrationIconView) -END_METADATA - -} // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.h b/chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.h deleted file mode 100644 index d2139526..0000000 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.h +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_ICON_VIEW_H_ -#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_ICON_VIEW_H_ - -#include "chrome/browser/ui/views/page_action/page_action_icon_view.h" -#include "ui/base/metadata/metadata_header_macros.h" - -class CommandUpdater; - -namespace autofill { - -class ManageMigrationUiController; - -// The icon shown in location bar for the intermediate local card migration -// bubble. -class LocalCardMigrationIconView : public PageActionIconView { - METADATA_HEADER(LocalCardMigrationIconView, PageActionIconView) - - public: - LocalCardMigrationIconView( - CommandUpdater* command_updater, - IconLabelBubbleView::Delegate* icon_label_bubble_delegate, - PageActionIconView::Delegate* page_action_icon_delegate); - - LocalCardMigrationIconView(const LocalCardMigrationIconView&) = delete; - LocalCardMigrationIconView& operator=(const LocalCardMigrationIconView&) = - delete; - - ~LocalCardMigrationIconView() override; - - // PageActionIconView: - views::BubbleDialogDelegate* GetBubble() const override; - void UpdateImpl() override; - - protected: - // PageActionIconView: - void OnExecuting(PageActionIconView::ExecuteSource execute_source) override; - const gfx::VectorIcon& GetVectorIcon() const override; - const gfx::VectorIcon& GetVectorIconBadge() const override; - - private: - ManageMigrationUiController* GetController() const; - - // IconLabelBubbleView: - void AnimationProgressed(const gfx::Animation* animation) override; - void AnimationEnded(const gfx::Animation* animation) override; -}; - -} // namespace autofill - -#endif // CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_LOCAL_CARD_MIGRATION_ICON_VIEW_H_
diff --git a/chrome/browser/ui/views/autofill/payments/local_card_migration_uitest.cc b/chrome/browser/ui/views/autofill/payments/local_card_migration_uitest.cc deleted file mode 100644 index 8209cab..0000000 --- a/chrome/browser/ui/views/autofill/payments/local_card_migration_uitest.cc +++ /dev/null
@@ -1,1180 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <ctime> -#include <list> -#include <memory> -#include <string> -#include <utility> - -#include "base/callback_list.h" -#include "base/command_line.h" -#include "base/functional/bind.h" -#include "base/memory/raw_ptr.h" -#include "base/run_loop.h" -#include "base/test/gmock_callback_support.h" -#include "base/test/metrics/histogram_tester.h" -#include "base/test/scoped_feature_list.h" -#include "build/build_config.h" -#include "chrome/browser/autofill/autofill_uitest_util.h" -#include "chrome/browser/autofill/personal_data_manager_factory.h" -#include "chrome/browser/signin/identity_manager_factory.h" -#include "chrome/browser/sync/sync_service_factory.h" -#include "chrome/browser/sync/test/integration/sync_service_impl_harness.h" -#include "chrome/browser/sync/test/integration/sync_test.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_bubble_controller_impl.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_dialog_controller_impl.h" -#include "chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_commands.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/location_bar/location_bar.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/ui/test/test_browser_dialog.h" -#include "chrome/browser/ui/views/autofill/payments/dialog_view_ids.h" -#include "chrome/browser/ui/views/autofill/payments/local_card_migration_bubble_views.h" -#include "chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.h" -#include "chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.h" -#include "chrome/browser/ui/views/autofill/payments/migratable_card_view.h" -#include "chrome/browser/ui/views/autofill/payments/save_card_bubble_views.h" -#include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/location_bar/location_bar_view.h" -#include "chrome/browser/ui/views/page_action/page_action_icon_container.h" -#include "chrome/browser/ui/views/page_action/page_action_icon_controller.h" -#include "chrome/browser/ui/views/page_action/page_action_icon_loading_indicator_view.h" -#include "chrome/browser/ui/views/page_action/page_action_icon_view.h" -#include "chrome/browser/ui/views/toolbar/toolbar_view.h" -#include "chrome/browser/webdata_services/web_data_service_factory.h" -#include "chrome/grit/generated_resources.h" -#include "chrome/test/base/in_process_browser_test.h" -#include "chrome/test/base/ui_test_utils.h" -#include "components/autofill/content/browser/content_autofill_client.h" -#include "components/autofill/content/browser/content_autofill_driver.h" -#include "components/autofill/content/browser/test_autofill_manager_injector.h" -#include "components/autofill/core/browser/data_manager/payments/payments_data_manager.h" -#include "components/autofill/core/browser/data_manager/personal_data_manager.h" -#include "components/autofill/core/browser/data_manager/personal_data_manager_observer.h" -#include "components/autofill/core/browser/data_manager/personal_data_manager_test_utils.h" -#include "components/autofill/core/browser/form_import/form_data_importer.h" -#include "components/autofill/core/browser/foundations/browser_autofill_manager.h" -#include "components/autofill/core/browser/foundations/test_autofill_manager_waiter.h" -#include "components/autofill/core/browser/metrics/payments/local_card_migration_metrics.h" -#include "components/autofill/core/browser/payments/credit_card_save_manager.h" -#include "components/autofill/core/browser/payments/local_card_migration_manager.h" -#include "components/autofill/core/browser/payments/payments_network_interface.h" -#include "components/autofill/core/browser/payments/payments_util.h" -#include "components/autofill/core/browser/test_utils/autofill_test_utils.h" -#include "components/autofill/core/browser/test_utils/test_event_waiter.h" -#include "components/autofill/core/browser/webdata/payments/payments_autofill_table.h" -#include "components/autofill/core/common/autofill_features.h" -#include "components/autofill/core/common/autofill_payments_features.h" -#include "components/autofill/core/common/credit_card_network_identifiers.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/keyed_service/core/service_access_type.h" -#include "components/network_session_configurator/common/network_switches.h" -#include "components/prefs/pref_registry_simple.h" -#include "components/signin/public/identity_manager/identity_manager.h" -#include "components/signin/public/identity_manager/identity_test_utils.h" -#include "components/sync/test/fake_server.h" -#include "components/sync/test/fake_server_network_resources.h" -#include "content/public/browser/web_contents_observer.h" -#include "content/public/test/browser_test.h" -#include "content/public/test/browser_test_utils.h" -#include "content/public/test/mock_navigation_handle.h" -#include "content/public/test/test_navigation_observer.h" -#include "net/test/embedded_test_server/embedded_test_server.h" -#include "services/device/public/cpp/test/scoped_geolocation_overrider.h" -#include "services/network/public/cpp/shared_url_loader_factory.h" -#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" -#include "services/network/test/test_url_loader_factory.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/events/base_event_utils.h" -#include "ui/views/bubble/bubble_frame_view.h" -#include "ui/views/controls/button/button.h" -#include "ui/views/controls/button/label_button.h" -#include "ui/views/layout/animating_layout_manager.h" -#include "ui/views/layout/animating_layout_manager_test_util.h" -#include "ui/views/test/widget_test.h" - -namespace autofill { -namespace { - -using ::base::Bucket; -using ::base::test::RunClosure; -using ::testing::ElementsAre; - -constexpr char kURLGetUploadDetailsRequest[] = - "https://payments.google.com/payments/apis/chromepaymentsservice/" - "getdetailsforsavecard"; -constexpr char kURLMigrateCardRequest[] = - "https://payments.google.com/payments/apis-secure/chromepaymentsservice/" - "migratecards" - "?s7e_suffix=chromewallet"; - -constexpr char kResponseGetUploadDetailsSuccess[] = - "{\"legal_message\":{\"line\":[{\"template\":\"Legal message template with " - "link: " - "{0}.\",\"template_parameter\":[{\"display_text\":\"Link\",\"url\":\"https:" - "//www.example.com/\"}]}]},\"context_token\":\"dummy_context_token\"}"; -constexpr char kResponseGetUploadDetailsSuccessLong[] = - "{\"legal_message\":{\"line\":[{\"template\":\"Long message 1 long message " - "2 long message 3 long message 4 long message 5 long message 6 long " - "message 7 long message 8 long message 9 long message 10 long message 11 " - "long message 12 long message 13 long message " - "14\"}]},\"context_token\":\"dummy_context_token\"}"; -constexpr char kResponseGetUploadDetailsFailure[] = - "{\"error\":{\"code\":\"FAILED_PRECONDITION\",\"user_error_message\":\"An " - "unexpected error has occurred. Please try again later.\"}}"; - -constexpr char kResponseMigrateCardSuccess[] = - "{\"save_result\":[{\"unique_id\":\"0\", \"status\":\"SUCCESS\"}, " - "{\"unique_id\":\"1\", \"status\":\"SUCCESS\"}], " - "\"value_prop_display_text\":\"example message.\"}"; - -constexpr char kCreditCardFormURL[] = - "/credit_card_upload_form_address_and_cc.html"; - -constexpr char kFirstCardNumber[] = "5428424047572420"; // Mastercard -constexpr char kSecondCardNumber[] = "4782187095085933"; // Visa -constexpr char kThirdCardNumber[] = "4111111111111111"; // Visa -constexpr char kInvalidCardNumber[] = "4444444444444444"; -constexpr char kMaskedCardNumber[] = "2420"; - -constexpr double kFakeGeolocationLatitude = 1.23; -constexpr double kFakeGeolocationLongitude = 4.56; - -} // namespace -// The anonymous namespace needs to end here because of `friend`ships between -// the tests and the production code. - -class LocalCardMigrationBrowserTest - : public SyncTest, - public LocalCardMigrationManager::ObserverForTest { - public: - LocalCardMigrationBrowserTest(const LocalCardMigrationBrowserTest&) = delete; - LocalCardMigrationBrowserTest& operator=( - const LocalCardMigrationBrowserTest&) = delete; - - protected: - class TestAutofillManager : public BrowserAutofillManager { - public: - explicit TestAutofillManager(ContentAutofillDriver* driver) - : BrowserAutofillManager(driver) {} - - testing::AssertionResult WaitForFormsSeen(int min_num_awaited_calls) { - return forms_seen_waiter_.Wait(min_num_awaited_calls); - } - - private: - TestAutofillManagerWaiter forms_seen_waiter_{ - *this, - {AutofillManagerEvent::kFormsSeen}}; - }; - - // Various events that can be waited on by the DialogEventWaiter. - enum class DialogEvent : int { - REQUESTED_LOCAL_CARD_MIGRATION, - RECEIVED_GET_UPLOAD_DETAILS_RESPONSE, - SENT_MIGRATE_CARDS_REQUEST, - RECEIVED_MIGRATE_CARDS_RESPONSE - }; - - LocalCardMigrationBrowserTest() : SyncTest(SINGLE_CLIENT) {} - - ~LocalCardMigrationBrowserTest() override = default; - - void SetUpOnMainThread() override { - SyncTest::SetUpOnMainThread(); - - // Set up the HTTPS server (uses the embedded_test_server). - ASSERT_TRUE(embedded_test_server()->InitializeAndListen()); - embedded_test_server()->ServeFilesFromSourceDirectory( - "components/test/data/autofill"); - embedded_test_server()->StartAcceptingConnections(); - - ASSERT_TRUE(SetupClients()); - chrome::NewTab(GetBrowser(0)); - - // Set up the URL loader factory for the PaymentsNetworkInterface so we can - // intercept those network requests too. - test_shared_loader_factory_ = - base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( - &test_url_loader_factory_); - ContentAutofillClient* client = - ContentAutofillClient::FromWebContents(GetActiveWebContents()); - client->GetPaymentsAutofillClient() - ->GetPaymentsNetworkInterface() - ->set_url_loader_factory_for_testing(test_shared_loader_factory_); - - // Set up this class as the ObserverForTest implementation. - client->GetFormDataImporter() - ->local_card_migration_manager() - ->SetEventObserverForTesting(this); - personal_data_ = - PersonalDataManagerFactory::GetForBrowserContext(GetProfile(0)); - - // Wait for Personal Data Manager to be fully loaded to prevent that - // spurious notifications deceive the tests. - WaitForPersonalDataManagerToBeLoaded(GetProfile(0)); - - // Set up the fake geolocation data. - geolocation_overrider_ = - std::make_unique<device::ScopedGeolocationOverrider>( - kFakeGeolocationLatitude, kFakeGeolocationLongitude); - - ASSERT_TRUE(SetupSync()); - - // Set the billing_customer_number to designate existence of a Payments - // account. - const PaymentsCustomerData data = - PaymentsCustomerData(/*customer_id=*/"123456"); - SetPaymentsCustomerData(data); - - SetUploadDetailsRpcPaymentsAccepts(); - SetUpMigrateCardsRpcPaymentsAccepts(); - } - - void TearDownOnMainThread() override { - personal_data_ = nullptr; - - SyncTest::TearDownOnMainThread(); - } - - void SetPaymentsCustomerDataOnDBSequence( - AutofillWebDataService* wds, - const PaymentsCustomerData& customer_data) { - DCHECK(wds->GetDBTaskRunner()->RunsTasksInCurrentSequence()); - PaymentsAutofillTable::FromWebDatabase(wds->GetDatabase()) - ->SetPaymentsCustomerData(&customer_data); - } - - void SetPaymentsCustomerData(const PaymentsCustomerData& customer_data) { - scoped_refptr<AutofillWebDataService> wds = - WebDataServiceFactory::GetAutofillWebDataForProfile( - GetProfile(0), ServiceAccessType::EXPLICIT_ACCESS); - base::RunLoop loop; - wds->GetDBTaskRunner()->PostTaskAndReply( - FROM_HERE, - base::BindOnce( - &LocalCardMigrationBrowserTest::SetPaymentsCustomerDataOnDBSequence, - base::Unretained(this), base::Unretained(wds.get()), customer_data), - base::BindOnce(&base::RunLoop::Quit, base::Unretained(&loop))); - loop.Run(); - WaitForOnPersonalDataChanged(); - } - - void WaitForOnPersonalDataChanged() { - personal_data_->AddObserver(&personal_data_observer_); - personal_data_->Refresh(); - - base::RunLoop run_loop; - EXPECT_CALL(personal_data_observer_, OnPersonalDataChanged()) - .WillRepeatedly(RunClosure(run_loop.QuitClosure())); - run_loop.Run(); - testing::Mock::VerifyAndClearExpectations(&personal_data_observer_); - personal_data_->RemoveObserver(&personal_data_observer_); - } - - TestAutofillManager* GetAutofillManager() { - return autofill_manager_injector_[GetActiveWebContents()]; - } - - void NavigateToAndWaitForForm(const std::string& file_path) { - ASSERT_TRUE(ui_test_utils::NavigateToURL( - GetBrowser(0), file_path.find("data:") == 0U - ? GURL(file_path) - : embedded_test_server()->GetURL(file_path))); - ASSERT_TRUE(GetAutofillManager()->WaitForFormsSeen(1)); - } - - void OnDecideToRequestLocalCardMigration() override { - if (event_waiter_) { - event_waiter_->OnEvent(DialogEvent::REQUESTED_LOCAL_CARD_MIGRATION); - } - } - - void OnReceivedGetUploadDetailsResponse() override { - if (event_waiter_) { - event_waiter_->OnEvent(DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE); - } - } - - void OnSentMigrateCardsRequest() override { - if (event_waiter_) { - event_waiter_->OnEvent(DialogEvent::SENT_MIGRATE_CARDS_REQUEST); - } - } - - void OnReceivedMigrateCardsResponse() override { - if (event_waiter_) { - event_waiter_->OnEvent(DialogEvent::RECEIVED_MIGRATE_CARDS_RESPONSE); - } - } - - CreditCard SaveLocalCard(std::string card_number, - bool set_as_expired_card = false, - bool set_nickname = false) { - CreditCard local_card; - test::SetCreditCardInfo(&local_card, "John Smith", card_number.c_str(), - "12", - set_as_expired_card ? test::LastYear().c_str() - : test::NextYear().c_str(), - "1"); - local_card.set_guid("00000000-0000-0000-0000-" + card_number.substr(0, 12)); - local_card.set_record_type(CreditCard::RecordType::kLocalCard); - if (set_nickname) { - local_card.SetNickname(u"card nickname"); - } - - AddTestCreditCard(GetProfile(0), local_card); - return local_card; - } - - CreditCard SaveServerCard(std::string card_number) { - CreditCard server_card; - test::SetCreditCardInfo(&server_card, "John Smith", card_number.c_str(), - "12", test::NextYear().c_str(), "1"); - server_card.set_guid("00000000-0000-0000-0000-" + - card_number.substr(0, 12)); - server_card.set_record_type(CreditCard::RecordType::kMaskedServerCard); - server_card.set_server_id("full_id_" + card_number); - server_card.SetNetworkForMaskedCard(kVisaCard); - AddTestServerCreditCard(GetProfile(0), server_card); - return server_card; - } - - void UseCardAndWaitForMigrationOffer(std::string card_number) { - // Reusing a card should show the migration offer bubble. - ResetEventWaiterForSequence( - {DialogEvent::REQUESTED_LOCAL_CARD_MIGRATION, - DialogEvent::RECEIVED_GET_UPLOAD_DETAILS_RESPONSE}); - FillAndSubmitFormWithCard(card_number); - ASSERT_TRUE(WaitForObservedEvent()); - } - - void ClickOnSaveButtonAndWaitForMigrationResults() { - ResetEventWaiterForSequence({DialogEvent::SENT_MIGRATE_CARDS_REQUEST, - DialogEvent::RECEIVED_MIGRATE_CARDS_RESPONSE}); - ClickOnOkButton(GetLocalCardMigrationMainDialogView()); - ASSERT_TRUE(WaitForObservedEvent()); - } - - void FillAndSubmitFormWithCard(std::string card_number) { - NavigateToAndWaitForForm(kCreditCardFormURL); - content::WebContents* web_contents = GetActiveWebContents(); - - const std::string click_fill_button_js = - "(function() { document.getElementById('fill_form').click(); })();"; - ASSERT_TRUE(content::ExecJs(web_contents, click_fill_button_js)); - - const std::string fill_cc_number_js = - "(function() { document.getElementsByName(\"cc_number\")[0].value = " + - card_number + "; })();"; - ASSERT_TRUE(content::ExecJs(web_contents, fill_cc_number_js)); - - const std::string click_submit_button_js = - "(function() { document.getElementById('submit').click(); })();"; - content::TestNavigationObserver nav_observer(web_contents); - ASSERT_TRUE(content::ExecJs(web_contents, click_submit_button_js)); - nav_observer.Wait(); - } - - void SetUploadDetailsRpcPaymentsAccepts() { - test_url_loader_factory()->AddResponse(kURLGetUploadDetailsRequest, - kResponseGetUploadDetailsSuccess); - } - - void SetUploadDetailsRpcPaymentsDeclines() { - test_url_loader_factory()->AddResponse(kURLGetUploadDetailsRequest, - kResponseGetUploadDetailsFailure); - } - - void SetUpMigrateCardsRpcPaymentsAccepts() { - test_url_loader_factory()->AddResponse(kURLMigrateCardRequest, - kResponseMigrateCardSuccess); - } - - void ClickOnView(views::View* view) { - CHECK(view); - ui::MouseEvent pressed(ui::EventType::kMousePressed, gfx::Point(), - gfx::Point(), ui::EventTimeForNow(), - ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); - view->OnMousePressed(pressed); - ui::MouseEvent released_event = - ui::MouseEvent(ui::EventType::kMouseReleased, gfx::Point(), - gfx::Point(), ui::EventTimeForNow(), - ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON); - view->OnMouseReleased(released_event); - } - - void ClickOnDialogViewAndWait( - views::View* view, - views::BubbleDialogDelegateView* local_card_migration_view) { - CHECK(local_card_migration_view); - views::test::WidgetDestroyedWaiter destroyed_waiter( - local_card_migration_view->GetWidget()); - local_card_migration_view->ResetViewShownTimeStampForTesting(); - views::BubbleFrameView* bubble_frame_view = - static_cast<views::BubbleFrameView*>( - local_card_migration_view->GetWidget() - ->non_client_view() - ->frame_view()); - bubble_frame_view->ResetViewShownTimeStampForTesting(); - ClickOnView(view); - destroyed_waiter.Wait(); - } - - views::View* FindViewInDialogById( - DialogViewId view_id, - views::BubbleDialogDelegateView* local_card_migration_view) { - CHECK(local_card_migration_view); - - views::View* specified_view = - local_card_migration_view->GetViewByID(static_cast<int>(view_id)); - - if (!specified_view) { - specified_view = - local_card_migration_view->GetWidget()->GetRootView()->GetViewByID( - static_cast<int>(view_id)); - } - - return specified_view; - } - - void ClickOnOkButton( - views::BubbleDialogDelegateView* local_card_migration_view) { - views::View* ok_button = local_card_migration_view->GetOkButton(); - - ClickOnDialogViewAndWait(ok_button, local_card_migration_view); - } - - void ClickOnCancelButton( - views::BubbleDialogDelegateView* local_card_migration_view) { - views::View* cancel_button = local_card_migration_view->GetCancelButton(); - ClickOnDialogViewAndWait(cancel_button, local_card_migration_view); - } - - LocalCardMigrationBubbleViews* GetLocalCardMigrationOfferBubbleViews() { - LocalCardMigrationBubbleControllerImpl* - local_card_migration_bubble_controller_impl = - LocalCardMigrationBubbleControllerImpl::FromWebContents( - GetActiveWebContents()); - if (!local_card_migration_bubble_controller_impl) { - return nullptr; - } - return static_cast<LocalCardMigrationBubbleViews*>( - local_card_migration_bubble_controller_impl - ->local_card_migration_bubble_view()); - } - - views::BubbleDialogDelegateView* GetLocalCardMigrationMainDialogView() { - LocalCardMigrationDialogControllerImpl* - local_card_migration_dialog_controller_impl = - LocalCardMigrationDialogControllerImpl::FromWebContents( - GetActiveWebContents()); - if (!local_card_migration_dialog_controller_impl) { - return nullptr; - } - return static_cast<LocalCardMigrationDialogView*>( - local_card_migration_dialog_controller_impl - ->local_card_migration_dialog_view()); - } - - PageActionIconView* GetLocalCardMigrationIconView() { - BrowserView* browser_view = - BrowserView::GetBrowserViewForBrowser(GetBrowser(0)); - PageActionIconView* icon = - browser_view->toolbar_button_provider()->GetPageActionIconView( - PageActionIconType::kLocalCardMigration); - EXPECT_TRUE(browser_view->GetLocationBarView()->Contains(icon)); - return icon; - } - - views::View* close_button() { - LocalCardMigrationBubbleViews* local_card_migration_bubble_views = - static_cast<LocalCardMigrationBubbleViews*>( - GetLocalCardMigrationOfferBubbleViews()); - CHECK(local_card_migration_bubble_views); - return local_card_migration_bubble_views->GetBubbleFrameView() - ->close_button(); - } - - views::View* GetCardListView() { - return static_cast<LocalCardMigrationDialogView*>( - GetLocalCardMigrationMainDialogView()) - ->card_list_view_; - } - - content::WebContents* GetActiveWebContents() { - return GetBrowser(0)->tab_strip_model()->GetActiveWebContents(); - } - - void ResetEventWaiterForSequence(std::list<DialogEvent> event_sequence) { - event_waiter_ = - std::make_unique<EventWaiter<DialogEvent>>(std::move(event_sequence)); - } - - [[nodiscard]] testing::AssertionResult WaitForObservedEvent() { - return event_waiter_->Wait(); - } - - network::TestURLLoaderFactory* test_url_loader_factory() { - return &test_url_loader_factory_; - } - - void WaitForCardDeletion() { WaitForPersonalDataChange(GetProfile(0)); } - - raw_ptr<PersonalDataManager> personal_data_ = nullptr; - PersonalDataLoadedObserverMock personal_data_observer_; - - private: - TestAutofillManagerInjector<TestAutofillManager> autofill_manager_injector_; - std::unique_ptr<autofill::EventWaiter<DialogEvent>> event_waiter_; - network::TestURLLoaderFactory test_url_loader_factory_; - scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_; - std::unique_ptr<device::ScopedGeolocationOverrider> geolocation_overrider_; - base::test::ScopedFeatureList feature_list_; -}; - -class LocalCardMigrationBrowserUiTest - : public SupportsTestDialog<LocalCardMigrationBrowserTest> { - public: - LocalCardMigrationBrowserUiTest(const LocalCardMigrationBrowserUiTest&) = - delete; - LocalCardMigrationBrowserUiTest& operator=( - const LocalCardMigrationBrowserUiTest&) = delete; - - protected: - LocalCardMigrationBrowserUiTest() = default; - ~LocalCardMigrationBrowserUiTest() override = default; - - // SupportsTestDialog: - void ShowUi(const std::string& name) override { - test_url_loader_factory()->AddResponse( - kURLGetUploadDetailsRequest, kResponseGetUploadDetailsSuccessLong); - SaveLocalCard(kFirstCardNumber); - SaveLocalCard(kSecondCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - ClickOnOkButton(GetLocalCardMigrationOfferBubbleViews()); - } -}; - -// Ensures that migration is not offered when user saves a new card. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_UsingNewCardDoesNotShowIntermediateMigrationOffer) { - base::HistogramTester histogram_tester; - - SaveLocalCard(kFirstCardNumber); - FillAndSubmitFormWithCard(kSecondCardNumber); - - // No migration bubble should be showing, because the single card upload - // bubble should be displayed instead. - EXPECT_EQ(nullptr, GetLocalCardMigrationOfferBubbleViews()); - // No metrics are recorded when migration is not offered. - histogram_tester.ExpectTotalCount( - "Autofill.LocalCardMigrationBubbleOffer.FirstShow", 0); -} - -// Ensures that migration is not offered when payments declines the cards. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_IntermediateMigrationOfferDoesNotShowWhenPaymentsDeclines) { - base::HistogramTester histogram_tester; - SetUploadDetailsRpcPaymentsDeclines(); - - SaveLocalCard(kFirstCardNumber); - SaveLocalCard(kSecondCardNumber); - FillAndSubmitFormWithCard(kFirstCardNumber); - - // No bubble should be showing. - EXPECT_EQ(nullptr, GetLocalCardMigrationOfferBubbleViews()); - // No metrics are recorded when migration is not offered. - histogram_tester.ExpectTotalCount( - "Autofill.LocalCardMigrationBubbleOffer.FirstShow", 0); -} - -// Ensures that the intermediate migration bubble is not shown after reusing -// a saved server card, if there are no other cards to migrate. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_ReusingServerCardDoesNotShowIntermediateMigrationOffer) { - base::HistogramTester histogram_tester; - - SaveServerCard(kMaskedCardNumber); - FillAndSubmitFormWithCard(kFirstCardNumber); - - // No bubble should be showing. - EXPECT_EQ(nullptr, GetLocalCardMigrationOfferBubbleViews()); - // No metrics are recorded when migration is not offered. - histogram_tester.ExpectTotalCount( - "Autofill.LocalCardMigrationBubbleOffer.FirstShow", 0); -} - -// Ensures that the intermediate migration bubble is shown after reusing -// a saved server card, if there is at least one card to migrate. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_ReusingServerCardWithMigratableLocalCardShowIntermediateMigrationOffer) { - base::HistogramTester histogram_tester; - - SaveServerCard(kMaskedCardNumber); - SaveLocalCard(kSecondCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - - // The intermediate migration bubble should show. - EXPECT_TRUE( - FindViewInDialogById(DialogViewId::MAIN_CONTENT_VIEW_MIGRATION_BUBBLE, - GetLocalCardMigrationOfferBubbleViews()) - ->GetVisible()); - // Metrics - EXPECT_THAT( - histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationBubbleOffer.FirstShow"), - ElementsAre( - Bucket(autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_REQUESTED, 1), - Bucket(autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_SHOWN, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationOrigin.UseOfServerCard"), - ElementsAre(Bucket(autofill_metrics::INTERMEDIATE_BUBBLE_SHOWN, 1))); -} - -// Ensures that the intermediate migration bubble is not shown after reusing -// a previously saved local card, if there are no other cards to migrate. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_ReusingLocalCardDoesNotShowIntermediateMigrationOffer) { - base::HistogramTester histogram_tester; - - SaveLocalCard(kFirstCardNumber); - FillAndSubmitFormWithCard(kFirstCardNumber); - - // No migration bubble should be showing, because the single card upload - // bubble should be displayed instead. - EXPECT_EQ(nullptr, GetLocalCardMigrationOfferBubbleViews()); - // No metrics are recorded when migration is not offered. - histogram_tester.ExpectTotalCount( - "Autofill.LocalCardMigrationBubbleOffer.FirstShow", 0); -} - -// Ensures that the intermediate migration bubble is triggered after reusing -// a saved local card, if there are multiple local cards available to migrate. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_ReusingLocalCardShowsIntermediateMigrationOffer) { - base::HistogramTester histogram_tester; - - SaveLocalCard(kFirstCardNumber); - SaveLocalCard(kSecondCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - - // The intermediate migration bubble should show. - EXPECT_TRUE( - FindViewInDialogById(DialogViewId::MAIN_CONTENT_VIEW_MIGRATION_BUBBLE, - GetLocalCardMigrationOfferBubbleViews()) - ->GetVisible()); - // Metrics - EXPECT_THAT( - histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationBubbleOffer.FirstShow"), - ElementsAre( - Bucket(autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_REQUESTED, 1), - Bucket(autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_SHOWN, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationOrigin.UseOfLocalCard"), - ElementsAre(Bucket(autofill_metrics::INTERMEDIATE_BUBBLE_SHOWN, 1))); -} - -// Ensures that clicking [X] on the offer bubble makes the bubble disappear. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_ClickingCloseClosesBubble) { - base::HistogramTester histogram_tester; - - SaveLocalCard(kFirstCardNumber); - SaveLocalCard(kSecondCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - ClickOnDialogViewAndWait(close_button(), - GetLocalCardMigrationOfferBubbleViews()); - - // No bubble should be showing. - EXPECT_EQ(nullptr, GetLocalCardMigrationOfferBubbleViews()); - // Metrics - EXPECT_THAT( - histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationOrigin.UseOfLocalCard"), - ElementsAre(Bucket(autofill_metrics::INTERMEDIATE_BUBBLE_SHOWN, 1))); -} - -// Ensures that the credit card icon will show in location bar. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_CreditCardIconShownInLocationBar) { - SaveServerCard(kMaskedCardNumber); - SaveLocalCard(kSecondCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - - EXPECT_TRUE(GetLocalCardMigrationIconView()->GetVisible()); -} - -// Ensures that clicking on the credit card icon in the omnibox reopens the -// offer bubble after closing it. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_ClickingOmniboxIconReshowsBubble) { - base::HistogramTester histogram_tester; - - SaveLocalCard(kFirstCardNumber); - SaveLocalCard(kSecondCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - ClickOnDialogViewAndWait(close_button(), - GetLocalCardMigrationOfferBubbleViews()); - ClickOnView(GetLocalCardMigrationIconView()); - - // Clicking the icon should reshow the bubble. - EXPECT_TRUE( - FindViewInDialogById(DialogViewId::MAIN_CONTENT_VIEW_MIGRATION_BUBBLE, - GetLocalCardMigrationOfferBubbleViews()) - ->GetVisible()); - // Metrics - EXPECT_THAT( - histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationOrigin.UseOfLocalCard"), - ElementsAre(Bucket(autofill_metrics::INTERMEDIATE_BUBBLE_SHOWN, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationBubbleOffer.Reshows"), - ElementsAre( - Bucket(autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_REQUESTED, 1), - Bucket(autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_SHOWN, 1))); -} - -// Ensures that accepting the intermediate migration offer opens up the main -// migration dialog. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_ClickingContinueOpensDialog) { - base::HistogramTester histogram_tester; - - SaveLocalCard(kFirstCardNumber); - SaveLocalCard(kSecondCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - // Click the [Continue] button. - ClickOnOkButton(GetLocalCardMigrationOfferBubbleViews()); - - // Dialog should be visible. - EXPECT_TRUE(FindViewInDialogById( - DialogViewId::MAIN_CONTENT_VIEW_MIGRATION_OFFER_DIALOG, - GetLocalCardMigrationMainDialogView()) - ->GetVisible()); - // Intermediate bubble should be gone. - EXPECT_EQ(nullptr, GetLocalCardMigrationOfferBubbleViews()); - // Metrics - EXPECT_THAT( - histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationOrigin.UseOfLocalCard"), - ElementsAre(Bucket(autofill_metrics::INTERMEDIATE_BUBBLE_SHOWN, 1), - Bucket(autofill_metrics::INTERMEDIATE_BUBBLE_ACCEPTED, 1), - Bucket(autofill_metrics::MAIN_DIALOG_SHOWN, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationBubbleResult.FirstShow"), - ElementsAre(Bucket( - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_ACCEPTED, 1))); - EXPECT_THAT( - histogram_tester.GetAllSamples("Autofill.LocalCardMigrationDialogOffer"), - ElementsAre( - Bucket(autofill_metrics::LOCAL_CARD_MIGRATION_DIALOG_SHOWN, 1))); -} - -// Ensures that the migration dialog contains all the valid card stored in -// Chrome browser local storage. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_DialogContainsAllValidMigratableCard) { - base::HistogramTester histogram_tester; - - CreditCard first_card = SaveLocalCard(kFirstCardNumber); - CreditCard second_card = SaveLocalCard(kSecondCardNumber); - SaveLocalCard(kThirdCardNumber, /*set_as_expired_card=*/true); - SaveLocalCard(kInvalidCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - // Click the [Continue] button. - ClickOnOkButton(GetLocalCardMigrationOfferBubbleViews()); - - views::View* card_list_view = GetCardListView(); - EXPECT_TRUE(card_list_view->GetVisible()); - ASSERT_EQ(2u, card_list_view->children().size()); - // Cards will be added to database in a reversed order. - EXPECT_EQ(static_cast<MigratableCardView*>(card_list_view->children()[0]) - ->GetCardIdentifierString(), - second_card.CardNameAndLastFourDigits()); - EXPECT_EQ(static_cast<MigratableCardView*>(card_list_view->children()[1]) - ->GetCardIdentifierString(), - first_card.CardNameAndLastFourDigits()); -} - -// Ensures that rejecting the main migration dialog closes the dialog. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_ClickingCancelClosesDialog) { - base::HistogramTester histogram_tester; - - SaveLocalCard(kFirstCardNumber); - SaveLocalCard(kSecondCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - // Click the [Continue] button. - ClickOnOkButton(GetLocalCardMigrationOfferBubbleViews()); - // Click the [Cancel] button. - ClickOnCancelButton(GetLocalCardMigrationMainDialogView()); - - // No dialog should be showing. - EXPECT_EQ(nullptr, GetLocalCardMigrationMainDialogView()); - // Metrics - EXPECT_THAT( - histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationOrigin.UseOfLocalCard"), - ElementsAre(Bucket(autofill_metrics::INTERMEDIATE_BUBBLE_SHOWN, 1), - Bucket(autofill_metrics::INTERMEDIATE_BUBBLE_ACCEPTED, 1), - Bucket(autofill_metrics::MAIN_DIALOG_SHOWN, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationDialogUserInteraction"), - ElementsAre(Bucket( - autofill_metrics:: - LOCAL_CARD_MIGRATION_DIALOG_CLOSED_CANCEL_BUTTON_CLICKED, - 1))); -} - -// Ensures that accepting the main migration dialog closes the dialog. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_ClickingSaveClosesDialog) { - base::HistogramTester histogram_tester; - - SaveLocalCard(kFirstCardNumber); - SaveLocalCard(kSecondCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - // Click the [Continue] button in the bubble. - ClickOnOkButton(GetLocalCardMigrationOfferBubbleViews()); - // Click the [Save] button in the dialog. - ClickOnSaveButtonAndWaitForMigrationResults(); - - // No dialog should be showing. - EXPECT_EQ(nullptr, GetLocalCardMigrationMainDialogView()); - // Metrics - EXPECT_THAT( - histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationOrigin.UseOfLocalCard"), - ElementsAre(Bucket(autofill_metrics::INTERMEDIATE_BUBBLE_SHOWN, 1), - Bucket(autofill_metrics::INTERMEDIATE_BUBBLE_ACCEPTED, 1), - Bucket(autofill_metrics::MAIN_DIALOG_SHOWN, 1), - Bucket(autofill_metrics::MAIN_DIALOG_ACCEPTED, 1))); - EXPECT_THAT(histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationDialogUserInteraction"), - ElementsAre(Bucket( - autofill_metrics:: - LOCAL_CARD_MIGRATION_DIALOG_CLOSED_SAVE_BUTTON_CLICKED, - 1))); -} - -// Ensures local cards will be deleted from browser local storage after being -// successfully migrated. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_DeleteSuccessfullyMigratedCardsFromLocal) { - base::HistogramTester histogram_tester; - - SaveLocalCard(kFirstCardNumber); - SaveLocalCard(kSecondCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - // Click the [Continue] button in the bubble. - ClickOnOkButton(GetLocalCardMigrationOfferBubbleViews()); - // Click the [Save] button in the dialog. - ClickOnSaveButtonAndWaitForMigrationResults(); - WaitForCardDeletion(); - - EXPECT_EQ(nullptr, - personal_data_->payments_data_manager().GetCreditCardByNumber( - kFirstCardNumber)); - EXPECT_EQ(nullptr, - personal_data_->payments_data_manager().GetCreditCardByNumber( - kSecondCardNumber)); -} - -// Ensures that accepting the main migration dialog adds strikes. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_AcceptingDialogAddsLocalCardMigrationStrikes) { - base::HistogramTester histogram_tester; - - SaveLocalCard(kFirstCardNumber); - SaveLocalCard(kSecondCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - ClickOnOkButton(GetLocalCardMigrationOfferBubbleViews()); - // Click the [Save] button, should add and log strikes. - ClickOnSaveButtonAndWaitForMigrationResults(); - - // Metrics - EXPECT_THAT( - histogram_tester.GetAllSamples( - "Autofill.StrikeDatabase.NthStrikeAdded.LocalCardMigration"), - ElementsAre(Bucket( - LocalCardMigrationStrikeDatabase::kStrikesToAddWhenDialogClosed, 1))); -} - -// Ensures that rejecting the main migration dialog adds strikes. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_RejectingDialogAddsLocalCardMigrationStrikes) { - base::HistogramTester histogram_tester; - - SaveLocalCard(kFirstCardNumber); - SaveLocalCard(kSecondCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - ClickOnOkButton(GetLocalCardMigrationOfferBubbleViews()); - // Click the [Cancel] button, should add and log strikes. - ClickOnCancelButton(GetLocalCardMigrationMainDialogView()); - - // Metrics - EXPECT_THAT( - histogram_tester.GetAllSamples( - "Autofill.StrikeDatabase.NthStrikeAdded.LocalCardMigration"), - ElementsAre(Bucket( - LocalCardMigrationStrikeDatabase::kStrikesToAddWhenDialogClosed, 1))); -} - -// Ensures that rejecting the migration bubble adds strikes. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_ClosingBubbleAddsLocalCardMigrationStrikes) { - base::HistogramTester histogram_tester; - - SaveLocalCard(kFirstCardNumber); - SaveLocalCard(kSecondCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - ClickOnDialogViewAndWait(close_button(), - GetLocalCardMigrationOfferBubbleViews()); - - // No bubble should be showing. - EXPECT_EQ(nullptr, GetLocalCardMigrationOfferBubbleViews()); - // Metrics - EXPECT_THAT( - histogram_tester.GetAllSamples( - "Autofill.StrikeDatabase.NthStrikeAdded.LocalCardMigration"), - ElementsAre(Bucket( - LocalCardMigrationStrikeDatabase::kStrikesToAddWhenBubbleClosed, 1))); -} - -// Ensures that rejecting the migration bubble repeatedly adds strikes every -// time, even for the same tab. Currently, it adds 3 strikes (out of 6), so this -// test can reliably test it being added twice. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_ClosingBubbleAgainAddsLocalCardMigrationStrikes) { - base::HistogramTester histogram_tester; - - SaveLocalCard(kFirstCardNumber); - SaveLocalCard(kSecondCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - ClickOnDialogViewAndWait(close_button(), - GetLocalCardMigrationOfferBubbleViews()); - // Do it again for the same tab. - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - ClickOnDialogViewAndWait(close_button(), - GetLocalCardMigrationOfferBubbleViews()); - - // No bubble should be showing. - EXPECT_EQ(nullptr, GetLocalCardMigrationOfferBubbleViews()); - // Metrics: Added 3 strikes each time, for totals of 3 then 6. - EXPECT_THAT( - histogram_tester.GetAllSamples( - "Autofill.StrikeDatabase.NthStrikeAdded.LocalCardMigration"), - ElementsAre( - Bucket( - LocalCardMigrationStrikeDatabase::kStrikesToAddWhenBubbleClosed, - 1), - Bucket( - LocalCardMigrationStrikeDatabase::kStrikesToAddWhenBubbleClosed * - 2, - 1))); -} - -// Ensures that reshowing and closing bubble after previously closing it does -// not add strikes. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_ReshowingBubbleDoesNotAddStrikes) { - SaveLocalCard(kFirstCardNumber); - SaveLocalCard(kSecondCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - ClickOnDialogViewAndWait(close_button(), - GetLocalCardMigrationOfferBubbleViews()); - base::HistogramTester histogram_tester; - ClickOnView(GetLocalCardMigrationIconView()); - - // Clicking the icon should reshow the bubble. - EXPECT_TRUE( - FindViewInDialogById(DialogViewId::MAIN_CONTENT_VIEW_MIGRATION_BUBBLE, - GetLocalCardMigrationOfferBubbleViews()) - ->GetVisible()); - - ClickOnDialogViewAndWait(close_button(), - GetLocalCardMigrationOfferBubbleViews()); - - // Metrics - histogram_tester.ExpectTotalCount( - "Autofill.LocalCardMigrationBubbleOffer.FirstShow", 0); -} - -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_ClosedReason_BubbleAccepted) { - base::HistogramTester histogram_tester; - - SaveLocalCard(kFirstCardNumber); - SaveLocalCard(kSecondCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - ClickOnOkButton(GetLocalCardMigrationOfferBubbleViews()); - - EXPECT_THAT(histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationBubbleResult.FirstShow"), - ElementsAre(Bucket( - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_ACCEPTED, 1))); -} - -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_ClosedReason_BubbleClosed) { - base::HistogramTester histogram_tester; - - SaveLocalCard(kFirstCardNumber); - SaveLocalCard(kSecondCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - ClickOnDialogViewAndWait(close_button(), - GetLocalCardMigrationOfferBubbleViews()); - - EXPECT_THAT(histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationBubbleResult.FirstShow"), - ElementsAre(Bucket( - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_CLOSED, 1))); -} - -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_ClosedReason_BubbleNotInteracted) { - base::HistogramTester histogram_tester; - - SaveLocalCard(kFirstCardNumber); - SaveLocalCard(kSecondCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - views::test::WidgetDestroyedWaiter destroyed_waiter( - GetLocalCardMigrationOfferBubbleViews()->GetWidget()); - GetBrowser(0)->tab_strip_model()->CloseAllTabs(); - destroyed_waiter.Wait(); - - EXPECT_THAT( - histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationBubbleResult.FirstShow"), - ElementsAre(Bucket( - autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_NOT_INTERACTED, 1))); -} - -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_ClosedReason_BubbleLostFocus) { - base::HistogramTester histogram_tester; - - SaveLocalCard(kFirstCardNumber); - SaveLocalCard(kSecondCardNumber); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - views::test::WidgetDestroyedWaiter destroyed_waiter( - GetLocalCardMigrationOfferBubbleViews()->GetWidget()); - GetLocalCardMigrationOfferBubbleViews()->GetWidget()->CloseWithReason( - views::Widget::ClosedReason::kLostFocus); - destroyed_waiter.Wait(); - - EXPECT_THAT( - histogram_tester.GetAllSamples( - "Autofill.LocalCardMigrationBubbleResult.FirstShow"), - ElementsAre( - Bucket(autofill_metrics::LOCAL_CARD_MIGRATION_BUBBLE_LOST_FOCUS, 1))); -} - -// Tests to ensure the card nickname is shown correctly in the local card -// migration dialog. -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_CardIdentifierString) { - base::HistogramTester histogram_tester; - - CreditCard first_card = SaveLocalCard( - kFirstCardNumber, /*set_as_expired_card=*/false, /*set_nickname=*/true); - CreditCard second_card = SaveLocalCard( - kSecondCardNumber, /*set_as_expired_card=*/false, /*set_nickname=*/false); - UseCardAndWaitForMigrationOffer(kFirstCardNumber); - // Click the [Continue] button. - ClickOnOkButton(GetLocalCardMigrationOfferBubbleViews()); - - views::View* card_list_view = GetCardListView(); - EXPECT_TRUE(card_list_view->GetVisible()); - ASSERT_EQ(2u, card_list_view->children().size()); - // Cards will be added to database in a reversed order. - EXPECT_EQ(static_cast<MigratableCardView*>(card_list_view->children()[0]) - ->GetCardIdentifierString(), - second_card.NetworkAndLastFourDigits()); - EXPECT_EQ(static_cast<MigratableCardView*>(card_list_view->children()[1]) - ->GetCardIdentifierString(), - first_card.NicknameAndLastFourDigitsForTesting()); -} - -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_IconViewAccessibleName) { - EXPECT_EQ( - GetLocalCardMigrationIconView()->GetViewAccessibility().GetCachedName(), - l10n_util::GetStringUTF16(IDS_TOOLTIP_MIGRATE_LOCAL_CARD)); - EXPECT_EQ( - GetLocalCardMigrationIconView()->GetTextForTooltipAndAccessibleName(), - l10n_util::GetStringUTF16(IDS_TOOLTIP_MIGRATE_LOCAL_CARD)); -} - -IN_PROC_BROWSER_TEST_F( - LocalCardMigrationBrowserUiTest, - // TODO(crbug.com/40649134): Flaky, but feature should soon be removed. - DISABLED_InvokeUi_default) { - ShowAndVerifyUi(); -} - -// TODO(crbug.com/41422186): -// - Add more tests for feedback dialog. - -} // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc b/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc deleted file mode 100644 index b80935c..0000000 --- a/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc +++ /dev/null
@@ -1,222 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/views/autofill/payments/migratable_card_view.h" - -#include "base/functional/bind.h" -#include "chrome/app/vector_icons/vector_icons.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_dialog_state.h" -#include "chrome/browser/ui/views/autofill/payments/local_card_migration_dialog_view.h" -#include "chrome/browser/ui/views/chrome_layout_provider.h" -#include "chrome/browser/ui/views/chrome_typography.h" -#include "components/autofill/core/browser/payments/local_card_migration_manager.h" -#include "components/grit/components_scaled_resources.h" -#include "components/strings/grit/components_strings.h" -#include "components/vector_icons/vector_icons.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/metadata/metadata_impl_macros.h" -#include "ui/color/color_id.h" -#include "ui/color/color_provider.h" -#include "ui/gfx/paint_vector_icon.h" -#include "ui/views/accessibility/view_accessibility.h" -#include "ui/views/animation/ink_drop.h" -#include "ui/views/controls/button/button.h" -#include "ui/views/controls/button/checkbox.h" -#include "ui/views/controls/button/image_button.h" -#include "ui/views/controls/button/image_button_factory.h" -#include "ui/views/controls/image_view.h" -#include "ui/views/controls/label.h" -#include "ui/views/layout/box_layout.h" - -namespace autofill { - -MigratableCardView::MigratableCardView( - const MigratableCreditCard& migratable_credit_card, - LocalCardMigrationDialogView* parent_dialog, - bool should_show_checkbox) - : migratable_credit_card_(migratable_credit_card), - parent_dialog_(parent_dialog) { - ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); - SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kVertical, gfx::Insets(), - provider->GetDistanceMetric(DISTANCE_CONTENT_LIST_VERTICAL_MULTI))); - - AddChildViewRaw(GetMigratableCardDescriptionView(migratable_credit_card, - should_show_checkbox) - .release()); - - checkbox_uncheck_text_container_ = - AddChildView(views::Builder<views::View>() - .SetBackground(views::CreateSolidBackground( - ui::kColorBubbleFooterBackground)) - .Build()); - views::BoxLayout* layout = checkbox_uncheck_text_container_->SetLayoutManager( - std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kVertical, - gfx::Insets::VH(provider->GetDistanceMetric( - views::DISTANCE_RELATED_CONTROL_VERTICAL), - provider->GetDistanceMetric( - views::DISTANCE_RELATED_CONTROL_HORIZONTAL)), - provider->GetDistanceMetric( - views::DISTANCE_RELATED_CONTROL_HORIZONTAL))); - layout->set_cross_axis_alignment( - views::BoxLayout::CrossAxisAlignment::kStart); - - checkbox_uncheck_text_container_->AddChildView(std::make_unique<views::Label>( - l10n_util::GetStringUTF16( - IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_CHECKBOX_UNCHECK_WARNING), - CONTEXT_DIALOG_BODY_TEXT_SMALL, ChromeTextStyle::STYLE_RED)); - checkbox_uncheck_text_container_->SetVisible(false); -} - -MigratableCardView::~MigratableCardView() = default; - -bool MigratableCardView::GetSelected() const { - return !checkbox_ || checkbox_->GetChecked(); -} - -std::string MigratableCardView::GetGuid() const { - return migratable_credit_card_.credit_card().guid(); -} - -std::u16string MigratableCardView::GetCardIdentifierString() const { - return migratable_credit_card_.credit_card().CardNameAndLastFourDigits(); -} - -std::unique_ptr<views::View> -MigratableCardView::GetMigratableCardDescriptionView( - const MigratableCreditCard& migratable_credit_card, - bool should_show_checkbox) { - auto migratable_card_description_view = std::make_unique<views::View>(); - ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); - - migratable_card_description_view->SetLayoutManager( - std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), - provider->GetDistanceMetric( - views::DISTANCE_RELATED_CONTROL_HORIZONTAL))); - - std::unique_ptr<views::Label> card_description = - std::make_unique<views::Label>(GetCardIdentifierString(), - views::style::CONTEXT_LABEL); - card_description->SetMultiLine(true); - card_description->SetHorizontalAlignment(gfx::ALIGN_LEFT); - constexpr int kCardDescriptionMaximumWidth = 260; - card_description->SetMaximumWidth(kCardDescriptionMaximumWidth); - - constexpr int kMigrationResultImageSize = 16; - switch (migratable_credit_card.migration_status()) { - case MigratableCreditCard::MigrationStatus::UNKNOWN: { - if (should_show_checkbox) { - checkbox_ = migratable_card_description_view->AddChildView( - std::make_unique<views::Checkbox>( - std::u16string(), - base::BindRepeating(&MigratableCardView::CheckboxPressed, - base::Unretained(this)))); - checkbox_->SetChecked(true); - // TODO(crbug.com/40586517): Currently the ink drop animation circle is - // cropped by the border of scroll bar view. Find a way to adjust the - // format. - views::InkDrop::Get(checkbox_->ink_drop_view()) - ->SetMode(views::InkDropHost::InkDropMode::OFF); - checkbox_->GetViewAccessibility().SetName(*card_description.get()); - } - break; - } - case MigratableCreditCard::MigrationStatus::SUCCESS_ON_UPLOAD: { - auto* migration_succeeded_image = - migratable_card_description_view->AddChildView( - std::make_unique<views::ImageView>()); - migration_succeeded_image->SetImage(ui::ImageModel::FromVectorIcon( - vector_icons::kCheckCircleIcon, ui::kColorAlertLowSeverity, - kMigrationResultImageSize)); - break; - } - case MigratableCreditCard::MigrationStatus::FAILURE_ON_UPLOAD: { - auto* migration_failed_image = - migratable_card_description_view->AddChildView( - std::make_unique<views::ImageView>()); - migration_failed_image->SetImage(ui::ImageModel::FromVectorIcon( - vector_icons::kErrorIcon, ui::kColorAlertHighSeverity, - kMigrationResultImageSize)); - break; - } - } - - std::unique_ptr<views::View> card_network_and_last_four_digits = - std::make_unique<views::View>(); - card_network_and_last_four_digits->SetLayoutManager( - std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kHorizontal, gfx::Insets(), - provider->GetDistanceMetric(DISTANCE_RELATED_LABEL_HORIZONTAL_LIST))); - - std::unique_ptr<views::ImageView> card_image = - std::make_unique<views::ImageView>(); - card_image->SetImage( - ui::ImageModel::FromResourceId(CreditCard::IconResourceId( - migratable_credit_card.credit_card().network()))); - card_image->GetViewAccessibility().SetName( - migratable_credit_card.credit_card().NetworkForDisplay()); - card_network_and_last_four_digits->AddChildViewRaw(card_image.release()); - card_network_and_last_four_digits->AddChildViewRaw( - card_description.release()); - migratable_card_description_view->AddChildViewRaw( - card_network_and_last_four_digits.release()); - - std::unique_ptr<views::Label> card_expiration = - std::make_unique<views::Label>( - migratable_credit_card.credit_card() - .AbbreviatedExpirationDateForDisplay(/*with_prefix=*/true), - views::style::CONTEXT_LABEL, views::style::STYLE_SECONDARY); - card_expiration->SetElideBehavior(gfx::ElideBehavior::NO_ELIDE); - card_expiration->SetMultiLine(true); - migratable_card_description_view->AddChildViewRaw(card_expiration.release()); - - // If card is not successfully uploaded we show the invalid card - // label and the trash can icon. - if (migratable_credit_card.migration_status() == - MigratableCreditCard::MigrationStatus::FAILURE_ON_UPLOAD) { - migratable_card_description_view->AddChildViewRaw(new views::Label( - l10n_util::GetStringUTF16( - IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_LABEL_INVALID_CARDS), - views::style::CONTEXT_LABEL, ChromeTextStyle::STYLE_RED)); - - auto delete_card_from_local_button = - views::CreateVectorImageButtonWithNativeTheme( - base::BindRepeating( - [](LocalCardMigrationDialogView* parent_dialog, - std::string guid) { - parent_dialog->DeleteCard(std::move(guid)); - }, - parent_dialog_, GetGuid()), - kTrashCanIcon); - delete_card_from_local_button->SetTooltipText(l10n_util::GetStringUTF16( - IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TRASH_CAN_BUTTON_TOOLTIP)); - delete_card_from_local_button->SetFocusBehavior( - FocusBehavior::ACCESSIBLE_ONLY); - delete_card_from_local_button_ = - migratable_card_description_view->AddChildView( - std::move(delete_card_from_local_button)); - } - - return migratable_card_description_view; -} - -void MigratableCardView::CheckboxPressed() { - // If the button clicked is a checkbox. Enable/disable the save - // button if needed. - parent_dialog_->OnCardCheckboxToggled(); - // The warning text will be visible only when user unchecks the checkbox. - checkbox_uncheck_text_container_->SetVisible(!checkbox_->GetChecked()); - InvalidateLayout(); - parent_dialog_->UpdateLayout(); -} - -BEGIN_METADATA(MigratableCardView) -ADD_READONLY_PROPERTY_METADATA(bool, Selected) -ADD_READONLY_PROPERTY_METADATA(std::string, Guid) -ADD_READONLY_PROPERTY_METADATA(std::u16string, CardIdentifierString) -END_METADATA - -} // namespace autofill
diff --git a/chrome/browser/ui/views/autofill/payments/migratable_card_view.h b/chrome/browser/ui/views/autofill/payments/migratable_card_view.h deleted file mode 100644 index ddb5a00..0000000 --- a/chrome/browser/ui/views/autofill/payments/migratable_card_view.h +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright 2018 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_MIGRATABLE_CARD_VIEW_H_ -#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_MIGRATABLE_CARD_VIEW_H_ - -#include "base/memory/raw_ptr.h" -#include "components/autofill/core/browser/payments/local_card_migration_manager.h" -#include "ui/base/metadata/metadata_header_macros.h" -#include "ui/views/view.h" - -namespace views { -class Checkbox; -class ImageButton; -} // namespace views - -namespace autofill { - -enum class LocalCardMigrationDialogState; -class LocalCardMigrationDialogView; -class MigratableCreditCard; - -// A view composed of a checkbox or an image indicating migration results, card -// network image, card network, last four digits of card number and card -// expiration date. Used by LocalCardMigrationDialogView. -class MigratableCardView : public views::View { - METADATA_HEADER(MigratableCardView, views::View) - - public: - MigratableCardView(const MigratableCreditCard& migratable_credit_card, - LocalCardMigrationDialogView* parent_dialog, - bool should_show_checkbox); - MigratableCardView(const MigratableCardView&) = delete; - MigratableCardView& operator=(const MigratableCardView&) = delete; - ~MigratableCardView() override; - - bool GetSelected() const; - std::string GetGuid() const; - std::u16string GetCardIdentifierString() const; - - private: - std::unique_ptr<views::View> GetMigratableCardDescriptionView( - const MigratableCreditCard& migratable_credit_card, - bool should_show_checkbox); - - void CheckboxPressed(); - - const MigratableCreditCard migratable_credit_card_; - - // The checkbox_ can remain null if the card list in the local - // card migration dialog contains only one card. - raw_ptr<views::Checkbox> checkbox_ = nullptr; - - raw_ptr<views::View> checkbox_uncheck_text_container_ = nullptr; - - raw_ptr<views::ImageButton> delete_card_from_local_button_ = nullptr; - - raw_ptr<LocalCardMigrationDialogView> parent_dialog_ = nullptr; -}; - -} // namespace autofill - -#endif // CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_MIGRATABLE_CARD_VIEW_H_
diff --git a/chrome/browser/ui/views/autofill/popup/popup_row_factory_utils.cc b/chrome/browser/ui/views/autofill/popup/popup_row_factory_utils.cc index 9c0d680..5492b310 100644 --- a/chrome/browser/ui/views/autofill/popup/popup_row_factory_utils.cc +++ b/chrome/browser/ui/views/autofill/popup/popup_row_factory_utils.cc
@@ -139,10 +139,6 @@ break; case FillingProduct::kCreditCard: if (text.should_truncate.value()) { - // `should_truncate` should only be set to true iff - // `kAutofillEnableCardProductName` is enabled. - DCHECK(base::FeatureList::IsEnabled( - autofill::features::kAutofillEnableCardProductName)); label.SetMaximumWidthSingleLine(maximum_width_single_line); } break;
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/shared_tab_group_interactive_uitest.cc b/chrome/browser/ui/views/bookmarks/saved_tab_groups/shared_tab_group_interactive_uitest.cc index 2759c61..b3e9834e 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/shared_tab_group_interactive_uitest.cc +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/shared_tab_group_interactive_uitest.cc
@@ -482,13 +482,10 @@ HoverTabGroupHeader(group_id), ClickMouse(ui_controls::RIGHT), WaitForShow(kTabGroupEditorBubbleId), PressButton(kTabGroupEditorBubbleLeaveGroupButtonId), - WaitForShow(kDataSharingBubbleElementId), Do([&]() { - // Close the dialog before the callback runs out of scope. - auto* controller = - DataSharingBubbleController::GetOrCreateForBrowser(browser()); - controller->Close(); - }), - FinishTabstripAnimations()); + WaitForHide(kTabGroupEditorBubbleLeaveGroupButtonId), + WaitForShow(kDeletionDialogCancelButtonId), + PressButton(kDeletionDialogCancelButtonId), + WaitForHide(kDeletionDialogCancelButtonId), FinishTabstripAnimations()); } // Verify members see the leave group button instead of the delete button in the @@ -507,13 +504,9 @@ SelectMenuItem(STGEverythingMenu::kTabGroup), EnsurePresent(STGTabsMenuModel::kLeaveGroupMenuItem), SelectMenuItem(STGTabsMenuModel::kLeaveGroupMenuItem), - WaitForShow(kDataSharingBubbleElementId), Do([&]() { - // Close the dialog before the callback runs out of scope. - auto* controller = - DataSharingBubbleController::GetOrCreateForBrowser(browser()); - controller->Close(); - }), - FinishTabstripAnimations()); + WaitForShow(kDeletionDialogCancelButtonId), + PressButton(kDeletionDialogCancelButtonId), FinishTabstripAnimations(), + WaitForHide(kDeletionDialogCancelButtonId)); } // Verify members see the recent activity button when activity exists.
diff --git a/chrome/browser/ui/views/download/bubble/download_bubble_partial_view.cc b/chrome/browser/ui/views/download/bubble/download_bubble_partial_view.cc index eb2720f..fb4521f 100644 --- a/chrome/browser/ui/views/download/bubble/download_bubble_partial_view.cc +++ b/chrome/browser/ui/views/download/bubble/download_bubble_partial_view.cc
@@ -283,6 +283,11 @@ void DownloadBubblePartialView::OnWillChangeFocus(views::View* before, views::View* now) { + // Check 'before' to make sure this is not the first focus change. + // This will happen when the bubble is first shown inside Mac PWA. + if (!before) { + return; + } if (now && Contains(now)) { OnInteracted(); }
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index e65985e..2cba3104 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -37,7 +37,6 @@ #include "chrome/browser/themes/theme_service_factory.h" #include "chrome/browser/translate/chrome_translate_client.h" #include "chrome/browser/translate/translate_service.h" -#include "chrome/browser/ui/autofill/payments/local_card_migration_bubble_controller_impl.h" #include "chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_actions.h" @@ -54,7 +53,6 @@ #include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/ui_features.h" -#include "chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/chrome_typography.h" #include "chrome/browser/ui/views/frame/browser_view.h" @@ -430,7 +428,6 @@ } params.types_enabled.push_back(PageActionIconType::kSaveCard); params.types_enabled.push_back(PageActionIconType::kSaveIban); - params.types_enabled.push_back(PageActionIconType::kLocalCardMigration); params.types_enabled.push_back(PageActionIconType::kFilledCardInformation); params.types_enabled.push_back(PageActionIconType::kVirtualCardEnroll); params.types_enabled.push_back(PageActionIconType::kMandatoryReauth);
diff --git a/chrome/browser/ui/views/page_action/BUILD.gn b/chrome/browser/ui/views/page_action/BUILD.gn index b6a55c9..b636a0fe 100644 --- a/chrome/browser/ui/views/page_action/BUILD.gn +++ b/chrome/browser/ui/views/page_action/BUILD.gn
@@ -27,6 +27,8 @@ "page_action_model.h", "page_action_model_observer.h", "page_action_observer.cc", + "page_action_properties.cc", + "page_action_properties.h", "page_action_triggers.cc", "page_action_view.cc", ]
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_controller.cc b/chrome/browser/ui/views/page_action/page_action_icon_controller.cc index ec9ed7bb..c0d519f 100644 --- a/chrome/browser/ui/views/page_action/page_action_icon_controller.cc +++ b/chrome/browser/ui/views/page_action/page_action_icon_controller.cc
@@ -22,7 +22,6 @@ #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/autofill/address_bubbles_icon_view.h" #include "chrome/browser/ui/views/autofill/payments/filled_card_information_icon_view.h" -#include "chrome/browser/ui/views/autofill/payments/local_card_migration_icon_view.h" #include "chrome/browser/ui/views/autofill/payments/mandatory_reauth_icon_view.h" #include "chrome/browser/ui/views/autofill/payments/offer_notification_icon_view.h" #include "chrome/browser/ui/views/autofill/payments/save_payment_icon_view.h" @@ -165,12 +164,6 @@ params.browser, params.icon_label_bubble_delegate, params.page_action_icon_delegate)); break; - case PageActionIconType::kLocalCardMigration: - add_page_action_icon( - type, std::make_unique<autofill::LocalCardMigrationIconView>( - params.command_updater, params.icon_label_bubble_delegate, - params.page_action_icon_delegate)); - break; case PageActionIconType::kManagePasswords: DCHECK(params.command_updater); add_page_action_icon(
diff --git a/chrome/browser/ui/views/page_action/page_action_properties.cc b/chrome/browser/ui/views/page_action/page_action_properties.cc new file mode 100644 index 0000000..150977d --- /dev/null +++ b/chrome/browser/ui/views/page_action/page_action_properties.cc
@@ -0,0 +1,40 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/page_action/page_action_properties.h" + +#include "base/check_is_test.h" +#include "base/containers/fixed_flat_map.h" +#include "base/containers/flat_map.h" +#include "chrome/browser/ui/actions/chrome_action_id.h" + +namespace page_actions { +namespace { + +constexpr PageActionProperties kDefaultConfig; + +constexpr auto kPageActionProperties = + base::MakeFixedFlatMap<actions::ActionId, PageActionProperties>({ + {kActionSidePanelShowLensOverlayResults, {"LensOverlay", true}}, + {kActionShowTranslate, {"Translate", true}}, + {kActionShowMemorySaverChip, {"MemorySaver", true}}, + {kActionShowIntentPicker, {"IntentPicker", true}}, + {kActionZoomNormal, {"Zoom", true}}, + {kActionOffersAndRewardsForPage, {"PaymentsOfferNotification", true}}, + }); + +} // namespace + +const PageActionProperties& GetPageActionProperties( + actions::ActionId page_action_id) { + // In unit tests, `page_action_id` may not be in `kPageActionProperties`. + if (!kPageActionProperties.contains(page_action_id)) { + CHECK_IS_TEST(); + return kDefaultConfig; + } + + return kPageActionProperties.at(page_action_id); +} + +} // namespace page_actions
diff --git a/chrome/browser/ui/views/page_action/page_action_properties.h b/chrome/browser/ui/views/page_action/page_action_properties.h new file mode 100644 index 0000000..6721717 --- /dev/null +++ b/chrome/browser/ui/views/page_action/page_action_properties.h
@@ -0,0 +1,27 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_PAGE_ACTION_PROPERTIES_H_ +#define CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_PAGE_ACTION_PROPERTIES_H_ + +#include "ui/actions/action_id.h" + +namespace page_actions { + +// Defines the static properties that a page action can have. The page action in +// mainly configured using the ActionItem. But the ActionItem is global. +// Therefore, for some properties, they should be scoped to page actions only. +struct PageActionProperties { + const char* histogram_name = nullptr; + bool is_ephemeral = false; +}; + +// Get the properties associated with the given action id. The provided action +// id is expected to exist in the configs array. +const PageActionProperties& GetPageActionProperties( + actions::ActionId page_action_id); + +} // namespace page_actions + +#endif // CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_PAGE_ACTION_PROPERTIES_H_
diff --git a/chrome/browser/ui/web_applications/app_browser_controller.cc b/chrome/browser/ui/web_applications/app_browser_controller.cc index 1a9eeb9..e64b3f7 100644 --- a/chrome/browser/ui/web_applications/app_browser_controller.cc +++ b/chrome/browser/ui/web_applications/app_browser_controller.cc
@@ -369,7 +369,6 @@ types_enabled.push_back(PageActionIconType::kZoom); types_enabled.push_back(PageActionIconType::kFileSystemAccess); types_enabled.push_back(PageActionIconType::kCookieControls); - types_enabled.push_back(PageActionIconType::kLocalCardMigration); types_enabled.push_back(PageActionIconType::kSaveCard); return types_enabled;
diff --git a/chrome/browser/ui/webui/ash/settings/pages/search/search_section.cc b/chrome/browser/ui/webui/ash/settings/pages/search/search_section.cc index 051e2a0b..0c49203 100644 --- a/chrome/browser/ui/webui/ash/settings/pages/search/search_section.cc +++ b/chrome/browser/ui/webui/ash/settings/pages/search/search_section.cc
@@ -436,12 +436,6 @@ html_source->AddBoolean("isLobsterSettingsToggleVisible", IsLobsterSettingsToggleVisible(profile())); - // We should not use `CanShowSunfishUi` here, as it is false when the toggle - // is false. - // TODO: crbug.com/395736972 - Add an enterprise policy check. - html_source->AddBoolean("isSunfishSettingsToggleVisible", - ash::features::IsSunfishFeatureEnabled()); - html_source->AddBoolean("isScannerSettingsToggleVisible", IsScannerSettingsToggleVisible());
diff --git a/chrome/browser/ui/webui/ash/settings/pages/search/search_section_unittest.cc b/chrome/browser/ui/webui/ash/settings/pages/search/search_section_unittest.cc index c9828b5..1633b12 100644 --- a/chrome/browser/ui/webui/ash/settings/pages/search/search_section_unittest.cc +++ b/chrome/browser/ui/webui/ash/settings/pages/search/search_section_unittest.cc
@@ -99,45 +99,6 @@ .value()); } -TEST_F(SearchSectionTest, - DoesNotIncludeSunfishSettingsWhenSunfishFeaturesDisabled) { - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures(/*enabled_features=*/{}, /*disabled_features=*/ - { - features::kSunfishFeature, - features::kScannerUpdate, - features::kScannerDogfood, - }); - search_section_ = - std::make_unique<SearchSection>(profile(), search_tag_registry()); - std::unique_ptr<content::TestWebUIDataSource> html_source = - content::TestWebUIDataSource::Create("test-search-section"); - // `AddLoadTimeData` assumes that `chromeos::MagicBoostState::Get()` returns - // a non-null pointer, so this cannot be removed. - chromeos::test::FakeMagicBoostState magic_boost_state; - - search_section_->AddLoadTimeData(html_source->GetWebUIDataSource()); - - EXPECT_FALSE(html_source->GetLocalizedStrings() - ->FindBool("isSunfishSettingsToggleVisible") - .value()); -} - -TEST_F(SearchSectionTest, IncludesSunfishSettingsWhenSunfishEnabled) { - base::test::ScopedFeatureList feature_list(features::kSunfishFeature); - search_section_ = - std::make_unique<SearchSection>(profile(), search_tag_registry()); - std::unique_ptr<content::TestWebUIDataSource> html_source = - content::TestWebUIDataSource::Create("test-search-section"); - chromeos::test::FakeMagicBoostState magic_boost_state; - - search_section_->AddLoadTimeData(html_source->GetWebUIDataSource()); - - EXPECT_TRUE(html_source->GetLocalizedStrings() - ->FindBool("isSunfishSettingsToggleVisible") - .value()); -} - // MagicBoost availability check requires an async operation. There is a short // period where `MagicBoostState` returns false for its availability even if a // user/device is eligible.
diff --git a/chrome/browser/ui/webui/managed_ui_handler.cc b/chrome/browser/ui/webui/managed_ui_handler.cc index e8970a4..dbee016 100644 --- a/chrome/browser/ui/webui/managed_ui_handler.cc +++ b/chrome/browser/ui/webui/managed_ui_handler.cc
@@ -113,7 +113,11 @@ base::Value::Dict ManagedUIHandler::GetDataSourceUpdate() const { base::Value::Dict update; -#if !BUILDFLAG(IS_ANDROID) + // TODO(crbug.com/394876083): Enable the management policy on android and + // remove the if-def. +#if BUILDFLAG(IS_ANDROID) + update.Set("managedByIcon", ""); +#else update.Set("managedByIcon", GetManagedUiWebUIIcon(profile_)); update.Set("managementPageUrl", GetManagedUiUrl(profile_).spec()); update.Set("browserManagedByOrg", GetManagedUiWebUILabel(profile_));
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index 14c9cc56..b9b785f47 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -1278,10 +1278,6 @@ {"editIban", IDS_SETTINGS_IBAN_EDIT}, {"removeLocalIbanConfirmationTitle", IDS_SETTINGS_LOCAL_IBAN_REMOVE_CONFIRMATION_TITLE}, - {"migrateCreditCardsLabel", IDS_SETTINGS_MIGRATABLE_CARDS_LABEL}, - {"migratableCardsInfoSingle", IDS_SETTINGS_SINGLE_MIGRATABLE_CARD_INFO}, - {"migratableCardsInfoMultiple", - IDS_SETTINGS_MULTIPLE_MIGRATABLE_CARDS_INFO}, {"remotePaymentMethodsLinkLabel", IDS_SETTINGS_REMOTE_PAYMENT_METHODS_LINK_LABEL}, {"canMakePaymentToggleLabel", IDS_SETTINGS_CAN_MAKE_PAYMENT_TOGGLE_LABEL}, @@ -1403,25 +1399,10 @@ html_source->AddString("autofillPayOverTimeSettingsLearnMoreUrl", chrome::kPayOverTimeLearnMoreUrl); - bool is_guest_mode = false; -#if BUILDFLAG(IS_CHROMEOS) - is_guest_mode = - user_manager::UserManager::Get()->IsLoggedInAsGuest() || - user_manager::UserManager::Get()->IsLoggedInAsManagedGuestSession(); -#else // !BUILDFLAG(IS_CHROMEOS) - is_guest_mode = profile->IsOffTheRecord(); -#endif // BUILDFLAG(IS_CHROMEOS) autofill::PaymentsDataManager& payments_data = autofill::PersonalDataManagerFactory::GetForBrowserContext(profile) ->payments_data_manager(); - html_source->AddBoolean( - "migrationEnabled", - !is_guest_mode && - autofill::IsCreditCardMigrationEnabled( - payments_data, SyncServiceFactory::GetForProfile(profile), - *profile->GetPrefs(), - /*is_test_mode=*/false, - /*log_manager=*/nullptr)); + html_source->AddBoolean("migrationEnabled", false); html_source->AddBoolean("showIbansSettings", autofill::ShouldShowIbanOnSettingsPage(
diff --git a/chrome/browser/ui/webui/version/version_ui.cc b/chrome/browser/ui/webui/version/version_ui.cc index 04741c5..c021991 100644 --- a/chrome/browser/ui/webui/version/version_ui.cc +++ b/chrome/browser/ui/webui/version/version_ui.cc
@@ -49,6 +49,7 @@ #endif #if BUILDFLAG(IS_CHROMEOS) +#include "build/util/LASTCHANGE_commit_position.h" #include "chrome/browser/ui/webui/version/version_handler_chromeos.h" #endif @@ -128,6 +129,16 @@ return base::JoinString(modifier_parts, "-"); } +std::string GetVersionInformationalSuffix() { +#if BUILDFLAG(IS_CHROMEOS) && CHROMIUM_COMMIT_POSITION_IS_MAIN + // Adds the revision number as a suffix to the version number if the chrome + // is built from the main branch. + return "-r" CHROMIUM_COMMIT_POSITION_NUMBER; +#else + return ""; +#endif +} + } // namespace VersionUI::VersionUI(content::WebUI* web_ui) @@ -211,6 +222,8 @@ // Data strings. html_source->AddString(version_ui::kVersion, version_info::GetVersionNumber()); + html_source->AddString(version_ui::kVersionSuffix, + GetVersionInformationalSuffix()); html_source->AddString(version_ui::kVersionModifier, GetProductModifier()); @@ -299,6 +312,7 @@ return l10n_util::GetStringFUTF16( IDS_SETTINGS_ABOUT_PAGE_BROWSER_VERSION, base::UTF8ToUTF16(version_info::GetVersionNumber()), + base::UTF8ToUTF16(GetVersionInformationalSuffix()), l10n_util::GetStringUTF16(version_info::IsOfficialBuild() ? IDS_VERSION_UI_OFFICIAL : IDS_VERSION_UI_UNOFFICIAL),
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn index 6a76febe..c572bcd7 100644 --- a/chrome/browser/web_applications/BUILD.gn +++ b/chrome/browser/web_applications/BUILD.gn
@@ -586,6 +586,8 @@ "preinstalled_web_apps/google_meet.h", "preinstalled_web_apps/messages_dogfood.cc", "preinstalled_web_apps/messages_dogfood.h", + "preinstalled_web_apps/notebook_lm.cc", + "preinstalled_web_apps/notebook_lm.h", ] }
diff --git a/chrome/browser/web_applications/app_service/web_apps.h b/chrome/browser/web_applications/app_service/web_apps.h index 4ab17026..b1104e87 100644 --- a/chrome/browser/web_applications/app_service/web_apps.h +++ b/chrome/browser/web_applications/app_service/web_apps.h
@@ -56,7 +56,7 @@ WebApps& operator=(const WebApps&) = delete; ~WebApps() override; - virtual void Shutdown(); + void Shutdown(); protected: const WebApp* GetWebApp(const webapps::AppId& app_id) const;
diff --git a/chrome/browser/web_applications/preinstalled_app_install_features.cc b/chrome/browser/web_applications/preinstalled_app_install_features.cc index fcaac41..b66d453 100644 --- a/chrome/browser/web_applications/preinstalled_app_install_features.cc +++ b/chrome/browser/web_applications/preinstalled_app_install_features.cc
@@ -44,26 +44,19 @@ bool g_always_enabled_for_testing = false; -struct FeatureWithEnabledFunction { - raw_ref<const base::Feature> feature; - bool (*enabled_func)(); -}; - // A hard coded list of features available for externally installed apps to -// gate their installation on via their config file settings. Each feature has a -// function to run to determine whether it is enabled. See |kFeatureName| in -// preinstalled_web_app_utils.h. +// gate their installation on via their config file settings. See |kFeatureName| +// in preinstalled_web_app_utils.h. // // After a feature flag has been shipped and should be cleaned up, move it into // kShippedPreinstalledAppInstallFeatures to ensure any external installation // configs that reference it continue to see it as enabled. -constexpr const FeatureWithEnabledFunction - kPreinstalledAppInstallFeaturesWithEnabledFunctions[] = { +constexpr const raw_ref<const base::Feature> kPreinstalledAppInstallFeatures[] = + { #if BUILDFLAG(IS_CHROMEOS) - {raw_ref(chromeos::features::kCloudGamingDevice), - &chromeos::features::IsCloudGamingDeviceEnabled}, - {raw_ref(chromeos::features::kGeminiAppPreinstall), - &chromeos::features::IsGeminiAppPreinstallEnabled} + raw_ref(chromeos::features::kCloudGamingDevice), + raw_ref(chromeos::features::kGeminiAppPreinstall), + raw_ref(chromeos::features::kNotebookLmAppPreinstall), #endif }; @@ -108,10 +101,10 @@ } } - for (const auto& feature_with_function : - kPreinstalledAppInstallFeaturesWithEnabledFunctions) { - if (feature_with_function.feature->name == feature_name) { - return feature_with_function.enabled_func(); + for (const raw_ref<const base::Feature> feature : + kPreinstalledAppInstallFeatures) { + if (feature->name == feature_name) { + return base::FeatureList::IsEnabled(*feature); } }
diff --git a/chrome/browser/web_applications/preinstalled_web_apps/notebook_lm.cc b/chrome/browser/web_applications/preinstalled_web_apps/notebook_lm.cc new file mode 100644 index 0000000..0fd9bd6 --- /dev/null +++ b/chrome/browser/web_applications/preinstalled_web_apps/notebook_lm.cc
@@ -0,0 +1,35 @@ +// Copyright 2025 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/web_applications/preinstalled_web_apps/notebook_lm.h" + +#include <memory> + +#include "ash/constants/web_app_id_constants.h" +#include "chrome/browser/apps/user_type_filter.h" +#include "chrome/browser/web_applications/external_install_options.h" +#include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h" +#include "chrome/browser/web_applications/web_app_constants.h" +#include "chromeos/constants/chromeos_features.h" +#include "url/gurl.h" + +namespace web_app { + +ExternalInstallOptions GetConfigForNotebookLm() { + static constexpr char kUrl[] = "https://notebooklm.google.com/install"; + ExternalInstallOptions options( + /*install_url=*/GURL(kUrl), + /*user_display_mode=*/mojom::UserDisplayMode::kStandalone, + /*install_source=*/ExternalInstallSource::kExternalDefault); + options.add_to_applications_menu = true; + options.add_to_search = true; + options.expected_app_id = ash::kNotebookLmAppId; + options.gate_on_feature = chromeos::features::kNotebookLmAppPreinstall.name; + options.is_preferred_app_for_supported_links = true; + options.user_type_allowlist = {apps::kUserTypeUnmanaged}; + + return options; +} + +} // namespace web_app
diff --git a/chrome/browser/web_applications/preinstalled_web_apps/notebook_lm.h b/chrome/browser/web_applications/preinstalled_web_apps/notebook_lm.h new file mode 100644 index 0000000..bc3dd52 --- /dev/null +++ b/chrome/browser/web_applications/preinstalled_web_apps/notebook_lm.h
@@ -0,0 +1,17 @@ +// Copyright 2025 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_WEB_APPLICATIONS_PREINSTALLED_WEB_APPS_NOTEBOOK_LM_H_ +#define CHROME_BROWSER_WEB_APPLICATIONS_PREINSTALLED_WEB_APPS_NOTEBOOK_LM_H_ + +#include "chrome/browser/web_applications/external_install_options.h" + +namespace web_app { + +// Returns the config for preinstalling the NotebookLm app. +ExternalInstallOptions GetConfigForNotebookLm(); + +} // namespace web_app + +#endif // CHROME_BROWSER_WEB_APPLICATIONS_PREINSTALLED_WEB_APPS_NOTEBOOK_LM_H_
diff --git a/chrome/browser/web_applications/preinstalled_web_apps/preinstalled_web_apps.cc b/chrome/browser/web_applications/preinstalled_web_apps/preinstalled_web_apps.cc index a290c8d..a25bed7d 100644 --- a/chrome/browser/web_applications/preinstalled_web_apps/preinstalled_web_apps.cc +++ b/chrome/browser/web_applications/preinstalled_web_apps/preinstalled_web_apps.cc
@@ -37,6 +37,7 @@ #include "chrome/browser/web_applications/preinstalled_web_apps/google_calendar.h" #include "chrome/browser/web_applications/preinstalled_web_apps/google_meet.h" #include "chrome/browser/web_applications/preinstalled_web_apps/messages_dogfood.h" +#include "chrome/browser/web_applications/preinstalled_web_apps/notebook_lm.h" #include "chrome/common/extensions/extension_constants.h" #include "extensions/common/constants.h" #include "google_apis/gaia/gaia_auth_util.h" @@ -98,6 +99,7 @@ #if BUILDFLAG(IS_CHROMEOS) GetConfigForCalculator(), GetConfigForGemini(device_info), + GetConfigForNotebookLm(), GetConfigForGoogleCalendar(), GetConfigForGoogleChat(/*is_standalone=*/true, /*only_for_new_users=*/false),
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt index ad0d1795..24028d3 100644 --- a/chrome/build/android-arm32.pgo.txt +++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@ -chrome-android32-main-1742839181-968acc22c0ea0bac86ca8311efc8814765aaf400-5e5a0303cdac3133c1ca1df63851d9f459c9cc80.profdata +chrome-android32-main-1742882230-a059e68f541991f38318e3c77b735c42a979a1ba-8f592e43518c024b6ce09d0568d1fd023e03141b.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt index 9b1c9943..68ae2be 100644 --- a/chrome/build/android-arm64.pgo.txt +++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@ -chrome-android64-main-1742854643-fd4aac90db2e4899e554709d83c8ef6bbed03c7b-3bb9dd22085a92bd8a86ce706b83cd7e6072a9a3.profdata +chrome-android64-main-1742888995-2595df649d784336cdc2028b355486ad303fd26b-a3ffe0fd561d6df5d6cdce8954bf8794901acda7.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 07a05a37..817e62fd 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1742817397-138755e46429f60f282e3b4d3887efc0b97b7e01-fbe631cbc5d4909cba43f5eed375a8d27e8a536b.profdata +chrome-linux-main-1742882230-c67fa1634302fc8801b8472c84bd6c1429013093-8f592e43518c024b6ce09d0568d1fd023e03141b.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 512386af..2d7b1e08 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1742853454-e545ef855245a5f1c82a23198dbb3871ab208f05-6310913d1503861c2b0739d869465876e90c7b96.profdata +chrome-mac-arm-main-1742889290-fc37746dc5ba38c44f93d04b41d3775b73390665-b7b2dc975befdc24d2aea4241c39b11c3ca6c3e7.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 4aab0fe0..53a6f61 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1742839181-d260c31d4f67f90df8e61ae202d75dbe1142414e-5e5a0303cdac3133c1ca1df63851d9f459c9cc80.profdata +chrome-mac-main-1742882230-e41330bd4e70860760de8525ff84b950dfe98298-8f592e43518c024b6ce09d0568d1fd023e03141b.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt index a1cf103..35e2399 100644 --- a/chrome/build/win-arm64.pgo.txt +++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@ -chrome-win-arm64-main-1742839181-ee6e1e92effa65cfbd99b8553af72b5f4ba26435-5e5a0303cdac3133c1ca1df63851d9f459c9cc80.profdata +chrome-win-arm64-main-1742882230-7c4ec78b90c27083358b7293b4364cc2c068aa21-8f592e43518c024b6ce09d0568d1fd023e03141b.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 8e33a8a0..2d45363 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1742839181-b510035f1a3bc715804daf3a821acee34b606b86-5e5a0303cdac3133c1ca1df63851d9f459c9cc80.profdata +chrome-win32-main-1742860773-cdc892c7353f61ed76b0b63771eddd5d211416e1-d4fa62ff1a3c594db19dae4dfd457fa02c2b559f.profdata
diff --git a/chrome/common/extensions/api/autofill_private.idl b/chrome/common/extensions/api/autofill_private.idl index 6709d946..bfba8ee5 100644 --- a/chrome/common/extensions/api/autofill_private.idl +++ b/chrome/common/extensions/api/autofill_private.idl
@@ -496,9 +496,6 @@ static void isValidIban( DOMString ibanValue, IsValidIbanCallback callback); - // Triggers local credit cards migration. - static void migrateCreditCards(); - // Logs that the server cards edit link was clicked. static void logServerCardLinkClicked();
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 9c2024fe..dc21c23e 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -4094,6 +4094,10 @@ inline constexpr char kZstdContentEncodingEnabled[] = "net.zstd_content_encoding_enabled"; +// Boolean that specifies whether Happy Eyeballs V3 is enabled. +inline constexpr char kHappyEyeballsV3Enabled[] = + "net.happy_eyeballs_v3_enabled"; + // Boolean that specifies whether IPv6 reachability check override is enabled. inline constexpr char kIPv6ReachabilityOverrideEnabled[] = "net.ipv6_reachability_override_enabled";
diff --git a/chrome/release_scripts b/chrome/release_scripts index c980d8c2..1bce10c 160000 --- a/chrome/release_scripts +++ b/chrome/release_scripts
@@ -1 +1 @@ -Subproject commit c980d8c24470ace9a2b0a71952d5ba3d60c6b323 +Subproject commit 1bce10c60293c2f7e3b3fae1e012ded458d86168
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index ea275275..f75d5da6 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -4098,7 +4098,6 @@ sources += [ "../browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl_browsertest.cc" ] } - # TODO(crbug.com/40118868): Update guard when pixel tests support widens. if (is_win || is_linux) { sources += [ "../browser/ui/views/profiles/managed_user_profile_notice_ui_browsertest.cc", @@ -10766,7 +10765,6 @@ "../browser/ui/thumbnails/thumbnail_tab_helper_interactive_uitest.cc", "../browser/ui/views/autofill/payments/bnpl_tos_view_desktop_interactive_uitest.cc", "../browser/ui/views/autofill/payments/iban_bubble_view_uitest.cc", - "../browser/ui/views/autofill/payments/local_card_migration_uitest.cc", "../browser/ui/views/content_test_utils.cc", "../browser/ui/views/content_test_utils.h", "../browser/ui/views/extensions/dialogs/mv2_deprecation_keep_dialog_interactive_uitest.cc",
diff --git a/chrome/test/data/extensions/api_test/autofill_private/test.js b/chrome/test/data/extensions/api_test/autofill_private/test.js index 0fef8f58..1529d4b 100644 --- a/chrome/test/data/extensions/api_test/autofill_private/test.js +++ b/chrome/test/data/extensions/api_test/autofill_private/test.js
@@ -857,12 +857,6 @@ chrome.test.succeed(); }, - function migrateCreditCards() { - chrome.autofillPrivate.migrateCreditCards(); - chrome.test.assertNoLastError(); - chrome.test.succeed(); - }, - function logServerCardLinkClicked() { chrome.autofillPrivate.logServerCardLinkClicked(); chrome.test.assertNoLastError(); @@ -1074,7 +1068,6 @@ ['isUserEligibleForAutofillImprovements'], 'predictionImprovementsIphFeatureUsed': ['predictionImprovementsIphFeatureUsed'], - 'migrateCreditCards': ['migrateCreditCards'], 'logServerCardLinkClicked': ['logServerCardLinkClicked'], 'addVirtualCard': ['addVirtualCard'], 'removeVirtualCard': ['removeVirtualCard'],
diff --git a/chrome/test/data/webui/chromeos/settings/os_search_page/search_and_assistant_settings_card_test.ts b/chrome/test/data/webui/chromeos/settings/os_search_page/search_and_assistant_settings_card_test.ts index 6963fd87..0fd43e3 100644 --- a/chrome/test/data/webui/chromeos/settings/os_search_page/search_and_assistant_settings_card_test.ts +++ b/chrome/test/data/webui/chromeos/settings/os_search_page/search_and_assistant_settings_card_test.ts
@@ -851,78 +851,6 @@ }); test( - 'when isSunfishSettingsToggleVisible flag is false, ' + - 'Sunfish toggle is hidden', - () => { - loadTimeData.overrideValues({ - isSunfishSettingsToggleVisible: false, - }); - createSearchAndAssistantCard(); - assertFalse( - isVisible(searchAndAssistantSettingsCard.shadowRoot!.querySelector( - '#sunfishToggle'))); - }); - - suite( - 'when isSunfishSettingsToggleVisible flag is true, Sunfish toggle', - () => { - let sunfishToggle: SettingsToggleButtonElement; - - setup(() => { - loadTimeData.overrideValues({ - isSunfishSettingsToggleVisible: true, - }); - createSearchAndAssistantCard(); - - const nullableSunfishToggle = - searchAndAssistantSettingsCard.shadowRoot! - .querySelector<SettingsToggleButtonElement>('#sunfishToggle'); - assertTrue(nullableSunfishToggle !== null); - sunfishToggle = nullableSunfishToggle; - }); - - test('should appear', () => { - assertTrue(isVisible(sunfishToggle)); - }); - - test('reflects pref value', () => { - searchAndAssistantSettingsCard.prefs = { - ash: { - capture_mode: { - sunfish_enabled: { - value: true, - }, - }, - }, - }; - flush(); - - assertTrue(isVisible(sunfishToggle)); - assertTrue(sunfishToggle.checked); - assertTrue(searchAndAssistantSettingsCard.get( - 'prefs.ash.capture_mode.sunfish_enabled.value')); - - sunfishToggle.click(); - assertFalse(sunfishToggle.checked); - assertFalse(searchAndAssistantSettingsCard.get( - 'prefs.ash.capture_mode.sunfish_enabled.value')); - }); - - test('is deep-linkable', async () => { - const setting = settingMojom.Setting.kSunfishOnOff; - const params = new URLSearchParams(); - params.append('settingId', setting.toString()); - Router.getInstance().navigateTo(defaultRoute, params); - - await waitAfterNextRender(sunfishToggle); - assertEquals( - sunfishToggle, - searchAndAssistantSettingsCard.shadowRoot!.activeElement, - `Element should be focused for settingId=${setting}.'`); - }); - }); - - test( 'when isScannerSettingsToggleVisible flag is false, ' + 'Scanner toggles are hidden', () => {
diff --git a/chrome/test/data/webui/glic/test_client/index.html b/chrome/test/data/webui/glic/test_client/index.html index dc366b4..cb3de60 100644 --- a/chrome/test/data/webui/glic/test_client/index.html +++ b/chrome/test/data/webui/glic/test_client/index.html
@@ -122,6 +122,32 @@ overflow-y: scroll; flex-grow: 1; } + + /* Dark Mode Styles */ + @media (prefers-color-scheme: dark) { + body { + background-color: #121212; + color: #eee; + } + + .section { + background-color: #2a2a2a; + box-shadow: 0 0 0.5em rgba(0, 0, 0, 0.5); + border: 1px solid #444; + } + + a { + color: #99ccff; + } + + a:hover { + color: #66b3ff; + } + + a:visited{ + color: #c8a2c8; + } + } </style> <div id="pageHeader"> <h1>Test Web Client</h1>
diff --git a/chrome/test/data/webui/settings/autofill_fake_data.ts b/chrome/test/data/webui/settings/autofill_fake_data.ts index b5c7651..1b6e5c2b8 100644 --- a/chrome/test/data/webui/settings/autofill_fake_data.ts +++ b/chrome/test/data/webui/settings/autofill_fake_data.ts
@@ -381,8 +381,6 @@ logServerIbanLinkClicked() {} - migrateCreditCards() {} - removeCreditCard(_guid: string) { this.methodCalled('removeCreditCard'); }
diff --git a/chrome/test/data/webui/settings/payments_section_test.ts b/chrome/test/data/webui/settings/payments_section_test.ts index 25424657..56013282 100644 --- a/chrome/test/data/webui/settings/payments_section_test.ts +++ b/chrome/test/data/webui/settings/payments_section_test.ts
@@ -125,55 +125,6 @@ assertFalse(addPaymentMethodsButton.disabled); }); - test('verifyMigrationButtonNotShownIfMigrationNotEnabled', async function() { - // Mock prerequisites are not met. - loadTimeData.overrideValues({migrationEnabled: false}); - - // Add one migratable credit card. - const creditCard = createCreditCardEntry(); - creditCard.metadata!.isMigratable = true; - const section = await createPaymentsSection( - [creditCard], /*ibans=*/[], /*payOverTimeIssuers=*/[], - {credit_card_enabled: {value: true}}); - - assertTrue(section.$.migrateCreditCards.hidden); - }); - - test('verifyMigrationButtonNotShownIfCreditCardDisabled', async function() { - // Add one migratable credit card. - const creditCard = createCreditCardEntry(); - creditCard.metadata!.isMigratable = true; - // Mock credit card save toggle is turned off by users. - const section = await createPaymentsSection( - [creditCard], /*ibans=*/[], /*payOverTimeIssuers=*/[], - {credit_card_enabled: {value: false}}); - - assertTrue(section.$.migrateCreditCards.hidden); - }); - - test('verifyMigrationButtonNotShownIfNoCardIsMigratable', async function() { - // Add one migratable credit card. - const creditCard = createCreditCardEntry(); - // Mock credit card is not valid. - creditCard.metadata!.isMigratable = false; - const section = await createPaymentsSection( - [creditCard], /*ibans=*/[], /*payOverTimeIssuers=*/[], - {credit_card_enabled: {value: true}}); - - assertTrue(section.$.migrateCreditCards.hidden); - }); - - test('verifyMigrationButtonShown', async function() { - // Add one migratable credit card. - const creditCard = createCreditCardEntry(); - creditCard.metadata!.isMigratable = true; - const section = await createPaymentsSection( - [creditCard], /*ibans=*/[], /*payOverTimeIssuers=*/[], - {credit_card_enabled: {value: true}}); - - assertFalse(section.$.migrateCreditCards.hidden); - }); - test('CanMakePaymentToggle_RecordsMetrics', async function() { const testMetricsBrowserProxy = new TestMetricsBrowserProxy(); MetricsBrowserProxyImpl.setInstance(testMetricsBrowserProxy);
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 6465d4e..8d5c1bbf 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -16231.0.0-1067713 \ No newline at end of file +16231.0.0-1067719 \ No newline at end of file
diff --git a/chromeos/ash/components/mantis/DEPS b/chromeos/ash/components/mantis/DEPS index 38bb7a67..70bb266 100644 --- a/chromeos/ash/components/mantis/DEPS +++ b/chromeos/ash/components/mantis/DEPS
@@ -3,6 +3,7 @@ # on other components. "+chromeos/ash/components/mojo_service_manager", "+chromeos/ash/components/specialized_features", + "+chromeos/services/machine_learning/public", "+components/signin/public/identity_manager", # TODO(crbug.com/402346171): Components should not have dependencies to //ash.
diff --git a/chromeos/ash/components/mantis/media_app/BUILD.gn b/chromeos/ash/components/mantis/media_app/BUILD.gn index 8967c959..a589129 100644 --- a/chromeos/ash/components/mantis/media_app/BUILD.gn +++ b/chromeos/ash/components/mantis/media_app/BUILD.gn
@@ -19,6 +19,8 @@ "//chromeos/ash/components/mantis/mojom", "//chromeos/ash/components/mojo_service_manager", "//chromeos/ash/components/specialized_features", + "//chromeos/services/machine_learning/public/cpp", + "//chromeos/services/machine_learning/public/mojom", "//components/prefs", "//components/signin/public/identity_manager", "//mojo/public/cpp/bindings", @@ -41,6 +43,8 @@ "//chromeos/ash/components/mojo_service_manager", "//chromeos/ash/components/mojo_service_manager:test_support", "//chromeos/ash/components/specialized_features", + "//chromeos/services/machine_learning/public/cpp:stub", + "//chromeos/services/machine_learning/public/mojom", "//components/prefs:test_support", "//mojo/public/cpp/bindings", "//mojo/public/cpp/system",
diff --git a/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager.cc b/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager.cc index bc309db..cc132ad 100644 --- a/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager.cc +++ b/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager.cc
@@ -21,15 +21,21 @@ #include "chromeos/ash/components/mojo_service_manager/connection.h" #include "chromeos/ash/components/mojo_service_manager/mojom/mojo_service_manager.mojom.h" #include "chromeos/ash/components/specialized_features/feature_access_checker.h" +#include "chromeos/services/machine_learning/public/cpp/service_connection.h" +#include "chromeos/services/machine_learning/public/mojom/machine_learning_service.mojom.h" +#include "chromeos/services/machine_learning/public/mojom/text_classifier.mojom.h" #include "components/signin/public/identity_manager/account_capabilities.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/cros_system_api/mojo/service_constants.h" namespace ash { namespace { using ::ash::media_app_ui::mojom::MantisUntrustedPage; +using ::chromeos::machine_learning::mojom::LoadModelResult; +using ::chromeos::machine_learning::mojom::TextClassifier; using ::mantis::mojom::PlatformModelProgressObserver; enum class GenAIPhotoEditingSettings { @@ -64,6 +70,8 @@ chromeos::mojo_services::kCrosMantisService, std::nullopt, cros_service_.BindNewPipeAndPassReceiver().PassPipe()); cros_service_.reset_on_disconnect(); + chromeos::machine_learning::ServiceConnection::GetInstance() + ->BindMachineLearningService(ml_service_.BindNewPipeAndPassReceiver()); } MantisUntrustedServiceManager::~MantisUntrustedServiceManager() = default; @@ -139,6 +147,18 @@ return progress_observer; } +mojo::PendingRemote<TextClassifier> +MantisUntrustedServiceManager::GetTextClassifier() { + mojo::PendingRemote<TextClassifier> text_classifier; + ml_service_->LoadTextClassifier( + text_classifier.InitWithNewPipeAndPassReceiver(), + base::BindOnce([](LoadModelResult result) { + LOG_IF(ERROR, result != LoadModelResult::OK) + << "LoadTextClassifier error: " << result; + })); + return text_classifier; +} + void MantisUntrustedServiceManager::Create( mojo::PendingRemote<MantisUntrustedPage> page, const std::optional<base::Uuid>& dlc_uuid, @@ -149,7 +169,7 @@ // This API is designed by CrOS service to handle multiple calls safely. cros_service_->Initialize( CreateProgressObserver(std::move(page)), - processor.InitWithNewPipeAndPassReceiver(), dlc_uuid, + processor.InitWithNewPipeAndPassReceiver(), dlc_uuid, GetTextClassifier(), base::BindOnce(&MantisUntrustedServiceManager::OnInitializeDone, weak_ptr_factory_.GetWeakPtr(), std::move(callback), std::move(processor)));
diff --git a/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager.h b/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager.h index 2514272..bc5ed4b 100644 --- a/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager.h +++ b/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager.h
@@ -14,6 +14,7 @@ #include "chromeos/ash/components/mantis/mojom/mantis_service.mojom.h" #include "chromeos/ash/components/mojo_service_manager/mojom/mojo_service_manager.mojom.h" #include "chromeos/ash/components/specialized_features/feature_access_checker.h" +#include "chromeos/services/machine_learning/public/mojom/machine_learning_service.mojom.h" #include "components/prefs/pref_service.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/remote.h" @@ -55,6 +56,8 @@ void OnQueryDone( base::OnceCallback<void(bool)> callback, chromeos::mojo_service_manager::mojom::ErrorOrServiceStatePtr result); + mojo::PendingRemote<chromeos::machine_learning::mojom::TextClassifier> + GetTextClassifier(); void OnInitializeDone( CreateCallback callback, mojo::PendingRemote<mantis::mojom::MantisProcessor> processor, @@ -63,6 +66,8 @@ mojo::Remote<mantis::mojom::MantisService> cros_service_; mojo::UniqueReceiverSet<mantis::mojom::PlatformModelProgressObserver> progress_observers_; + mojo::Remote<chromeos::machine_learning::mojom::MachineLearningService> + ml_service_; std::unique_ptr<specialized_features::FeatureAccessChecker> access_checker_; std::unique_ptr<MantisUntrustedService> mantis_untrusted_service_;
diff --git a/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager_unittest.cc b/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager_unittest.cc index 2655fef..f07d277 100644 --- a/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager_unittest.cc +++ b/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager_unittest.cc
@@ -21,6 +21,8 @@ #include "chromeos/ash/components/mojo_service_manager/fake_mojo_service_manager.h" #include "chromeos/ash/components/mojo_service_manager/mojom/mojo_service_manager.mojom.h" #include "chromeos/ash/components/specialized_features/feature_access_checker.h" +#include "chromeos/services/machine_learning/public/cpp/fake_service_connection.h" +#include "chromeos/services/machine_learning/public/mojom/text_classifier.mojom.h" #include "components/prefs/testing_pref_service.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -79,6 +81,7 @@ (mojo::PendingRemote<mantis::mojom::PlatformModelProgressObserver>, mojo::PendingReceiver<mantis::mojom::MantisProcessor>, const std::optional<base::Uuid>&, + mojo::PendingRemote<chromeos::machine_learning::mojom::TextClassifier>, InitializeCallback), (override)); @@ -127,6 +130,10 @@ ash::prefs::kGenAIPhotoEditingSettings, static_cast<int>(GenAIPhotoEditingSettings::kAllowed)); + chromeos::machine_learning::ServiceConnection:: + UseFakeServiceConnectionForTesting(&fake_connection_); + chromeos::machine_learning::ServiceConnection::GetInstance()->Initialize(); + // Set Mantis is available by default in this test, so that we can check // each unavailable case one by one. ON_CALL(*access_checker_, Check) @@ -140,6 +147,7 @@ std::unique_ptr<NiceMock<MockMojoMantisService>> mock_mojo_service_; std::unique_ptr<NiceMock<MockFeatureAccessChecker>> access_checker_; TestingPrefServiceSimple pref_; + chromeos::machine_learning::FakeServiceConnectionImpl fake_connection_; }; TEST_F(MantisUntrustedServiceManagerTest, IsAvailable) { @@ -216,7 +224,7 @@ TEST_F(MantisUntrustedServiceManagerTest, CreateSuccess) { constexpr double kProgress = 1.0; EXPECT_CALL(*mock_mojo_service_, Initialize) - .WillOnce(testing::WithArgs<0, 3>( + .WillOnce(testing::WithArgs<0, 4>( [](mojo::PendingRemote<PlatformModelProgressObserver> pending_observer, base::OnceCallback<void(InitializeResult)> callback) { @@ -242,7 +250,7 @@ TEST_F(MantisUntrustedServiceManagerTest, CreateFailed) { EXPECT_CALL(*mock_mojo_service_, Initialize) - .WillOnce(RunOnceCallback<3>(InitializeResult::kFailedToLoadLibrary)); + .WillOnce(RunOnceCallback<4>(InitializeResult::kFailedToLoadLibrary)); MantisUntrustedServiceManager manager(std::move(access_checker_)); MockMantisUntrustedPage page;
diff --git a/chromeos/ash/components/mantis/mojom/BUILD.gn b/chromeos/ash/components/mantis/mojom/BUILD.gn index fb65db5a..23fa5c0 100644 --- a/chromeos/ash/components/mantis/mojom/BUILD.gn +++ b/chromeos/ash/components/mantis/mojom/BUILD.gn
@@ -11,7 +11,10 @@ "mantis_processor.mojom", "mantis_service.mojom", ] - public_deps = [ "//mojo/public/mojom/base" ] + public_deps = [ + "//chromeos/services/machine_learning/public/mojom", + "//mojo/public/mojom/base", + ] webui_module_path = "/" # The generated Mojo needs to be imported into the internal repository.
diff --git a/chromeos/ash/components/mantis/mojom/mantis_service.mojom b/chromeos/ash/components/mantis/mojom/mantis_service.mojom index 8fa2cc23..0166a6e8 100644 --- a/chromeos/ash/components/mantis/mojom/mantis_service.mojom +++ b/chromeos/ash/components/mantis/mojom/mantis_service.mojom
@@ -8,6 +8,7 @@ module mantis.mojom; import "chromeos/ash/components/mantis/mojom/mantis_processor.mojom"; +import "chromeos/services/machine_learning/public/mojom/text_classifier.mojom"; import "mojo/public/mojom/base/uuid.mojom"; // The feature status used to restrict Mantis functionality if applicable. @@ -53,6 +54,8 @@ Initialize@0( pending_remote<PlatformModelProgressObserver>? progress_observer, pending_receiver<MantisProcessor> processor, - [MinVersion=3] mojo_base.mojom.Uuid? dlc_uuid) - => (InitializeResult result); + [MinVersion=3] mojo_base.mojom.Uuid? dlc_uuid, + [MinVersion=4] + pending_remote<chromeos.machine_learning.mojom.TextClassifier>? + text_classifier) => (InitializeResult result); };
diff --git a/chromeos/ash/services/coral/public/mojom/coral_service.mojom b/chromeos/ash/services/coral/public/mojom/coral_service.mojom index 6e936363..d575a7d 100644 --- a/chromeos/ash/services/coral/public/mojom/coral_service.mojom +++ b/chromeos/ash/services/coral/public/mojom/coral_service.mojom
@@ -240,5 +240,6 @@ Initialize@3( pending_remote<chromeos.machine_learning.mojom.MachineLearningService>? ml_service, - pending_receiver<CoralProcessor> processor); + pending_receiver<CoralProcessor> processor, + [MinVersion=2] string? language_code); };
diff --git a/chromeos/ash/services/cros_safety/cros_safety_service.cc b/chromeos/ash/services/cros_safety/cros_safety_service.cc index 3e29d1b..c80f79a 100644 --- a/chromeos/ash/services/cros_safety/cros_safety_service.cc +++ b/chromeos/ash/services/cros_safety/cros_safety_service.cc
@@ -79,10 +79,10 @@ void CrosSafetyService::CreateOnDeviceSafetySession( mojo::PendingReceiver<cros_safety::mojom::OnDeviceSafetySession> session, CreateOnDeviceSafetySessionCallback callback) { - // This function should only be called during the primary user's session. - CHECK(user_manager::UserManager::Get()->IsPrimaryUser( - user_manager::UserManager::Get()->GetActiveUser())); - if (!arc::IsArcAvailable() || !arc::ArcServiceManager::Get()) { + // ARC is only available under primary user session. + if (!user_manager::UserManager::Get()->IsPrimaryUser( + user_manager::UserManager::Get()->GetActiveUser()) || + !arc::IsArcAvailable() || !arc::ArcServiceManager::Get()) { // TODO(crbug.com/379073760) Separate kArcDisabledByUser cases so we can // inform the user to enable arc. std::move(callback).Run(
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc index 08aa22b..b15aa55d 100644 --- a/chromeos/constants/chromeos_features.cc +++ b/chromeos/constants/chromeos_features.cc
@@ -160,6 +160,11 @@ "MahiSummarizeSelected", base::FEATURE_ENABLED_BY_DEFAULT); +// Controls whether NotebookLM is preinstalled. +BASE_FEATURE(kNotebookLmAppPreinstall, + "NotebookLmAppPreinstall", + base::FEATURE_DISABLED_BY_DEFAULT); + // Kill switch to disable the new guest profile implementation on CrOS that is // consistent with desktop chrome. // TODO(crbug.com/40233408): Remove if the change is fully launched.
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h index ee46c00..0057b50 100644 --- a/chromeos/constants/chromeos_features.h +++ b/chromeos/constants/chromeos_features.h
@@ -76,6 +76,8 @@ COMPONENT_EXPORT(CHROMEOS_CONSTANTS) BASE_DECLARE_FEATURE(kFeatureManagementRoundedWindows); COMPONENT_EXPORT(CHROMEOS_CONSTANTS) +BASE_DECLARE_FEATURE(kNotebookLmAppPreinstall); +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) BASE_DECLARE_FEATURE(kNewGuestProfile); COMPONENT_EXPORT(CHROMEOS_CONSTANTS) BASE_DECLARE_FEATURE(kNotificationWidthIncrease);
diff --git a/chromeos/services/machine_learning/public/mojom/BUILD.gn b/chromeos/services/machine_learning/public/mojom/BUILD.gn index e70ec07..8fbdbae 100644 --- a/chromeos/services/machine_learning/public/mojom/BUILD.gn +++ b/chromeos/services/machine_learning/public/mojom/BUILD.gn
@@ -28,6 +28,11 @@ deps = [ "//ui/gfx/geometry/mojom" ] + webui_module_path = "/" + + # ChromeOS relies heavily on old legacy bindings. + generate_legacy_js_bindings = true + output_prefix = "mlservice_mojom" macro_prefix = "MLSERVICE_MOJOM" }
diff --git a/clank b/clank index 3caed26..bbe79ff 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit 3caed26bf65373a93272f352981764ff9e3b6209 +Subproject commit bbe79ffff6ec262fc09466047ee360fd84f9f675
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index 320cb645..fbcfedc 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -192,6 +192,7 @@ "data_model/usage_history_information.h", "data_model/valuables/loyalty_card.cc", "data_model/valuables/loyalty_card.h", + "data_model/valuables/valuable_types.h", "data_quality/addresses/address_normalization_manager.cc", "data_quality/addresses/address_normalization_manager.h", "data_quality/addresses/address_normalizer.h", @@ -399,8 +400,6 @@ "metrics/payments/filled_card_information_bubble_metrics.h", "metrics/payments/iban_metrics.cc", "metrics/payments/iban_metrics.h", - "metrics/payments/local_card_migration_metrics.cc", - "metrics/payments/local_card_migration_metrics.h", "metrics/payments/manage_cards_prompt_metrics.cc", "metrics/payments/manage_cards_prompt_metrics.h", "metrics/payments/mandatory_reauth_metrics.cc", @@ -911,13 +910,6 @@ sources += [ "crowdsourcing/server_prediction_overrides.cc", "crowdsourcing/server_prediction_overrides.h", - "payments/local_card_migration_manager.cc", - "payments/local_card_migration_manager.h", - "payments/payments_requests/migrate_cards_request.cc", - "payments/payments_requests/migrate_cards_request.h", - "strike_databases/payments/local_card_migration_strike_database.h", - "ui/payments/local_card_migration_bubble_controller.h", - "ui/payments/local_card_migration_dialog_controller.h", ] deps += [ "//ui/native_theme", @@ -1181,13 +1173,6 @@ "//third_party/blink/public/common", ] } - - if (!is_ios && !is_android) { - sources += [ - "payments/test_local_card_migration_manager.cc", - "payments/test_local_card_migration_manager.h", - ] - } } bundle_data("unit_tests_bundle_data") { @@ -1492,11 +1477,7 @@ } if (!is_ios && !is_android) { - sources += [ - "crowdsourcing/server_prediction_overrides_unittest.cc", - "payments/local_card_migration_manager_unittest.cc", - "payments/payments_requests/migrate_cards_request_unittest.cc", - ] + sources += [ "crowdsourcing/server_prediction_overrides_unittest.cc" ] } if (build_with_tflite_lib) {
diff --git a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc index 1129321..13684f5 100644 --- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc +++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc
@@ -359,6 +359,7 @@ // Helper function for EncodeUploadRequest(). void EncodeFormFieldsForUpload( const FormStructure& form, + base::optional_ref<RandomizedEncoder> encoder, const std::map<FieldGlobalId, base::flat_set<std::u16string>>& format_strings, base::span<AutofillField*> upload_fields, @@ -418,9 +419,9 @@ added_field->set_properties_mask(field->properties_mask()); } - if (form.randomized_encoder().has_value()) { + if (encoder.has_value()) { PopulateRandomizedFieldMetadata( - *form.randomized_encoder(), form, *field, + *encoder, form, *field, added_field->mutable_randomized_field_metadata()); } @@ -687,6 +688,7 @@ std::vector<AutofillUploadContents> EncodeUploadRequest( const FormStructure& form, + base::optional_ref<RandomizedEncoder> encoder, const std::map<FieldGlobalId, base::flat_set<std::u16string>>& format_strings, const FieldTypeSet& available_field_types, @@ -705,8 +707,7 @@ upload.set_autofill_used(false); upload.set_data_present(data_present); upload.set_has_form_tag(form.is_form_element()); - if (!form.current_page_language()->empty() && - form.randomized_encoder().has_value()) { + if (!form.current_page_language()->empty() && encoder.has_value()) { upload.set_language(form.current_page_language().value()); } @@ -741,15 +742,16 @@ return {}; // Malformed form, skip it. } - if (form.randomized_encoder().has_value()) { - PopulateRandomizedFormMetadata(*form.randomized_encoder(), form, + if (encoder.has_value()) { + PopulateRandomizedFormMetadata(*encoder, form, upload.mutable_randomized_form_metadata()); } std::vector<AutofillField*> upload_fields(form.fields().size()); std::ranges::transform(form.fields(), upload_fields.begin(), &std::unique_ptr<AutofillField>::get); - EncodeFormFieldsForUpload(form, format_strings, upload_fields, &upload); + EncodeFormFieldsForUpload(form, encoder, format_strings, upload_fields, + &upload); std::vector<AutofillUploadContents> uploads = {std::move(upload)}; // Build AutofillUploadContents for the renderer forms that have been @@ -781,7 +783,7 @@ (*subform_begin)->renderer_form_id(); }); // SAFETY: The iterators are from the same container. - EncodeFormFieldsForUpload(form, format_strings, + EncodeFormFieldsForUpload(form, encoder, format_strings, UNSAFE_BUFFERS({subform_begin, subform_end}), &uploads.back()); subform_begin = subform_end;
diff --git a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.h b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.h index ed53859..dac5f9e 100644 --- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.h +++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.h
@@ -9,6 +9,7 @@ #include <string> #include "components/autofill/core/browser/autofill_field.h" +#include "components/autofill/core/browser/crowdsourcing/randomized_encoder.h" #include "components/autofill/core/browser/form_structure.h" #include "components/autofill/core/browser/logging/log_manager.h" #include "components/autofill/core/browser/proto/api_v1.pb.h" @@ -49,6 +50,7 @@ // form signatures of forms 1 and 2. std::vector<AutofillUploadContents> EncodeUploadRequest( const FormStructure& form, + base::optional_ref<RandomizedEncoder> encoder, const std::map<FieldGlobalId, base::flat_set<std::u16string>>& format_strings, const FieldTypeSet& available_field_types,
diff --git a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding_unittest.cc b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding_unittest.cc index c3b9eddb..10b0a6b 100644 --- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding_unittest.cc +++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding_unittest.cc
@@ -76,10 +76,9 @@ const std::vector<FieldType> field_types; }; -// Matches any protobuf `actual` whose serialization is equal to the -// string-serialization of the protobuf `expected`. -template <typename T> -auto SerializesSameAs(const T& expected) { +// TODO(crbug.com/406066782): Add deep comparison for descriptive error messages. +Matcher<AutofillUploadContents> SerializesSameAs( + const AutofillUploadContents& expected) { std::string expected_string; CHECK(expected.SerializeToString(&expected_string)); return ResultOf( @@ -91,14 +90,38 @@ Eq(expected_string)); } -template <typename... Matchers> -auto ElementsSerializeSameAs(Matchers... element_matchers) { - return ElementsAre(SerializesSameAs(element_matchers)...); +// TODO(crbug.com/406066782): Add deep comparison for descriptive error messages. +Matcher<AutofillPageQueryRequest> SerializesSameAs( + const AutofillPageQueryRequest& expected) { + std::string expected_string; + CHECK(expected.SerializeToString(&expected_string)); + return ResultOf( + [](const auto& actual) { + std::string actual_string; + CHECK(actual.SerializeToString(&actual_string)); + return actual_string; + }, + Eq(expected_string)); } -template <typename... Matchers> -auto UnorderedElementsSerializeSameAs(Matchers... element_matchers) { - return UnorderedElementsAre(SerializesSameAs(element_matchers)...); +// Matches `AutofillUploadContents` that are equivalent to `expected`, ignoring +// data that is only set if there is RandomizedEncoder. +// +// TODO(crbug.com/406066782): This matcher should not exist. It was only +// introduced to make test cases work that do not populate the metadata. +// Once SerializesSameAs() produces useful error messages, it should be easy to +// adjust the tests and remove WithoutMetadataSerializesSameAs(). +Matcher<AutofillUploadContents> WithoutMetadataSerializesSameAs( + AutofillUploadContents expected) { + auto strip_metadata = [](AutofillUploadContents upload_content) { + upload_content.clear_language(); + upload_content.clear_randomized_form_metadata(); + for (int i = 0; i < upload_content.field_data_size(); ++i) { + upload_content.mutable_field_data(i)->clear_randomized_field_metadata(); + } + return upload_content; + }; + return ResultOf(strip_metadata, SerializesSameAs(strip_metadata(expected))); } std::string SerializeAndEncode(const AutofillQueryResponse& response) { @@ -236,6 +259,10 @@ form_structure->field(i)->set_possible_types(possible_field_types[i]); } + RandomizedEncoder encoder("seed for testing", + AutofillRandomizedValue_EncodingType_ALL_BITS, + /*anonymous_url_collection_is_enabled=*/true); + FieldTypeSet available_field_types; available_field_types.insert(NAME_FIRST); available_field_types.insert(NAME_LAST); @@ -262,11 +289,11 @@ test::FillUploadField(upload.add_field_data(), 466116101U, 14U); test::FillUploadField(upload.add_field_data(), 2799270304U, 36U); - EXPECT_THAT(EncodeUploadRequest(*form_structure, /*format_strings=*/{}, - available_field_types, + EXPECT_THAT(EncodeUploadRequest(*form_structure, encoder, + /*format_strings=*/{}, available_field_types, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true), - ElementsSerializeSameAs(upload)); + ElementsAre(WithoutMetadataSerializesSameAs(upload))); // Add 2 address fields - this should be still a valid form. for (size_t i = 0; i < 2; ++i) { @@ -300,11 +327,11 @@ test::FillUploadField(upload.mutable_field_data(5), 509334676U, 31U); test::FillUploadField(upload.mutable_field_data(6), 509334676U, 31U); - EXPECT_THAT(EncodeUploadRequest(*form_structure, /*format_strings=*/{}, - available_field_types, + EXPECT_THAT(EncodeUploadRequest(*form_structure, encoder, + /*format_strings=*/{}, available_field_types, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true), - ElementsSerializeSameAs(upload)); + ElementsAre(WithoutMetadataSerializesSameAs(upload))); // Add 300 address fields - now the form is invalid, as it has too many // fields. @@ -320,13 +347,72 @@ form_structure->field(i)->set_possible_types(possible_field_types[i]); } - EXPECT_TRUE(EncodeUploadRequest(*form_structure, /*format_strings=*/{}, - available_field_types, + EXPECT_TRUE(EncodeUploadRequest(*form_structure, encoder, + /*format_strings=*/{}, available_field_types, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true) .empty()); } +// Tests that EncodeUploadRequest() behaves reasonably in the absence of a +// RandomizedEncoder. +TEST_F(AutofillCrowdsourcingEncoding, + EncodeUploadRequest_WithOrWithoutEncoder) { + std::unique_ptr<FormStructure> form_structure; + FormData form; + form.set_url(GURL("http://www.foo.com/")); + form.set_renderer_id(test::MakeFormRendererId()); + form.set_fields({CreateTestFormField("First Name", "firstname", "", + FormControlType::kInputText), + CreateTestFormField("Last Name", "lastname", "", + FormControlType::kInputText)}); + + form_structure = std::make_unique<FormStructure>(form); + + // Prepare the expected proto. + AutofillUploadContents upload; + upload.set_submission(true); + upload.set_client_version( + std::string(GetProductNameAndVersionForUserAgent())); + upload.set_form_signature(form_structure->form_signature().value()); + upload.set_autofill_used(false); + upload.set_data_present("10"); + upload.set_submission_event( + AutofillUploadContents_SubmissionIndicatorEvent_NONE); + upload.set_has_form_tag(true); + { + AutofillUploadContents::Field* upload_firstname_field = + upload.add_field_data(); + upload_firstname_field->set_signature( + *form_structure->field(0)->GetFieldSignature()); + } + { + AutofillUploadContents::Field* upload_date_field = upload.add_field_data(); + upload_date_field->set_signature( + *form_structure->field(1)->GetFieldSignature()); + } + + // Without encoder. + EXPECT_THAT(EncodeUploadRequest(*form_structure, + /*encoder=*/std::nullopt, /*format_strings=*/ + {}, + /*available_field_types=*/{NAME_FIRST}, + /*login_form_signature=*/std::nullopt, + /*observed_submission=*/true), + ElementsAre(SerializesSameAs(upload))); + + // With encoder. + RandomizedEncoder encoder("seed for testing", + AutofillRandomizedValue_EncodingType_ALL_BITS, + /*anonymous_url_collection_is_enabled=*/true); + EXPECT_THAT(EncodeUploadRequest(*form_structure, encoder, /*format_strings=*/ + {}, + /*available_field_types=*/{NAME_FIRST}, + /*login_form_signature=*/std::nullopt, + /*observed_submission=*/true), + ElementsAre(WithoutMetadataSerializesSameAs(upload))); +} + TEST_F(AutofillCrowdsourcingEncoding, EncodeUploadRequestWithFormatStrings) { std::unique_ptr<FormStructure> form_structure; FormData form; @@ -342,6 +428,10 @@ fs_field->set_host_form_signature(form_structure->form_signature()); } + RandomizedEncoder encoder("seed for testing", + AutofillRandomizedValue_EncodingType_ALL_BITS, + /*anonymous_url_collection_is_enabled=*/true); + // Prepare the expected proto string. AutofillUploadContents upload; upload.set_submission(true); @@ -383,14 +473,13 @@ // `available_field_types`. EXPECT_THAT( EncodeUploadRequest( - *form_structure, - /*format_strings=*/ + *form_structure, encoder, /*format_strings=*/ std::map<FieldGlobalId, base::flat_set<std::u16string>>{ {form_structure->fields()[1]->global_id(), {u"DD/MM/YYYY", u"MM/DD/YYYY"}}}, /*available_field_types=*/{NAME_FIRST}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true), - ElementsSerializeSameAs(upload)); + ElementsAre(WithoutMetadataSerializesSameAs(upload))); } TEST_F(AutofillCrowdsourcingEncoding, @@ -440,6 +529,10 @@ } } + RandomizedEncoder encoder("seed for testing", + AutofillRandomizedValue_EncodingType_ALL_BITS, + /*anonymous_url_collection_is_enabled=*/true); + FieldTypeSet available_field_types; available_field_types.insert(NAME_FIRST); available_field_types.insert(NAME_LAST); @@ -490,11 +583,11 @@ MANUALLY_TRIGGERED_GENERATION_ON_SIGN_UP_FORM); upload_password_field->set_generated_password_changed(true); - EXPECT_THAT(EncodeUploadRequest(*form_structure, /*format_strings=*/{}, - available_field_types, + EXPECT_THAT(EncodeUploadRequest(*form_structure, encoder, + /*format_strings=*/{}, available_field_types, /*login_form_signature=*/FormSignature(42), /*observed_submission=*/true), - ElementsSerializeSameAs(upload)); + ElementsAre(WithoutMetadataSerializesSameAs(upload))); } TEST_F(AutofillCrowdsourcingEncoding, EncodeUploadRequestWithPropertiesMask) { @@ -551,6 +644,10 @@ form_structure->field(i)->set_possible_types(possible_field_types[i]); } + RandomizedEncoder encoder("seed for testing", + AutofillRandomizedValue_EncodingType_ALL_BITS, + /*anonymous_url_collection_is_enabled=*/true); + FieldTypeSet available_field_types; available_field_types.insert(NAME_FIRST); available_field_types.insert(NAME_LAST); @@ -578,11 +675,11 @@ upload.mutable_field_data(2)->set_properties_mask( FieldPropertiesFlags::kHadFocus | FieldPropertiesFlags::kUserTyped); - EXPECT_THAT(EncodeUploadRequest(*form_structure, /*format_strings=*/{}, - available_field_types, + EXPECT_THAT(EncodeUploadRequest(*form_structure, encoder, + /*format_strings=*/{}, available_field_types, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true), - ElementsSerializeSameAs(upload)); + ElementsAre(WithoutMetadataSerializesSameAs(upload))); } TEST_F(AutofillCrowdsourcingEncoding, @@ -617,6 +714,10 @@ form_structure->field(i)->set_possible_types(possible_field_types[i]); } + RandomizedEncoder encoder("seed for testing", + AutofillRandomizedValue_EncodingType_ALL_BITS, + /*anonymous_url_collection_is_enabled=*/true); + FieldTypeSet available_field_types; available_field_types.insert(NAME_FIRST); available_field_types.insert(NAME_LAST); @@ -638,11 +739,11 @@ test::FillUploadField(upload.add_field_data(), 3494530716U, 5U); test::FillUploadField(upload.add_field_data(), 1029417091U, 9U); - EXPECT_THAT(EncodeUploadRequest(*form_structure, /*format_strings=*/{}, - available_field_types, + EXPECT_THAT(EncodeUploadRequest(*form_structure, encoder, + /*format_strings=*/{}, available_field_types, /*login_form_signature=*/std::nullopt, /*observed_submission=*/false), - ElementsSerializeSameAs(upload)); + ElementsAre(WithoutMetadataSerializesSameAs(upload))); } TEST_F(AutofillCrowdsourcingEncoding, EncodeUploadRequest_WithLabels) { @@ -673,6 +774,10 @@ form_structure->field(i)->set_possible_types(possible_field_types[i]); } + RandomizedEncoder encoder("seed for testing", + AutofillRandomizedValue_EncodingType_ALL_BITS, + /*anonymous_url_collection_is_enabled=*/true); + FieldTypeSet available_field_types; available_field_types.insert(NAME_FIRST); available_field_types.insert(NAME_LAST); @@ -694,11 +799,11 @@ test::FillUploadField(upload.add_field_data(), 1318412689U, 5U); test::FillUploadField(upload.add_field_data(), 1318412689U, 9U); - EXPECT_THAT(EncodeUploadRequest(*form_structure, /*format_strings=*/{}, - available_field_types, + EXPECT_THAT(EncodeUploadRequest(*form_structure, encoder, + /*format_strings=*/{}, available_field_types, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true), - ElementsSerializeSameAs(upload)); + ElementsAre(WithoutMetadataSerializesSameAs(upload))); } // Tests that when the form is the result of flattening multiple forms into one, @@ -747,6 +852,10 @@ form_structure->field(i)->set_possible_types(possible_field_types[i]); } + RandomizedEncoder encoder("seed for testing", + AutofillRandomizedValue_EncodingType_ALL_BITS, + /*anonymous_url_collection_is_enabled=*/true); + FieldTypeSet available_field_types; available_field_types.insert(CREDIT_CARD_NAME_FULL); available_field_types.insert(CREDIT_CARD_NUMBER); @@ -806,12 +915,15 @@ return upload; }(); - EXPECT_THAT(EncodeUploadRequest(*form_structure, /*format_strings=*/{}, - available_field_types, - /*login_form_signature=*/std::nullopt, - /*observed_submission=*/true), - UnorderedElementsSerializeSameAs(upload_main, upload_name_exp, - upload_number, upload_cvc)); + EXPECT_THAT( + EncodeUploadRequest(*form_structure, encoder, + /*format_strings=*/{}, available_field_types, + /*login_form_signature=*/std::nullopt, + /*observed_submission=*/true), + UnorderedElementsAre(WithoutMetadataSerializesSameAs(upload_main), + WithoutMetadataSerializesSameAs(upload_name_exp), + WithoutMetadataSerializesSameAs(upload_number), + WithoutMetadataSerializesSameAs(upload_cvc))); } // Check that we compute the "datapresent" string correctly for the given @@ -836,6 +948,10 @@ form_structure.field(i)->set_possible_types(possible_field_types[i]); } + RandomizedEncoder encoder("seed for testing", + AutofillRandomizedValue_EncodingType_ALL_BITS, + /*anonymous_url_collection_is_enabled=*/true); + // No available types. // datapresent should be "" == trimmed(0x0000000000000000) == // 0b0000000000000000000000000000000000000000000000000000000000000000 @@ -857,11 +973,11 @@ test::FillUploadField(upload.add_field_data(), 2404144663U, 1U); test::FillUploadField(upload.add_field_data(), 420638584U, 1U); - EXPECT_THAT(EncodeUploadRequest(form_structure, /*format_strings=*/{}, - available_field_types, + EXPECT_THAT(EncodeUploadRequest(form_structure, encoder, + /*format_strings=*/{}, available_field_types, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true), - ElementsSerializeSameAs(upload)); + ElementsAre(WithoutMetadataSerializesSameAs(upload))); // Only a few types available. // datapresent should be "1540000240" == trimmed(0x1540000240000000) == @@ -883,11 +999,11 @@ // Adjust the expected proto string. upload.set_data_present("1540000240"); - EXPECT_THAT(EncodeUploadRequest(form_structure, /*format_strings=*/{}, - available_field_types, + EXPECT_THAT(EncodeUploadRequest(form_structure, encoder, + /*format_strings=*/{}, available_field_types, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true), - ElementsSerializeSameAs(upload)); + ElementsAre(WithoutMetadataSerializesSameAs(upload))); // All supported non-credit card types available. // datapresent should be "1f7e000378000008" == trimmed(0x1f7e000378000008) == @@ -933,11 +1049,11 @@ // Adjust the expected proto string. upload.set_data_present("1f7e000378000008"); - EXPECT_THAT(EncodeUploadRequest(form_structure, /*format_strings=*/{}, - available_field_types, + EXPECT_THAT(EncodeUploadRequest(form_structure, encoder, + /*format_strings=*/{}, available_field_types, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true), - ElementsSerializeSameAs(upload)); + ElementsAre(WithoutMetadataSerializesSameAs(upload))); // All supported credit card types available. // datapresent should be "0000000000001fc0" == trimmed(0x0000000000001fc0) == @@ -961,11 +1077,11 @@ // Adjust the expected proto string. upload.set_data_present("0000000000001fc0"); - EXPECT_THAT(EncodeUploadRequest(form_structure, /*format_strings=*/{}, - available_field_types, + EXPECT_THAT(EncodeUploadRequest(form_structure, encoder, + /*format_strings=*/{}, available_field_types, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true), - ElementsSerializeSameAs(upload)); + ElementsAre(WithoutMetadataSerializesSameAs(upload))); // All supported types available. // datapresent should be "1f7e000378001fc8" == trimmed(0x1f7e000378001fc8) == @@ -1025,11 +1141,11 @@ // Adjust the expected proto string. upload.set_data_present("1f7e000378001fc8"); - EXPECT_THAT(EncodeUploadRequest(form_structure, /*format_strings=*/{}, - available_field_types, + EXPECT_THAT(EncodeUploadRequest(form_structure, encoder, + /*format_strings=*/{}, available_field_types, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true), - ElementsSerializeSameAs(upload)); + ElementsAre(WithoutMetadataSerializesSameAs(upload))); } TEST_F(AutofillCrowdsourcingEncoding, CheckMultipleTypes) { @@ -1079,6 +1195,10 @@ form_structure->field(i)->set_possible_types(possible_field_types[i]); } + RandomizedEncoder encoder("seed for testing", + AutofillRandomizedValue_EncodingType_ALL_BITS, + /*anonymous_url_collection_is_enabled=*/true); + // Prepare the expected proto string. AutofillUploadContents upload; upload.set_submission(true); @@ -1096,11 +1216,11 @@ test::FillUploadField(upload.add_field_data(), 2404144663U, 5U); test::FillUploadField(upload.add_field_data(), 509334676U, 30U); - EXPECT_THAT(EncodeUploadRequest(*form_structure, /*format_strings=*/{}, - available_field_types, + EXPECT_THAT(EncodeUploadRequest(*form_structure, encoder, + /*format_strings=*/{}, available_field_types, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true), - ElementsSerializeSameAs(upload)); + ElementsAre(WithoutMetadataSerializesSameAs(upload))); // Match third field as both first and last. possible_field_types[2].insert(NAME_FIRST); @@ -1112,11 +1232,11 @@ upload.mutable_field_data(2)->mutable_autofill_type()->SwapElements(0, 1); - EXPECT_THAT(EncodeUploadRequest(*form_structure, /*format_strings=*/{}, - available_field_types, + EXPECT_THAT(EncodeUploadRequest(*form_structure, encoder, + /*format_strings=*/{}, available_field_types, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true), - ElementsSerializeSameAs(upload)); + ElementsAre(WithoutMetadataSerializesSameAs(upload))); // Match last field as both address home line 1 and 2. possible_field_types[3].insert(ADDRESS_HOME_LINE2); @@ -1127,11 +1247,11 @@ // Adjust the expected upload proto. test::FillUploadField(upload.mutable_field_data(3), 509334676U, 31U); - EXPECT_THAT(EncodeUploadRequest(*form_structure, /*format_strings=*/{}, - available_field_types, + EXPECT_THAT(EncodeUploadRequest(*form_structure, encoder, + /*format_strings=*/{}, available_field_types, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true), - ElementsSerializeSameAs(upload)); + ElementsAre(WithoutMetadataSerializesSameAs(upload))); // Replace the address line 2 prediction by company name. possible_field_types[3].clear(); @@ -1144,11 +1264,11 @@ // Adjust the expected upload proto. upload.mutable_field_data(3)->set_autofill_type(1, 60); - EXPECT_THAT(EncodeUploadRequest(*form_structure, /*format_strings=*/{}, - available_field_types, + EXPECT_THAT(EncodeUploadRequest(*form_structure, encoder, + /*format_strings=*/{}, available_field_types, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true), - ElementsSerializeSameAs(upload)); + ElementsAre(WithoutMetadataSerializesSameAs(upload))); } TEST_F(AutofillCrowdsourcingEncoding, EncodeUploadRequest_PasswordsRevealed) { @@ -1164,8 +1284,12 @@ fs_field->set_host_form_signature(form_structure.form_signature()); } + RandomizedEncoder encoder("seed for testing", + AutofillRandomizedValue_EncodingType_ALL_BITS, + /*anonymous_url_collection_is_enabled=*/true); + std::vector<AutofillUploadContents> uploads = EncodeUploadRequest( - form_structure, /*format_strings=*/{}, + form_structure, encoder, /*format_strings=*/{}, /*available_field_types=*/{NO_SERVER_DATA}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true); ASSERT_EQ(1u, uploads.size()); @@ -1182,8 +1306,11 @@ for (auto& fs_field : form_structure) { fs_field->set_host_form_signature(form_structure.form_signature()); } + RandomizedEncoder encoder("seed for testing", + AutofillRandomizedValue_EncodingType_ALL_BITS, + /*anonymous_url_collection_is_enabled=*/true); std::vector<AutofillUploadContents> uploads = - EncodeUploadRequest(form_structure, /*format_strings=*/{}, + EncodeUploadRequest(form_structure, encoder, /*format_strings=*/{}, /*available_field_types=*/{NO_SERVER_DATA}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true); @@ -1325,14 +1452,12 @@ /*anonymous_url_collection_is_enabled=*/true); FormStructure form_structure(form); - form_structure.set_randomized_encoder( - std::make_unique<RandomizedEncoder>(encoder)); for (auto& field : form_structure) { field->set_host_form_signature(form_structure.form_signature()); } std::vector<AutofillUploadContents> uploads = EncodeUploadRequest( - form_structure, /*format_strings=*/{}, + form_structure, encoder, /*format_strings=*/{}, /*available_field_types=*/{NO_SERVER_DATA}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true); ASSERT_EQ(1u, uploads.size()); @@ -1516,14 +1641,12 @@ /*anonymous_url_collection_is_enabled=*/true); FormStructure form_structure(form); - form_structure.set_randomized_encoder( - std::make_unique<RandomizedEncoder>(encoder)); for (auto& field : form_structure) { field->set_host_form_signature(form_structure.form_signature()); } std::vector<AutofillUploadContents> uploads = EncodeUploadRequest( - form_structure, /*format_strings=*/{}, + form_structure, encoder, /*format_strings=*/{}, /*available_field_types=*/{NO_SERVER_DATA}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true); ASSERT_EQ(uploads.size(), 1u); @@ -1554,14 +1677,12 @@ /*anonymous_url_collection_is_enabled=*/true); FormStructure form_structure(form); - form_structure.set_randomized_encoder( - std::make_unique<RandomizedEncoder>(encoder)); for (auto& field : form_structure) { field->set_host_form_signature(form_structure.form_signature()); } std::vector<AutofillUploadContents> uploads = EncodeUploadRequest( - form_structure, /*format_strings=*/{}, + form_structure, encoder, /*format_strings=*/{}, /*available_field_types=*/{NO_SERVER_DATA}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true); ASSERT_EQ(uploads.size(), 1u); @@ -1599,9 +1720,9 @@ prefs.SetString(prefs::kAutofillUploadEncodingSeed, "user_secret"); FormStructure form_structure(form); - form_structure.set_randomized_encoder(RandomizedEncoder::Create(&prefs)); std::vector<AutofillUploadContents> uploads = EncodeUploadRequest( - form_structure, /*format_strings=*/{}, /*available_field_types=*/{}, + form_structure, *RandomizedEncoder::Create(&prefs), + /*format_strings=*/{}, /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true); EXPECT_EQ(has_consent, @@ -1627,8 +1748,12 @@ fs_field->set_host_form_signature(form_structure.form_signature()); } + RandomizedEncoder encoder("seed for testing", + AutofillRandomizedValue_EncodingType_ALL_BITS, + /*anonymous_url_collection_is_enabled=*/true); + std::vector<AutofillUploadContents> uploads = EncodeUploadRequest( - form_structure, /*format_strings=*/{}, + form_structure, encoder, /*format_strings=*/{}, /*available_field_types=*/{NO_SERVER_DATA}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true); ASSERT_EQ(1u, uploads.size()); @@ -1651,8 +1776,11 @@ EXPECT_EQ(FormSignature(1234u), form->form_signature()); ASSERT_EQ(3u, form->field_count()); ASSERT_EQ(FieldSignature(100u), form->field(2)->GetFieldSignature()); + RandomizedEncoder encoder("seed for testing", + AutofillRandomizedValue_EncodingType_ALL_BITS, + /*anonymous_url_collection_is_enabled=*/true); std::vector<AutofillUploadContents> uploads = EncodeUploadRequest( - *form, /*format_strings=*/{}, /*available_field_types=*/{}, + *form, encoder, /*format_strings=*/{}, /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true); ASSERT_EQ(1u, uploads.size()); @@ -1670,8 +1798,13 @@ for (auto& field : *form) { field->set_host_form_signature(form->form_signature()); } + + RandomizedEncoder encoder("seed for testing", + AutofillRandomizedValue_EncodingType_ALL_BITS, + /*anonymous_url_collection_is_enabled=*/true); + std::vector<AutofillUploadContents> uploads = EncodeUploadRequest( - *form, /*format_strings=*/{}, /*available_field_types=*/{}, + *form, encoder, /*format_strings=*/{}, /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true); ASSERT_EQ(1u, uploads.size()); static constexpr char kChromeVersionRegex[] = @@ -1717,8 +1850,12 @@ cached_form_structure, FormStructure::RetrieveFromCacheReason::kFormImport); + RandomizedEncoder encoder("seed for testing", + AutofillRandomizedValue_EncodingType_ALL_BITS, + /*anonymous_url_collection_is_enabled=*/true); + const std::vector<AutofillUploadContents> uploads = EncodeUploadRequest( - form_structure, + form_structure, encoder, /*format_strings=*/{}, /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true); ASSERT_EQ(uploads.size(), 1UL); @@ -1744,8 +1881,12 @@ FormData form = test::GetFormData({.fields = {{.role = NAME_FIRST}}}); FormStructure form_structure(form); + RandomizedEncoder encoder("seed for testing", + AutofillRandomizedValue_EncodingType_ALL_BITS, + /*anonymous_url_collection_is_enabled=*/true); + std::vector<AutofillUploadContents> uploads = EncodeUploadRequest( - form_structure, + form_structure, encoder, /*format_strings=*/{}, /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true); ASSERT_GE(uploads.size(), 1u); @@ -1757,7 +1898,7 @@ // fallback. form_structure.field(0)->set_autofilled_type(NAME_FULL); uploads = - EncodeUploadRequest(form_structure, + EncodeUploadRequest(form_structure, encoder, /*format_strings=*/{}, /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true);
diff --git a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager_unittest.cc b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager_unittest.cc index a9324d5..c687a69 100644 --- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager_unittest.cc +++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_manager_unittest.cc
@@ -297,6 +297,9 @@ SetCorrectFieldHostFormSignatures(*form_structure); } + std::unique_ptr<RandomizedEncoder> randomized_encoder = + RandomizedEncoder::Create(client().GetPrefs()); + auto crowdsourcing_manager = AutofillCrowdsourcingManagerTestApi::CreateManagerForApiKey(&client(), "dummykey"); @@ -321,7 +324,8 @@ // Request with id 1. std::vector<AutofillUploadContents> upload_contents_1 = EncodeUploadRequest( - *form_structures[0], /*format_strings=*/{}, /*available_field_types=*/{}, + *form_structures[0], *randomized_encoder, /*format_strings=*/{}, + /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true); EXPECT_TRUE(crowdsourcing_manager->StartUploadRequest( std::move(upload_contents_1), form_structures[0]->submission_source(), @@ -329,7 +333,8 @@ // Request with id 2. std::vector<AutofillUploadContents> upload_contents_2 = EncodeUploadRequest( - *form_structures[1], /*format_strings=*/{}, /*available_field_types=*/{}, + *form_structures[1], *randomized_encoder, /*format_strings=*/{}, + /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true); EXPECT_TRUE(crowdsourcing_manager->StartUploadRequest( std::move(upload_contents_2), form_structures[1]->submission_source(), @@ -337,7 +342,8 @@ // Request with id 3. Upload request with a non-empty additional password form // signature. std::vector<AutofillUploadContents> upload_contents_3 = EncodeUploadRequest( - *form_structures[2], /*format_strings=*/{}, /*available_field_types=*/{}, + *form_structures[2], *randomized_encoder, /*format_strings=*/{}, + /*available_field_types=*/{}, /*login_form_signature=*/FormSignature(42), /*observed_submission=*/true); EXPECT_TRUE(crowdsourcing_manager->StartUploadRequest( std::move(upload_contents_3), form_structures[1]->submission_source(), @@ -623,12 +629,16 @@ form_structure.set_submission_source(SubmissionSource::FORM_SUBMISSION); SetCorrectFieldHostFormSignatures(form_structure); + std::unique_ptr<RandomizedEncoder> randomized_encoder = + RandomizedEncoder::Create(client().GetPrefs()); + auto crowdsourcing_manager = AutofillCrowdsourcingManagerTestApi::CreateManagerForApiKey(&client(), "dummykey"); std::vector<AutofillUploadContents> upload_contents = EncodeUploadRequest( - form_structure, /*format_strings=*/{}, /*available_field_types=*/{}, + form_structure, *randomized_encoder, /*format_strings=*/{}, + /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true); EXPECT_TRUE(crowdsourcing_manager->StartUploadRequest( std::move(upload_contents), form_structure.submission_source(), @@ -719,9 +729,13 @@ form_structure.set_submission_source(SubmissionSource::FORM_SUBMISSION); SetCorrectFieldHostFormSignatures(form_structure); + std::unique_ptr<RandomizedEncoder> randomized_encoder = + RandomizedEncoder::Create(client().GetPrefs()); + // Request with id 0. std::vector<AutofillUploadContents> upload_contents = EncodeUploadRequest( - form_structure, /*format_strings=*/{}, /*available_field_types=*/{}, + form_structure, *randomized_encoder, /*format_strings=*/{}, + /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true); EXPECT_TRUE(crowdsourcing_manager().StartUploadRequest( std::move(upload_contents), form_structure.submission_source(), @@ -747,7 +761,8 @@ form_structure.set_submission_source(SubmissionSource::XHR_SUCCEEDED); base::HistogramTester histogram; std::vector<AutofillUploadContents> upload_contents_2 = EncodeUploadRequest( - form_structure, /*format_strings=*/{}, /*available_field_types=*/{}, + form_structure, *randomized_encoder, /*format_strings=*/{}, + /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true); EXPECT_TRUE(crowdsourcing_manager().StartUploadRequest( std::move(upload_contents_2), form_structure.submission_source(), @@ -820,9 +835,13 @@ form_structure.set_submission_source(SubmissionSource::FORM_SUBMISSION); SetCorrectFieldHostFormSignatures(form_structure); + std::unique_ptr<RandomizedEncoder> randomized_encoder = + RandomizedEncoder::Create(client().GetPrefs()); + // Request with id 0. std::vector<AutofillUploadContents> upload_contents = EncodeUploadRequest( - form_structure, /*format_strings=*/{}, /*available_field_types=*/{}, + form_structure, *randomized_encoder, /*format_strings=*/{}, + /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true); EXPECT_TRUE(crowdsourcing_manager().StartUploadRequest( std::move(upload_contents), form_structure.submission_source(), @@ -1178,6 +1197,7 @@ } bool SendUploadRequest(const FormStructure& form, + RandomizedEncoder& randomized_encoder, const FieldTypeSet& available_field_types, std::optional<FormSignature> login_form_signature, bool observed_submission, @@ -1189,9 +1209,9 @@ AutofillCrowdsourcingManager crowdsourcing_manager( &client(), version_info::Channel::UNKNOWN); - std::vector<AutofillUploadContents> upload_contents = - EncodeUploadRequest(form, /*format_strings=*/{}, available_field_types, - login_form_signature, observed_submission); + std::vector<AutofillUploadContents> upload_contents = EncodeUploadRequest( + form, randomized_encoder, /*format_strings=*/{}, available_field_types, + login_form_signature, observed_submission); bool succeeded = crowdsourcing_manager.StartUploadRequest( std::move(upload_contents), form.submission_source(), is_password_manager_upload); @@ -1250,12 +1270,14 @@ TEST_P(AutofillServerCommunicationTest, Upload) { AutofillCrowdsourcingManager crowdsourcing_manager( &client(), version_info::Channel::UNKNOWN); + std::unique_ptr<RandomizedEncoder> randomized_encoder = + RandomizedEncoder::Create(client().GetPrefs()); EXPECT_EQ(GetParam() != DISABLED, SendUploadRequest(FormStructure(test::GetFormData( {.fields = {{.role = NAME_FIRST}, {.role = NAME_LAST}, {.role = EMAIL_ADDRESS}}})), - /*available_field_types=*/{}, + *randomized_encoder, /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true, /*is_password_manager_upload=*/false)); @@ -1586,19 +1608,21 @@ SCOPED_TRACE(testing::Message() << "submission source = " << submission_source); form_structure.set_submission_source(submission_source); - form_structure.set_randomized_encoder( - RandomizedEncoder::Create(client().GetPrefs())); + std::unique_ptr<RandomizedEncoder> randomized_encoder = + RandomizedEncoder::Create(client().GetPrefs()); payloads().clear(); // The first attempt should succeed. - EXPECT_TRUE(SendUploadRequest(form_structure, /*available_field_types=*/{}, + EXPECT_TRUE(SendUploadRequest(form_structure, *randomized_encoder, + /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true, /*is_password_manager_upload=*/false)); // The second attempt should always fail. - EXPECT_FALSE(SendUploadRequest(form_structure, /*available_field_types=*/{}, + EXPECT_FALSE(SendUploadRequest(form_structure, *randomized_encoder, + /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true, /*is_password_manager_upload=*/false)); @@ -1661,15 +1685,19 @@ SCOPED_TRACE(testing::Message() << "submission source = " << submission_source); form_structure.set_submission_source(submission_source); + std::unique_ptr<RandomizedEncoder> randomized_encoder = + RandomizedEncoder::Create(client().GetPrefs()); // The first attempt should succeed. - EXPECT_TRUE(SendUploadRequest(form_structure, /*available_field_types=*/{}, + EXPECT_TRUE(SendUploadRequest(form_structure, *randomized_encoder, + /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true, /*is_password_manager_upload=*/false)); // The second attempt should always fail. - EXPECT_FALSE(SendUploadRequest(form_structure, /*available_field_types=*/{}, + EXPECT_FALSE(SendUploadRequest(form_structure, *randomized_encoder, + /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true, /*is_password_manager_upload=*/false)); @@ -1704,18 +1732,20 @@ SubmissionSource submission_source = SubmissionSource::FORM_SUBMISSION; form_structure.set_submission_source(submission_source); - form_structure.set_randomized_encoder( - RandomizedEncoder::Create(client().GetPrefs())); + std::unique_ptr<RandomizedEncoder> randomized_encoder = + RandomizedEncoder::Create(client().GetPrefs()); base::HistogramTester histogram_tester; // The first upload must be successfully sent to the Autofill server. - EXPECT_TRUE(SendUploadRequest(form_structure, /*available_field_types=*/{}, + EXPECT_TRUE(SendUploadRequest(form_structure, *randomized_encoder, + /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true, /*is_password_manager_upload=*/false)); // The second upload also must be successfully sent to the Autofill server. - EXPECT_TRUE(SendUploadRequest(form_structure, /*available_field_types=*/{}, + EXPECT_TRUE(SendUploadRequest(form_structure, *randomized_encoder, + /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true, /*is_password_manager_upload=*/false)); @@ -1776,13 +1806,17 @@ {.role = EMAIL_ADDRESS}}})); form_structure.set_submission_source(submission_source); + std::unique_ptr<RandomizedEncoder> randomized_encoder = + RandomizedEncoder::Create(client().GetPrefs()); + base::HistogramTester histogram_tester; TestAutofillClock test_clock; test_clock.SetNow(AutofillClock::Now()); // The first attempt should succeed. - EXPECT_TRUE(SendUploadRequest(form_structure, /*available_field_types=*/{}, + EXPECT_TRUE(SendUploadRequest(form_structure, *randomized_encoder, + /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true, /*is_password_manager_upload=*/false)); @@ -1790,7 +1824,8 @@ // Advance the clock, but not past the reset period. The pref won't reset, // so the upload should not be sent. test_clock.Advance(base::Days(15)); - EXPECT_FALSE(SendUploadRequest(form_structure, /*available_field_types=*/{}, + EXPECT_FALSE(SendUploadRequest(form_structure, *randomized_encoder, + /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true, /*is_password_manager_upload=*/false)); @@ -1798,7 +1833,8 @@ // Advance the clock beyond the reset period. The pref should be reset and // the upload should succeed. test_clock.Advance(base::Days(2)); // Total = 29 - EXPECT_TRUE(SendUploadRequest(form_structure, /*available_field_types=*/{}, + EXPECT_TRUE(SendUploadRequest(form_structure, *randomized_encoder, + /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true, /*is_password_manager_upload=*/false)); @@ -1829,20 +1865,25 @@ {.role = EMAIL_ADDRESS}}})); form_structure.set_submission_source(submission_source); + std::unique_ptr<RandomizedEncoder> randomized_encoder = + RandomizedEncoder::Create(client().GetPrefs()); + base::HistogramTester histogram_tester; TestAutofillClock test_clock; test_clock.SetNow(AutofillClock::Now()); // The first attempt should succeed. - EXPECT_TRUE(SendUploadRequest(form_structure, /*available_field_types=*/{}, + EXPECT_TRUE(SendUploadRequest(form_structure, *randomized_encoder, + /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true, /*is_password_manager_upload=*/false)); // Clear the upload throttling history. AutofillCrowdsourcingManager::ClearUploadHistory(client().GetPrefs()); - EXPECT_TRUE(SendUploadRequest(form_structure, /*available_field_types=*/{}, + EXPECT_TRUE(SendUploadRequest(form_structure, *randomized_encoder, + /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true, /*is_password_manager_upload=*/false)); @@ -1863,18 +1904,20 @@ SubmissionSource submission_source = SubmissionSource::FORM_SUBMISSION; form_structure.set_submission_source(submission_source); - form_structure.set_randomized_encoder( - RandomizedEncoder::Create(client().GetPrefs())); + std::unique_ptr<RandomizedEncoder> randomized_encoder = + RandomizedEncoder::Create(client().GetPrefs()); base::HistogramTester histogram_tester; // The first upload must be successfully sent to the Autofill server. - EXPECT_TRUE(SendUploadRequest(form_structure, /*available_field_types=*/{}, + EXPECT_TRUE(SendUploadRequest(form_structure, *randomized_encoder, + /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true, /*is_password_manager_upload=*/true)); // The second upload also must be successfully sent to the Autofill server. - EXPECT_TRUE(SendUploadRequest(form_structure, /*available_field_types=*/{}, + EXPECT_TRUE(SendUploadRequest(form_structure, *randomized_encoder, + /*available_field_types=*/{}, /*login_form_signature=*/std::nullopt, /*observed_submission=*/true, /*is_password_manager_upload=*/true));
diff --git a/components/autofill/core/browser/crowdsourcing/votes_uploader.cc b/components/autofill/core/browser/crowdsourcing/votes_uploader.cc index c1625ea..00f4d34b 100644 --- a/components/autofill/core/browser/crowdsourcing/votes_uploader.cc +++ b/components/autofill/core/browser/crowdsourcing/votes_uploader.cc
@@ -239,9 +239,6 @@ // Annotate the form with the source language of the page. form->set_current_page_language(current_page_language); - // Attach the Randomized Encoder. - form->set_randomized_encoder(RandomizedEncoder::Create(client_->GetPrefs())); - // Determine |ADDRESS_HOME_STATE| as a possible types for the fields in the // |form| with the help of |AlternativeStateNameMap|. // |AlternativeStateNameMap| can only be accessed on the main UI thread. @@ -254,7 +251,8 @@ const std::vector<CreditCard>& credit_cards, const std::u16string& last_unlocked_credit_card_cvc, const std::string& app_locale, bool observed_submission, - std::unique_ptr<FormStructure> form) { + std::unique_ptr<FormStructure> form, + std::unique_ptr<RandomizedEncoder> randomized_encoder) { DeterminePossibleFieldTypesForUpload(profiles, credit_cards, last_unlocked_credit_card_cvc, app_locale, *form); @@ -274,7 +272,7 @@ std::vector<AutofillUploadContents> upload_contents = EncodeUploadRequest( - *form, + *form, randomized_encoder.get(), DeterminePossibleFormatStringsForUpload(form->fields()), non_empty_types, /*login_form_signature=*/std::nullopt, observed_submission); @@ -282,7 +280,8 @@ }, std::move(copied_profiles), std::move(copied_credit_cards), last_unlocked_credit_card_cvc, client_->GetAppLocale(), - observed_submission, std::move(form)), + observed_submission, std::move(form), + RandomizedEncoder::Create(client_->GetPrefs())), base::BindOnce(&VotesUploader::OnFieldTypesDetermined, weak_ptr_factory_.GetWeakPtr(), initial_interaction_timestamp, base::TimeTicks::Now(),
diff --git a/components/autofill/core/browser/data_model/payments/credit_card.cc b/components/autofill/core/browser/data_model/payments/credit_card.cc index a592aeb..e23ee01 100644 --- a/components/autofill/core/browser/data_model/payments/credit_card.cc +++ b/components/autofill/core/browser/data_model/payments/credit_card.cc
@@ -1048,8 +1048,7 @@ if (HasNonEmptyValidNickname() || !customized_nickname.empty()) { return customized_nickname.empty() ? nickname_ : customized_nickname; } - if (base::FeatureList::IsEnabled(features::kAutofillEnableCardProductName) && - !product_description_.empty()) { + if (!product_description_.empty()) { return product_description_; } return NetworkForDisplay();
diff --git a/components/autofill/core/browser/data_model/payments/credit_card_unittest.cc b/components/autofill/core/browser/data_model/payments/credit_card_unittest.cc index 2689ad1..4c7a671 100644 --- a/components/autofill/core/browser/data_model/payments/credit_card_unittest.cc +++ b/components/autofill/core/browser/data_model/payments/credit_card_unittest.cc
@@ -295,10 +295,6 @@ // nickname and product description are unavailable. TEST(CreditCardTest, CardIdentifierStringsForAutofillDisplay_NoNicknameNoProductDescription) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - features::kAutofillEnableCardProductName); - CreditCard credit_card(base::Uuid::GenerateRandomV4().AsLowercaseString(), "https://www.example.com/"); test::SetCreditCardInfo(&credit_card, "John Dillinger", @@ -315,10 +311,6 @@ TEST( CreditCardTest, CardIdentifierStringsForAutofillDisplay_InvalidNicknameNoProductDescription) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - features::kAutofillEnableCardProductName); - CreditCard credit_card(base::Uuid::GenerateRandomV4().AsLowercaseString(), "https://www.example.com/"); test::SetCreditCardInfo(&credit_card, "John Dillinger", @@ -335,10 +327,6 @@ // nickname is unavailable. TEST(CreditCardTest, CardIdentifierStringsForAutofillDisplay_NoNicknameWithProductDescription) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - features::kAutofillEnableCardProductName); - std::u16string product_description = u"ABC bank XYZ card"; CreditCard credit_card(base::Uuid::GenerateRandomV4().AsLowercaseString(), @@ -359,10 +347,6 @@ TEST( CreditCardTest, CardIdentifierStringsForAutofillDisplay_InvalidNicknameWithProductDescription) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - features::kAutofillEnableCardProductName); - std::u16string product_description = u"ABC bank XYZ card"; CreditCard credit_card(base::Uuid::GenerateRandomV4().AsLowercaseString(), @@ -382,10 +366,6 @@ // Test that card identifier string shows nickname when it is valid. TEST(CreditCardTest, CardIdentifierStringsForAutofillDisplay_WithValidNickname) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - features::kAutofillEnableCardProductName); - std::u16string valid_nickname = u"My Visa Card"; CreditCard credit_card(base::Uuid::GenerateRandomV4().AsLowercaseString(), @@ -405,10 +385,6 @@ // Test that customized nickname takes precedence over credit card's nickname. TEST(CreditCardTest, CardIdentifierStringsForAutofillDisplay_WithCustomizedNickname) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - features::kAutofillEnableCardProductName); - std::u16string customized_nickname = u"My grocery shopping Visa card"; CreditCard credit_card(base::Uuid::GenerateRandomV4().AsLowercaseString(), @@ -503,10 +479,6 @@ // Test that the card number is formatted as per the obfuscation length. TEST(CreditCardTest, CardIdentifierStringsForAutofillDisplay_WithObfuscationLength) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - features::kAutofillEnableCardProductName); - int obfuscation_length = 2; CreditCard credit_card(base::Uuid::GenerateRandomV4().AsLowercaseString(),
diff --git a/components/autofill/core/browser/data_model/valuables/loyalty_card.cc b/components/autofill/core/browser/data_model/valuables/loyalty_card.cc index 6aa7ea1..2207841 100644 --- a/components/autofill/core/browser/data_model/valuables/loyalty_card.cc +++ b/components/autofill/core/browser/data_model/valuables/loyalty_card.cc
@@ -4,9 +4,13 @@ #include "components/autofill/core/browser/data_model/valuables/loyalty_card.h" +#include <string> + +#include "components/autofill/core/browser/data_model/valuables/valuable_types.h" + namespace autofill { -LoyaltyCard::LoyaltyCard(std::string id, +LoyaltyCard::LoyaltyCard(ValuableId id, std::string merchant_name, std::string program_name, GURL program_logo, @@ -23,7 +27,8 @@ LoyaltyCard::~LoyaltyCard() = default; bool LoyaltyCard::IsValid() const { - return !id_.empty() && (program_logo_.is_empty() || program_logo_.is_valid()); + return !id_->empty() && + (program_logo_.is_empty() || program_logo_.is_valid()); } } // namespace autofill
diff --git a/components/autofill/core/browser/data_model/valuables/loyalty_card.h b/components/autofill/core/browser/data_model/valuables/loyalty_card.h index 3d2d160..88529ad 100644 --- a/components/autofill/core/browser/data_model/valuables/loyalty_card.h +++ b/components/autofill/core/browser/data_model/valuables/loyalty_card.h
@@ -7,6 +7,7 @@ #include <string> +#include "components/autofill/core/browser/data_model/valuables/valuable_types.h" #include "url/gurl.h" namespace autofill { @@ -14,7 +15,7 @@ // Represents a loyalty card coming from the Google Wallet. class LoyaltyCard final { public: - LoyaltyCard(std::string loyalty_card_id, + LoyaltyCard(ValuableId loyalty_card_id, std::string merchant_name, std::string program_name, GURL program_logo, @@ -27,8 +28,8 @@ ~LoyaltyCard(); - const std::string& id() const { return id_; } - void set_id(const std::string& id) { id_ = id; } + const ValuableId& id() const { return id_; } + void set_id(const ValuableId& id) { id_ = id; } const std::string& merchant_name() const { return merchant_name_; } void set_merchant_name(const std::string& merchant_name) { @@ -62,8 +63,7 @@ private: // A unique identifier coming from the server, which is used as a primary key // for storing loyalty cards in the database. - std::string id_; - + ValuableId id_; // The merchant name e.g. "Deutsche Bahn". std::string merchant_name_;
diff --git a/components/autofill/core/browser/data_model/valuables/valuable_types.h b/components/autofill/core/browser/data_model/valuables/valuable_types.h new file mode 100644 index 0000000..a0080bc --- /dev/null +++ b/components/autofill/core/browser/data_model/valuables/valuable_types.h
@@ -0,0 +1,19 @@ +// Copyright 2025 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_DATA_MODEL_VALUABLES_VALUABLE_TYPES_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_DATA_MODEL_VALUABLES_VALUABLE_TYPES_H_ + +#include <string> + +#include "base/types/strong_alias.h" + +namespace autofill { + +// Id for valuables coming from Google Wallet. +using ValuableId = base::StrongAlias<class ValuableIdTag, std::string>; + +} // namespace autofill + +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_DATA_MODEL_VALUABLES_VALUABLE_TYPES_H_
diff --git a/components/autofill/core/browser/form_import/form_data_importer.cc b/components/autofill/core/browser/form_import/form_data_importer.cc index 33c1fa7b4..d7b466c 100644 --- a/components/autofill/core/browser/form_import/form_data_importer.cc +++ b/components/autofill/core/browser/form_import/form_data_importer.cc
@@ -52,7 +52,6 @@ #include "components/autofill/core/browser/metrics/profile_import_metrics.h" #include "components/autofill/core/browser/payments/credit_card_save_manager.h" #include "components/autofill/core/browser/payments/iban_save_manager.h" -#include "components/autofill/core/browser/payments/local_card_migration_manager.h" #include "components/autofill/core/browser/payments/mandatory_reauth_manager.h" #include "components/autofill/core/browser/payments/payments_autofill_client.h" #include "components/autofill/core/browser/payments/payments_network_interface.h" @@ -240,10 +239,6 @@ #if !BUILDFLAG(IS_IOS) iban_save_manager_(std::make_unique<IbanSaveManager>(client)), #endif // !BUILDFLAG(IS_IOS) -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - local_card_migration_manager_( - std::make_unique<LocalCardMigrationManager>(client)), -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) multistep_importer_(client_->GetAppLocale(), client_->GetVariationConfigCountryCode()) { address_data_manager_observation_.Observe(&address_data_manager()); @@ -860,19 +855,6 @@ return true; } -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - // A credit card was successfully extracted, but it's possible it is already a - // local or server card. First, check to see if we should offer local card - // migration in this case, as local cards could go either way. - if (local_card_migration_manager_ && - local_card_migration_manager_->ShouldOfferLocalCardMigration( - extracted_credit_card, credit_card_import_type_)) { - local_card_migration_manager_->AttemptToOfferLocalCardMigration( - /*is_from_settings_page=*/false); - return true; - } -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - // Proceed with card or CVC saving if applicable. return extracted_credit_card && credit_card_save_manager_->ProceedWithSavingIfApplicable(
diff --git a/components/autofill/core/browser/form_import/form_data_importer.h b/components/autofill/core/browser/form_import/form_data_importer.h index 03605578..c3b2d44 100644 --- a/components/autofill/core/browser/form_import/form_data_importer.h +++ b/components/autofill/core/browser/form_import/form_data_importer.h
@@ -32,7 +32,6 @@ class AutofillClient; class CreditCardSaveManager; class IbanSaveManager; -class LocalCardMigrationManager; class PaymentsDataManager; enum class NonInteractivePaymentMethodType; @@ -99,12 +98,6 @@ // them. void CacheFetchedVirtualCard(const std::u16string& last_four); -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - LocalCardMigrationManager* local_card_migration_manager() { - return local_card_migration_manager_.get(); - } -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - CreditCardSaveManager* GetCreditCardSaveManager() { return credit_card_save_manager_.get(); } @@ -332,11 +325,6 @@ // Responsible for managing IBAN save flows. It is guaranteed to be non-null. std::unique_ptr<IbanSaveManager> iban_save_manager_; -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - // Responsible for migrating locally saved credit cards to Google Pay. - std::unique_ptr<LocalCardMigrationManager> local_card_migration_manager_; -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - base::ScopedObservation<history::HistoryService, HistoryServiceObserver> history_service_observation_{this}; @@ -344,9 +332,9 @@ address_data_manager_observation_{this}; // Represents the type of the credit card import candidate from the submitted - // form. It will be used to determine whether to offer upload save or card - // migration. Will be passed to `credit_card_save_manager_` for metrics. If no - // credit card was found in the form, the type will be `kNoCard`. + // form. It will be used to determine whether to offer upload save or not. + // Will be passed to `credit_card_save_manager_` for metrics. If no credit + // card was found in the form, the type will be `kNoCard`. CreditCardImportType credit_card_import_type_ = CreditCardImportType::kNoCard; // Used to store the last four digits of the fetched virtual cards.
diff --git a/components/autofill/core/browser/form_import/form_data_importer_test_api.h b/components/autofill/core/browser/form_import/form_data_importer_test_api.h index f795d5d..9eea5d63 100644 --- a/components/autofill/core/browser/form_import/form_data_importer_test_api.h +++ b/components/autofill/core/browser/form_import/form_data_importer_test_api.h
@@ -12,7 +12,6 @@ #include "components/autofill/core/browser/form_import/form_data_importer.h" #include "components/autofill/core/browser/payments/credit_card_save_manager.h" #include "components/autofill/core/browser/payments/iban_save_manager.h" -#include "components/autofill/core/browser/payments/local_card_migration_manager.h" namespace autofill { @@ -39,14 +38,6 @@ fdi_->iban_save_manager_ = std::move(iban_save_manager); } -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - void set_local_card_migration_manager( - std::unique_ptr<LocalCardMigrationManager> local_card_migration_manager) { - fdi_->local_card_migration_manager_ = - std::move(local_card_migration_manager); - } -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - FormDataImporter::CreditCardImportType credit_card_import_type() const { return fdi_->credit_card_import_type_; }
diff --git a/components/autofill/core/browser/form_import/form_data_importer_unittest.cc b/components/autofill/core/browser/form_import/form_data_importer_unittest.cc index 9a7f977..d9bf3e6 100644 --- a/components/autofill/core/browser/form_import/form_data_importer_unittest.cc +++ b/components/autofill/core/browser/form_import/form_data_importer_unittest.cc
@@ -3782,11 +3782,6 @@ .set_credit_card_import_type( FormDataImporter::CreditCardImportType::kLocalCard); - // We need a sync service so that - // LocalCardMigrationManager::ShouldOfferLocalCardMigration() does not crash. - syncer::TestSyncService sync_service; - personal_data_manager().SetSyncServiceForTest(&sync_service); - EXPECT_FALSE( test_api(form_data_importer()) .ProcessExtractedCreditCard(*form_structure, extracted_credit_card, @@ -3810,12 +3805,6 @@ FormDataImporter::CreditCardImportType::kServerCard); form_data_importer().SetFetchedCardInstrumentId(2222); - // We need a sync service so that - // LocalCardMigrationManager::ShouldOfferLocalCardMigration() does not - // crash. - syncer::TestSyncService sync_service; - personal_data_manager().SetSyncServiceForTest(&sync_service); - EXPECT_CALL(virtual_card_enrollment_manager(), InitVirtualCardEnroll(_, VirtualCardEnrollmentSource::kDownstream, _, _, _, _))
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc index 19328199..630a0b4 100644 --- a/components/autofill/core/browser/form_structure.cc +++ b/components/autofill/core/browser/form_structure.cc
@@ -40,7 +40,6 @@ #include "build/build_config.h" #include "components/autofill/core/browser/autofill_field.h" #include "components/autofill/core/browser/autofill_type.h" -#include "components/autofill/core/browser/crowdsourcing/randomized_encoder.h" #include "components/autofill/core/browser/crowdsourcing/server_prediction_overrides.h" #include "components/autofill/core/browser/data_quality/autofill_data_util.h" #include "components/autofill/core/browser/data_quality/validation.h" @@ -895,11 +894,6 @@ return form_types; } -void FormStructure::set_randomized_encoder( - std::unique_ptr<RandomizedEncoder> encoder) { - randomized_encoder_ = std::move(encoder); -} - void FormStructure::RationalizePhoneNumberFieldsForFilling() { FormStructureRationalizer rationalizer(&fields_); rationalizer.RationalizePhoneNumbersForFilling();
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h index 7274906..54a025f3 100644 --- a/components/autofill/core/browser/form_structure.h +++ b/components/autofill/core/browser/form_structure.h
@@ -54,8 +54,6 @@ class FormData; struct FormDataPredictions; -class RandomizedEncoder; - // FormStructure stores a single HTML form together with the values entered // in the fields along with additional information needed by Autofill. class FormStructure { @@ -340,12 +338,6 @@ return developer_engagement_metrics_; } - void set_randomized_encoder(std::unique_ptr<RandomizedEncoder> encoder); - - base::optional_ref<const RandomizedEncoder> randomized_encoder() const { - return randomized_encoder_.get(); - } - const LanguageCode& current_page_language() const { return current_page_language_; } @@ -509,10 +501,6 @@ mojom::SubmissionSource submission_source_ = mojom::SubmissionSource::NONE; - // The randomized encoder to use to encode form metadata during upload. - // If this is nullptr, no randomized metadata will be sent. - std::unique_ptr<RandomizedEncoder> randomized_encoder_; - // True iff queries encoded from this form structure should include rich // form/field metadata. bool is_rich_query_enabled_ = false;
diff --git a/components/autofill/core/browser/foundations/browser_autofill_manager.cc b/components/autofill/core/browser/foundations/browser_autofill_manager.cc index b1af629..09afc34 100644 --- a/components/autofill/core/browser/foundations/browser_autofill_manager.cc +++ b/components/autofill/core/browser/foundations/browser_autofill_manager.cc
@@ -140,10 +140,12 @@ #include "components/autofill/core/common/form_data.h" #include "components/autofill/core/common/form_data_predictions.h" #include "components/autofill/core/common/form_field_data.h" +#include "components/autofill/core/common/logging/log_macros.h" #include "components/autofill/core/common/mojom/autofill_types.mojom-shared.h" #include "components/autofill/core/common/password_form_fill_data.h" #include "components/autofill/core/common/signatures.h" #include "components/autofill/core/common/unique_ids.h" +#include "components/optimization_guide/proto/features/model_prototyping.pb.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" #include "components/security_interstitials/core/pref_names.h" @@ -2134,9 +2136,20 @@ return; } - LOG_AF(log_manager()) << LoggingScope::kAutofillAi - << "Requesting model run for form." << Br{} << *form; - model_executor->GetPredictions(form->ToFormData()); + if (features::kAutofillAiServerModelSendPageContent.Get()) { + LOG_AF(log_manager()) + << LoggingScope::kAutofillAi + << "Requesting page page content for model run for form." << Br{} + << *form; + client().GetAiPageContent( + base::BindOnce(&AutofillAiModelExecutor::GetPredictions, + model_executor->GetWeakPtr(), form->ToFormData())); + } else { + LOG_AF(log_manager()) + << LoggingScope::kAutofillAi << "Requesting model run for form." + << Br{} << *form; + model_executor->GetPredictions(form->ToFormData(), {}); + } } }
diff --git a/components/autofill/core/browser/foundations/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/foundations/browser_autofill_manager_unittest.cc index 36a785d..1cdaff3f 100644 --- a/components/autofill/core/browser/foundations/browser_autofill_manager_unittest.cc +++ b/components/autofill/core/browser/foundations/browser_autofill_manager_unittest.cc
@@ -61,6 +61,7 @@ #include "components/autofill/core/browser/form_import/form_data_importer_test_api.h" #include "components/autofill/core/browser/form_structure.h" #include "components/autofill/core/browser/form_structure_test_api.h" +#include "components/autofill/core/browser/foundations/autofill_client.h" #include "components/autofill/core/browser/foundations/browser_autofill_manager_test_api.h" #include "components/autofill/core/browser/foundations/test_autofill_client.h" #include "components/autofill/core/browser/foundations/test_autofill_driver.h" @@ -180,8 +181,6 @@ using upload_contents_matchers::FormSignatureIs; using upload_contents_matchers::ObservedSubmissionIs; -const std::string kArbitraryNickname = "Grocery Card"; -const std::u16string kArbitraryNickname16 = u"Grocery Card"; constexpr Suggestion::Icon kAddressEntryIcon = Suggestion::Icon::kAccount; constexpr char kPlusAddress[] = "plus+remote@plus.plus"; @@ -202,11 +201,7 @@ bool ShouldSplitCardNameAndLastFourDigitsForMetadata() { // Splitting card name and last four logic does not apply to iOS because iOS // doesn't currently support it. -#if BUILDFLAG(IS_IOS) - return false; -#else - return base::FeatureList::IsEnabled(features::kAutofillEnableCardProductName); -#endif + return !BUILDFLAG(IS_IOS); } // The number of obfuscation dots we use as a prefix when showing a credit @@ -760,6 +755,7 @@ MockAutofillClient& operator=(const MockAutofillClient&) = delete; ~MockAutofillClient() override = default; + MOCK_METHOD(void, GetAiPageContent, (GetAiPageContentCallback), (override)); MOCK_METHOD(AutofillAiModelCache*, GetAutofillAiModelCache, (), (override)); MOCK_METHOD(AutofillAiModelExecutor*, GetAutofillAiModelExecutor, @@ -1450,41 +1446,6 @@ std::unique_ptr<MockAutofillDriver> driver_; }; -class SuggestionMatchingTest : public BrowserAutofillManagerTest, - public testing::WithParamInterface<bool> { - protected: - void SetUp() override { - BrowserAutofillManagerTest::SetUp(); - InitializeFeatures(); - } - bool IsMetadataEnabled() const { return GetParam(); } - void InitializeFeatures(); - - base::test::ScopedFeatureList features_; -}; - -#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) -void SuggestionMatchingTest::InitializeFeatures() {} -#else -void SuggestionMatchingTest::InitializeFeatures() { - features_.InitWithFeatureStates( - {{features::kAutofillEnableCardProductName, IsMetadataEnabled()}}); -} -#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) - -// Credit card suggestion tests related with keyboard accessory. -class CreditCardSuggestionTest : public BrowserAutofillManagerTest { - protected: - void SetUp() override { - BrowserAutofillManagerTest::SetUp(); - feature_list_card_metadata_and_product_name_.InitAndDisableFeature( - features::kAutofillEnableCardProductName); - } - - private: - base::test::ScopedFeatureList feature_list_card_metadata_and_product_name_; -}; - // Test that calling OnFormsSeen consecutively with a different set of forms // will query for each separately. TEST_F(BrowserAutofillManagerTest, OnFormsSeen_DifferentFormStructures) { @@ -1777,7 +1738,7 @@ // Test that we return all address profile suggestions when all form fields // are empty. -TEST_P(SuggestionMatchingTest, GetProfileSuggestions_EmptyValue) { +TEST_F(BrowserAutofillManagerTest, GetProfileSuggestions_EmptyValue) { // Set up our form data. FormData form = CreateTestAddressFormData(); FormsSeen({form}); @@ -1795,7 +1756,7 @@ // Test that we return only matching address profile suggestions when the // selected form field has been partially filled out. -TEST_P(SuggestionMatchingTest, GetProfileSuggestions_MatchCharacter) { +TEST_F(BrowserAutofillManagerTest, GetProfileSuggestions_MatchCharacter) { // Set up our form data. FormData form = CreateTestAddressFormData(); FormFieldData& firstname_field = test_api(form).field(0); @@ -1814,7 +1775,7 @@ // Tests that we return address profile suggestions values when the section // is already autofilled, and that we merge identical values. -TEST_P(SuggestionMatchingTest, +TEST_F(BrowserAutofillManagerTest, GetProfileSuggestions_AlreadyAutofilledMergeValues) { personal_data().test_address_data_manager().ClearProfiles(); // Set up our form data. @@ -1865,7 +1826,7 @@ // Tests that we return address field swapping suggestions when the field // is already autofilled. -TEST_P(SuggestionMatchingTest, +TEST_F(BrowserAutofillManagerTest, GetProfileSuggestions_AlreadyAutofilledNoLabels) { // Set up our form data. FormData form = CreateTestAddressFormData(); @@ -1929,7 +1890,7 @@ } // Test that we call duplicate profile suggestions. -TEST_P(SuggestionMatchingTest, GetProfileSuggestions_WithDuplicates) { +TEST_F(BrowserAutofillManagerTest, GetProfileSuggestions_WithDuplicates) { // Set up our form data. FormData form = CreateTestAddressFormData(); FormsSeen({form}); @@ -2017,15 +1978,7 @@ : public BrowserAutofillManagerTest, public testing::WithParamInterface<bool> { public: - BrowserAutofillManagerTestForMetadataCardSuggestions() { - card_metadata_flags_.InitWithFeatureState( - features::kAutofillEnableCardProductName, IsMetadataEnabled()); - } - - bool IsMetadataEnabled() const { return GetParam(); } - - private: - base::test::ScopedFeatureList card_metadata_flags_; + BrowserAutofillManagerTestForMetadataCardSuggestions() = default; }; INSTANTIATE_TEST_SUITE_P(All, @@ -2166,106 +2119,6 @@ /*with_gpay_logo=*/false)}); } -// Test that we return credit card profile suggestions when the selected form -// field is the credit card number field. -TEST_F(CreditCardSuggestionTest, GetCreditCardSuggestions_CCNumber) { - // Set nickname with the corresponding guid of the Mastercard 8765. - personal_data().test_payments_data_manager().SetNicknameForCardWithGUID( - MakeGuid(5), kArbitraryNickname); - // Set up our form data. - FormData form = - CreateTestCreditCardFormData(/*is_https=*/true, /*use_month_type=*/false); - FormsSeen({form}); - - const FormFieldData& credit_card_number_field = form.fields()[1]; - OnAskForValuesToFill(form, credit_card_number_field); - const std::string visa_value = - std::string("Visa ") + - test::ObfuscatedCardDigitsAsUTF8( - "3456", ObfuscationLengthForCreditCardLastFourDigits()); - // Mastercard has a valid nickname. Display nickname + last four in the - // suggestion title. - const std::string master_card_value = - kArbitraryNickname + " " + - test::ObfuscatedCardDigitsAsUTF8( - "8765", ObfuscationLengthForCreditCardLastFourDigits()); - -#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) - const std::string visa_label = std::string("04/99"); - const std::string master_card_label = std::string("10/98"); -#else - const std::string visa_label = std::string("Expires on 04/99"); - const std::string master_card_label = std::string("Expires on 10/98"); -#endif - - // Test that we sent the right values to the external delegate. - external_delegate()->CheckSuggestions( - credit_card_number_field.global_id(), - {Suggestion(visa_value, visa_label, Suggestion::Icon::kCardVisa, - SuggestionType::kCreditCardEntry), - Suggestion(master_card_value, master_card_label, - Suggestion::Icon::kCardMasterCard, - SuggestionType::kCreditCardEntry), - CreateSeparator(), - CreateManageCreditCardsSuggestion( - /*with_gpay_logo=*/false)}); -} - -// Test that we return credit card profile suggestions when the selected form -// field is not the credit card number field. -TEST_F(CreditCardSuggestionTest, GetCreditCardSuggestions_NonCCNumber) { - // Set nickname with the corresponding guid of the Mastercard 8765. - personal_data().test_payments_data_manager().SetNicknameForCardWithGUID( - MakeGuid(5), kArbitraryNickname); - // Set up our form data. - FormData form = - CreateTestCreditCardFormData(/*is_https=*/true, /*use_month_type=*/false); - FormsSeen({form}); - - const FormFieldData& cardholder_name_field = form.fields()[0]; - OnAskForValuesToFill(form, cardholder_name_field); - - const std::string obfuscated_last_four_digits1 = - test::ObfuscatedCardDigitsAsUTF8( - "3456", ObfuscationLengthForCreditCardLastFourDigits()); - const std::string obfuscated_last_four_digits2 = - test::ObfuscatedCardDigitsAsUTF8( - "8765", ObfuscationLengthForCreditCardLastFourDigits()); - -#if BUILDFLAG(IS_ANDROID) - // For Android always show obfuscated last four. - const std::string visa_label = obfuscated_last_four_digits1; - // Mastercard has a valid nickname. - const std::string master_card_label = obfuscated_last_four_digits2; - -#elif BUILDFLAG(IS_IOS) - const std::string visa_label = obfuscated_last_four_digits1; - const std::string master_card_label = obfuscated_last_four_digits2; - -#else - // If no nickname available, we will show network. - const std::string visa_label = base::JoinString( - {"Visa ", obfuscated_last_four_digits1, ", expires on 04/99"}, ""); - // When nickname is available, show nickname. Otherwise, show network. - const std::string master_card_label = - base::JoinString({kArbitraryNickname + " ", obfuscated_last_four_digits2, - ", expires on 10/98"}, - ""); -#endif - - // Test that we sent the right values to the external delegate. - external_delegate()->CheckSuggestions( - cardholder_name_field.global_id(), - {Suggestion("Elvis Presley", visa_label, Suggestion::Icon::kCardVisa, - SuggestionType::kCreditCardEntry), - Suggestion("Buddy Holly", master_card_label, - Suggestion::Icon::kCardMasterCard, - SuggestionType::kCreditCardEntry), - CreateSeparator(), - CreateManageCreditCardsSuggestion( - /*with_gpay_logo=*/false)}); -} - // Test that we return a warning explaining that credit card profile suggestions // are unavailable when the page is secure, but the form action URL is valid but // not secure. @@ -2569,7 +2422,7 @@ } // Test that we return profile and credit card suggestions for combined forms. -TEST_P(SuggestionMatchingTest, GetAddressAndCreditCardSuggestions) { +TEST_F(BrowserAutofillManagerTest, GetAddressAndCreditCardSuggestions) { // Set up our form data. FormData form = CreateTestAddressFormData(); const size_t first_credit_card_field = form.fields().size(); @@ -3143,7 +2996,7 @@ // Test that we return normal Autofill suggestions when trying to autofill // already filled forms. -TEST_P(SuggestionMatchingTest, GetFieldSuggestionsWhenFormIsAutofilled) { +TEST_F(BrowserAutofillManagerTest, GetFieldSuggestionsWhenFormIsAutofilled) { // Set up our form data. FormData form = CreateTestAddressFormData(); FormsSeen({form}); @@ -3167,7 +3020,7 @@ #if !BUILDFLAG(IS_ANDROID) // Test that we do not return duplicate values drawn from multiple profiles when // filling an already filled field. -TEST_P(SuggestionMatchingTest, GetFieldSuggestionsWithDuplicateValues) { +TEST_F(BrowserAutofillManagerTest, GetFieldSuggestionsWithDuplicateValues) { // Set up our form data. FormData form = CreateTestAddressFormData(); FormsSeen({form}); @@ -5644,8 +5497,6 @@ TEST_F(BrowserAutofillManagerTest, GetCreditCardSuggestions_VirtualCard_MetadataEnabled) { base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - features::kAutofillEnableCardProductName); personal_data().test_payments_data_manager().ClearCreditCards(); CreditCard masked_server_card(CreditCard::RecordType::kMaskedServerCard, /*server_id=*/"a123"); @@ -7055,18 +6906,36 @@ base::test::ScopedFeatureList feature_list_; AutofillWebDataServiceTestHelper webdata_helper_{ std::make_unique<EntityTable>()}; - MockAutofillAiModelCache cache_; - MockAutofillAiModelExecutor executor_; + NiceMock<MockAutofillAiModelCache> cache_; + NiceMock<MockAutofillAiModelExecutor> executor_; }; // Tests that the Autofill AI server model is run if cache and model are // available and the form is not contained in the cache. TEST_F(BrowserAutofillManagerWithAiModelTest, AutofillAiServerModelRun) { ON_CALL(cache(), Contains).WillByDefault(Return(false)); + EXPECT_CALL(client(), GetAiPageContent).Times(0); EXPECT_CALL(executor(), GetPredictions); SeeForm(/*may_run_model=*/true); } +// Tests that BAM requests annotated page content and passes it on to the +// model executor if kAutofillAiServerModelSendPageContent is true. +TEST_F(BrowserAutofillManagerWithAiModelTest, + AutofillAiServerModelReceivesAnnotatedPageContent) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeatureWithParameters( + features::kAutofillAiServerModel, + {{"autofill_ai_model_send_apc", "true"}}); + + ON_CALL(cache(), Contains).WillByDefault(Return(false)); + EXPECT_CALL(client(), GetAiPageContent) + .WillOnce(RunOnceCallback<0>( + optimization_guide::proto::AnnotatedPageContent())); + EXPECT_CALL(executor(), GetPredictions(_, Not(Eq(std::nullopt)))); + SeeForm(/*may_run_model=*/true); +} + // Tests that the Autofill AI server model is not run if the form is already // contained in the cache. TEST_F(BrowserAutofillManagerWithAiModelTest, @@ -7288,25 +7157,18 @@ INSTANTIATE_TEST_SUITE_P(All, OnFocusOnFormFieldTest, testing::Bool()); -#if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) -INSTANTIATE_TEST_SUITE_P(, SuggestionMatchingTest, testing::Values(false)); -#else -INSTANTIATE_TEST_SUITE_P(All, SuggestionMatchingTest, testing::Bool()); -#endif // BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) - struct ShareNicknameTestParam { std::string local_nickname; std::string server_nickname; std::string expected_nickname; - bool metadata_enabled; }; const ShareNicknameTestParam kShareNicknameTestParam[] = { - {"", "", "", false}, - {"", "server nickname", "server nickname", false}, - {"local nickname", "", "local nickname", false}, - {"local nickname", "server nickname", "local nickname", false}, - {"local nickname", "server nickname", "local nickname", true}, + {"", "", ""}, + {"", "server nickname", "server nickname"}, + {"local nickname", "", "local nickname"}, + {"local nickname", "server nickname", "local nickname"}, + {"local nickname", "server nickname", "local nickname"}, }; class BrowserAutofillManagerTestForSharingNickname @@ -7316,10 +7178,7 @@ BrowserAutofillManagerTestForSharingNickname() : local_nickname_(GetParam().local_nickname), server_nickname_(GetParam().server_nickname), - expected_nickname_(GetParam().expected_nickname) { - card_metadata_flags_.InitWithFeatureState( - features::kAutofillEnableCardProductName, GetParam().metadata_enabled); - } + expected_nickname_(GetParam().expected_nickname) {} CreditCard GetLocalCard() { CreditCard local_card("287151C8-6AB1-487C-9095-28E80BE5DA15",
diff --git a/components/autofill/core/browser/foundations/test_autofill_client.h b/components/autofill/core/browser/foundations/test_autofill_client.h index 9e325baa..d478b3e 100644 --- a/components/autofill/core/browser/foundations/test_autofill_client.h +++ b/components/autofill/core/browser/foundations/test_autofill_client.h
@@ -38,7 +38,6 @@ #include "components/autofill/core/browser/logging/text_log_receiver.h" #include "components/autofill/core/browser/metrics/autofill_metrics.h" #include "components/autofill/core/browser/metrics/form_interactions_ukm_logger.h" -#include "components/autofill/core/browser/payments/local_card_migration_manager.h" #include "components/autofill/core/browser/payments/test_payments_autofill_client.h" #include "components/autofill/core/browser/permissions/autofill_ai/autofill_ai_permission_utils.h" #include "components/autofill/core/browser/single_field_fillers/autocomplete/mock_autocomplete_history_manager.h" @@ -650,8 +649,6 @@ // Test addresses used to allow developers to test their forms. std::vector<AutofillProfile> test_addresses_; - std::vector<std::string> migration_card_selection_; - std::vector<Suggestion> suggestions_; // A mock translate driver which provides the language state.
diff --git a/components/autofill/core/browser/metrics/payments/card_metadata_metrics.cc b/components/autofill/core/browser/metrics/payments/card_metadata_metrics.cc index 3f41f717..4a497fc 100644 --- a/components/autofill/core/browser/metrics/payments/card_metadata_metrics.cc +++ b/components/autofill/core/browser/metrics/payments/card_metadata_metrics.cc
@@ -112,9 +112,7 @@ // `metadata_logging_context` that we have shown at least one product // description so we can log it later. if (!card.product_description().empty()) { - metadata_logging_context.card_product_description_shown = - base::FeatureList::IsEnabled( - features::kAutofillEnableCardProductName); + metadata_logging_context.card_product_description_shown = true; } // If there is rich card art we received from the metadata for this card,
diff --git a/components/autofill/core/browser/metrics/payments/card_metadata_metrics_unittest.cc b/components/autofill/core/browser/metrics/payments/card_metadata_metrics_unittest.cc index 46c0a4b..77150ea6 100644 --- a/components/autofill/core/browser/metrics/payments/card_metadata_metrics_unittest.cc +++ b/components/autofill/core/browser/metrics/payments/card_metadata_metrics_unittest.cc
@@ -469,27 +469,23 @@ } // Params: -// 1) Whether card product name feature flag is enabled. -// 2) Whether card metadata (both product name and card art image) are provided. -// 3) Whether the card has linked virtual card (only card art is provided). +// 1) Whether card metadata (both product name and card art image) are provided. +// 2) Whether the card has linked virtual card (only card art is provided). class CardMetadataLatencyMetricsTest : public AutofillMetricsBaseTest, public testing::Test, - public testing::WithParamInterface<std::tuple<bool, bool, bool>> { + public testing::WithParamInterface<std::tuple<bool, bool>> { public: CardMetadataLatencyMetricsTest() = default; ~CardMetadataLatencyMetricsTest() override = default; - bool card_product_name_enabled() { return std::get<0>(GetParam()); } - bool card_metadata_available() { return std::get<1>(GetParam()); } - bool card_has_static_art_image() { return std::get<2>(GetParam()); } + bool card_metadata_available() { return std::get<0>(GetParam()); } + bool card_has_static_art_image() { return std::get<1>(GetParam()); } FormData form() { return form_; } void SetUp() override { SetUpHelper(); - feature_list_card_product_name_.InitWithFeatureState( - features::kAutofillEnableCardProductName, card_product_name_enabled()); // Set up the form data. Reset form action to skip the IsFormMixedContent // check. form_ = @@ -530,7 +526,6 @@ INSTANTIATE_TEST_SUITE_P(All, CardMetadataLatencyMetricsTest, testing::Combine(testing::Bool(), - testing::Bool(), testing::Bool())); // Test to ensure that we log card metadata related metrics only when card @@ -555,18 +550,13 @@ "Autofill.CreditCard.SelectionLatencySinceShown."; std::string latency_histogram_suffix; - // Card product name is shown when card_metadata_available() and - // card_product_name_enabled() both return true. + // Card product name is shown when card_metadata_available() return true. // Card art image is shown when 1. card_has_linked_virtual_card() or // 2. card_metadata_available() returns true. // TODO(crbug.com/387391138): Determine appropriate cases and modify test // coverage accordingly. if (card_metadata_available()) { - if (card_product_name_enabled()) { - latency_histogram_suffix = kProductNameAndArtImageBothShownSuffix; - } else { - latency_histogram_suffix = kArtImageShownOnlySuffix; - } + latency_histogram_suffix = kProductNameAndArtImageBothShownSuffix; } else { latency_histogram_suffix = kProductNameAndArtImageNotShownSuffix; } @@ -1222,10 +1212,9 @@ Bucket(FORM_EVENT_LOCAL_SUGGESTION_FILLED, 1))); EXPECT_THAT( histogram_tester.GetAllSamples("Autofill.FormEvents.CreditCard"), - BucketsInclude( - Bucket( - FORM_EVENT_SUGGESTION_FOR_SERVER_CARD_WITH_BENEFIT_AVAILABLE_FILLED, - 1))); + BucketsInclude(Bucket( + FORM_EVENT_SUGGESTION_FOR_SERVER_CARD_WITH_BENEFIT_AVAILABLE_FILLED, + 1))); } // Tests that when a form is submitted after a masked server card with a
diff --git a/components/autofill/core/browser/metrics/payments/local_card_migration_metrics.cc b/components/autofill/core/browser/metrics/payments/local_card_migration_metrics.cc deleted file mode 100644 index a60f193b..0000000 --- a/components/autofill/core/browser/metrics/payments/local_card_migration_metrics.cc +++ /dev/null
@@ -1,113 +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 "components/autofill/core/browser/metrics/payments/local_card_migration_metrics.h" - -#include "base/metrics/histogram_functions.h" -#include "base/metrics/histogram_macros.h" - -namespace autofill::autofill_metrics { - -void LogLocalCardMigrationBubbleOfferMetric( - LocalCardMigrationBubbleOfferMetric metric, - bool is_reshow) { - DCHECK_LT(metric, NUM_LOCAL_CARD_MIGRATION_BUBBLE_OFFER_METRICS); - std::string histogram_name = "Autofill.LocalCardMigrationBubbleOffer."; - histogram_name += is_reshow ? "Reshows" : "FirstShow"; - base::UmaHistogramEnumeration(histogram_name, metric, - NUM_LOCAL_CARD_MIGRATION_BUBBLE_OFFER_METRICS); -} - -void LogLocalCardMigrationBubbleResultMetric( - LocalCardMigrationBubbleResultMetric metric, - bool is_reshow) { - DCHECK_LT(metric, NUM_LOCAL_CARD_MIGRATION_BUBBLE_RESULT_METRICS); - std::string suffix = is_reshow ? ".Reshows" : ".FirstShow"; - base::UmaHistogramEnumeration( - "Autofill.LocalCardMigrationBubbleResult" + suffix, metric, - NUM_LOCAL_CARD_MIGRATION_BUBBLE_RESULT_METRICS); -} - -void LogLocalCardMigrationDecisionMetric( - LocalCardMigrationDecisionMetric metric) { - UMA_HISTOGRAM_ENUMERATION("Autofill.LocalCardMigrationDecision", metric); -} - -void LogLocalCardMigrationDialogOfferMetric( - LocalCardMigrationDialogOfferMetric metric) { - DCHECK_LT(metric, NUM_LOCAL_CARD_MIGRATION_DIALOG_OFFER_METRICS); - std::string histogram_name = "Autofill.LocalCardMigrationDialogOffer"; - base::UmaHistogramEnumeration(histogram_name, metric, - NUM_LOCAL_CARD_MIGRATION_DIALOG_OFFER_METRICS); -} - -void LogLocalCardMigrationDialogUserInteractionMetric( - base::TimeDelta duration, - LocalCardMigrationDialogUserInteractionMetric metric) { - DCHECK_LT(metric, NUM_LOCAL_CARD_MIGRATION_DIALOG_USER_INTERACTION_METRICS); - base::UmaHistogramEnumeration( - "Autofill.LocalCardMigrationDialogUserInteraction", metric, - NUM_LOCAL_CARD_MIGRATION_DIALOG_USER_INTERACTION_METRICS); - - // Do not log duration metrics for - // LOCAL_CARD_MIGRATION_DIALOG_DELETE_CARD_ICON_CLICKED, as it can happen - // multiple times in one dialog. - std::string suffix; - switch (metric) { - case LOCAL_CARD_MIGRATION_DIALOG_CLOSED_SAVE_BUTTON_CLICKED: - suffix = "Accepted"; - break; - case LOCAL_CARD_MIGRATION_DIALOG_CLOSED_CANCEL_BUTTON_CLICKED: - suffix = "Denied"; - break; - case LOCAL_CARD_MIGRATION_DIALOG_CLOSED_VIEW_CARDS_BUTTON_CLICKED: - case LOCAL_CARD_MIGRATION_DIALOG_CLOSED_DONE_BUTTON_CLICKED: - suffix = "Closed"; - break; - default: - return; - } - - base::UmaHistogramLongTimes( - "Autofill.LocalCardMigrationDialogActiveDuration." + suffix, duration); -} - -void LogLocalCardMigrationDialogUserSelectionPercentageMetric(int selected, - int total) { - UMA_HISTOGRAM_PERCENTAGE( - "Autofill.LocalCardMigrationDialogUserSelectionPercentage", - 100 * selected / total); -} - -void LogLocalCardMigrationNotOfferedDueToMaxStrikesMetric( - AutofillMetrics::SaveTypeMetric metric) { - UMA_HISTOGRAM_ENUMERATION( - "Autofill.StrikeDatabase.LocalCardMigrationNotOfferedDueToMaxStrikes", - metric); -} - -void LogLocalCardMigrationPromptMetric( - LocalCardMigrationOrigin local_card_migration_origin, - LocalCardMigrationPromptMetric metric) { - DCHECK_LT(metric, NUM_LOCAL_CARD_MIGRATION_PROMPT_METRICS); - std::string histogram_name = "Autofill.LocalCardMigrationOrigin."; - // Switch to different sub-histogram depending on local card migration origin. - switch (local_card_migration_origin) { - case LocalCardMigrationOrigin::UseOfLocalCard: - histogram_name += "UseOfLocalCard"; - break; - case LocalCardMigrationOrigin::UseOfServerCard: - histogram_name += "UseOfServerCard"; - break; - case LocalCardMigrationOrigin::SettingsPage: - histogram_name += "SettingsPage"; - break; - default: - NOTREACHED(); - } - base::UmaHistogramEnumeration(histogram_name, metric, - NUM_LOCAL_CARD_MIGRATION_PROMPT_METRICS); -} - -} // namespace autofill::autofill_metrics
diff --git a/components/autofill/core/browser/metrics/payments/local_card_migration_metrics.h b/components/autofill/core/browser/metrics/payments/local_card_migration_metrics.h deleted file mode 100644 index 68156d6..0000000 --- a/components/autofill/core/browser/metrics/payments/local_card_migration_metrics.h +++ /dev/null
@@ -1,176 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_PAYMENTS_LOCAL_CARD_MIGRATION_METRICS_H_ -#define COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_PAYMENTS_LOCAL_CARD_MIGRATION_METRICS_H_ - -#include "base/time/time.h" -#include "components/autofill/core/browser/metrics/autofill_metrics.h" - -namespace autofill::autofill_metrics { - -// Metrics to track events when local credit card migration is offered. -enum LocalCardMigrationBubbleOfferMetric { - // These values are persisted to logs. Entries should not be renumbered and - // numeric values should never be reused. - - // The bubble is requested due to a credit card being used or - // local card migration icon in the omnibox being clicked. - LOCAL_CARD_MIGRATION_BUBBLE_REQUESTED = 0, - // The bubble is actually shown to the user. - LOCAL_CARD_MIGRATION_BUBBLE_SHOWN = 1, - NUM_LOCAL_CARD_MIGRATION_BUBBLE_OFFER_METRICS, -}; - -// Metrics to track user action result of the bubble when the bubble is -// closed. -enum LocalCardMigrationBubbleResultMetric { - // These values are persisted to logs. Entries should not be renumbered and - // numeric values should never be reused. - - // The user explicitly accepted the offer. - LOCAL_CARD_MIGRATION_BUBBLE_ACCEPTED = 0, - // The user explicitly closed the bubble with the close button or ESC. - LOCAL_CARD_MIGRATION_BUBBLE_CLOSED = 1, - // The user did not interact with the bubble. - LOCAL_CARD_MIGRATION_BUBBLE_NOT_INTERACTED = 2, - // The bubble lost its focus and was deactivated. - LOCAL_CARD_MIGRATION_BUBBLE_LOST_FOCUS = 3, - // The reason why the prompt is closed is not clear. Possible reason is the - // logging function is invoked before the closed reason is correctly set. - LOCAL_CARD_MIGRATION_BUBBLE_RESULT_UNKNOWN = 4, - NUM_LOCAL_CARD_MIGRATION_BUBBLE_RESULT_METRICS, -}; - -// Metrics to record the decision on whether to offer local card migration. -enum class LocalCardMigrationDecisionMetric { - // These values are persisted to logs. Entries should not be renumbered and - // numeric values should never be reused. - - // All the required conditions are satisfied and main prompt is shown. - OFFERED = 0, - // Migration not offered because user uses new card. - NOT_OFFERED_USE_NEW_CARD = 1, - // Migration not offered because failed migration prerequisites. - NOT_OFFERED_FAILED_PREREQUISITES = 2, - // The Autofill StrikeDatabase decided not to allow offering migration - // because max strike count was reached. - NOT_OFFERED_REACHED_MAX_STRIKE_COUNT = 3, - // Migration not offered because no migratable cards. - NOT_OFFERED_NO_MIGRATABLE_CARDS = 4, - // Met the migration requirements but the request to Payments for upload - // details failed. - NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED = 5, - // Abandoned the migration because no supported local cards were left after - // filtering out unsupported cards. - NOT_OFFERED_NO_SUPPORTED_CARDS = 6, - // User used a local card and they only have a single migratable local card - // on file, we will offer Upstream instead. - NOT_OFFERED_SINGLE_LOCAL_CARD = 7, - // User used an unsupported local card, we will abort the migration. - NOT_OFFERED_USE_UNSUPPORTED_LOCAL_CARD = 8, - // Legal message was invalid, we will abort the migration. - NOT_OFFERED_INVALID_LEGAL_MESSAGE = 9, - kMaxValue = NOT_OFFERED_INVALID_LEGAL_MESSAGE, -}; - -// Metrics to track events when local card migration dialog is offered. -enum LocalCardMigrationDialogOfferMetric { - // These values are persisted to logs. Entries should not be renumbered and - // numeric values should never be reused. - - // The dialog is shown to the user. - LOCAL_CARD_MIGRATION_DIALOG_SHOWN = 0, - // The dialog is not shown due to legal message being invalid. - LOCAL_CARD_MIGRATION_DIALOG_NOT_SHOWN_INVALID_LEGAL_MESSAGE = 1, - // The dialog is shown when migration feedback is available. - LOCAL_CARD_MIGRATION_DIALOG_FEEDBACK_SHOWN = 2, - // The dialog is shown when migration fails due to server error. - LOCAL_CARD_MIGRATION_DIALOG_FEEDBACK_SERVER_ERROR_SHOWN = 3, - NUM_LOCAL_CARD_MIGRATION_DIALOG_OFFER_METRICS, -}; - -// Metrics to track user interactions with the dialog. -enum LocalCardMigrationDialogUserInteractionMetric { - // These values are persisted to logs. Entries should not be renumbered and - // numeric values should never be reused. - - // The user explicitly accepts the offer by clicking the save button. - LOCAL_CARD_MIGRATION_DIALOG_CLOSED_SAVE_BUTTON_CLICKED = 0, - // The user explicitly denies the offer by clicking the cancel button. - LOCAL_CARD_MIGRATION_DIALOG_CLOSED_CANCEL_BUTTON_CLICKED = 1, - // The user clicks the legal message. - LOCAL_CARD_MIGRATION_DIALOG_LEGAL_MESSAGE_CLICKED = 2, - // The user clicks the view card button after successfully migrated cards. - LOCAL_CARD_MIGRATION_DIALOG_CLOSED_VIEW_CARDS_BUTTON_CLICKED = 3, - // The user clicks the done button to close dialog after migration. - LOCAL_CARD_MIGRATION_DIALOG_CLOSED_DONE_BUTTON_CLICKED = 4, - // The user clicks the trash icon to delete invalid card. - LOCAL_CARD_MIGRATION_DIALOG_DELETE_CARD_ICON_CLICKED = 5, - NUM_LOCAL_CARD_MIGRATION_DIALOG_USER_INTERACTION_METRICS, -}; - -// These metrics are logged for each local card migration origin. These are -// used to derive the conversion rate for each triggering source. -enum LocalCardMigrationPromptMetric { - // These values are persisted to logs. Entries should not be renumbered and - // numeric values should never be reused. - - // The intermediate bubble is shown to the user. - INTERMEDIATE_BUBBLE_SHOWN = 0, - // The intermediate bubble is accepted by the user. - INTERMEDIATE_BUBBLE_ACCEPTED = 1, - // The main dialog is shown to the user. - MAIN_DIALOG_SHOWN = 2, - // The main dialog is accepted by the user. - MAIN_DIALOG_ACCEPTED = 3, - NUM_LOCAL_CARD_MIGRATION_PROMPT_METRICS, -}; - -// Local card migration origin denotes from where the migration is triggered. -enum LocalCardMigrationOrigin { - // These values are persisted to logs. Entries should not be renumbered and - // numeric values should never be reused. - - // Trigger when user submitted a form using local card. - UseOfLocalCard, - // Trigger when user submitted a form using server card. - UseOfServerCard, - // Trigger from settings page. - SettingsPage, -}; - -void LogLocalCardMigrationBubbleOfferMetric( - LocalCardMigrationBubbleOfferMetric metric, - bool is_reshow); - -void LogLocalCardMigrationBubbleResultMetric( - LocalCardMigrationBubbleResultMetric metric, - bool is_reshow); - -void LogLocalCardMigrationDecisionMetric( - LocalCardMigrationDecisionMetric metric); - -void LogLocalCardMigrationDialogOfferMetric( - LocalCardMigrationDialogOfferMetric metric); - -void LogLocalCardMigrationDialogUserInteractionMetric( - base::TimeDelta duration, - LocalCardMigrationDialogUserInteractionMetric metric); - -void LogLocalCardMigrationDialogUserSelectionPercentageMetric(int selected, - int total); - -// When local card migration is not offered due to max strike limit reached, -// logs the occurrence. -void LogLocalCardMigrationNotOfferedDueToMaxStrikesMetric( - AutofillMetrics::SaveTypeMetric metric); - -void LogLocalCardMigrationPromptMetric( - LocalCardMigrationOrigin local_card_migration_origin, - LocalCardMigrationPromptMetric metric); - -} // namespace autofill::autofill_metrics - -#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_PAYMENTS_LOCAL_CARD_MIGRATION_METRICS_H_
diff --git a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor.h b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor.h index e144905..e38c105 100644 --- a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor.h +++ b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor.h
@@ -5,8 +5,15 @@ #ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_ML_MODEL_AUTOFILL_AI_AUTOFILL_AI_MODEL_EXECUTOR_H_ #define COMPONENTS_AUTOFILL_CORE_BROWSER_ML_MODEL_AUTOFILL_AI_AUTOFILL_AI_MODEL_EXECUTOR_H_ +#include <optional> + +#include "base/memory/weak_ptr.h" #include "components/keyed_service/core/keyed_service.h" +namespace optimization_guide::proto { +class AnnotatedPageContent; +} + namespace autofill { class FormData; @@ -19,7 +26,14 @@ // the model execution completes. Errors during model execution also lead to // cache writes, but with empty values. If there is already an ongoing cache // request for a form of the same signature, the model is not run. - virtual void GetPredictions(FormData form_data) = 0; + // If `annotated_page_content` is set, it includes it in its upload to the + // model. + virtual void GetPredictions( + FormData form_data, + std::optional<optimization_guide::proto::AnnotatedPageContent> + annotated_page_content) = 0; + + virtual base::WeakPtr<AutofillAiModelExecutor> GetWeakPtr() = 0; }; } // namespace autofill
diff --git a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl.cc b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl.cc index 827945a31..8d1fc6fe 100644 --- a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl.cc +++ b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl.cc
@@ -43,7 +43,10 @@ AutofillAiModelExecutorImpl::~AutofillAiModelExecutorImpl() = default; -void AutofillAiModelExecutorImpl::GetPredictions(FormData form_data) { +void AutofillAiModelExecutorImpl::GetPredictions( + FormData form_data, + std::optional<optimization_guide::proto::AnnotatedPageContent> + annotated_page_content) { // If there is already an ongoing request for the same form signature, then // do not start a new one. if (!ongoing_queries_.insert(CalculateFormSignature(form_data)).second) { @@ -59,10 +62,14 @@ } else { page_context->set_url(form_data.main_frame_origin().Serialize()); } - *request.mutable_form_data() = ToFormDataProto(form_data, FormDataProtoConversionReason::kModelRequest); + if (annotated_page_content) { + *request.mutable_annotated_page_content() = + *std::move(annotated_page_content); + } + optimization_guide::ModelExecutionCallbackWithLogging< optimization_guide::proto::FormsClassificationsLoggingData> wrapper_callback = @@ -75,6 +82,11 @@ std::move(wrapper_callback)); } +base::WeakPtr<AutofillAiModelExecutor> +AutofillAiModelExecutorImpl::GetWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); +} + void AutofillAiModelExecutorImpl::OnModelExecuted( FormData form_data, optimization_guide::OptimizationGuideModelExecutionResult execution_result,
diff --git a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl.h b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl.h index 961f3d1b..1ac3788b 100644 --- a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl.h +++ b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl.h
@@ -6,6 +6,7 @@ #define COMPONENTS_AUTOFILL_CORE_BROWSER_ML_MODEL_AUTOFILL_AI_AUTOFILL_AI_MODEL_EXECUTOR_IMPL_H_ #include <memory> +#include <optional> #include "base/containers/flat_set.h" #include "base/functional/callback_forward.h" @@ -17,6 +18,7 @@ #include "components/optimization_guide/core/model_quality/model_quality_logs_uploader_service.h" #include "components/optimization_guide/core/optimization_guide_model_executor.h" #include "components/optimization_guide/proto/features/forms_classifications.pb.h" +#include "components/optimization_guide/proto/features/model_prototyping.pb.h" namespace autofill { @@ -32,7 +34,11 @@ ~AutofillAiModelExecutorImpl() override; // AutofillAiModelExecutor: - void GetPredictions(FormData form_data) override; + void GetPredictions( + FormData form_data, + std::optional<optimization_guide::proto::AnnotatedPageContent> + annotated_page_content) override; + base::WeakPtr<AutofillAiModelExecutor> GetWeakPtr() override; private: // Writes the model execution response into the cache.
diff --git a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl_unittest.cc b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl_unittest.cc index 0f178437..60de7a05 100644 --- a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl_unittest.cc +++ b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl_unittest.cc
@@ -5,6 +5,7 @@ #include "components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor_impl.h" #include <memory> +#include <optional> #include "base/test/gmock_callback_support.h" #include "base/test/gmock_move_support.h" @@ -94,7 +95,7 @@ .signature = CalculateFieldSignatureForField(form.fields()[0]), .rank_in_signature_group = 0}))); - engine()->GetPredictions(form); + engine()->GetPredictions(form, std::nullopt); } // Tests that if there is an ongoing request with the same form signature, then @@ -141,14 +142,14 @@ .signature = CalculateFieldSignatureForField(form1.fields()[0]), .rank_in_signature_group = 0}))); - engine()->GetPredictions(form1); + engine()->GetPredictions(form1, std::nullopt); // We expect this call not to trigger a run. - engine()->GetPredictions(form1); + engine()->GetPredictions(form1, std::nullopt); // The simulated model call for a different form runs immediately and // completes successfully. - engine()->GetPredictions(form2); + engine()->GetPredictions(form2, std::nullopt); ASSERT_TRUE(model_callback2); std::move(model_callback2) .Run(OptimizationGuideModelExecutionResult( @@ -186,7 +187,7 @@ Update(CalculateFormSignature(form), base::test::EqualsProto(AutofillAiTypeResponse()), IsEmpty())); - engine()->GetPredictions(form); + engine()->GetPredictions(form, std::nullopt); } // Tests that wrongly typed model responses are handled by writing an empty @@ -207,7 +208,7 @@ Update(CalculateFormSignature(form), base::test::EqualsProto(AutofillAiTypeResponse()), IsEmpty())); - engine()->GetPredictions(form); + engine()->GetPredictions(form, std::nullopt); } } // namespace
diff --git a/components/autofill/core/browser/ml_model/autofill_ai/mock_autofill_ai_model_executor.cc b/components/autofill/core/browser/ml_model/autofill_ai/mock_autofill_ai_model_executor.cc index 7c44a52..fc73e4be 100644 --- a/components/autofill/core/browser/ml_model/autofill_ai/mock_autofill_ai_model_executor.cc +++ b/components/autofill/core/browser/ml_model/autofill_ai/mock_autofill_ai_model_executor.cc
@@ -10,4 +10,9 @@ MockAutofillAiModelExecutor::~MockAutofillAiModelExecutor() = default; +base::WeakPtr<AutofillAiModelExecutor> +MockAutofillAiModelExecutor::GetWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); +} + } // namespace autofill
diff --git a/components/autofill/core/browser/ml_model/autofill_ai/mock_autofill_ai_model_executor.h b/components/autofill/core/browser/ml_model/autofill_ai/mock_autofill_ai_model_executor.h index 402acda..b434ea28 100644 --- a/components/autofill/core/browser/ml_model/autofill_ai/mock_autofill_ai_model_executor.h +++ b/components/autofill/core/browser/ml_model/autofill_ai/mock_autofill_ai_model_executor.h
@@ -5,8 +5,10 @@ #ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_ML_MODEL_AUTOFILL_AI_MOCK_AUTOFILL_AI_MODEL_EXECUTOR_H_ #define COMPONENTS_AUTOFILL_CORE_BROWSER_ML_MODEL_AUTOFILL_AI_MOCK_AUTOFILL_AI_MODEL_EXECUTOR_H_ +#include "base/memory/weak_ptr.h" #include "components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_executor.h" #include "components/autofill/core/common/form_data.h" +#include "components/optimization_guide/proto/features/common_quality_data.pb.h" #include "testing/gmock/include/gmock/gmock.h" namespace autofill { @@ -19,7 +21,15 @@ delete; ~MockAutofillAiModelExecutor() override; - MOCK_METHOD(void, GetPredictions, (FormData), (override)); + MOCK_METHOD(void, + GetPredictions, + (FormData, + std::optional<optimization_guide::proto::AnnotatedPageContent>), + (override)); + base::WeakPtr<AutofillAiModelExecutor> GetWeakPtr() override; + + private: + base::WeakPtrFactory<MockAutofillAiModelExecutor> weak_ptr_factory_{this}; }; } // namespace autofill
diff --git a/components/autofill/core/browser/payments/autofill_payments_feature_availability.cc b/components/autofill/core/browser/payments/autofill_payments_feature_availability.cc index a5d6d65..bb51a9cd 100644 --- a/components/autofill/core/browser/payments/autofill_payments_feature_availability.cc +++ b/components/autofill/core/browser/payments/autofill_payments_feature_availability.cc
@@ -15,8 +15,7 @@ bool ShouldShowCardMetadata(const CreditCard& card) { // The product name and the art image must both be valid. return !card.product_description().empty() && - card.card_art_url().is_valid() && - base::FeatureList::IsEnabled(features::kAutofillEnableCardProductName); + card.card_art_url().is_valid(); } bool DidDisplayBenefitForCard(const CreditCard& card,
diff --git a/components/autofill/core/browser/payments/credit_card_otp_authenticator_unittest.cc b/components/autofill/core/browser/payments/credit_card_otp_authenticator_unittest.cc index 82a65fd..36e657c 100644 --- a/components/autofill/core/browser/payments/credit_card_otp_authenticator_unittest.cc +++ b/components/autofill/core/browser/payments/credit_card_otp_authenticator_unittest.cc
@@ -943,10 +943,9 @@ // Params of the CreditCardOtpAuthenticatorCardMetadataTest: // -- bool card_name_available; // -- bool card_art_available; -// -- bool metadata_enabled; class CreditCardOtpAuthenticatorCardMetadataTest : public CreditCardOtpAuthenticatorTestBase, - public testing::WithParamInterface<std::tuple<bool, bool, bool>> { + public testing::WithParamInterface<std::tuple<bool, bool>> { public: CreditCardOtpAuthenticatorCardMetadataTest() = default; ~CreditCardOtpAuthenticatorCardMetadataTest() override = default; @@ -959,26 +958,13 @@ bool CardNameAvailable() { return std::get<0>(GetParam()); } bool CardArtAvailable() { return std::get<1>(GetParam()); } - bool MetadataEnabled() { return std::get<2>(GetParam()); } }; INSTANTIATE_TEST_SUITE_P(, CreditCardOtpAuthenticatorCardMetadataTest, - testing::Combine(testing::Bool(), - testing::Bool(), - testing::Bool())); + testing::Combine(testing::Bool(), testing::Bool())); TEST_P(CreditCardOtpAuthenticatorCardMetadataTest, MetadataSignal) { - base::test::ScopedFeatureList metadata_feature_list; - if (MetadataEnabled()) { - metadata_feature_list.InitWithFeatures( - /*enabled_features=*/{features::kAutofillEnableCardProductName}, - /*disabled_features=*/{}); - } else { - metadata_feature_list.InitWithFeaturesAndParameters( - /*enabled_features=*/{}, - /*disabled_features=*/{features::kAutofillEnableCardProductName}); - } if (CardNameAvailable()) { card_.set_product_description(u"fake product description"); } @@ -1012,7 +998,7 @@ payments_network_interface().unmask_request()->risk_data.empty()); std::vector<ClientBehaviorConstants> signals = payments_network_interface().unmask_request()->client_behavior_signals; - if (MetadataEnabled() && CardNameAvailable() && CardArtAvailable()) { + if (CardNameAvailable() && CardArtAvailable()) { EXPECT_NE( signals.end(), std::ranges::find(
diff --git a/components/autofill/core/browser/payments/credit_card_risk_based_authenticator_unittest.cc b/components/autofill/core/browser/payments/credit_card_risk_based_authenticator_unittest.cc index 649b3bf..49ae1bd 100644 --- a/components/autofill/core/browser/payments/credit_card_risk_based_authenticator_unittest.cc +++ b/components/autofill/core/browser/payments/credit_card_risk_based_authenticator_unittest.cc
@@ -452,37 +452,24 @@ // Params of the CreditCardRiskBasedAuthenticatorCardMetadataTest: // -- bool card_name_available; // -- bool card_art_available; -// -- bool metadata_enabled; class CreditCardRiskBasedAuthenticatorCardMetadataTest : public CreditCardRiskBasedAuthenticatorTest, - public testing::WithParamInterface<std::tuple<bool, bool, bool>> { + public testing::WithParamInterface<std::tuple<bool, bool>> { public: CreditCardRiskBasedAuthenticatorCardMetadataTest() = default; ~CreditCardRiskBasedAuthenticatorCardMetadataTest() override = default; bool CardNameAvailable() { return std::get<0>(GetParam()); } bool CardArtAvailable() { return std::get<1>(GetParam()); } - bool MetadataEnabled() { return std::get<2>(GetParam()); } }; INSTANTIATE_TEST_SUITE_P(, CreditCardRiskBasedAuthenticatorCardMetadataTest, - testing::Combine(testing::Bool(), - testing::Bool(), - testing::Bool())); + testing::Combine(testing::Bool(), testing::Bool())); TEST_P(CreditCardRiskBasedAuthenticatorCardMetadataTest, MetadataSignal) { base::test::ScopedFeatureList metadata_feature_list; CreditCard virtual_card = test::GetVirtualCard(); - if (MetadataEnabled()) { - metadata_feature_list.InitWithFeatures( - /*enabled_features=*/{features::kAutofillEnableCardProductName}, - /*disabled_features=*/{}); - } else { - metadata_feature_list.InitWithFeaturesAndParameters( - /*enabled_features=*/{}, - /*disabled_features=*/{features::kAutofillEnableCardProductName}); - } if (CardNameAvailable()) { virtual_card.set_product_description(u"Fake card product name"); } @@ -502,7 +489,7 @@ ->last_committed_primary_main_frame_origin.has_value()); std::vector<ClientBehaviorConstants> signals = payments_network_interface()->unmask_request()->client_behavior_signals; - if (MetadataEnabled() && CardNameAvailable() && CardArtAvailable()) { + if (CardNameAvailable() && CardArtAvailable()) { EXPECT_NE( signals.end(), std::ranges::find(
diff --git a/components/autofill/core/browser/payments/credit_card_save_manager.cc b/components/autofill/core/browser/payments/credit_card_save_manager.cc index e684389..0506f4bc 100644 --- a/components/autofill/core/browser/payments/credit_card_save_manager.cc +++ b/components/autofill/core/browser/payments/credit_card_save_manager.cc
@@ -624,18 +624,6 @@ } } -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) -LocalCardMigrationStrikeDatabase* -CreditCardSaveManager::GetLocalCardMigrationStrikeDatabase() { - if (local_card_migration_strike_database_.get() == nullptr) { - local_card_migration_strike_database_ = - std::make_unique<LocalCardMigrationStrikeDatabase>( - LocalCardMigrationStrikeDatabase(client_->GetStrikeDatabase())); - } - return local_card_migration_strike_database_.get(); -} -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - void CreditCardSaveManager::OnDidGetUploadDetails( ukm::SourceId ukm_source_id, PaymentsRpcResult result, @@ -846,12 +834,6 @@ GetCreditCardSaveStrikeDatabase()->ClearStrikes( base::UTF16ToUTF8(card_save_candidate_.LastFourDigits())); -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - // Clear some local card migration strikes, as there is now a new card - // eligible for migration. - GetLocalCardMigrationStrikeDatabase()->RemoveStrikes( - LocalCardMigrationStrikeDatabase::kStrikesToRemoveWhenLocalCardAdded); -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) payments_data_manager().OnAcceptedLocalCreditCardSave( card_save_candidate_); break;
diff --git a/components/autofill/core/browser/payments/credit_card_save_manager.h b/components/autofill/core/browser/payments/credit_card_save_manager.h index d91df4c..79a9ff7f 100644 --- a/components/autofill/core/browser/payments/credit_card_save_manager.h +++ b/components/autofill/core/browser/payments/credit_card_save_manager.h
@@ -25,7 +25,6 @@ #include "components/autofill/core/browser/payments/payments_request_details.h" #include "components/autofill/core/browser/strike_databases/payments/credit_card_save_strike_database.h" #include "components/autofill/core/browser/strike_databases/payments/cvc_storage_strike_database.h" -#include "components/autofill/core/browser/strike_databases/payments/local_card_migration_strike_database.h" #include "url/origin.h" class SaveCardOfferObserver; @@ -183,7 +182,6 @@ private: friend class CreditCardSaveManagerTest; friend class CreditCardSaveManagerTestObserverBridge; - friend class LocalCardMigrationBrowserTest; friend class TestCreditCardSaveManager; friend class SaveCardBubbleViewsFullFormBrowserTest; friend class FakeCreditCardServer; @@ -213,11 +211,6 @@ // this CVC should be blocked. bool DetermineAndLogCvcSaveStrikeDatabaseBlockDecision(); -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - // Returns the GetLocalCardMigrationStrikeDatabase for |client_|. - LocalCardMigrationStrikeDatabase* GetLocalCardMigrationStrikeDatabase(); -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - // Returns the legal message retrieved from Payments. On failure or not // meeting Payments's conditions for upload, |legal_message| will contain // nullptr. |supported_card_bin_ranges| is a list of BIN prefix ranges which @@ -421,11 +414,6 @@ // card. std::vector<AutofillProfile> preliminarily_imported_address_profiles_; -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - std::unique_ptr<LocalCardMigrationStrikeDatabase> - local_card_migration_strike_database_; -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - // May be null. raw_ptr<ObserverForTest> observer_for_testing_ = nullptr;
diff --git a/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc index 484553f..c86e409 100644 --- a/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc +++ b/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc
@@ -5577,106 +5577,6 @@ "Autofill.StrikeDatabase.CreditCardSaveNotOfferedDueToMaxStrikes", AutofillMetrics::SaveTypeMetric::SERVER, 1); } - -// Tests that 2 LocalCardMigrationStrikes are removed when cards are saved -// locally. -TEST_F(CreditCardSaveManagerTest, - LocalCreditCard_LocalCardMigrationStrikesRemovedOnLocalSave) { - LocalCardMigrationStrikeDatabase local_card_migration_strike_database = - LocalCardMigrationStrikeDatabase(&strike_database()); - - // Start with 3 strikes in |local_card_migration_strike_database|. - local_card_migration_strike_database.AddStrikes(3); - EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 3); - - credit_card_save_manager_->SetCreditCardUploadEnabled(false); - - // Create, fill and submit an address form in order to establish a recent - // profile which can be selected for the upload request. - FormData address_form = CreateTestAddressFormData(); - FormsSeen(std::vector<FormData>(1, address_form)); - ExpectUniqueFillableFormParsedUkm(); - - ManuallyFillAddressForm("Jane", "Doe", "77401", "US", &address_form); - FormSubmitted(address_form); - - // Set up our credit card form data with credit card first and last name - // fields. - FormData credit_card_form = CreateTestCreditCardFormData( - CreditCardFormOptions().with_split_names(true)); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - test_api(credit_card_form).field(0).set_value(u"Jane"); - test_api(credit_card_form).field(1).set_value(u"Doe"); - test_api(credit_card_form).field(2).set_value(u"4111111111111111"); - test_api(credit_card_form) - .field(3) - .set_value(ASCIIToUTF16(test::NextMonth())); - test_api(credit_card_form).field(4).set_value(ASCIIToUTF16(test::NextYear())); - test_api(credit_card_form).field(5).set_value(u"123"); - - base::HistogramTester histogram_tester; - - EXPECT_CALL(payments_client(), ConfirmSaveCreditCardLocally); - - FormSubmitted(credit_card_form); - - EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded()); - - // 2 strikes should be removed when card was saved locally. - EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 1); -} - -// Tests that no LocalCardMigrationStrikes get removed due to cards being -// uploaded. -TEST_F(CreditCardSaveManagerTest, - UploadCreditCard_NoLocalSaveMigrationStrikesRemovedOnUpload) { - LocalCardMigrationStrikeDatabase local_card_migration_strike_database = - LocalCardMigrationStrikeDatabase(&strike_database()); - - // Start with 3 strikes in |local_card_migration_strike_database|. - local_card_migration_strike_database.AddStrikes(3); - EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 3); - - credit_card_save_manager_->SetCreditCardUploadEnabled(true); - - // Create, fill and submit an address form in order to establish a recent - // profile which can be selected for the upload request. - FormData address_form = CreateTestAddressFormData(); - FormsSeen(std::vector<FormData>(1, address_form)); - ExpectUniqueFillableFormParsedUkm(); - - ManuallyFillAddressForm("Jane", "Doe", "77401", "US", &address_form); - FormSubmitted(address_form); - - // Set up our credit card form data with credit card first and last name - // fields. - FormData credit_card_form = CreateTestCreditCardFormData( - CreditCardFormOptions().with_split_names(true)); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - test_api(credit_card_form).field(0).set_value(u"Jane"); - test_api(credit_card_form).field(1).set_value(u"Doe"); - test_api(credit_card_form).field(2).set_value(u"4111111111111111"); - test_api(credit_card_form) - .field(3) - .set_value(ASCIIToUTF16(test::NextMonth())); - test_api(credit_card_form).field(4).set_value(ASCIIToUTF16(test::NextYear())); - test_api(credit_card_form).field(5).set_value(u"123"); - - base::HistogramTester histogram_tester; - - EXPECT_CALL(payments_client(), ConfirmSaveCreditCardLocally).Times(0); - - FormSubmitted(credit_card_form); - - EXPECT_TRUE(credit_card_save_manager_->CreditCardWasUploaded()); - - // Strike count shouldn't change. - EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 3); -} #endif // Tests that adding a card clears all strikes for that card.
diff --git a/components/autofill/core/browser/payments/full_card_request_unittest.cc b/components/autofill/core/browser/payments/full_card_request_unittest.cc index 455c2766..ca29aa2 100644 --- a/components/autofill/core/browser/payments/full_card_request_unittest.cc +++ b/components/autofill/core/browser/payments/full_card_request_unittest.cc
@@ -746,38 +746,26 @@ // Params of the FullCardRequestCardMetadataTest: // -- bool card_name_available; // -- bool card_art_available; -// -- bool metadata_enabled; class FullCardRequestCardMetadataTest : public FullCardRequestTest, - public testing::WithParamInterface<std::tuple<bool, bool, bool>> { + public testing::WithParamInterface<std::tuple<bool, bool>> { public: FullCardRequestCardMetadataTest() = default; ~FullCardRequestCardMetadataTest() override = default; bool CardNameAvailable() { return std::get<0>(GetParam()); } bool CardArtAvailable() { return std::get<1>(GetParam()); } - bool MetadataEnabled() { return std::get<2>(GetParam()); } }; INSTANTIATE_TEST_SUITE_P(, FullCardRequestCardMetadataTest, testing::Combine(testing::Bool(), - testing::Bool(), testing::Bool())); // Verify the metadata signal is correctly set in the unmask request. TEST_P(FullCardRequestCardMetadataTest, MetadataSignal) { base::test::ScopedFeatureList metadata_feature_list; CreditCard card = test::GetMaskedServerCard(); - if (MetadataEnabled()) { - metadata_feature_list.InitWithFeatures( - /*enabled_features=*/{features::kAutofillEnableCardProductName}, - /*disabled_features=*/{}); - } else { - metadata_feature_list.InitWithFeaturesAndParameters( - /*enabled_features=*/{}, - /*disabled_features=*/{features::kAutofillEnableCardProductName}); - } if (CardNameAvailable()) { card.set_product_description(u"fake product description"); } @@ -790,7 +778,7 @@ EXPECT_TRUE(request().GetShouldUnmaskCardForTesting()); std::vector<ClientBehaviorConstants> signals = request().GetUnmaskRequestDetailsForTesting()->client_behavior_signals; - if (MetadataEnabled() && CardNameAvailable() && CardArtAvailable()) { + if (CardNameAvailable() && CardArtAvailable()) { EXPECT_NE( signals.end(), std::ranges::find(
diff --git a/components/autofill/core/browser/payments/local_card_migration_manager.cc b/components/autofill/core/browser/payments/local_card_migration_manager.cc deleted file mode 100644 index 00efcf7..0000000 --- a/components/autofill/core/browser/payments/local_card_migration_manager.cc +++ /dev/null
@@ -1,476 +0,0 @@ -// Copyright 2018 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/payments/local_card_migration_manager.h" - -#include <stddef.h> - -#include <algorithm> -#include <unordered_map> -#include <vector> - -#include "base/check_deref.h" -#include "base/containers/contains.h" -#include "base/functional/bind.h" -#include "base/metrics/histogram_functions.h" -#include "base/strings/utf_string_conversions.h" -#include "components/autofill/core/browser/data_manager/payments/payments_data_manager.h" -#include "components/autofill/core/browser/data_manager/personal_data_manager.h" -#include "components/autofill/core/browser/data_model/payments/credit_card.h" -#include "components/autofill/core/browser/form_import/form_data_importer.h" -#include "components/autofill/core/browser/foundations/autofill_client.h" -#include "components/autofill/core/browser/metrics/autofill_metrics.h" -#include "components/autofill/core/browser/metrics/payments/local_card_migration_metrics.h" -#include "components/autofill/core/browser/payments/client_behavior_constants.h" -#include "components/autofill/core/browser/payments/credit_card_save_manager.h" -#include "components/autofill/core/browser/payments/payments_network_interface.h" -#include "components/autofill/core/browser/payments/payments_requests/payments_request.h" -#include "components/autofill/core/browser/payments/payments_util.h" -#include "components/autofill/core/browser/studies/autofill_experiments.h" -#include "components/autofill/core/common/autofill_features.h" -#include "components/autofill/core/common/autofill_payments_features.h" -#include "components/signin/public/identity_manager/identity_manager.h" - -namespace autofill { -namespace { - -using PaymentsRpcResult = payments::PaymentsAutofillClient::PaymentsRpcResult; - -} // namespace - -MigratableCreditCard::MigratableCreditCard(const CreditCard& credit_card) - : credit_card_(credit_card) {} - -MigratableCreditCard::MigratableCreditCard(const MigratableCreditCard&) = - default; - -MigratableCreditCard::MigratableCreditCard(MigratableCreditCard&&) = default; - -MigratableCreditCard& MigratableCreditCard::operator=( - const MigratableCreditCard&) = default; - -MigratableCreditCard& MigratableCreditCard::operator=(MigratableCreditCard&&) = - default; - -MigratableCreditCard::~MigratableCreditCard() = default; - -LocalCardMigrationManager::LocalCardMigrationManager(AutofillClient* client) - : client_(CHECK_DEREF(client)) {} - -LocalCardMigrationManager::~LocalCardMigrationManager() = default; - -bool LocalCardMigrationManager::ShouldOfferLocalCardMigration( - const std::optional<CreditCard>& extracted_credit_card, - int credit_card_import_type) { - // Reset and store the extracted credit card info for a later check of whether - // the extracted card is supported. - extracted_credit_card_number_.reset(); - if (extracted_credit_card) { - extracted_credit_card_number_ = extracted_credit_card->number(); - } - credit_card_import_type_ = credit_card_import_type; - // Must be an existing card. New cards always get Upstream or local save. - switch (credit_card_import_type_) { - case FormDataImporter::CreditCardImportType::kLocalCard: - local_card_migration_origin_ = - autofill_metrics::LocalCardMigrationOrigin::UseOfLocalCard; - break; - case FormDataImporter::CreditCardImportType::kServerCard: - local_card_migration_origin_ = - autofill_metrics::LocalCardMigrationOrigin::UseOfServerCard; - break; - default: - autofill_metrics::LogLocalCardMigrationDecisionMetric( - autofill_metrics::LocalCardMigrationDecisionMetric:: - NOT_OFFERED_USE_NEW_CARD); - return false; - } - - if (!IsCreditCardMigrationEnabled()) { - autofill_metrics::LogLocalCardMigrationDecisionMetric( - autofill_metrics::LocalCardMigrationDecisionMetric:: - NOT_OFFERED_FAILED_PREREQUISITES); - return false; - } - - if (GetLocalCardMigrationStrikeDatabase()->ShouldBlockFeature()) { - switch (credit_card_import_type_) { - case FormDataImporter::CreditCardImportType::kLocalCard: - autofill_metrics::LogLocalCardMigrationNotOfferedDueToMaxStrikesMetric( - AutofillMetrics::SaveTypeMetric::LOCAL); - break; - case FormDataImporter::CreditCardImportType::kServerCard: - autofill_metrics::LogLocalCardMigrationNotOfferedDueToMaxStrikesMetric( - AutofillMetrics::SaveTypeMetric::SERVER); - break; - } - autofill_metrics::LogLocalCardMigrationDecisionMetric( - autofill_metrics::LocalCardMigrationDecisionMetric:: - NOT_OFFERED_REACHED_MAX_STRIKE_COUNT); - return false; - } - - // Fetch all migratable credit cards and store in |migratable_credit_cards_|. - GetMigratableCreditCards(); - - // If the form was submitted with a local card, only offer migration instead - // of Upstream if there are other local cards to migrate as well. If the form - // was submitted with a server card, offer migration if ANY local cards can be - // migrated. - if ((credit_card_import_type_ == - FormDataImporter::CreditCardImportType::kLocalCard && - migratable_credit_cards_.size() > 1) || - (credit_card_import_type_ == - FormDataImporter::CreditCardImportType::kServerCard && - !migratable_credit_cards_.empty())) { - return true; - } else if (credit_card_import_type_ == - FormDataImporter::CreditCardImportType::kLocalCard && - migratable_credit_cards_.size() == 1) { - autofill_metrics::LogLocalCardMigrationDecisionMetric( - autofill_metrics::LocalCardMigrationDecisionMetric:: - NOT_OFFERED_SINGLE_LOCAL_CARD); - return false; - } else { - autofill_metrics::LogLocalCardMigrationDecisionMetric( - autofill_metrics::LocalCardMigrationDecisionMetric:: - NOT_OFFERED_NO_MIGRATABLE_CARDS); - return false; - } -} - -void LocalCardMigrationManager::AttemptToOfferLocalCardMigration( - bool is_from_settings_page) { - payments::PaymentsNetworkInterface* payments_network_interface = - client_->GetPaymentsAutofillClient()->GetPaymentsNetworkInterface(); - // If `payments_network_interface` is nullptr, we can not offer local card - // migration as it requires a server call. - if (!payments_network_interface) { - return; - } - migration_request_ = payments::MigrationRequestDetails(); - - if (observer_for_testing_) - observer_for_testing_->OnDecideToRequestLocalCardMigration(); - - payments_network_interface->GetCardUploadDetails( - std::vector<AutofillProfile>(), GetDetectedValues(), - /*client_behavior_signals=*/std::vector<ClientBehaviorConstants>(), - client_->GetAppLocale(), - base::BindOnce(&LocalCardMigrationManager::OnDidGetUploadDetails, - weak_ptr_factory_.GetWeakPtr(), is_from_settings_page), - payments::kMigrateCardsBillableServiceNumber, - payments::GetBillingCustomerId(payments_data_manager()), - is_from_settings_page - ? payments::UploadCardSource::LOCAL_CARD_MIGRATION_SETTINGS_PAGE - : payments::UploadCardSource::LOCAL_CARD_MIGRATION_CHECKOUT_FLOW); -} - -// Callback function when user agrees to migration on the intermediate dialog. -// Call ShowMainMigrationDialog() to pop up a larger, modal dialog showing the -// local cards to be uploaded. -void LocalCardMigrationManager::OnUserAcceptedIntermediateMigrationDialog() { - autofill_metrics::LogLocalCardMigrationPromptMetric( - local_card_migration_origin_, - autofill_metrics::INTERMEDIATE_BUBBLE_ACCEPTED); - ShowMainMigrationDialog(); -} - -// Send the migration request once risk data is available. -void LocalCardMigrationManager::OnUserAcceptedMainMigrationDialog( - const std::vector<std::string>& selected_card_guids) { - user_accepted_main_migration_dialog_ = true; - autofill_metrics::LogLocalCardMigrationPromptMetric( - local_card_migration_origin_, autofill_metrics::MAIN_DIALOG_ACCEPTED); - - // Log number of LocalCardMigration strikes when migration was accepted. - base::UmaHistogramCounts1000( - "Autofill.StrikeDatabase.StrikesPresentWhenLocalCardMigrationAccepted", - GetLocalCardMigrationStrikeDatabase()->GetStrikes()); - - // Update the |migratable_credit_cards_| with the |selected_card_guids|. This - // will remove any card from |migratable_credit_cards_| of which the GUID is - // not in |selected_card_guids|. - auto card_is_selected = [&selected_card_guids](MigratableCreditCard& card) { - return !base::Contains(selected_card_guids, card.credit_card().guid()); - }; - std::erase_if(migratable_credit_cards_, card_is_selected); - // Populating risk data and offering migration two-round pop-ups occur - // asynchronously. If |migration_risk_data_| has already been loaded, send the - // migrate local cards request. Otherwise, continue to wait and let - // OnDidGetUploadRiskData handle it. - if (!migration_request_.risk_data.empty()) - SendMigrateLocalCardsRequest(); -} - -void LocalCardMigrationManager::OnUserDeletedLocalCardViaMigrationDialog( - const std::string& deleted_card_guid) { - payments_data_manager().RemoveByGUID(deleted_card_guid); -} - -bool LocalCardMigrationManager::IsCreditCardMigrationEnabled() { - return ::autofill::IsCreditCardMigrationEnabled( - payments_data_manager(), client_->GetSyncService(), *client_->GetPrefs(), - /*is_test_mode=*/observer_for_testing_, client_->GetCurrentLogManager()); -} - -void LocalCardMigrationManager::OnDidGetUploadDetails( - bool is_from_settings_page, - PaymentsRpcResult result, - const std::u16string& context_token, - std::unique_ptr<base::Value::Dict> legal_message, - std::vector<std::pair<int, int>> supported_card_bin_ranges) { - if (observer_for_testing_) - observer_for_testing_->OnReceivedGetUploadDetailsResponse(); - - if (result == PaymentsRpcResult::kSuccess) { - LegalMessageLine::Parse(*legal_message, &legal_message_lines_, - /*escape_apostrophes=*/true); - - if (legal_message_lines_.empty()) { - autofill_metrics::LogLocalCardMigrationDecisionMetric( - autofill_metrics::LocalCardMigrationDecisionMetric:: - NOT_OFFERED_INVALID_LEGAL_MESSAGE); - return; - } - - migration_request_.context_token = context_token; - migration_request_.risk_data.clear(); - - // If we successfully received the legal docs, trigger the offer-to-migrate - // dialog. If triggered from settings page, we pop-up the main prompt - // directly. If not, we pop up the intermediate bubble. - if (is_from_settings_page) { - // Set the origin to SettingsPage. - local_card_migration_origin_ = - autofill_metrics::LocalCardMigrationOrigin::SettingsPage; - // Pops up a larger, modal dialog showing the local cards to be uploaded. - ShowMainMigrationDialog(); - } else { - // Check if an extracted local card is listed in - // `supported_card_bin_ranges`. Abort the migration when the user uses an - // unsupported local card. - if (!supported_card_bin_ranges.empty() && - credit_card_import_type_ == - FormDataImporter::CreditCardImportType::kLocalCard && - extracted_credit_card_number_.has_value() && - !payments::IsCreditCardNumberSupported( - extracted_credit_card_number_.value(), - supported_card_bin_ranges)) { - autofill_metrics::LogLocalCardMigrationDecisionMetric( - autofill_metrics::LocalCardMigrationDecisionMetric:: - NOT_OFFERED_USE_UNSUPPORTED_LOCAL_CARD); - return; - } - // Filter the migratable credit cards with |supported_card_bin_ranges|. - FilterOutUnsupportedLocalCards(supported_card_bin_ranges); - // Abandon the migration if no supported card left. - if (migratable_credit_cards_.empty()) { - autofill_metrics::LogLocalCardMigrationDecisionMetric( - autofill_metrics::LocalCardMigrationDecisionMetric:: - NOT_OFFERED_NO_SUPPORTED_CARDS); - return; - } - client_->GetPaymentsAutofillClient()->ShowLocalCardMigrationDialog( - base::BindOnce(&LocalCardMigrationManager:: - OnUserAcceptedIntermediateMigrationDialog, - weak_ptr_factory_.GetWeakPtr())); - autofill_metrics::LogLocalCardMigrationPromptMetric( - local_card_migration_origin_, - autofill_metrics::INTERMEDIATE_BUBBLE_SHOWN); - } - - client_->GetPaymentsAutofillClient()->LoadRiskData( - base::BindOnce(&LocalCardMigrationManager::OnDidGetMigrationRiskData, - weak_ptr_factory_.GetWeakPtr())); - autofill_metrics::LogLocalCardMigrationDecisionMetric( - autofill_metrics::LocalCardMigrationDecisionMetric::OFFERED); - } else { - autofill_metrics::LogLocalCardMigrationDecisionMetric( - autofill_metrics::LocalCardMigrationDecisionMetric:: - NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED); - } -} - -void LocalCardMigrationManager::OnDidMigrateLocalCards( - PaymentsRpcResult result, - std::unique_ptr<std::unordered_map<std::string, std::string>> save_result, - const std::string& display_text) { - if (observer_for_testing_) - observer_for_testing_->OnReceivedMigrateCardsResponse(); - - if (!save_result) - return; - - if (result == PaymentsRpcResult::kSuccess) { - std::vector<CreditCard> migrated_cards; - // Traverse the migratable credit cards to update each migrated card status. - for (MigratableCreditCard& card : migratable_credit_cards_) { - // If it is run in a test, count all cards as successfully migrated. - if (observer_for_testing_) { - migrated_cards.push_back(card.credit_card()); - continue; - } - - // Not every card exists in the |save_result| since some cards are - // unchecked by the user and not migrated. - auto it = save_result->find(card.credit_card().guid()); - // If current card does not exist in the |save_result|, skip it. - if (it == save_result->end()) - continue; - - // Otherwise update its migration status. Server-side response can return - // SUCCESS, TEMPORARY_FAILURE, or PERMANENT_FAILURE (see SaveResult - // enum). Branch here depending on which is received. - if (it->second == kMigrationResultPermanentFailure || - it->second == kMigrationResultTemporaryFailure) { - card.set_migration_status( - MigratableCreditCard::MigrationStatus::FAILURE_ON_UPLOAD); - } else if (it->second == kMigrationResultSuccess) { - card.set_migration_status( - MigratableCreditCard::MigrationStatus::SUCCESS_ON_UPLOAD); - migrated_cards.push_back(card.credit_card()); - } else { - NOTREACHED(); - } - } - - // Remove cards that were successfully migrated from local storage. - payments_data_manager().DeleteLocalCreditCards(migrated_cards); - } - - client_->GetPaymentsAutofillClient()->ShowLocalCardMigrationResults( - result != PaymentsRpcResult::kSuccess, base::UTF8ToUTF16(display_text), - migratable_credit_cards_, - base::BindRepeating( - &LocalCardMigrationManager::OnUserDeletedLocalCardViaMigrationDialog, - weak_ptr_factory_.GetWeakPtr())); -} - -void LocalCardMigrationManager::OnDidGetMigrationRiskData( - const std::string& risk_data) { - migration_request_.risk_data = risk_data; - // Populating risk data and offering migration two-round pop-ups occur - // asynchronously. If the main migration dialog has already been accepted, - // send the migrate local cards request. Otherwise, continue to wait for the - // user to accept the two round dialog. - if (user_accepted_main_migration_dialog_) - SendMigrateLocalCardsRequest(); -} - -// Send the migration request. Will call -// `client_->GetPaymentsAutofillClient()->GetPaymentsNetworkInterface()` to -// create a new PaymentsRequest. Also create a new callback function -// OnDidMigrateLocalCards. -void LocalCardMigrationManager::SendMigrateLocalCardsRequest() { - if (observer_for_testing_) - observer_for_testing_->OnSentMigrateCardsRequest(); - - migration_request_.app_locale = client_->GetAppLocale(); - migration_request_.billing_customer_number = - payments::GetBillingCustomerId(payments_data_manager()); - client_->GetPaymentsAutofillClient() - ->GetPaymentsNetworkInterface() - ->MigrateCards( - migration_request_, migratable_credit_cards_, - base::BindOnce(&LocalCardMigrationManager::OnDidMigrateLocalCards, - weak_ptr_factory_.GetWeakPtr())); - user_accepted_main_migration_dialog_ = false; -} - -LocalCardMigrationStrikeDatabase* -LocalCardMigrationManager::GetLocalCardMigrationStrikeDatabase() { - if (local_card_migration_strike_database_.get() == nullptr) { - local_card_migration_strike_database_ = - std::make_unique<LocalCardMigrationStrikeDatabase>( - LocalCardMigrationStrikeDatabase(client_->GetStrikeDatabase())); - } - return local_card_migration_strike_database_.get(); -} - -// Pops up a larger, modal dialog showing the local cards to be uploaded. Pass -// the reference of vector<MigratableCreditCard> and the callback function is -// OnUserAcceptedMainMigrationDialog(). Can be called when user agrees to -// migration on the intermediate dialog or directly from settings page. -void LocalCardMigrationManager::ShowMainMigrationDialog() { - autofill_metrics::LogLocalCardMigrationPromptMetric( - local_card_migration_origin_, autofill_metrics::MAIN_DIALOG_SHOWN); - // Pops up a larger, modal dialog showing the local cards to be uploaded. - client_->GetPaymentsAutofillClient()->ConfirmMigrateLocalCardToCloud( - legal_message_lines_, - payments_data_manager().GetAccountInfoForPaymentsServer().email, - migratable_credit_cards_, - base::BindOnce( - &LocalCardMigrationManager::OnUserAcceptedMainMigrationDialog, - weak_ptr_factory_.GetWeakPtr())); -} - -int LocalCardMigrationManager::GetDetectedValues() const { - int detected_values = 0; - - // If all cards to be migrated have a cardholder name, include it in the - // detected values. - bool all_cards_have_cardholder_name = true; - for (MigratableCreditCard migratable_credit_card : migratable_credit_cards_) { - all_cards_have_cardholder_name &= - !migratable_credit_card.credit_card() - .GetInfo(CREDIT_CARD_NAME_FULL, client_->GetAppLocale()) - .empty(); - } - if (all_cards_have_cardholder_name) - detected_values |= CreditCardSaveManager::DetectedValue::CARDHOLDER_NAME; - - // Local card migration should ONLY be offered when the user already has a - // Google Payments account. - DCHECK(payments::HasGooglePaymentsAccount(payments_data_manager())); - detected_values |= - CreditCardSaveManager::DetectedValue::HAS_GOOGLE_PAYMENTS_ACCOUNT; - - return detected_values; -} - -void LocalCardMigrationManager::GetMigratableCreditCards() { - // Empty previous state. - migratable_credit_cards_.clear(); - // Initialize the local credit card list and queue for showing and uploading. - for (const CreditCard* credit_card : - payments_data_manager().GetLocalCreditCards()) { - // If the card is valid (has a valid card number, expiration date, and is - // not expired) and is not a server card, add it to the list of migratable - // cards. - if (credit_card->IsValid() && - !payments_data_manager().IsServerCard(credit_card)) { - migratable_credit_cards_.emplace_back(*credit_card); - } - } -} - -void LocalCardMigrationManager::FilterOutUnsupportedLocalCards( - const std::vector<std::pair<int, int>>& supported_card_bin_ranges) { - if (!supported_card_bin_ranges.empty()) { - // Update the |migratable_credit_cards_| with the - // |supported_card_bin_ranges|. This will remove any card from - // |migratable_credit_cards_| of which the card number is not in - // |supported_card_bin_ranges|. - auto card_is_unsupported = - [&supported_card_bin_ranges](MigratableCreditCard& card) { - return !payments::IsCreditCardNumberSupported( - card.credit_card().number(), supported_card_bin_ranges); - }; - std::erase_if(migratable_credit_cards_, card_is_unsupported); - } -} - -PaymentsDataManager& LocalCardMigrationManager::payments_data_manager() { - return const_cast<PaymentsDataManager&>( - const_cast<const LocalCardMigrationManager*>(this) - ->payments_data_manager()); -} - -const PaymentsDataManager& LocalCardMigrationManager::payments_data_manager() - const { - return client_->GetPersonalDataManager().payments_data_manager(); -} - -} // namespace autofill
diff --git a/components/autofill/core/browser/payments/local_card_migration_manager.h b/components/autofill/core/browser/payments/local_card_migration_manager.h deleted file mode 100644 index 7861ed334..0000000 --- a/components/autofill/core/browser/payments/local_card_migration_manager.h +++ /dev/null
@@ -1,254 +0,0 @@ -// Copyright 2018 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_PAYMENTS_LOCAL_CARD_MIGRATION_MANAGER_H_ -#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_LOCAL_CARD_MIGRATION_MANAGER_H_ - -#include <memory> -#include <optional> -#include <string> -#include <unordered_map> -#include <utility> -#include <vector> - -#include "base/gtest_prod_util.h" -#include "base/memory/raw_ptr.h" -#include "components/autofill/core/browser/metrics/autofill_metrics.h" -#include "components/autofill/core/browser/metrics/payments/local_card_migration_metrics.h" -#include "components/autofill/core/browser/payments/legal_message_line.h" -#include "components/autofill/core/browser/payments/payments_autofill_client.h" -#include "components/autofill/core/browser/payments/payments_request_details.h" -#include "components/autofill/core/browser/strike_databases/payments/local_card_migration_strike_database.h" - -namespace autofill { - -class CreditCard; -class PaymentsDataManager; - -// Server-side response can return SUCCESS, TEMPORARY_FAILURE, or -// PERMANENT_FAILURE (see SaveResult enum). Use these to extract migration -// result. -inline constexpr char kMigrationResultPermanentFailure[] = "PERMANENT_FAILURE"; -inline constexpr char kMigrationResultTemporaryFailure[] = "TEMPORARY_FAILURE"; -inline constexpr char kMigrationResultSuccess[] = "SUCCESS"; - -// MigratableCreditCard class is used as a data structure to work as an -// intermediary between the UI side and the migration manager. Besides the basic -// credit card information, it also includes a boolean that represents whether -// the card was chosen for upload. We use each card's guid to distinguish each -// credit card for upload request/response. -class MigratableCreditCard { - public: - // Possible states for the migratable local card. - enum class MigrationStatus { - // Set if the migratable card have not been uploaded. - UNKNOWN, - // Set if the migratable card was successfully uploaded to the server. - SUCCESS_ON_UPLOAD, - // Set if the migratable card encountered a failure during upload. - FAILURE_ON_UPLOAD, - }; - - explicit MigratableCreditCard(const CreditCard& credit_card); - MigratableCreditCard(const MigratableCreditCard&); - MigratableCreditCard(MigratableCreditCard&&); - MigratableCreditCard& operator=(const MigratableCreditCard&); - MigratableCreditCard& operator=(MigratableCreditCard&&); - ~MigratableCreditCard(); - - CreditCard credit_card() const { return credit_card_; } - - MigrationStatus migration_status() const { return migration_status_; } - void set_migration_status(MigrationStatus migration_status) { - migration_status_ = migration_status; - } - - private: - // The main card information of the current migratable card. - CreditCard credit_card_; - - // Migration status for this card. - MigrationStatus migration_status_ = MigrationStatus::UNKNOWN; -}; - -// Manages logic for determining whether migration of locally saved credit cards -// to Google Payments is available as well as multiple local card uploading. -// Owned by FormDataImporter. -class LocalCardMigrationManager { - public: - // An observer class used by browsertests that gets notified whenever - // particular actions occur. - class ObserverForTest { - public: - virtual void OnDecideToRequestLocalCardMigration() = 0; - virtual void OnReceivedGetUploadDetailsResponse() = 0; - virtual void OnSentMigrateCardsRequest() = 0; - virtual void OnReceivedMigrateCardsResponse() = 0; - }; - - // `client` must outlive the LocalCardMigrationManager. - explicit LocalCardMigrationManager(AutofillClient* client); - - LocalCardMigrationManager(const LocalCardMigrationManager&) = delete; - LocalCardMigrationManager& operator=(const LocalCardMigrationManager&) = - delete; - - virtual ~LocalCardMigrationManager(); - - // Returns true if all of the conditions for allowing local credit card - // migration are satisfied. Initializes the local card list for upload. Stores - // a local copy of `extracted_credit_card` and - // `credit_card_import_type` locally for later check whether - // the imported card is supported. `extracted_credit_card` might be - // null if a user used server card. - bool ShouldOfferLocalCardMigration( - const std::optional<CreditCard>& extracted_credit_card, - int credit_card_import_type); - - // Called from FormDataImporter or settings page when all migration - // requirements are met. Fetches legal documents and triggers the - // OnDidGetUploadDetails callback. |is_from_settings_page| to denote the user - // triggers the migration from settings page. It will trigger the main prompt - // directly if the get upload details call returns success. - void AttemptToOfferLocalCardMigration(bool is_from_settings_page); - - // Callback function when user agrees to migration on the intermediate dialog. - // Pops up a larger, modal dialog showing the local cards to be uploaded. - // Exposed for testing. - virtual void OnUserAcceptedIntermediateMigrationDialog(); - - // Callback function when user confirms migration on the main migration - // dialog. Removes any MigratableCreditCard of which the guid is not in - // |selected_card_guids| from |migratable_credit_cards_|. Sets - // |user_accepted_main_migration_dialog_| and sends the migration request - // once risk data is available. Exposed for testing. - virtual void OnUserAcceptedMainMigrationDialog( - const std::vector<std::string>& selected_card_guids); - - // Callback function when user clicks the trash can button in the - // action-required dialog to delete one credit card from Chrome. - // |deleted_card_guid| is the GUID of the card to be deleted. - virtual void OnUserDeletedLocalCardViaMigrationDialog( - const std::string& deleted_card_guid); - - // Check that the user is signed in, syncing, and the proper experiment - // flags are enabled. Override in the test class. - virtual bool IsCreditCardMigrationEnabled(); - - // Determines what detected_values metadata to send (generally, cardholder - // name if it exists on all cards, and existence of Payments customer). - int GetDetectedValues() const; - - // Fetch all migratable credit cards and store in |migratable_credit_cards_|. - // Migratable cards are cards whose card number passed luhn check and - // expiration date are valid. We do NOT filter unsupported cards here. - // Any other usage of this function other than ShouldOfferLocalCardMigration() - // and from settings page after OnDidGetUploadDetails, you should call - // FilterOutUnsupportedLocalCards right after this function to filter out - // unsupported cards. If so, the first OnDidGetUploadDetails() will need to - // store the supported ranges locally. - void GetMigratableCreditCards(); - - protected: - // Callback after successfully getting the legal documents. On success, - // displays the offer-to-migrate dialog, which the user can accept or not. - // When |is_from_settings_page| is true, it will trigger the main prompt - // directly. If not, trigger the intermediate prompt. Exposed for testing. - virtual void OnDidGetUploadDetails( - bool is_from_settings_page, - payments::PaymentsAutofillClient::PaymentsRpcResult result, - const std::u16string& context_token, - std::unique_ptr<base::Value::Dict> legal_message, - std::vector<std::pair<int, int>> supported_card_bin_ranges); - - // Callback after successfully getting the migration save results. Map - // migration save result to each card depending on the |save_result|. Will - // trigger a window showing the migration result together with display text to - // the user. - void OnDidMigrateLocalCards( - payments::PaymentsAutofillClient::PaymentsRpcResult result, - std::unique_ptr<std::unordered_map<std::string, std::string>> save_result, - const std::string& display_text); - - PaymentsDataManager& payments_data_manager(); - const PaymentsDataManager& payments_data_manager() const; - - private: - friend class LocalCardMigrationBrowserTest; - FRIEND_TEST_ALL_PREFIXES(LocalCardMigrationManagerTest, - MigrateCreditCard_MigrateWhenHasSupportedLocalCard); - FRIEND_TEST_ALL_PREFIXES(LocalCardMigrationManagerTest, - MigrateCreditCard_MigrationPermanentFailure); - FRIEND_TEST_ALL_PREFIXES(LocalCardMigrationManagerTest, - MigrateCreditCard_MigrationTemporaryFailure); - FRIEND_TEST_ALL_PREFIXES(LocalCardMigrationManagerTest, - MigrateCreditCard_MigrationSuccess); - FRIEND_TEST_ALL_PREFIXES(LocalCardMigrationManagerTest, - MigrateCreditCard_ToggleIsChosen); - - // Returns the LocalCardMigrationStrikeDatabase for |client_|. - LocalCardMigrationStrikeDatabase* GetLocalCardMigrationStrikeDatabase(); - - // Filter the |migratable_credit_cards_| with |supported_card_bin_ranges| and - // keep supported local cards in |migratable_credit_cards_|. - // Effective after one successful GetUploadDetails call where we fetch the - // |supported_card_bin_ranges|. - void FilterOutUnsupportedLocalCards( - const std::vector<std::pair<int, int>>& supported_card_bin_ranges); - - // Pops up a larger, modal dialog showing the local cards to be uploaded. - void ShowMainMigrationDialog(); - - // Callback function when migration risk data is ready. Saves risk data in - // |migration_risk_data_| and calls SendMigrateLocalCardsRequest if the user - // has accepted the main migration dialog. - void OnDidGetMigrationRiskData(const std::string& risk_data); - - // Finalizes the migration request and calls the PaymentsNetworkInterface. - void SendMigrateLocalCardsRequest(); - - // For testing. - void SetEventObserverForTesting(ObserverForTest* observer) { - observer_for_testing_ = observer; - } - - const raw_ref<AutofillClient> client_; - - // The parsed lines from the legal message return from GetUploadDetails. - LegalMessageLines legal_message_lines_; - - // The imported credit card number from the form submission. - std::optional<std::u16string> extracted_credit_card_number_; - - // The imported credit card record type from the form submission. - int credit_card_import_type_; - - // Collected information about a pending migration request. - payments::MigrationRequestDetails migration_request_; - - // The local credit cards to be uploaded. Owned by LocalCardMigrationManager. - // The order of cards should not be changed. - // TODO(crbug.com/40586517): Currently we will not handle the case of local - // cards added/deleted during migration. - std::vector<MigratableCreditCard> migratable_credit_cards_; - - // |true| if the user has accepted migrating their local cards to Google Pay - // on the main dialog. - bool user_accepted_main_migration_dialog_ = false; - - // Record the triggering source of the local card migration. - autofill_metrics::LocalCardMigrationOrigin local_card_migration_origin_; - - // Initialized only during tests. - raw_ptr<ObserverForTest> observer_for_testing_ = nullptr; - - std::unique_ptr<LocalCardMigrationStrikeDatabase> - local_card_migration_strike_database_; - - base::WeakPtrFactory<LocalCardMigrationManager> weak_ptr_factory_{this}; -}; - -} // namespace autofill - -#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_LOCAL_CARD_MIGRATION_MANAGER_H_
diff --git a/components/autofill/core/browser/payments/local_card_migration_manager_unittest.cc b/components/autofill/core/browser/payments/local_card_migration_manager_unittest.cc deleted file mode 100644 index 18fc8172..0000000 --- a/components/autofill/core/browser/payments/local_card_migration_manager_unittest.cc +++ /dev/null
@@ -1,1457 +0,0 @@ -// Copyright 2018 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/payments/local_card_migration_manager.h" - -#include <stddef.h> - -#include <algorithm> -#include <list> -#include <map> -#include <memory> -#include <string> -#include <string_view> -#include <utility> -#include <vector> - -#include "base/memory/raw_ptr.h" -#include "base/metrics/metrics_hashes.h" -#include "base/strings/utf_string_conversions.h" -#include "base/test/metrics/histogram_tester.h" -#include "base/test/task_environment.h" -#include "base/time/time.h" -#include "base/uuid.h" -#include "build/build_config.h" -#include "components/autofill/core/browser/crowdsourcing/test_votes_uploader.h" -#include "components/autofill/core/browser/data_manager/payments/payments_data_manager.h" -#include "components/autofill/core/browser/data_manager/personal_data_manager.h" -#include "components/autofill/core/browser/data_manager/test_personal_data_manager.h" -#include "components/autofill/core/browser/data_model/addresses/autofill_profile.h" -#include "components/autofill/core/browser/data_model/payments/credit_card.h" -#include "components/autofill/core/browser/data_quality/validation.h" -#include "components/autofill/core/browser/form_import/form_data_importer_test_api.h" -#include "components/autofill/core/browser/foundations/test_autofill_client.h" -#include "components/autofill/core/browser/foundations/test_autofill_driver.h" -#include "components/autofill/core/browser/foundations/test_browser_autofill_manager.h" -#include "components/autofill/core/browser/metrics/autofill_metrics.h" -#include "components/autofill/core/browser/metrics/payments/local_card_migration_metrics.h" -#include "components/autofill/core/browser/payments/iban_save_manager.h" -#include "components/autofill/core/browser/payments/payments_customer_data.h" -#include "components/autofill/core/browser/payments/payments_util.h" -#include "components/autofill/core/browser/payments/test_credit_card_save_manager.h" -#include "components/autofill/core/browser/payments/test_local_card_migration_manager.h" -#include "components/autofill/core/browser/payments/test_payments_autofill_client.h" -#include "components/autofill/core/browser/payments/test_payments_network_interface.h" -#include "components/autofill/core/browser/test_utils/autofill_test_utils.h" -#include "components/autofill/core/browser/test_utils/test_autofill_clock.h" -#include "components/autofill/core/browser/webdata/autofill_webdata_service.h" -#include "components/autofill/core/common/autofill_clock.h" -#include "components/autofill/core/common/autofill_payments_features.h" -#include "components/autofill/core/common/autofill_prefs.h" -#include "components/autofill/core/common/credit_card_network_identifiers.h" -#include "components/autofill/core/common/form_data.h" -#include "components/autofill/core/common/form_data_test_api.h" -#include "components/autofill/core/common/form_field_data.h" -#include "components/prefs/pref_service.h" -#include "components/sync/test/test_sync_service.h" -#include "services/metrics/public/cpp/ukm_builders.h" -#include "services/network/public/cpp/shared_url_loader_factory.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -namespace autofill { - -using base::ASCIIToUTF16; -using test::CreateTestCreditCardFormData; -using ::testing::_; -using ::testing::NiceMock; - -class LocalCardMigrationManagerTest : public testing::Test { - public: - void SetUp() override { - autofill_client_.SetPrefs(test::PrefServiceForTesting()); - personal_data().SetPrefService(autofill_client_.GetPrefs()); - personal_data().SetSyncServiceForTest(&sync_service_); - autofill_driver_ = std::make_unique<TestAutofillDriver>(&autofill_client_); - payments_network_interface_ = new payments::TestPaymentsNetworkInterface( - autofill_client_.GetURLLoaderFactory(), - autofill_client_.GetIdentityManager(), &personal_data()); - autofill_client_.GetPaymentsAutofillClient() - ->set_payments_network_interface( - std::unique_ptr<payments::TestPaymentsNetworkInterface>( - payments_network_interface_)); - auto credit_card_save_manager = - std::make_unique<TestCreditCardSaveManager>(&autofill_client_); - credit_card_save_manager_ = credit_card_save_manager.get(); - credit_card_save_manager_->SetCreditCardUploadEnabled(true); - auto local_card_migration_manager = - std::make_unique<TestLocalCardMigrationManager>(&autofill_client_); - local_card_migration_manager_ = local_card_migration_manager.get(); - std::unique_ptr<TestStrikeDatabase> test_strike_database = - std::make_unique<TestStrikeDatabase>(); - strike_database_ = test_strike_database.get(); - autofill_client_.set_test_strike_database(std::move(test_strike_database)); - test_api(*autofill_client_.GetFormDataImporter()) - .set_credit_card_save_manager(std::move(credit_card_save_manager)); -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - test_api(*autofill_client_.GetFormDataImporter()) - .set_local_card_migration_manager( - std::move(local_card_migration_manager)); -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - - browser_autofill_manager_ = - std::make_unique<TestBrowserAutofillManager>(autofill_driver_.get()); - autofill_client_.GetVotesUploader().set_expected_observed_submission(true); - } - - void TearDown() override { - // Order of destruction is important as BrowserAutofillManager relies on - // PersonalDataManager to be around when it gets destroyed. - browser_autofill_manager_.reset(); - autofill_driver_.reset(); - - personal_data().SetPrefService(nullptr); - personal_data().test_payments_data_manager().ClearCreditCards(); - } - - void FormsSeen(const std::vector<FormData>& updated_forms) { - browser_autofill_manager_->OnFormsSeen(/*updated_forms=*/updated_forms, - /*removed_forms=*/{}); - } - - void FormSubmitted(const FormData& form) { - browser_autofill_manager_->OnFormSubmitted( - form, mojom::SubmissionSource::FORM_SUBMISSION); - } - - void EditCreditCardForm(FormData& credit_card_form, - std::string_view name_on_card, - std::string_view card_number, - std::string_view expiration_month, - std::string_view expiration_year, - std::string_view cvc) { - DCHECK(credit_card_form.fields().size() >= 5); - test_api(credit_card_form).field(0).set_value(ASCIIToUTF16(name_on_card)); - test_api(credit_card_form).field(1).set_value(ASCIIToUTF16(card_number)); - test_api(credit_card_form) - .field(2) - .set_value(ASCIIToUTF16(expiration_month)); - test_api(credit_card_form) - .field(3) - .set_value(ASCIIToUTF16(expiration_year)); - test_api(credit_card_form).field(4).set_value(ASCIIToUTF16(cvc)); - } - - void AddLocalCreditCard(TestPersonalDataManager& personal_data, - const char* name_on_card, - const char* card_number, - const char* expiration_month, - const char* expiration_year, - const std::string& billing_address_id, - const base::Uuid& guid) { - CreditCard local_card; - test::SetCreditCardInfo(&local_card, name_on_card, card_number, - expiration_month, expiration_year, - billing_address_id); - local_card.set_record_type(CreditCard::RecordType::kLocalCard); - local_card.set_guid(guid.AsLowercaseString()); - personal_data.payments_data_manager().AddCreditCard(local_card); - } - - // Set the parsed response |result| for the provided |guid|. - void SetUpMigrationResponseForGuid(const std::string& guid, - const std::string& result) { - std::unique_ptr<std::unordered_map<std::string, std::string>> save_result = - std::make_unique<std::unordered_map<std::string, std::string>>(); - save_result->insert(std::make_pair(guid, result)); - payments_network_interface_->SetSaveResultForCardsMigration( - std::move(save_result)); - } - - // Verify that the correct histogram entry (and only that) was logged. - void ExpectUniqueLocalCardMigrationDecision( - const base::HistogramTester& histogram_tester, - autofill_metrics::LocalCardMigrationDecisionMetric metric) { - histogram_tester.ExpectUniqueSample("Autofill.LocalCardMigrationDecision", - metric, 1); - } - - void UseNewCardWithLocalCardsOnFile() { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a local credit card (but it will not match what we will enter below). - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - // Add another local credit card (but it will not match what we will enter - // below). - AddLocalCreditCard(personal_data(), "Jane Doe", "4444333322221111", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Set up our credit card form data. - FormData credit_card_form = CreateTestCreditCardFormData(true, false); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - EditCreditCardForm(credit_card_form, "Jane Doe", "5555555555554444", "11", - test::NextYear(), "123"); - FormSubmitted(credit_card_form); - } - - void UseLocalCardWithOtherLocalCardsOnFile() { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a local credit card whose |TypeAndLastFourDigits| matches what we - // will enter below. - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - // Add another local credit card. - AddLocalCreditCard(personal_data(), "Jane Doe", "5555555555554444", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Set up our credit card form data. - FormData credit_card_form = CreateTestCreditCardFormData(true, false); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - EditCreditCardForm(credit_card_form, "Jane Doe", "4111111111111111", "11", - test::NextYear(), "123"); - FormSubmitted(credit_card_form); - } - - void UseLocalCardWithInvalidLocalCardsOnFile() { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a local credit card whose |TypeAndLastFourDigits| matches what we - // will enter below. - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - // Add other invalid local credit cards (invalid card number or expired), so - // it will not trigger migration. - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111112", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - AddLocalCreditCard(personal_data(), "Jane Doe", "5555555555554444", "11", - test::LastYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Set up our credit card form data. - FormData credit_card_form = CreateTestCreditCardFormData(true, false); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - EditCreditCardForm(credit_card_form, "Jane Doe", "4111111111111111", "11", - test::NextYear(), "123"); - FormSubmitted(credit_card_form); - } - - void UseServerCardWithOtherValidLocalCardsOnFile() { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a masked server credit card whose |TypeAndLastFourDigits| matches - // what we will enter below. - CreditCard credit_card(CreditCard::RecordType::kMaskedServerCard, - /*server_id=*/"a123"); - test::SetCreditCardInfo(&credit_card, "Jane Doe", "1111", "11", - test::NextYear().c_str(), "1"); - credit_card.SetNetworkForMaskedCard(kVisaCard); - personal_data().test_payments_data_manager().AddServerCreditCard( - credit_card); - // Add one valid local credit card, so it will trigger migration - AddLocalCreditCard(personal_data(), "Jane Doe", "5555555555554444", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Set up our credit card form data. - FormData credit_card_form = CreateTestCreditCardFormData(true, false); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - EditCreditCardForm(credit_card_form, "Jane Doe", "4111111111111111", "11", - test::NextYear(), "123"); - FormSubmitted(credit_card_form); - } - - void UseServerCardWithInvalidLocalCardsOnFile() { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a masked credit card whose |TypeAndLastFourDigits| matches what we - // will enter below. - CreditCard credit_card(CreditCard::RecordType::kMaskedServerCard, - /*server_id=*/"a123"); - test::SetCreditCardInfo(&credit_card, "Jane Doe", "1111", "11", - test::NextYear().c_str(), "1"); - credit_card.SetNetworkForMaskedCard(kVisaCard); - personal_data().test_payments_data_manager().AddServerCreditCard( - credit_card); - // Add other invalid local credit cards (invalid card number or expired), so - // it will not trigger migration. - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111112", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - AddLocalCreditCard(personal_data(), "Jane Doe", "5555555555554444", "11", - test::LastYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Set up our credit card form data. - FormData credit_card_form = CreateTestCreditCardFormData(true, false); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - EditCreditCardForm(credit_card_form, "Jane Doe", "4111111111111111", "11", - test::NextYear(), "123"); - FormSubmitted(credit_card_form); - } - - protected: - TestPersonalDataManager& personal_data() { - return autofill_client_.GetPersonalDataManager(); - } - - payments::TestPaymentsAutofillClient& payments_autofill_client() { - return *autofill_client_.GetPaymentsAutofillClient(); - } - - base::test::TaskEnvironment task_environment_; - test::AutofillUnitTestEnvironment autofill_test_environment_; - syncer::TestSyncService sync_service_; - TestAutofillClient autofill_client_; - std::unique_ptr<TestAutofillDriver> autofill_driver_; - std::unique_ptr<TestBrowserAutofillManager> browser_autofill_manager_; - // Ends up getting owned (and destroyed) by TestAutofillClient: - raw_ptr<TestStrikeDatabase> strike_database_; - // Ends up getting owned (and destroyed) by TestFormDataImporter: - raw_ptr<TestCreditCardSaveManager> credit_card_save_manager_; - // Ends up getting owned (and destroyed) by TestFormDataImporter: - raw_ptr<TestLocalCardMigrationManager> local_card_migration_manager_; - // Ends up getting owned (and destroyed) by TestAutofillClient: - raw_ptr<payments::TestPaymentsNetworkInterface> payments_network_interface_; -}; - -// Having one local card on file and using it will not trigger migration. -TEST_F(LocalCardMigrationManagerTest, - MigrateCreditCard_UseLocalCardWithOneLocal) { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a local credit card whose |TypeAndLastFourDigits| matches what we will - // enter below. - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Set up our credit card form data. - FormData credit_card_form = CreateTestCreditCardFormData(true, false); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - EditCreditCardForm(credit_card_form, "Jane Doe", "4111111111111111", "11", - test::NextYear(), "123"); - FormSubmitted(credit_card_form); - EXPECT_FALSE(local_card_migration_manager_->LocalCardMigrationWasTriggered()); -} - -// Having any number of local cards on file and using a new card will not -// trigger migration. -TEST_F(LocalCardMigrationManagerTest, - MigrateCreditCard_UseNewCardWithAnyLocal) { - UseNewCardWithLocalCardsOnFile(); - - EXPECT_FALSE(local_card_migration_manager_->LocalCardMigrationWasTriggered()); -} - -// Use one local card with more valid local cards available, will trigger -// migration. -TEST_F(LocalCardMigrationManagerTest, - MigrateCreditCard_UseLocalCardWithMoreLocal) { - // Use one local card with more valid local cards available. - UseLocalCardWithOtherLocalCardsOnFile(); - - EXPECT_TRUE(local_card_migration_manager_->LocalCardMigrationWasTriggered()); -} - -// Using a local card will not trigger migration even if there are other local -// cards as long as the other local cards are not eligible for migration. -TEST_F(LocalCardMigrationManagerTest, - MigrateCreditCard_UseLocalCardWithInvalidLocal) { - UseLocalCardWithInvalidLocalCardsOnFile(); - - EXPECT_FALSE(local_card_migration_manager_->LocalCardMigrationWasTriggered()); -} - -// Using a server card when any number of local cards are eligible for migration -// will trigger migration. -TEST_F(LocalCardMigrationManagerTest, - MigrateCreditCard_UseServerCardWithOneValidLocal) { - // Use one server card with more valid local cards available. - UseServerCardWithOtherValidLocalCardsOnFile(); - - EXPECT_TRUE(local_card_migration_manager_->LocalCardMigrationWasTriggered()); -} - -// Using a server card will not trigger migration even if there are other local -// cards as long as the other local cards are not eligible for migration. -TEST_F(LocalCardMigrationManagerTest, - MigrateCreditCard_UseServerCardWithNoneValidLocal) { - UseServerCardWithInvalidLocalCardsOnFile(); - - EXPECT_FALSE(local_card_migration_manager_->LocalCardMigrationWasTriggered()); -} - -// Trigger migration if user only signs in. -TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_SignInOnly) { - // Mock Chrome Sync is disabled. - local_card_migration_manager_->EnablePaymentsWalletSyncInTransportMode(); - - // Use one local card with more valid local cards available. - UseLocalCardWithOtherLocalCardsOnFile(); - - EXPECT_TRUE(local_card_migration_manager_->LocalCardMigrationWasTriggered()); -} - -// Use one local card with more valid local cards available but billing customer -// number is blank, will not trigger migration. -TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_NoPaymentsAccount) { - // Add a local credit card whose |TypeAndLastFourDigits| matches what we will - // enter below. - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - // Add another local credit card. - AddLocalCreditCard(personal_data(), "Jane Doe", "5555555555554444", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Set up our credit card form data. - FormData credit_card_form = CreateTestCreditCardFormData(true, false); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - EditCreditCardForm(credit_card_form, "Jane Doe", "4111111111111111", "11", - test::NextYear(), "123"); - FormSubmitted(credit_card_form); - EXPECT_FALSE(local_card_migration_manager_->LocalCardMigrationWasTriggered()); -} - -// Tests that local cards that match masked server cards do not count as -// migratable. -TEST_F(LocalCardMigrationManagerTest, - MigrateCreditCard_LocalCardMatchMaskedServerCard) { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a masked server card whose |TypeAndLastFourDigits| matches a local - // card. - CreditCard server_card(CreditCard::RecordType::kMaskedServerCard, "a123"); - test::SetCreditCardInfo(&server_card, "Jane Doe", "1111", "11", - test::NextYear().c_str(), "1"); - server_card.SetNetworkForMaskedCard(kVisaCard); - personal_data().test_payments_data_manager().AddServerCreditCard(server_card); - // Add a local card whose |TypeAndLastFourDigits| matches a masked server - // card. - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - // Add another local credit card - AddLocalCreditCard(personal_data(), "Jane Doe", "5555555555554444", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Set up our credit card form data. - FormData credit_card_form = CreateTestCreditCardFormData(true, false); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - EditCreditCardForm(credit_card_form, "Jane Doe", "5555555555554444", "11", - test::NextYear(), "123"); - FormSubmitted(credit_card_form); - EXPECT_FALSE(local_card_migration_manager_->LocalCardMigrationWasTriggered()); -} - -// GetDetectedValues() should includes cardholder name if all cards have it. -TEST_F(LocalCardMigrationManagerTest, GetDetectedValues_AllWithCardHolderName) { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a local credit card whose |TypeAndLastFourDigits| matches what we will - // enter below. - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - // Add another local credit card with a different cardholder name. - AddLocalCreditCard(personal_data(), "John Smith", "5555555555554444", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Set up our credit card form data. - FormData credit_card_form = CreateTestCreditCardFormData(true, false); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - EditCreditCardForm(credit_card_form, "Jane Doe", "4111111111111111", "11", - test::NextYear(), "123"); - FormSubmitted(credit_card_form); - EXPECT_TRUE(local_card_migration_manager_->LocalCardMigrationWasTriggered()); - EXPECT_TRUE(local_card_migration_manager_->GetDetectedValues() & - CreditCardSaveManager::DetectedValue::CARDHOLDER_NAME); -} - -// GetDetectedValues() should not include cardholder name if not all cards have -// a cardholder name. -TEST_F(LocalCardMigrationManagerTest, - GetDetectedValues_OneCardWithoutCardHolderName) { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a local credit card whose |TypeAndLastFourDigits| matches what we will - // enter below. - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - // Add another local credit card without card holder name. - AddLocalCreditCard(personal_data(), "", "5555555555554444", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - // Set up our credit card form data. - FormData credit_card_form = CreateTestCreditCardFormData(true, false); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - EditCreditCardForm(credit_card_form, "Jane Doe", "4111111111111111", "11", - test::NextYear(), "123"); - FormSubmitted(credit_card_form); - EXPECT_TRUE(local_card_migration_manager_->LocalCardMigrationWasTriggered()); - EXPECT_FALSE(local_card_migration_manager_->GetDetectedValues() & - CreditCardSaveManager::DetectedValue::CARDHOLDER_NAME); -} - -// GetDetectedValues() should include the existence of a Google Payments -// account. -TEST_F(LocalCardMigrationManagerTest, - GetDetectedValues_IncludeGooglePaymentsAccount) { - // Use one local card with more valid local cards available. - UseLocalCardWithOtherLocalCardsOnFile(); - - EXPECT_TRUE( - local_card_migration_manager_->GetDetectedValues() & - CreditCardSaveManager::DetectedValue::HAS_GOOGLE_PAYMENTS_ACCOUNT); -} - -TEST_F(LocalCardMigrationManagerTest, - MigrateCreditCard_ShouldAddMigrateCardsBillableServiceNumberInRequest) { - // Use one local card with more valid local cards available. - UseLocalCardWithOtherLocalCardsOnFile(); - - // Confirm that the preflight request contained - // kMigrateCardsBillableServiceNumber in the request. - EXPECT_EQ(payments::kMigrateCardsBillableServiceNumber, - payments_network_interface_->billable_service_number_in_request()); -} - -TEST_F(LocalCardMigrationManagerTest, - MigrateCreditCard_ShouldAddMigrateCardsBillingCustomerNumberInRequest) { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Use one local card with more valid local cards available. - UseLocalCardWithOtherLocalCardsOnFile(); - - // Confirm that the preflight request contained - // billing customer number in the request. - EXPECT_EQ(123456L, - payments_network_interface_->billing_customer_number_in_request()); -} - -TEST_F(LocalCardMigrationManagerTest, - MigrateCreditCard_ShouldAddUploadCardSourceInRequest_CheckoutFlow) { - // Use one local card with more valid local cards available. - UseLocalCardWithOtherLocalCardsOnFile(); - - // Confirm that the preflight request contained the correct UploadCardSource. - EXPECT_EQ(payments::UploadCardSource::LOCAL_CARD_MIGRATION_CHECKOUT_FLOW, - payments_network_interface_->upload_card_source_in_request()); -} - -TEST_F(LocalCardMigrationManagerTest, - MigrateCreditCard_ShouldAddUploadCardSourceInRequest_SettingsPage) { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a local credit card. One migratable credit card will still trigger - // migration on settings page. - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Do the same operation as we bridge back from the settings page. - local_card_migration_manager_->GetMigratableCreditCards(); - local_card_migration_manager_->AttemptToOfferLocalCardMigration(true); - - EXPECT_FALSE(local_card_migration_manager_->IntermediatePromptWasShown()); - EXPECT_TRUE(local_card_migration_manager_->MainPromptWasShown()); - - // Confirm that the preflight request contained the correct UploadCardSource. - EXPECT_EQ(payments::UploadCardSource::LOCAL_CARD_MIGRATION_SETTINGS_PAGE, - payments_network_interface_->upload_card_source_in_request()); -} - -// Verify that when triggering from settings page, intermediate prompt will not -// be triggered. -TEST_F(LocalCardMigrationManagerTest, - MigrateCreditCard_TriggerFromSettingsPage) { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a local credit card. One migratable credit card will still trigger - // migration on settings page. - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Do the same operation as we bridge back from the settings page. - local_card_migration_manager_->GetMigratableCreditCards(); - local_card_migration_manager_->AttemptToOfferLocalCardMigration(true); - - EXPECT_FALSE(local_card_migration_manager_->IntermediatePromptWasShown()); - EXPECT_TRUE(local_card_migration_manager_->MainPromptWasShown()); -} - -// Verify that when triggering from submitted form, intermediate prompt and main -// prompt are both triggered. -TEST_F(LocalCardMigrationManagerTest, - MigrateCreditCard_TriggerFromSubmittedForm) { - // Use one local card with more valid local cards available. - UseLocalCardWithOtherLocalCardsOnFile(); - - EXPECT_TRUE(local_card_migration_manager_->IntermediatePromptWasShown()); - EXPECT_TRUE(local_card_migration_manager_->MainPromptWasShown()); -} - -// Verify that given the parsed response from the PaymentsNetworkInterface, the -// migration status is correctly set. -TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_MigrationSuccess) { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a local credit card for migration. - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Verify that it exists in the local database. - EXPECT_TRUE(personal_data().payments_data_manager().GetCreditCardByNumber( - "4111111111111111")); - - // Get the migratable credit cards. - local_card_migration_manager_->GetMigratableCreditCards(); - - // Set the parsed response to success. - SetUpMigrationResponseForGuid( - local_card_migration_manager_->migratable_credit_cards_[0] - .credit_card() - .guid(), - kMigrationResultSuccess); - - EXPECT_EQ(local_card_migration_manager_->migratable_credit_cards_[0] - .migration_status(), - MigratableCreditCard::MigrationStatus::UNKNOWN); - - local_card_migration_manager_->AttemptToOfferLocalCardMigration(true); - - EXPECT_EQ(local_card_migration_manager_->migratable_credit_cards_[0] - .migration_status(), - MigratableCreditCard::MigrationStatus::SUCCESS_ON_UPLOAD); - - // Local card should *not* be present as it is migrated already. - EXPECT_FALSE(personal_data().payments_data_manager().GetCreditCardByNumber( - "4111111111111111")); -} - -// Verify that given the parsed response from the PaymentsNetworkInterface, the -// migration status is correctly set. -TEST_F(LocalCardMigrationManagerTest, - MigrateCreditCard_MigrationTemporaryFailure) { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a local credit card. One migratable credit card will still trigger - // migration on settings page. - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Verify that it exists in local database. - EXPECT_TRUE(personal_data().payments_data_manager().GetCreditCardByNumber( - "4111111111111111")); - - // Get the migratable credit cards. - local_card_migration_manager_->GetMigratableCreditCards(); - - // Set the parsed response to temporary failure. - SetUpMigrationResponseForGuid( - local_card_migration_manager_->migratable_credit_cards_[0] - .credit_card() - .guid(), - kMigrationResultTemporaryFailure); - - EXPECT_EQ(local_card_migration_manager_->migratable_credit_cards_[0] - .migration_status(), - MigratableCreditCard::MigrationStatus::UNKNOWN); - - // Start the migration. - local_card_migration_manager_->AttemptToOfferLocalCardMigration(true); - - EXPECT_EQ(local_card_migration_manager_->migratable_credit_cards_[0] - .migration_status(), - MigratableCreditCard::MigrationStatus::FAILURE_ON_UPLOAD); - - // Local card should be present as it is not migrated. - EXPECT_TRUE(personal_data().payments_data_manager().GetCreditCardByNumber( - "4111111111111111")); -} - -// Verify that given the parsed response from the PaymentsNetworkInterface, the -// migration status is correctly set. -TEST_F(LocalCardMigrationManagerTest, - MigrateCreditCard_MigrationPermanentFailure) { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a local credit card. One migratable credit card will still trigger - // migration on settings page. - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Verify that it exists in local database. - EXPECT_TRUE(personal_data().payments_data_manager().GetCreditCardByNumber( - "4111111111111111")); - - // Get the migratable credit cards. - local_card_migration_manager_->GetMigratableCreditCards(); - - // Set the parsed response to permanent failure. - SetUpMigrationResponseForGuid( - local_card_migration_manager_->migratable_credit_cards_[0] - .credit_card() - .guid(), - kMigrationResultPermanentFailure); - - EXPECT_EQ(local_card_migration_manager_->migratable_credit_cards_[0] - .migration_status(), - MigratableCreditCard::MigrationStatus::UNKNOWN); - - // Start the migration. - local_card_migration_manager_->AttemptToOfferLocalCardMigration(true); - - EXPECT_EQ(local_card_migration_manager_->migratable_credit_cards_[0] - .migration_status(), - MigratableCreditCard::MigrationStatus::FAILURE_ON_UPLOAD); - - // Local card should be present as it is not migrated. - EXPECT_TRUE(personal_data().payments_data_manager().GetCreditCardByNumber( - "4111111111111111")); -} - -// Verify selected cards are correctly passed to manager. -TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_ToggleIsChosen) { - const base::Uuid guid1 = base::Uuid::GenerateRandomV4(); - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", guid1); - - const base::Uuid guid2 = base::Uuid::GenerateRandomV4(); - AddLocalCreditCard(personal_data(), "Jane Doe", "5454545454545454", "11", - test::NextYear().c_str(), "1", guid2); - - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - local_card_migration_manager_->GetMigratableCreditCards(); - - payments_autofill_client().set_migration_card_selections( - std::vector<std::string>{guid1.AsLowercaseString()}); - local_card_migration_manager_->AttemptToOfferLocalCardMigration(true); - - EXPECT_EQ(static_cast<int>( - local_card_migration_manager_->migratable_credit_cards_.size()), - 1); - EXPECT_EQ(local_card_migration_manager_->migratable_credit_cards_[0] - .credit_card() - .guid(), - guid1.AsLowercaseString()); -} - -TEST_F(LocalCardMigrationManagerTest, DeleteLocalCardViaMigrationDialog) { - const base::Uuid guid = base::Uuid::GenerateRandomV4(); - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", guid); - - const std::string guid_str = guid.AsLowercaseString(); - EXPECT_TRUE( - personal_data().payments_data_manager().GetCreditCardByGUID(guid_str)); - - local_card_migration_manager_->OnUserDeletedLocalCardViaMigrationDialog( - guid_str); - - EXPECT_FALSE( - personal_data().payments_data_manager().GetCreditCardByGUID(guid_str)); -} - -// Use one local card with more valid local cards available, don't show prompt -// if max strikes reached. -TEST_F(LocalCardMigrationManagerTest, - MigrateLocalCreditCard_MaxStrikesReached) { - LocalCardMigrationStrikeDatabase local_card_migration_strike_database = - LocalCardMigrationStrikeDatabase(strike_database_); - local_card_migration_strike_database.AddStrikes( - local_card_migration_strike_database.GetMaxStrikesLimit()); - - EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), - local_card_migration_strike_database.GetMaxStrikesLimit()); - - base::HistogramTester histogram_tester; - // Use one local card with more valid local cards available. - UseLocalCardWithOtherLocalCardsOnFile(); - - // Local card migration not triggered since max strikes have been reached. - EXPECT_FALSE(local_card_migration_manager_->LocalCardMigrationWasTriggered()); - - // Verify that the correct histogram entry was logged. - histogram_tester.ExpectBucketCount( - "Autofill.StrikeDatabase.LocalCardMigrationNotOfferedDueToMaxStrikes", - AutofillMetrics::SaveTypeMetric::LOCAL, 1); -} - -// Use one server card with more valid local cards available, don't show prompt -// if max strikes reached. -TEST_F(LocalCardMigrationManagerTest, - MigrateServerCreditCard_MaxStrikesReached) { - LocalCardMigrationStrikeDatabase local_card_migration_strike_database = - LocalCardMigrationStrikeDatabase(strike_database_); - local_card_migration_strike_database.AddStrikes( - local_card_migration_strike_database.GetMaxStrikesLimit()); - - EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), - local_card_migration_strike_database.GetMaxStrikesLimit()); - - base::HistogramTester histogram_tester; - // Use one server card with more valid local cards available. - UseServerCardWithOtherValidLocalCardsOnFile(); - - // Local card migration not triggered since max strikes have been reached. - EXPECT_FALSE(local_card_migration_manager_->LocalCardMigrationWasTriggered()); - - // Verify that the correct histogram entry was logged. - histogram_tester.ExpectBucketCount( - "Autofill.StrikeDatabase.LocalCardMigrationNotOfferedDueToMaxStrikes", - AutofillMetrics::SaveTypeMetric::SERVER, 1); -} - -// When local card migration is accepted, UMA metrics for LocalCardMigration -// strike count is logged. -TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_StrikeCountUMALogged) { - const base::Uuid guid1 = base::Uuid::GenerateRandomV4(); - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", guid1); - - const base::Uuid guid2 = base::Uuid::GenerateRandomV4(); - AddLocalCreditCard(personal_data(), "Jane Doe", "5454545454545454", "11", - test::NextYear().c_str(), "1", guid2); - - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - local_card_migration_manager_->GetMigratableCreditCards(); - - // Add 4 LocalCardMigration strikes. - LocalCardMigrationStrikeDatabase local_card_migration_strike_database = - LocalCardMigrationStrikeDatabase(strike_database_); - local_card_migration_strike_database.AddStrikes(4); - EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), 4); - - base::HistogramTester histogram_tester; - - // Select the cards. - payments_autofill_client().set_migration_card_selections( - std::vector<std::string>{guid1.AsLowercaseString(), - guid2.AsLowercaseString()}); - local_card_migration_manager_->AttemptToOfferLocalCardMigration(true); - - // Verify that the strike count was logged when card migration accepted. - histogram_tester.ExpectBucketCount( - "Autofill.StrikeDatabase.StrikesPresentWhenLocalCardMigrationAccepted", 4, - 1); -} - -// Use one unsupported local card with more supported local cards will not -// show intermediate prompt. -TEST_F(LocalCardMigrationManagerTest, - MigrateCreditCard_MigrationAbortWhenUseUnsupportedLocalCard) { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a local credit card whose |TypeAndLastFourDigits| matches what we will - // enter below. - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - // Add another local credit card. - AddLocalCreditCard(personal_data(), "Jane Doe", "5555555555554444", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Set up our credit card form data. - FormData credit_card_form = CreateTestCreditCardFormData(true, false); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Set up the supported card bin ranges so that the used local card is not - // supported but the one left is supported. - std::vector<std::pair<int, int>> supported_card_bin_ranges{ - std::make_pair(300, 305), std::make_pair(555, 555)}; - payments_network_interface_->SetSupportedBINRanges(supported_card_bin_ranges); - - // Edit the data, and submit. - EditCreditCardForm(credit_card_form, "Jane Doe", "4111111111111111", "11", - test::NextYear(), "123"); - FormSubmitted(credit_card_form); - EXPECT_FALSE(local_card_migration_manager_->IntermediatePromptWasShown()); -} - -// Use one supported local card with more unsupported local cards available -// will show intermediate prompt with the only supported local card. -TEST_F(LocalCardMigrationManagerTest, - MigrateCreditCard_MigrateWhenHasSupportedLocalCard) { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a local credit card whose |TypeAndLastFourDigits| matches what we will - // enter below. - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - // Add another local credit card. - AddLocalCreditCard(personal_data(), "Jane Doe", "5555555555554444", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Set up the supported card bin ranges so that the used local card is the - // only supported card. - std::vector<std::pair<int, int>> supported_card_bin_ranges{ - std::make_pair(300, 305), std::make_pair(411, 412)}; - payments_network_interface_->SetSupportedBINRanges(supported_card_bin_ranges); - - // Set up our credit card form data. - FormData credit_card_form = CreateTestCreditCardFormData(true, false); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - EditCreditCardForm(credit_card_form, "Jane Doe", "4111111111111111", "11", - test::NextYear(), "123"); - FormSubmitted(credit_card_form); - - EXPECT_EQ(static_cast<int>( - local_card_migration_manager_->migratable_credit_cards_.size()), - 1); - EXPECT_EQ(local_card_migration_manager_->migratable_credit_cards_[0] - .credit_card() - .number(), - u"4111111111111111"); - EXPECT_TRUE(local_card_migration_manager_->IntermediatePromptWasShown()); -} - -// Use one unsupported server card with more supported local cards available -// will still show intermediate prompt. -TEST_F( - LocalCardMigrationManagerTest, - MigrateCreditCard_MigrateWhenUseUnsupportedServerCardWithSupportedLocalCard) { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a masked server credit card whose |TypeAndLastFourDigits| matches what - // we will enter below. - CreditCard credit_card(CreditCard::RecordType::kMaskedServerCard, "a123"); - test::SetCreditCardInfo(&credit_card, "Jane Doe", "1111", "11", - test::NextYear().c_str(), "1"); - credit_card.SetNetworkForMaskedCard(kVisaCard); - personal_data().test_payments_data_manager().AddServerCreditCard(credit_card); - // Add one valid local credit card, so it will trigger migration - AddLocalCreditCard(personal_data(), "Jane Doe", "5555555555554444", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Set up the supported card bin ranges so that the used server card is - // unsupported but the one left is supported. - std::vector<std::pair<int, int>> supported_card_bin_ranges{ - std::make_pair(300, 305), std::make_pair(555, 555)}; - payments_network_interface_->SetSupportedBINRanges(supported_card_bin_ranges); - - // Set up our credit card form data. - FormData credit_card_form = CreateTestCreditCardFormData(true, false); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - EditCreditCardForm(credit_card_form, "Jane Doe", "4111111111111111", "11", - test::NextYear(), "123"); - FormSubmitted(credit_card_form); - - EXPECT_TRUE(local_card_migration_manager_->IntermediatePromptWasShown()); -} - -// Use one supported server card with more unsupported local cards will not show -// intermediate prompt. -TEST_F( - LocalCardMigrationManagerTest, - MigrateCreditCard_MigrateAbortWhenUseSupportedServerCardWithUnsupportedLocalCard) { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a masked server credit card whose |TypeAndLastFourDigits| matches what - // we will enter below. - CreditCard credit_card(CreditCard::RecordType::kMaskedServerCard, "a123"); - test::SetCreditCardInfo(&credit_card, "Jane Doe", "1111", "11", - test::NextYear().c_str(), "1"); - credit_card.SetNetworkForMaskedCard(kVisaCard); - personal_data().test_payments_data_manager().AddServerCreditCard(credit_card); - // Add one valid local credit card, so it will trigger migration - AddLocalCreditCard(personal_data(), "Jane Doe", "5555555555554444", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Set up the supported card bin ranges so that the used server card is - // supported while the one left is unsupported. - std::vector<std::pair<int, int>> supported_card_bin_ranges{ - std::make_pair(300, 305), std::make_pair(411, 411)}; - payments_network_interface_->SetSupportedBINRanges(supported_card_bin_ranges); - - // Set up our credit card form data. - FormData credit_card_form = CreateTestCreditCardFormData(true, false); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - EditCreditCardForm(credit_card_form, "Jane Doe", "4111111111111111", "11", - test::NextYear(), "123"); - FormSubmitted(credit_card_form); - - EXPECT_FALSE(local_card_migration_manager_->IntermediatePromptWasShown()); -} - -// All migration requirements are met but GetUploadDetails rpc fails. Verified -// that the intermediate prompt was not shown. -TEST_F(LocalCardMigrationManagerTest, MigrateCreditCard_GetUploadDetailsFails) { - // Anything other than "en-US" will cause GetUploadDetails to return a failure - // response. - autofill_client_.set_app_locale("pt-BR"); - - UseLocalCardWithOtherLocalCardsOnFile(); - - EXPECT_FALSE(local_card_migration_manager_->IntermediatePromptWasShown()); -} - -// Use one local card with more valid local cards available, will log to -// UseOfLocalCard sub-histogram. -TEST_F(LocalCardMigrationManagerTest, - LogMigrationOrigin_UseLocalCardWithMoreLocal) { - base::HistogramTester histogram_tester; - // Use one local card with more valid local cards available. - UseLocalCardWithOtherLocalCardsOnFile(); - - // Verify that metrics are correctly logged to the UseOfLocalCard - // sub-histogram. - histogram_tester.ExpectBucketCount( - "Autofill.LocalCardMigrationOrigin.UseOfLocalCard", - autofill_metrics::INTERMEDIATE_BUBBLE_SHOWN, 1); - histogram_tester.ExpectBucketCount( - "Autofill.LocalCardMigrationOrigin.UseOfLocalCard", - autofill_metrics::INTERMEDIATE_BUBBLE_ACCEPTED, 1); - histogram_tester.ExpectBucketCount( - "Autofill.LocalCardMigrationOrigin.UseOfLocalCard", - autofill_metrics::MAIN_DIALOG_SHOWN, 1); - histogram_tester.ExpectBucketCount( - "Autofill.LocalCardMigrationOrigin.UseOfLocalCard", - autofill_metrics::MAIN_DIALOG_ACCEPTED, 1); -} - -// Using a server card when any number of local cards are eligible for migration -// will log to UseOfServerCard sub-histogram. -TEST_F(LocalCardMigrationManagerTest, - LogMigrationOrigin_UseServerCardWithOneValidLocal) { - base::HistogramTester histogram_tester; - // Use one server card with more valid local cards available. - UseServerCardWithOtherValidLocalCardsOnFile(); - - // Verify that metrics are correctly logged to the UseOfServerCard - // sub-histogram. - histogram_tester.ExpectBucketCount( - "Autofill.LocalCardMigrationOrigin.UseOfServerCard", - autofill_metrics::INTERMEDIATE_BUBBLE_SHOWN, 1); - histogram_tester.ExpectBucketCount( - "Autofill.LocalCardMigrationOrigin.UseOfServerCard", - autofill_metrics::INTERMEDIATE_BUBBLE_ACCEPTED, 1); - histogram_tester.ExpectBucketCount( - "Autofill.LocalCardMigrationOrigin.UseOfServerCard", - autofill_metrics::MAIN_DIALOG_SHOWN, 1); - histogram_tester.ExpectBucketCount( - "Autofill.LocalCardMigrationOrigin.UseOfServerCard", - autofill_metrics::MAIN_DIALOG_ACCEPTED, 1); -} - -// Using a server card will not trigger migration even if there are other local -// cards as long as the other local cards are not eligible for migration. Verify -// that it will not log to UseOfServerCard sub-histogram. -TEST_F(LocalCardMigrationManagerTest, - LogMigrationOrigin_UseServerCardWithNoneValidLocal) { - base::HistogramTester histogram_tester; - UseServerCardWithInvalidLocalCardsOnFile(); - - // Verify that metrics are correctly logged to the UseOfServerCard - // sub-histogram. - histogram_tester.ExpectTotalCount( - "Autofill.LocalCardMigrationOrigin.UseOfServerCard", 0); -} - -// Verify that triggering from settings page will log to SettingsPage -// sub-histogram. -TEST_F(LocalCardMigrationManagerTest, - LogMigrationOrigin_TriggerFromSettingsPage) { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a local credit card. One migratable credit card will still trigger - // migration on settings page. - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - base::HistogramTester histogram_tester; - // Do the same operation as we bridge back from the settings page. - local_card_migration_manager_->GetMigratableCreditCards(); - local_card_migration_manager_->AttemptToOfferLocalCardMigration(true); - - // Verify that metrics are correctly logged to the SettingsPage sub-histogram. - // Triggering from settings page won't show intermediate bubble. - histogram_tester.ExpectBucketCount( - "Autofill.LocalCardMigrationOrigin.SettingsPage", - autofill_metrics::INTERMEDIATE_BUBBLE_SHOWN, 0); - histogram_tester.ExpectBucketCount( - "Autofill.LocalCardMigrationOrigin.SettingsPage", - autofill_metrics::INTERMEDIATE_BUBBLE_ACCEPTED, 0); - histogram_tester.ExpectBucketCount( - "Autofill.LocalCardMigrationOrigin.SettingsPage", - autofill_metrics::MAIN_DIALOG_SHOWN, 1); - histogram_tester.ExpectBucketCount( - "Autofill.LocalCardMigrationOrigin.SettingsPage", - autofill_metrics::MAIN_DIALOG_ACCEPTED, 1); -} - -// Use new card when submit so migration was not offered. Verify the migration -// decision metric is logged as new card used. -TEST_F(LocalCardMigrationManagerTest, LogMigrationDecisionMetric_UseNewCard) { - base::HistogramTester histogram_tester; - UseNewCardWithLocalCardsOnFile(); - - ExpectUniqueLocalCardMigrationDecision( - histogram_tester, autofill_metrics::LocalCardMigrationDecisionMetric:: - NOT_OFFERED_USE_NEW_CARD); -} - -// Use one local card with more valid local cards available but billing customer -// number is blank, will not trigger migration. Verify the migration decision -// metric is logged as failed enablement prerequisites. -TEST_F(LocalCardMigrationManagerTest, - LogMigrationDecisionMetric_FailedEnablementPrerequisites) { - base::HistogramTester histogram_tester; - // Add a local credit card whose |TypeAndLastFourDigits| matches what we will - // enter below. - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - // Add another local credit card. - AddLocalCreditCard(personal_data(), "Jane Doe", "5555555555554444", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Set up our credit card form data. - FormData credit_card_form = CreateTestCreditCardFormData(true, false); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - EditCreditCardForm(credit_card_form, "Jane Doe", "4111111111111111", "11", - test::NextYear(), "123"); - FormSubmitted(credit_card_form); - - ExpectUniqueLocalCardMigrationDecision( - histogram_tester, autofill_metrics::LocalCardMigrationDecisionMetric:: - NOT_OFFERED_FAILED_PREREQUISITES); -} - -// All migration requirements are met but max strikes reached. Verify the -// migration decision metric is logged as max strikes reached. -TEST_F(LocalCardMigrationManagerTest, - LogMigrationDecisionMetric_MaxStrikesReached) { - LocalCardMigrationStrikeDatabase local_card_migration_strike_database = - LocalCardMigrationStrikeDatabase(strike_database_); - local_card_migration_strike_database.AddStrikes( - local_card_migration_strike_database.GetMaxStrikesLimit()); - - EXPECT_EQ(local_card_migration_strike_database.GetStrikes(), - local_card_migration_strike_database.GetMaxStrikesLimit()); - - base::HistogramTester histogram_tester; - UseLocalCardWithOtherLocalCardsOnFile(); - - ExpectUniqueLocalCardMigrationDecision( - histogram_tester, autofill_metrics::LocalCardMigrationDecisionMetric:: - NOT_OFFERED_REACHED_MAX_STRIKE_COUNT); -} - -// Use one local card with invalid local card so migration was not offered. -// Verify the migration decision metric is logged as not offered single local -// card. -TEST_F(LocalCardMigrationManagerTest, - LogMigrationDecisionMetric_NotOfferedSingleLocalCard) { - base::HistogramTester histogram_tester; - UseLocalCardWithInvalidLocalCardsOnFile(); - - ExpectUniqueLocalCardMigrationDecision( - histogram_tester, autofill_metrics::LocalCardMigrationDecisionMetric:: - NOT_OFFERED_SINGLE_LOCAL_CARD); -} - -// Use one server card with invalid local card so migration was not offered. -// Verify the migration decision metric is logged as no migratable cards. -TEST_F(LocalCardMigrationManagerTest, - LogMigrationDecisionMetric_NoMigratableCards) { - base::HistogramTester histogram_tester; - UseServerCardWithInvalidLocalCardsOnFile(); - - ExpectUniqueLocalCardMigrationDecision( - histogram_tester, autofill_metrics::LocalCardMigrationDecisionMetric:: - NOT_OFFERED_NO_MIGRATABLE_CARDS); -} - -// All migration requirements are met but GetUploadDetails rpc fails. Verify the -// migration decision metric is logged as get upload details failed. -TEST_F(LocalCardMigrationManagerTest, - LogMigrationDecisionMetric_GetUploadDetailsFails) { - // Anything other than "en-US" will cause GetUploadDetails to return a failure - // response. - autofill_client_.set_app_locale("pt-BR"); - - base::HistogramTester histogram_tester; - UseLocalCardWithOtherLocalCardsOnFile(); - - ExpectUniqueLocalCardMigrationDecision( - histogram_tester, autofill_metrics::LocalCardMigrationDecisionMetric:: - NOT_OFFERED_GET_UPLOAD_DETAILS_FAILED); -} - -// Use one unsupported local card with more supported local cards will not -// show intermediate prompt. Verify the migration decision metric is logged as -// use unsupported local card. -TEST_F(LocalCardMigrationManagerTest, - LogMigrationDecisionMetric_UseUnsupportedLocalCard) { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a local credit card whose |TypeAndLastFourDigits| matches what we will - // enter below. - AddLocalCreditCard(personal_data(), "Jane Doe", "4111111111111111", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - // Add another local credit card. - AddLocalCreditCard(personal_data(), "Jane Doe", "5555555555554444", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - base::HistogramTester histogram_tester; - // Set up our credit card form data. - FormData credit_card_form = CreateTestCreditCardFormData(true, false); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Set up the supported card bin ranges so that the used local card is not - // supported but the one left is supported. - std::vector<std::pair<int, int>> supported_card_bin_ranges{ - std::make_pair(300, 305), std::make_pair(555, 555)}; - payments_network_interface_->SetSupportedBINRanges(supported_card_bin_ranges); - - // Edit the data, and submit. - EditCreditCardForm(credit_card_form, "Jane Doe", "4111111111111111", "11", - test::NextYear(), "123"); - FormSubmitted(credit_card_form); - - ExpectUniqueLocalCardMigrationDecision( - histogram_tester, autofill_metrics::LocalCardMigrationDecisionMetric:: - NOT_OFFERED_USE_UNSUPPORTED_LOCAL_CARD); -} - -// Use one supported server card with more unsupported local cards will not show -// intermediate prompt. Verify the migration decision metric is logged as no -// supported cards. -TEST_F(LocalCardMigrationManagerTest, - LogMigrationDecisionMetric_NoSupportedCardsForSupportedServerCard) { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a masked server credit card whose |TypeAndLastFourDigits| matches what - // we will enter below. - CreditCard credit_card(CreditCard::RecordType::kMaskedServerCard, "a123"); - test::SetCreditCardInfo(&credit_card, "Jane Doe", "1111", "11", - test::NextYear().c_str(), "1"); - credit_card.SetNetworkForMaskedCard(kVisaCard); - personal_data().test_payments_data_manager().AddServerCreditCard(credit_card); - // Add one valid local credit card, so it will trigger migration - AddLocalCreditCard(personal_data(), "Jane Doe", "5555555555554444", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Set up the supported card bin ranges so that the used server card is - // supported while the one left is unsupported. - std::vector<std::pair<int, int>> supported_card_bin_ranges{ - std::make_pair(300, 305), std::make_pair(411, 411)}; - payments_network_interface_->SetSupportedBINRanges(supported_card_bin_ranges); - - base::HistogramTester histogram_tester; - // Set up our credit card form data. - FormData credit_card_form = CreateTestCreditCardFormData(true, false); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - EditCreditCardForm(credit_card_form, "Jane Doe", "4111111111111111", "11", - test::NextYear(), "123"); - FormSubmitted(credit_card_form); - - ExpectUniqueLocalCardMigrationDecision( - histogram_tester, autofill_metrics::LocalCardMigrationDecisionMetric:: - NOT_OFFERED_NO_SUPPORTED_CARDS); -} - -// Use one unsupported server card with more unsupported local cards will not -// show intermediate prompt. Verify the migration decision metric is logged as -// no supported cards. -TEST_F(LocalCardMigrationManagerTest, - LogMigrationDecisionMetric_NoSupportedCardsForUnsupportedServerCard) { - // Set the billing_customer_number to designate existence of a Payments - // account. - personal_data().test_payments_data_manager().SetPaymentsCustomerData( - std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); - - // Add a masked server credit card whose |TypeAndLastFourDigits| matches what - // we will enter below. - CreditCard credit_card(CreditCard::RecordType::kMaskedServerCard, "a123"); - test::SetCreditCardInfo(&credit_card, "Jane Doe", "1111", "11", - test::NextYear().c_str(), "1"); - credit_card.SetNetworkForMaskedCard(kVisaCard); - personal_data().test_payments_data_manager().AddServerCreditCard(credit_card); - // Add one valid local credit card, so it will trigger migration - AddLocalCreditCard(personal_data(), "Jane Doe", "5555555555554444", "11", - test::NextYear().c_str(), "1", - base::Uuid::GenerateRandomV4()); - - // Set up the supported card bin ranges so that the used server card and local - // cards are all unsupported. - std::vector<std::pair<int, int>> supported_card_bin_ranges{ - std::make_pair(300, 305), std::make_pair(400, 400)}; - payments_network_interface_->SetSupportedBINRanges(supported_card_bin_ranges); - - base::HistogramTester histogram_tester; - // Set up our credit card form data. - FormData credit_card_form = CreateTestCreditCardFormData(true, false); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - EditCreditCardForm(credit_card_form, "Jane Doe", "4111111111111111", "11", - test::NextYear(), "123"); - FormSubmitted(credit_card_form); - - ExpectUniqueLocalCardMigrationDecision( - histogram_tester, autofill_metrics::LocalCardMigrationDecisionMetric:: - NOT_OFFERED_NO_SUPPORTED_CARDS); -} - -// All migration requirements are met and migration was offered. Verify the -// migration decision metric is logged as migration offered. -TEST_F(LocalCardMigrationManagerTest, - LogMigrationDecisionMetric_MigrationOffered) { - base::HistogramTester histogram_tester; - UseLocalCardWithOtherLocalCardsOnFile(); - - ExpectUniqueLocalCardMigrationDecision( - histogram_tester, - autofill_metrics::LocalCardMigrationDecisionMetric::OFFERED); -} - -// Tests that if the PaymentsNetworkInterface returns an invalid legal message, -// migration should not be offered. -TEST_F(LocalCardMigrationManagerTest, - InvalidLegalMessageInOnDidGetUploadDetails) { - payments_network_interface_->SetUseInvalidLegalMessageInGetUploadDetails( - true); - - base::HistogramTester histogram_tester; - UseLocalCardWithOtherLocalCardsOnFile(); - - // Verify that the correct histogram entries were logged. - ExpectUniqueLocalCardMigrationDecision( - histogram_tester, autofill_metrics::LocalCardMigrationDecisionMetric:: - NOT_OFFERED_INVALID_LEGAL_MESSAGE); -} - -} // namespace autofill
diff --git a/components/autofill/core/browser/payments/payments_autofill_client.cc b/components/autofill/core/browser/payments/payments_autofill_client.cc index 5b70096..2133e41 100644 --- a/components/autofill/core/browser/payments/payments_autofill_client.cc +++ b/components/autofill/core/browser/payments/payments_autofill_client.cc
@@ -34,21 +34,6 @@ return nullptr; } #elif !BUILDFLAG(IS_IOS) -void PaymentsAutofillClient::ShowLocalCardMigrationDialog( - base::OnceClosure show_migration_dialog_closure) {} - -void PaymentsAutofillClient::ConfirmMigrateLocalCardToCloud( - const LegalMessageLines& legal_message_lines, - const std::string& user_email, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - LocalCardMigrationCallback start_migrating_cards_callback) {} - -void PaymentsAutofillClient::ShowLocalCardMigrationResults( - bool has_server_error, - const std::u16string& tip_message, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - MigrationDeleteCardCallback delete_local_card_callback) {} - void PaymentsAutofillClient::ShowWebauthnOfferDialog( WebauthnDialogCallback offer_dialog_callback) {}
diff --git a/components/autofill/core/browser/payments/payments_autofill_client.h b/components/autofill/core/browser/payments/payments_autofill_client.h index d79dfd4..147b7ef 100644 --- a/components/autofill/core/browser/payments/payments_autofill_client.h +++ b/components/autofill/core/browser/payments/payments_autofill_client.h
@@ -44,7 +44,6 @@ class IbanAccessManager; class IbanManager; class MerchantPromoCodeManager; -class MigratableCreditCard; struct OfferNotificationOptions; class OtpUnmaskDelegate; class PaymentsDataManager; @@ -214,18 +213,6 @@ std::u16string expiration_date_year; }; - // Callback to run if user presses the Save button in the migration dialog. - // Will pass a vector of GUIDs of cards that the user selected to upload to - // LocalCardMigrationManager. - using LocalCardMigrationCallback = - base::OnceCallback<void(const std::vector<std::string>&)>; - - // Callback to run if the user presses the trash can button in the - // action-required dialog. Will pass to LocalCardMigrationManager a - // string of GUID of the card that the user selected to delete from local - // storage. - using MigrationDeleteCardCallback = - base::RepeatingCallback<void(const std::string&)>; // Callback to run after local/upload IBAN save is offered. The callback runs // with `user_decision` indicating whether the prompt was accepted, declined, // or ignored. `nickname` is optionally provided by the user when IBAN local @@ -266,33 +253,6 @@ virtual AutofillSaveCardBottomSheetBridge* GetOrCreateAutofillSaveCardBottomSheetBridge(); #elif !BUILDFLAG(IS_IOS) - // Runs `show_migration_dialog_closure` if the user accepts the card - // migration offer. This causes the card migration dialog to be shown. - virtual void ShowLocalCardMigrationDialog( - base::OnceClosure show_migration_dialog_closure); - - // Shows a dialog with the given `legal_message_lines` and the `user_email`. - // Runs `start_migrating_cards_callback` if the user would like the selected - // cards in the `migratable_credit_cards` to be uploaded to cloud. - virtual void ConfirmMigrateLocalCardToCloud( - const LegalMessageLines& legal_message_lines, - const std::string& user_email, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - LocalCardMigrationCallback start_migrating_cards_callback); - - // Will show a dialog containing a error message if `has_server_error` - // is true, or the migration results for cards in - // `migratable_credit_cards` otherwise. If migration succeeds the dialog will - // contain a `tip_message`. `migratable_credit_cards` will be used when - // constructing the dialog. The dialog is invoked when the migration process - // is finished. Runs `delete_local_card_callback` if the user chose to delete - // one invalid card from local storage. - virtual void ShowLocalCardMigrationResults( - bool has_server_error, - const std::u16string& tip_message, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - MigrationDeleteCardCallback delete_local_card_callback); - // TODO(crbug.com/40639086): Find a way to merge these two functions. // Shouldn't use WebauthnDialogState as that state is a purely UI state // (should not be accessible for managers?), and some of the states
diff --git a/components/autofill/core/browser/payments/payments_network_interface.cc b/components/autofill/core/browser/payments/payments_network_interface.cc index 96b36e1..0589771 100644 --- a/components/autofill/core/browser/payments/payments_network_interface.cc +++ b/components/autofill/core/browser/payments/payments_network_interface.cc
@@ -39,11 +39,6 @@ #include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_payments_features.h" -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) -#include "components/autofill/core/browser/payments/local_card_migration_manager.h" -#include "components/autofill/core/browser/payments/payments_requests/migrate_cards_request.h" -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - namespace autofill::payments { namespace { @@ -169,18 +164,6 @@ std::move(callback))); } -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) -void PaymentsNetworkInterface::MigrateCards( - const MigrationRequestDetails& request_details, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - MigrateCardsCallback callback) { - IssueRequest(std::make_unique<MigrateCardsRequest>( - request_details, migratable_credit_cards, - account_info_getter_->IsSyncFeatureEnabledForPaymentsServerMetrics(), - std::move(callback))); -} -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - void PaymentsNetworkInterface::SelectChallengeOption( const SelectChallengeOptionRequestDetails& request_details, base::OnceCallback<void(PaymentsRpcResult, const std::string&)> callback) {
diff --git a/components/autofill/core/browser/payments/payments_network_interface.h b/components/autofill/core/browser/payments/payments_network_interface.h index 13bb800..d924ab4 100644 --- a/components/autofill/core/browser/payments/payments_network_interface.h +++ b/components/autofill/core/browser/payments/payments_network_interface.h
@@ -37,9 +37,6 @@ namespace autofill { class AccountInfoGetter; -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) -class MigratableCreditCard; -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) namespace payments { @@ -49,18 +46,6 @@ std::unique_ptr<base::Value::Dict> legal_message, std::vector<std::pair<int, int>> supported_card_bin_ranges)>; -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) -// Callback type for MigrateCards callback. |result| is the Payments Rpc result. -// |save_result| is an unordered_map parsed from the response whose key is the -// unique id (guid) for each card and value is the server save result string. -// |display_text| is the returned tip from Payments to show on the UI. -typedef base::OnceCallback<void( - PaymentsAutofillClient::PaymentsRpcResult result, - std::unique_ptr<std::unordered_map<std::string, std::string>> save_result, - const std::string& display_text)> - MigrateCardsCallback; -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - // PaymentsNetworkInterface issues Payments RPCs and manages responses and failure // conditions. Only one request may be active at a time. Initiating a new // request will cancel a pending request. @@ -177,16 +162,6 @@ base::OnceCallback<void(PaymentsAutofillClient::PaymentsRpcResult)> callback); -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - // The user has indicated that they would like to migrate their local credit - // cards. This request will fail server-side if a successful call to - // GetCardUploadDetails has not already been made. - virtual void MigrateCards( - const MigrationRequestDetails& details, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - MigrateCardsCallback callback); -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - // The user has chosen one of the available challenge options. Send the // selected challenge option to server to continue the unmask flow. virtual void SelectChallengeOption(
diff --git a/components/autofill/core/browser/payments/payments_network_interface_unittest.cc b/components/autofill/core/browser/payments/payments_network_interface_unittest.cc index 6d527086..2b416fe 100644 --- a/components/autofill/core/browser/payments/payments_network_interface_unittest.cc +++ b/components/autofill/core/browser/payments/payments_network_interface_unittest.cc
@@ -26,7 +26,6 @@ #include "components/autofill/core/browser/payments/autofill_error_dialog_context.h" #include "components/autofill/core/browser/payments/card_unmask_challenge_option.h" #include "components/autofill/core/browser/payments/client_behavior_constants.h" -#include "components/autofill/core/browser/payments/local_card_migration_manager.h" #include "components/autofill/core/browser/payments/payments_autofill_client.h" #include "components/autofill/core/browser/payments/payments_network_interface_test_base.h" #include "components/autofill/core/browser/payments/payments_request_details.h" @@ -195,18 +194,6 @@ upload_card_response_details_ = upload_card_respone_details; } -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - void OnDidMigrateLocalCards( - PaymentsRpcResult result, - std::unique_ptr<std::unordered_map<std::string, std::string>> - migration_save_results, - const std::string& display_text) { - result_ = result; - migration_save_results_ = std::move(migration_save_results); - display_text_ = display_text; - } -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - void OnDidSelectChallengeOption(PaymentsRpcResult result, const std::string& updated_context_token) { result_ = result; @@ -354,23 +341,6 @@ GetWeakPtr())); } -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - void StartMigrating() { - MigrationRequestDetails request_details; - request_details.context_token = u"context token"; - request_details.risk_data = "some risk data"; - request_details.app_locale = "language-LOCALE"; - - migratable_credit_cards_.clear(); - migratable_credit_cards_.emplace_back(test::GetCreditCard()); - migratable_credit_cards_.emplace_back(test::GetCreditCard2()); - payments_network_interface_->MigrateCards( - request_details, migratable_credit_cards_, - base::BindOnce(&PaymentsNetworkInterfaceTest::OnDidMigrateLocalCards, - GetWeakPtr())); - } -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - void StartSelectingChallengeOption( CardUnmaskChallengeOptionType challenge_type = CardUnmaskChallengeOptionType::kSmsOtp, @@ -486,16 +456,6 @@ // instrument. std::string instrument_id_; -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - // Credit cards to be upload saved during a local credit card migration call. - std::vector<MigratableCreditCard> migratable_credit_cards_; - // A mapping of results from a local credit card migration call. - std::unique_ptr<std::unordered_map<std::string, std::string>> - migration_save_results_; - // A tip message to be displayed during local card migration. - std::string display_text_; -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - private: std::optional<UnmaskDetails> unmask_details_; // The UnmaskResponseDetails retrieved from an UnmaskRequest. Includes PAN. @@ -1516,77 +1476,6 @@ /*expected_count=*/0); } -// Tests for the local card migration flow. Desktop only. -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) -TEST_F(PaymentsNetworkInterfaceTest, GetDetailsFollowedByMigrationSuccess) { - StartGettingUploadDetails(); - IssueOAuthToken(); - ReturnResponse( - payments_network_interface_.get(), net::HTTP_OK, - "{ \"context_token\": \"some_token\", \"legal_message\": {} }"); - EXPECT_EQ(PaymentsRpcResult::kSuccess, result_); - - result_ = PaymentsRpcResult::kNone; - - StartMigrating(); - ReturnResponse( - payments_network_interface_.get(), net::HTTP_OK, - "{\"save_result\":[],\"value_prop_display_text\":\"display text\"}"); - EXPECT_EQ(PaymentsRpcResult::kSuccess, result_); -} -#endif - -// Tests for the local card migration flow. Desktop only. -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) -TEST_F(PaymentsNetworkInterfaceTest, MigrateCardsVariationsTest) { - // Register a trial and variation id, so that there is data in variations - // headers. - CreateFieldTrialWithId("AutofillTest", "Group", 369); - StartMigrating(); - IssueOAuthToken(); - - // Note that experiment information is stored in X-Client-Data. - EXPECT_TRUE(HasVariationsHeader()); -} - -TEST_F(PaymentsNetworkInterfaceTest, MigrationSuccessWithSaveResult) { - StartMigrating(); - IssueOAuthToken(); - ReturnResponse(payments_network_interface_.get(), net::HTTP_OK, - "{\"save_result\":[{\"unique_id\":\"0\",\"status\":" - "\"SUCCESS\"},{\"unique_id\":\"1\",\"status\":\"TEMPORARY_" - "FAILURE\"}],\"value_prop_display_text\":\"display text\"}"); - - EXPECT_EQ(PaymentsRpcResult::kSuccess, result_); - EXPECT_TRUE(migration_save_results_.get()); - EXPECT_TRUE(migration_save_results_->find("0") != - migration_save_results_->end()); - EXPECT_TRUE(migration_save_results_->at("0") == "SUCCESS"); - EXPECT_TRUE(migration_save_results_->find("1") != - migration_save_results_->end()); - EXPECT_TRUE(migration_save_results_->at("1") == "TEMPORARY_FAILURE"); -} - -TEST_F(PaymentsNetworkInterfaceTest, MigrationMissingSaveResult) { - StartMigrating(); - IssueOAuthToken(); - ReturnResponse(payments_network_interface_.get(), net::HTTP_OK, - "{\"value_prop_display_text\":\"display text\"}"); - EXPECT_EQ(PaymentsRpcResult::kPermanentFailure, result_); - EXPECT_EQ(nullptr, migration_save_results_.get()); -} - -TEST_F(PaymentsNetworkInterfaceTest, MigrationSuccessWithDisplayText) { - StartMigrating(); - IssueOAuthToken(); - ReturnResponse(payments_network_interface_.get(), net::HTTP_OK, - "{\"save_result\":[{\"unique_id\":\"0\",\"status\":" - "\"SUCCESS\"}],\"value_prop_display_text\":\"display text\"}"); - EXPECT_EQ(PaymentsRpcResult::kSuccess, result_); - EXPECT_EQ("display text", display_text_); -} -#endif - TEST_F(PaymentsNetworkInterfaceTest, SelectChallengeOptionWithSmsOtpMethod) { StartSelectingChallengeOption(CardUnmaskChallengeOptionType::kSmsOtp, "arbitrary id for sms otp");
diff --git a/components/autofill/core/browser/payments/payments_request_details.h b/components/autofill/core/browser/payments/payments_request_details.h index 78e28b1e..b73f1b7f 100644 --- a/components/autofill/core/browser/payments/payments_request_details.h +++ b/components/autofill/core/browser/payments/payments_request_details.h
@@ -345,12 +345,6 @@ UPSTREAM_SETTINGS_PAGE, // Single card is being uploaded after being scanned by OCR. UPSTREAM_CARD_OCR, - // 1+ cards are being uploaded from a migration request that started during - // a checkout flow. - LOCAL_CARD_MIGRATION_CHECKOUT_FLOW, - // 1+ cards are being uploaded from a migration request that was initiated - // from chrome://settings/payments. - LOCAL_CARD_MIGRATION_SETTINGS_PAGE, }; // A collection of information received in the response for an
diff --git a/components/autofill/core/browser/payments/payments_requests/get_card_upload_details_request.cc b/components/autofill/core/browser/payments/payments_requests/get_card_upload_details_request.cc index 33b07f2e..a893b35 100644 --- a/components/autofill/core/browser/payments/payments_requests/get_card_upload_details_request.cc +++ b/components/autofill/core/browser/payments/payments_requests/get_card_upload_details_request.cc
@@ -98,14 +98,6 @@ case UploadCardSource::UPSTREAM_CARD_OCR: request_dict.Set("upload_card_source", "UPSTREAM_CARD_OCR"); break; - case UploadCardSource::LOCAL_CARD_MIGRATION_CHECKOUT_FLOW: - request_dict.Set("upload_card_source", - "LOCAL_CARD_MIGRATION_CHECKOUT_FLOW"); - break; - case UploadCardSource::LOCAL_CARD_MIGRATION_SETTINGS_PAGE: - request_dict.Set("upload_card_source", - "LOCAL_CARD_MIGRATION_SETTINGS_PAGE"); - break; default: NOTREACHED(); }
diff --git a/components/autofill/core/browser/payments/payments_requests/get_card_upload_details_request_unittest.cc b/components/autofill/core/browser/payments/payments_requests/get_card_upload_details_request_unittest.cc index 3bf16a7..551da6da 100644 --- a/components/autofill/core/browser/payments/payments_requests/get_card_upload_details_request_unittest.cc +++ b/components/autofill/core/browser/payments/payments_requests/get_card_upload_details_request_unittest.cc
@@ -172,32 +172,6 @@ std::string::npos); } -TEST( - GetCardUploadDetailsRequestTest, - GetDetailsIncludesLocalCardMigrationCheckoutFlowUploadCardSourceInRequest) { - std::unique_ptr<GetCardUploadDetailsRequest> request = - CreateGetCardUploadDetailsRequest( - GetCardUploadDetailsOptions().with_upload_card_source( - UploadCardSource::LOCAL_CARD_MIGRATION_CHECKOUT_FLOW)); - - // Verify that the correct upload card source was included in the request. - EXPECT_TRUE(request->GetRequestContent().find( - "LOCAL_CARD_MIGRATION_CHECKOUT_FLOW") != std::string::npos); -} - -TEST( - GetCardUploadDetailsRequestTest, - GetDetailsIncludesLocalCardMigrationSettingsPageUploadCardSourceInRequest) { - std::unique_ptr<GetCardUploadDetailsRequest> request = - CreateGetCardUploadDetailsRequest( - GetCardUploadDetailsOptions().with_upload_card_source( - UploadCardSource::LOCAL_CARD_MIGRATION_SETTINGS_PAGE)); - - // Verify that the correct upload card source was included in the request. - EXPECT_TRUE(request->GetRequestContent().find( - "LOCAL_CARD_MIGRATION_SETTINGS_PAGE") != std::string::npos); -} - TEST(GetCardUploadDetailsRequestTest, GetDetailsIncludesUnknownUploadCardSourceInRequest) { std::unique_ptr<GetCardUploadDetailsRequest> request =
diff --git a/components/autofill/core/browser/payments/payments_requests/migrate_cards_request.cc b/components/autofill/core/browser/payments/payments_requests/migrate_cards_request.cc deleted file mode 100644 index e63dd198..0000000 --- a/components/autofill/core/browser/payments/payments_requests/migrate_cards_request.cc +++ /dev/null
@@ -1,140 +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 "components/autofill/core/browser/payments/payments_requests/migrate_cards_request.h" - -#include <string> -#include <utility> - -#include "base/containers/span.h" -#include "base/json/json_writer.h" -#include "base/strings/escape.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "components/autofill/core/browser/payments/local_card_migration_manager.h" - -namespace autofill::payments { - -namespace { -constexpr char kMigrateCardsRequestPath[] = - "payments/apis-secure/chromepaymentsservice/migratecards" - "?s7e_suffix=chromewallet"; -constexpr char kMigrateCardsRequestFormat[] = - "requestContentType=application/json; charset=utf-8&request=%s"; -} // namespace - -MigrateCardsRequest::MigrateCardsRequest( - const MigrationRequestDetails& request_details, - base::span<const MigratableCreditCard> migratable_credit_cards, - const bool full_sync_enabled, - MigrateCardsCallback callback) - : request_details_(request_details), - migratable_credit_cards_(migratable_credit_cards.begin(), - migratable_credit_cards.end()), - full_sync_enabled_(full_sync_enabled), - callback_(std::move(callback)) {} - -MigrateCardsRequest::~MigrateCardsRequest() = default; - -std::string MigrateCardsRequest::GetRequestUrlPath() { - return kMigrateCardsRequestPath; -} - -std::string MigrateCardsRequest::GetRequestContentType() { - return "application/x-www-form-urlencoded"; -} - -std::string MigrateCardsRequest::GetRequestContent() { - base::Value::Dict request_dict; - - request_dict.Set("risk_data_encoded", - BuildRiskDictionary(request_details_.risk_data)); - - const std::string& app_locale = request_details_.app_locale; - base::Value::Dict context; - context.Set("language_code", app_locale); - context.Set("billable_service", kMigrateCardsBillableServiceNumber); - if (request_details_.billing_customer_number != 0) { - context.Set("customer_context", - BuildCustomerContextDictionary( - request_details_.billing_customer_number)); - } - request_dict.Set("context", std::move(context)); - - base::Value::Dict chrome_user_context; - chrome_user_context.Set("full_sync_enabled", full_sync_enabled_); - request_dict.Set("chrome_user_context", std::move(chrome_user_context)); - request_dict.Set("context_token", request_details_.context_token); - - std::string all_pans_data; - base::Value::List migrate_cards; - for (size_t index = 0; index < migratable_credit_cards_.size(); ++index) { - std::string pan_field_name = GetPanFieldName(index); - // Generate credit card dictionary. - migrate_cards.Append( - BuildCreditCardDictionary(migratable_credit_cards_[index].credit_card(), - app_locale, pan_field_name)); - // Append pan data to the |all_pans_data|. - all_pans_data += GetAppendPan(migratable_credit_cards_[index].credit_card(), - app_locale, pan_field_name); - } - request_dict.Set("local_card", std::move(migrate_cards)); - - std::string json_request; - base::JSONWriter::Write(request_dict, &json_request); - std::string request_content = base::StringPrintf( - kMigrateCardsRequestFormat, - base::EscapeUrlEncodedData(json_request, true).c_str()); - request_content += all_pans_data; - return request_content; -} - -void MigrateCardsRequest::ParseResponse(const base::Value::Dict& response) { - const auto* found_list = response.FindList("save_result"); - if (!found_list) - return; - - save_result_ = - std::make_unique<std::unordered_map<std::string, std::string>>(); - for (const base::Value& result : *found_list) { - if (result.is_dict()) { - const std::string* unique_id = result.GetDict().FindString("unique_id"); - const std::string* status = result.GetDict().FindString("status"); - save_result_->insert( - std::make_pair(unique_id ? *unique_id : std::string(), - status ? *status : std::string())); - } - } - - const std::string* display_text = - response.FindString("value_prop_display_text"); - display_text_ = display_text ? *display_text : std::string(); -} - -bool MigrateCardsRequest::IsResponseComplete() { - return !display_text_.empty() && save_result_; -} - -void MigrateCardsRequest::RespondToDelegate( - PaymentsAutofillClient::PaymentsRpcResult result) { - std::move(callback_).Run(result, std::move(save_result_), display_text_); -} - -std::string MigrateCardsRequest::GetPanFieldName(const size_t& index) { - return "s7e_1_pan" + base::NumberToString(index); -} - -std::string MigrateCardsRequest::GetAppendPan( - const CreditCard& credit_card, - const std::string& app_locale, - const std::string& pan_field_name) { - const std::u16string pan = - credit_card.GetInfo(CREDIT_CARD_NUMBER, app_locale); - std::string pan_str = - base::EscapeUrlEncodedData(base::UTF16ToASCII(pan), true).c_str(); - std::string append_pan = "&" + pan_field_name + "=" + pan_str; - return append_pan; -} - -} // namespace autofill::payments
diff --git a/components/autofill/core/browser/payments/payments_requests/migrate_cards_request.h b/components/autofill/core/browser/payments/payments_requests/migrate_cards_request.h deleted file mode 100644 index 6ad51735..0000000 --- a/components/autofill/core/browser/payments/payments_requests/migrate_cards_request.h +++ /dev/null
@@ -1,76 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_REQUESTS_MIGRATE_CARDS_REQUEST_H_ -#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_REQUESTS_MIGRATE_CARDS_REQUEST_H_ - -#include <string> - -#include "base/containers/span.h" -#include "base/functional/callback.h" -#include "base/memory/raw_ref.h" -#include "components/autofill/core/browser/payments/payments_autofill_client.h" -#include "components/autofill/core/browser/payments/payments_request_details.h" -#include "components/autofill/core/browser/payments/payments_requests/payments_request.h" - -namespace base { -class Value; -} // namespace base - -namespace autofill::payments { - -// TODO(crbug.com/362785288): This now lives in this file and -// PaymentsNetworkInterface. Clean it up in a separate CL. -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) -// Callback type for MigrateCards callback. `result` is the Payments Rpc result. -// `save_result` is an unordered_map parsed from the response whose key is the -// unique id (guid) for each card and value is the server save result string. -// `display_text` is the returned tip from Payments to show on the UI. -typedef base::OnceCallback<void( - PaymentsAutofillClient::PaymentsRpcResult result, - std::unique_ptr<std::unordered_map<std::string, std::string>> save_result, - const std::string& display_text)> - MigrateCardsCallback; -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - -class MigrateCardsRequest : public PaymentsRequest { - public: - MigrateCardsRequest( - const MigrationRequestDetails& request_details, - base::span<const MigratableCreditCard> migratable_credit_cards, - const bool full_sync_enabled, - MigrateCardsCallback callback); - MigrateCardsRequest(const MigrateCardsRequest&) = delete; - MigrateCardsRequest& operator=(const MigrateCardsRequest&) = delete; - ~MigrateCardsRequest() override; - - // PaymentsRequest: - std::string GetRequestUrlPath() override; - std::string GetRequestContentType() override; - std::string GetRequestContent() override; - void ParseResponse(const base::Value::Dict& response) override; - bool IsResponseComplete() override; - void RespondToDelegate( - PaymentsAutofillClient::PaymentsRpcResult result) override; - - private: - // Return the pan field name for the encrypted pan based on the |index|. - std::string GetPanFieldName(const size_t& index); - - // Return the formatted pan to append to the end of the request. - std::string GetAppendPan(const CreditCard& credit_card, - const std::string& app_locale, - const std::string& pan_field_name); - - const MigrationRequestDetails request_details_; - const std::vector<MigratableCreditCard> migratable_credit_cards_; - const bool full_sync_enabled_; - MigrateCardsCallback callback_; - std::unique_ptr<std::unordered_map<std::string, std::string>> save_result_; - std::string display_text_; -}; - -} // namespace autofill::payments - -#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_REQUESTS_MIGRATE_CARDS_REQUEST_H_
diff --git a/components/autofill/core/browser/payments/payments_requests/migrate_cards_request_unittest.cc b/components/autofill/core/browser/payments/payments_requests/migrate_cards_request_unittest.cc deleted file mode 100644 index 280160273..0000000 --- a/components/autofill/core/browser/payments/payments_requests/migrate_cards_request_unittest.cc +++ /dev/null
@@ -1,144 +0,0 @@ -// 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/autofill/core/browser/payments/payments_requests/migrate_cards_request.h" - -#include <memory> -#include <vector> - -#include "base/feature_list.h" -#include "base/functional/callback_helpers.h" -#include "base/strings/utf_string_conversions.h" -#include "base/test/scoped_feature_list.h" -#include "components/autofill/core/browser/data_model/payments/credit_card.h" -#include "components/autofill/core/browser/payments/local_card_migration_manager.h" -#include "components/autofill/core/browser/payments/test/autofill_payments_test_utils.h" -#include "components/autofill/core/browser/test_utils/autofill_test_utils.h" -#include "testing/gtest/include/gtest/gtest.h" - -using ::testing::HasSubstr; - -namespace autofill::payments { -namespace { - -std::unique_ptr<MigrateCardsRequest> CreateMigrateCardsRequest( - std::vector<MigratableCreditCard>* migratable_credit_cards, - bool has_cardholder_name, - bool set_nickname_for_first_card = false) { - CHECK(migratable_credit_cards); - CHECK(migratable_credit_cards->empty()); - - MigrationRequestDetails request_details; - request_details.context_token = u"context token"; - request_details.risk_data = "some risk data"; - request_details.app_locale = "language-LOCALE"; - - CreditCard card1 = test::GetCreditCard(); - if (set_nickname_for_first_card) { - card1.SetNickname(u"grocery"); - } - CreditCard card2 = test::GetCreditCard2(); - if (!has_cardholder_name) { - card1.SetRawInfo(CREDIT_CARD_NAME_FULL, u""); - card2.SetRawInfo(CREDIT_CARD_NAME_FULL, u""); - } - migratable_credit_cards->emplace_back(card1); - migratable_credit_cards->emplace_back(card2); - - return std::make_unique<MigrateCardsRequest>( - request_details, *migratable_credit_cards, - /*full_sync_enabled=*/true, base::DoNothing()); -} - -TEST(MigrateCardsRequestTest, MigrationRequestIncludesUniqueId) { - std::vector<MigratableCreditCard> migratable_credit_cards; - std::unique_ptr<MigrateCardsRequest> request = CreateMigrateCardsRequest( - &migratable_credit_cards, /*has_cardholder_name=*/true); - - // Verify that the unique id was included in the request. - EXPECT_TRUE(request->GetRequestContent().find("unique_id") != - std::string::npos); - EXPECT_TRUE(request->GetRequestContent().find( - migratable_credit_cards[0].credit_card().guid()) != - std::string::npos); - EXPECT_TRUE(request->GetRequestContent().find( - migratable_credit_cards[1].credit_card().guid()) != - std::string::npos); -} - -TEST(MigrateCardsRequestTest, MigrationRequestIncludesEncryptedPan) { - std::vector<MigratableCreditCard> migratable_credit_cards; - std::unique_ptr<MigrateCardsRequest> request = CreateMigrateCardsRequest( - &migratable_credit_cards, /*has_cardholder_name=*/true); - - // Verify that the encrypted_pan and s7e_1_pan parameters were included - // in the request. - EXPECT_TRUE(request->GetRequestContent().find("encrypted_pan") != - std::string::npos); - EXPECT_TRUE(request->GetRequestContent().find("__param:s7e_1_pan0") != - std::string::npos); - EXPECT_TRUE(request->GetRequestContent().find( - "&s7e_1_pan0=4111111111111111") != std::string::npos); - EXPECT_TRUE(request->GetRequestContent().find("__param:s7e_1_pan1") != - std::string::npos); - EXPECT_TRUE(request->GetRequestContent().find( - "&s7e_1_pan1=378282246310005") != std::string::npos); -} - -TEST(MigrateCardsRequestTest, - MigrationRequestIncludesCardholderNameWhenItExists) { - std::vector<MigratableCreditCard> migratable_credit_cards; - std::unique_ptr<MigrateCardsRequest> request = CreateMigrateCardsRequest( - &migratable_credit_cards, /*has_cardholder_name=*/true); - - EXPECT_TRUE(!request->GetRequestContent().empty()); - // Verify that the cardholder name is sent if it exists. - EXPECT_TRUE(request->GetRequestContent().find("cardholder_name") != - std::string::npos); -} - -TEST(MigrateCardsRequestTest, - MigrationRequestExcludesCardholderNameWhenItDoesNotExist) { - std::vector<MigratableCreditCard> migratable_credit_cards; - std::unique_ptr<MigrateCardsRequest> request = CreateMigrateCardsRequest( - &migratable_credit_cards, /*has_cardholder_name=*/false); - - EXPECT_TRUE(!request->GetRequestContent().empty()); - // Verify that the cardholder name is not sent if it doesn't exist. - EXPECT_TRUE(request->GetRequestContent().find("cardholder_name") == - std::string::npos); -} - -TEST(MigrateCardsRequestTest, MigrationRequestIncludesChromeUserContext) { - std::vector<MigratableCreditCard> migratable_credit_cards; - std::unique_ptr<MigrateCardsRequest> request = CreateMigrateCardsRequest( - &migratable_credit_cards, /*has_cardholder_name=*/true); - - // ChromeUserContext was set. - EXPECT_TRUE(request->GetRequestContent().find("chrome_user_context") != - std::string::npos); - EXPECT_TRUE(request->GetRequestContent().find("full_sync_enabled") != - std::string::npos); -} - -TEST(MigrateCardsRequestTest, MigrationRequestIncludesCardNickname) { - std::vector<MigratableCreditCard> migratable_credit_cards; - std::unique_ptr<MigrateCardsRequest> request = CreateMigrateCardsRequest( - &migratable_credit_cards, /*has_cardholder_name=*/true, - /*set_nickname_for_first_card=*/true); - - // Nickname was set for the first card. - std::size_t pos = request->GetRequestContent().find("nickname"); - EXPECT_TRUE(pos != std::string::npos); - EXPECT_TRUE(request->GetRequestContent().find(base::UTF16ToUTF8( - migratable_credit_cards[0].credit_card().nickname())) != - std::string::npos); - - // Nickname was not set for the second card. - EXPECT_FALSE(request->GetRequestContent().find("nickname", pos + 1) != - std::string::npos); -} - -} // namespace -} // namespace autofill::payments
diff --git a/components/autofill/core/browser/payments/test_local_card_migration_manager.cc b/components/autofill/core/browser/payments/test_local_card_migration_manager.cc deleted file mode 100644 index fb6d1963..0000000 --- a/components/autofill/core/browser/payments/test_local_card_migration_manager.cc +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2018 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/payments/test_local_card_migration_manager.h" - -#include "components/autofill/core/browser/data_manager/payments/test_payments_data_manager.h" -#include "components/autofill/core/browser/metrics/autofill_metrics.h" -#include "components/autofill/core/browser/payments/payments_util.h" -#include "components/autofill/core/common/autofill_payments_features.h" - -namespace autofill { - -TestLocalCardMigrationManager::~TestLocalCardMigrationManager() = default; - -bool TestLocalCardMigrationManager::IsCreditCardMigrationEnabled() { - return payments::HasGooglePaymentsAccount(payments_data_manager()); -} - -bool TestLocalCardMigrationManager::LocalCardMigrationWasTriggered() { - return local_card_migration_was_triggered_; -} - -bool TestLocalCardMigrationManager::IntermediatePromptWasShown() { - return intermediate_prompt_was_shown_; -} - -bool TestLocalCardMigrationManager::MainPromptWasShown() { - return main_prompt_was_shown_; -} - -void TestLocalCardMigrationManager:: - OnUserAcceptedIntermediateMigrationDialog() { - intermediate_prompt_was_shown_ = true; - LocalCardMigrationManager::OnUserAcceptedIntermediateMigrationDialog(); -} - -void TestLocalCardMigrationManager::OnUserAcceptedMainMigrationDialog( - const std::vector<std::string>& selected_cards) { - main_prompt_was_shown_ = true; - LocalCardMigrationManager::OnUserAcceptedMainMigrationDialog(selected_cards); -} - -void TestLocalCardMigrationManager::EnablePaymentsWalletSyncInTransportMode() { - static_cast<TestPaymentsDataManager&>(payments_data_manager()) - .SetIsPaymentsWalletSyncTransportEnabled(true); -} - -void TestLocalCardMigrationManager::OnDidGetUploadDetails( - bool is_from_settings_page, - payments::PaymentsAutofillClient::PaymentsRpcResult result, - const std::u16string& context_token, - std::unique_ptr<base::Value::Dict> legal_message, - std::vector<std::pair<int, int>> supported_bin_ranges) { - if (result == payments::PaymentsAutofillClient::PaymentsRpcResult::kSuccess) { - local_card_migration_was_triggered_ = true; - } - LocalCardMigrationManager::OnDidGetUploadDetails( - is_from_settings_page, result, context_token, std::move(legal_message), - supported_bin_ranges); -} - -} // namespace autofill
diff --git a/components/autofill/core/browser/payments/test_local_card_migration_manager.h b/components/autofill/core/browser/payments/test_local_card_migration_manager.h deleted file mode 100644 index fba0f32..0000000 --- a/components/autofill/core/browser/payments/test_local_card_migration_manager.h +++ /dev/null
@@ -1,72 +0,0 @@ -// Copyright 2018 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_PAYMENTS_TEST_LOCAL_CARD_MIGRATION_MANAGER_H_ -#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_LOCAL_CARD_MIGRATION_MANAGER_H_ - -#include <memory> -#include <string> -#include <utility> -#include <vector> - -#include "components/autofill/core/browser/payments/local_card_migration_manager.h" - -namespace autofill { - -class TestLocalCardMigrationManager : public LocalCardMigrationManager { - public: - using LocalCardMigrationManager::LocalCardMigrationManager; - - TestLocalCardMigrationManager(const TestLocalCardMigrationManager&) = delete; - TestLocalCardMigrationManager& operator=( - const TestLocalCardMigrationManager&) = delete; - - ~TestLocalCardMigrationManager() override; - - // Override the base function. Checks the existnece of billing customer number - // and the experiment flag, but unlike the real class, does not check if the - // user is signed in/syncing. - bool IsCreditCardMigrationEnabled() override; - - // Returns whether the local card migration was triggered. - bool LocalCardMigrationWasTriggered(); - - // Returns whether the first round intermediate pop-up window was shown. - bool IntermediatePromptWasShown(); - - // Returns whether the main prompt window was shown. - bool MainPromptWasShown(); - - // Override the base function. When called, represents the intermediate prompt - // is shown. Set the |intermediate_prompt_was_shown_|. - void OnUserAcceptedIntermediateMigrationDialog() override; - - // Override the base function. When called, represent the main prompt is - // shown. Set the |main_prompt_was_shown_|. - void OnUserAcceptedMainMigrationDialog( - const std::vector<std::string>& selected_cards) override; - - // By default, the `LocalCardMigrationManager` syncing state is "signed in - // and sync-the-feature enabled". Using this function, tests can simulate - // sync transport mode. - void EnablePaymentsWalletSyncInTransportMode(); - - private: - void OnDidGetUploadDetails( - bool is_from_settings_page, - payments::PaymentsAutofillClient::PaymentsRpcResult result, - const std::u16string& context_token, - std::unique_ptr<base::Value::Dict> legal_message, - std::vector<std::pair<int, int>> supported_bin_ranges) override; - - bool local_card_migration_was_triggered_ = false; - - bool intermediate_prompt_was_shown_ = false; - - bool main_prompt_was_shown_ = false; -}; - -} // namespace autofill - -#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_TEST_LOCAL_CARD_MIGRATION_MANAGER_H_
diff --git a/components/autofill/core/browser/payments/test_payments_autofill_client.cc b/components/autofill/core/browser/payments/test_payments_autofill_client.cc index 12b99d6..87a7ed9 100644 --- a/components/autofill/core/browser/payments/test_payments_autofill_client.cc +++ b/components/autofill/core/browser/payments/test_payments_autofill_client.cc
@@ -35,10 +35,6 @@ #include "components/webauthn/core/browser/internal_authenticator.h" #endif // !BUILDFLAG(IS_IOS) -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) -#include "components/autofill/core/browser/payments/local_card_migration_manager.h" -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - namespace autofill::payments { TestPaymentsAutofillClient::TestPaymentsAutofillClient(AutofillClient* client) @@ -55,27 +51,6 @@ } #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) -void TestPaymentsAutofillClient::ShowLocalCardMigrationDialog( - base::OnceClosure show_migration_dialog_closure) { - std::move(show_migration_dialog_closure).Run(); -} - -void TestPaymentsAutofillClient::ConfirmMigrateLocalCardToCloud( - const LegalMessageLines& legal_message_lines, - const std::string& user_email, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - PaymentsAutofillClient::LocalCardMigrationCallback - start_migrating_cards_callback) { - // If `migration_card_selection_` hasn't been preset by tests, default to - // selecting all migratable cards. - if (migration_card_selection_.empty()) { - for (MigratableCreditCard card : migratable_credit_cards) { - migration_card_selection_.push_back(card.credit_card().guid()); - } - } - std::move(start_migrating_cards_callback).Run(migration_card_selection_); -} - void TestPaymentsAutofillClient::ConfirmSaveIbanLocally( const Iban& iban, bool should_show_prompt,
diff --git a/components/autofill/core/browser/payments/test_payments_autofill_client.h b/components/autofill/core/browser/payments/test_payments_autofill_client.h index 7b8bcf8..cb94aa22 100644 --- a/components/autofill/core/browser/payments/test_payments_autofill_client.h +++ b/components/autofill/core/browser/payments/test_payments_autofill_client.h
@@ -62,14 +62,6 @@ // PaymentsAutofillClient: #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - void ShowLocalCardMigrationDialog( - base::OnceClosure show_migration_dialog_closure) override; - void ConfirmMigrateLocalCardToCloud( - const LegalMessageLines& legal_message_lines, - const std::string& user_email, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - PaymentsAutofillClient::LocalCardMigrationCallback - start_migrating_cards_callback) override; void ConfirmSaveIbanLocally( const Iban& iban, bool should_show_prompt, @@ -135,11 +127,6 @@ bool GetMandatoryReauthOptInPromptWasReshown(); - void set_migration_card_selections( - const std::vector<std::string>& migration_card_selection) { - migration_card_selection_ = migration_card_selection; - } - bool autofill_progress_dialog_shown() { return autofill_progress_dialog_shown_; } @@ -217,8 +204,6 @@ std::unique_ptr<PaymentsNetworkInterface> payments_network_interface_; - std::vector<std::string> migration_card_selection_; - bool autofill_progress_dialog_shown_ = false; bool autofill_error_dialog_shown_ = false;
diff --git a/components/autofill/core/browser/payments/test_payments_network_interface.cc b/components/autofill/core/browser/payments/test_payments_network_interface.cc index 93a6f44..387a11d 100644 --- a/components/autofill/core/browser/payments/test_payments_network_interface.cc +++ b/components/autofill/core/browser/payments/test_payments_network_interface.cc
@@ -93,16 +93,6 @@ upload_card_response_details_); } -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) -void TestPaymentsNetworkInterface::MigrateCards( - const MigrationRequestDetails& details, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - MigrateCardsCallback callback) { - std::move(callback).Run(PaymentsRpcResult::kSuccess, std::move(save_result_), - "this is display text"); -} -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - void TestPaymentsNetworkInterface::SelectChallengeOption( const SelectChallengeOptionRequestDetails& details, base::OnceCallback<void(PaymentsRpcResult, const std::string&)> callback) { @@ -191,11 +181,6 @@ upload_card_response_details_ = upload_card_response_details; } -void TestPaymentsNetworkInterface::SetSaveResultForCardsMigration( - std::unique_ptr<std::unordered_map<std::string, std::string>> save_result) { - save_result_ = std::move(save_result); -} - void TestPaymentsNetworkInterface::SetSupportedBINRanges( std::vector<std::pair<int, int>> bin_ranges) { supported_card_bin_ranges_ = bin_ranges;
diff --git a/components/autofill/core/browser/payments/test_payments_network_interface.h b/components/autofill/core/browser/payments/test_payments_network_interface.h index 4548709..c3e5ae3 100644 --- a/components/autofill/core/browser/payments/test_payments_network_interface.h +++ b/components/autofill/core/browser/payments/test_payments_network_interface.h
@@ -67,13 +67,6 @@ const UploadCardResponseDetails&)> callback) override; -#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - void MigrateCards( - const MigrationRequestDetails& details, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - MigrateCardsCallback callback) override; -#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) - void SelectChallengeOption( const SelectChallengeOptionRequestDetails& details, base::OnceCallback<void(PaymentsAutofillClient::PaymentsRpcResult, @@ -108,10 +101,6 @@ void SetUploadCardResponseDetailsForUploadCard( const UploadCardResponseDetails& upload_card_response_details); - void SetSaveResultForCardsMigration( - std::unique_ptr<std::unordered_map<std::string, std::string>> - save_result); - void SetSupportedBINRanges(std::vector<std::pair<int, int>> bin_ranges); void SetUseInvalidLegalMessageInGetUploadDetails( @@ -187,7 +176,6 @@ int billable_service_number_; int64_t billing_customer_number_; UploadCardSource upload_card_source_; - std::unique_ptr<std::unordered_map<std::string, std::string>> save_result_; bool use_invalid_legal_message_ = false; bool use_legal_message_with_multiple_lines_ = false; std::unique_ptr<base::Value::Dict> LegalMessage();
diff --git a/components/autofill/core/browser/strike_databases/payments/local_card_migration_strike_database.h b/components/autofill/core/browser/strike_databases/payments/local_card_migration_strike_database.h deleted file mode 100644 index 11316bf..0000000 --- a/components/autofill/core/browser/strike_databases/payments/local_card_migration_strike_database.h +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2019 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_STRIKE_DATABASES_PAYMENTS_LOCAL_CARD_MIGRATION_STRIKE_DATABASE_H_ -#define COMPONENTS_AUTOFILL_CORE_BROWSER_STRIKE_DATABASES_PAYMENTS_LOCAL_CARD_MIGRATION_STRIKE_DATABASE_H_ - -#include "components/autofill/core/browser/strike_databases/simple_autofill_strike_database.h" - -namespace autofill { - -struct LocalCardMigrationStrikeDatabaseTraits { - static constexpr std::string_view kName = "LocalCardMigration"; - static constexpr std::optional<size_t> kMaxStrikeEntities = std::nullopt; - static constexpr std::optional<size_t> kMaxStrikeEntitiesAfterCleanup = - std::nullopt; - static constexpr size_t kMaxStrikeLimit = 6; - static constexpr std::optional<base::TimeDelta> kExpiryTimeDelta = - std::nullopt; - static constexpr bool kUniqueIdRequired = false; -}; - -class LocalCardMigrationStrikeDatabase - : public SimpleAutofillStrikeDatabase< - LocalCardMigrationStrikeDatabaseTraits> { - public: - using SimpleAutofillStrikeDatabase< - LocalCardMigrationStrikeDatabaseTraits>::SimpleAutofillStrikeDatabase; - - static constexpr int kStrikesToRemoveWhenLocalCardAdded = 2; - static constexpr int kStrikesToAddWhenBubbleClosed = 3; - static constexpr int kStrikesToAddWhenDialogClosed = 6; -}; - -} // namespace autofill - -#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_STRIKE_DATABASES_PAYMENTS_LOCAL_CARD_MIGRATION_STRIKE_DATABASE_H_
diff --git a/components/autofill/core/browser/studies/autofill_experiments.cc b/components/autofill/core/browser/studies/autofill_experiments.cc index 3242ee5..0a50056 100644 --- a/components/autofill/core/browser/studies/autofill_experiments.cc +++ b/components/autofill/core/browser/studies/autofill_experiments.cc
@@ -19,13 +19,11 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" -#include "components/autofill/core/browser/data_manager/payments/payments_data_manager.h" #include "components/autofill/core/browser/data_model/payments/iban.h" #include "components/autofill/core/browser/logging/log_manager.h" #include "components/autofill/core/browser/metrics/autofill_metrics.h" #include "components/autofill/core/browser/metrics/autofill_settings_metrics.h" #include "components/autofill/core/browser/metrics/payments/credit_card_save_metrics.h" -#include "components/autofill/core/browser/payments/payments_util.h" #include "components/autofill/core/browser/suggestions/suggestion.h" #include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_internals/log_message.h" @@ -247,37 +245,6 @@ return true; } -bool IsCreditCardMigrationEnabled( - const PaymentsDataManager& payments_data_manager, - const syncer::SyncService* sync_service, - const PrefService& pref_service, - bool is_test_mode, - LogManager* log_manager) { - if (base::FeatureList::IsEnabled( - features::kAutofillDisableLocalCardMigration)) { - // Feature is being turned down. - return false; - } - - // If |is_test_mode| is set, assume we are in a browsertest and - // credit card upload should be enabled by default to fix flaky - // local card migration browsertests. - if (!is_test_mode && - !IsCreditCardUploadEnabled( - sync_service, pref_service, - payments_data_manager.GetCountryCodeForExperimentGroup(), - payments_data_manager.GetPaymentsSigninStateForMetrics(), - log_manager)) { - return false; - } - - if (!payments::HasGooglePaymentsAccount(payments_data_manager)) { - return false; - } - - return payments_data_manager.IsPaymentsDownloadActive(); -} - bool IsInAutofillSuggestionsDisabledExperiment() { std::string group_name = base::FieldTrialList::FindFullName("AutofillEnabled");
diff --git a/components/autofill/core/browser/studies/autofill_experiments.h b/components/autofill/core/browser/studies/autofill_experiments.h index 5d790641..04088d2 100644 --- a/components/autofill/core/browser/studies/autofill_experiments.h +++ b/components/autofill/core/browser/studies/autofill_experiments.h
@@ -24,7 +24,6 @@ namespace autofill { class LogManager; -class PaymentsDataManager; // Returns true if uploading credit cards to Wallet servers is enabled. This // requires the appropriate flags and user settings to be true and the user to @@ -36,14 +35,6 @@ AutofillMetrics::PaymentsSigninState signin_state_for_metrics, LogManager* log_manager); -// Returns true if autofill local card migration flow is enabled. -bool IsCreditCardMigrationEnabled( - const PaymentsDataManager& payments_data_manager, - const syncer::SyncService* sync_service, - const PrefService& pref_service, - bool is_test_mode, - LogManager* log_manager); - // Returns true if autofill suggestions are disabled via experiment. The // disabled experiment isn't the same as disabling autofill completely since we // still want to run detection code for metrics purposes. This experiment just
diff --git a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.cc b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.cc index 6d480787..70d3b4f6 100644 --- a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.cc +++ b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.cc
@@ -138,11 +138,7 @@ } bool ShouldSplitCardNameAndLastFourDigits() { -#if BUILDFLAG(IS_IOS) - return false; -#else - return base::FeatureList::IsEnabled(features::kAutofillEnableCardProductName); -#endif + return !BUILDFLAG(IS_IOS); } // Returns whether the `suggestion_canon` is a valid match given
diff --git a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc index e946611a..823f45e 100644 --- a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc +++ b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc
@@ -337,7 +337,6 @@ /*enabled_features=*/ {features::kAutofillEnableCardBenefitsForAmericanExpress, features::kAutofillEnableCardBenefitsForBmo, - features::kAutofillEnableCardProductName, features::kAutofillEnableCardBenefitsIph}, /*disabled_features=*/{}); @@ -2109,11 +2108,8 @@ : public PaymentsSuggestionGeneratorTest { public: AutofillCreditCardSuggestionContentTest() { - feature_list_metadata_.InitWithFeatures( - /*enabled_features=*/{features::kAutofillEnableCardProductName, - features:: - kAutofillEnableVcnGrayOutForMerchantOptOut}, - /*disabled_features=*/{}); + feature_list_metadata_.InitAndEnableFeature( + features::kAutofillEnableVcnGrayOutForMerchantOptOut); } ~AutofillCreditCardSuggestionContentTest() override = default; @@ -2660,27 +2656,18 @@ class PaymentsSuggestionGeneratorTestForMetadata : public PaymentsSuggestionGeneratorTest, - public testing::WithParamInterface<std::tuple<bool, bool>> { + public testing::WithParamInterface<bool> { public: - PaymentsSuggestionGeneratorTestForMetadata() { - feature_list_card_product_description_.InitWithFeatureState( - features::kAutofillEnableCardProductName, std::get<0>(GetParam())); - } + PaymentsSuggestionGeneratorTestForMetadata() = default; ~PaymentsSuggestionGeneratorTestForMetadata() override = default; - bool card_product_description_enabled() const { - return std::get<0>(GetParam()); - } - bool card_has_capital_one_icon() const { return std::get<1>(GetParam()); } - - private: - base::test::ScopedFeatureList feature_list_card_product_description_; + bool card_has_capital_one_icon() const { return GetParam(); } }; INSTANTIATE_TEST_SUITE_P(All, PaymentsSuggestionGeneratorTestForMetadata, - testing::Combine(testing::Bool(), testing::Bool())); + testing::Bool()); TEST_P(PaymentsSuggestionGeneratorTestForMetadata, CreateCreditCardSuggestion_ServerCard) { @@ -2832,8 +2819,8 @@ EXPECT_TRUE( summary.metadata_logging_context.instruments_with_metadata_available .contains(server_card_with_metadata.instrument_id())); - EXPECT_EQ(summary.metadata_logging_context.card_product_description_shown, - card_product_description_enabled()); + EXPECT_TRUE( + summary.metadata_logging_context.card_product_description_shown); EXPECT_TRUE(summary.metadata_logging_context.card_art_image_shown); // Verify that a record is added that a Capital One card suggestion @@ -2933,10 +2920,6 @@ // card has card linked offer available. TEST_P(PaymentsSuggestionGeneratorTestForOffer, CreateCreditCardSuggestion_ServerCardWithOffer) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitWithFeatures( - /*enabled_features=*/{features::kAutofillEnableCardProductName}, - /*disabled_features=*/{}); // Create a server card. CreditCard server_card1 = CreateServerCard(/*guid=*/"00000000-0000-0000-0000-000000000001"); @@ -3097,7 +3080,6 @@ TEST_F( PaymentsSuggestionGeneratorTest, GetCreditCardOrCvcFieldSuggestions_GetVirtualCreditCardsForStandaloneCvcField) { - // Set up virtual card usage data and credit cards. payments_data().ClearCreditCards(); CreditCard masked_server_card = test::GetVirtualCard();
diff --git a/components/autofill/core/browser/test_utils/autofill_form_test_utils.cc b/components/autofill/core/browser/test_utils/autofill_form_test_utils.cc index 17a2213..3f192a49 100644 --- a/components/autofill/core/browser/test_utils/autofill_form_test_utils.cc +++ b/components/autofill/core/browser/test_utils/autofill_form_test_utils.cc
@@ -24,6 +24,7 @@ FormFieldData CreateFieldByRole(FieldType role) { FormFieldData field; + // TODO(crbug.com/406073718): Add the missing roles and/or fail loudly. switch (role) { case FieldType::USERNAME: field.set_label(u"Username"); @@ -82,7 +83,10 @@ field.set_name(u"password"); break; case FieldType::EMPTY_TYPE: + break; default: + LOG(ERROR) << __func__ << "() does not know the role " + << FieldTypeToStringView(role) << "!"; break; } return field;
diff --git a/components/autofill/core/browser/test_utils/valuables_data_test_utils.cc b/components/autofill/core/browser/test_utils/valuables_data_test_utils.cc index 8f0112d..81b9fbba 100644 --- a/components/autofill/core/browser/test_utils/valuables_data_test_utils.cc +++ b/components/autofill/core/browser/test_utils/valuables_data_test_utils.cc
@@ -5,20 +5,21 @@ #include "components/autofill/core/browser/test_utils/valuables_data_test_utils.h" #include "components/autofill/core/browser/data_model/valuables/loyalty_card.h" +#include "components/autofill/core/browser/data_model/valuables/valuable_types.h" #include "url/gurl.h" namespace autofill::test { LoyaltyCard CreateLoyaltyCard() { return LoyaltyCard( - /*loyalty_card_id=*/"loyalty_card_id_1", + /*loyalty_card_id=*/ValuableId("loyalty_card_id_1"), /*merchant_name=*/"Deutsche Bahn", /*program_name=*/"BahnBonus", /*program_logo=*/GURL("https://empty.url.com"), /*unmasked_loyalty_card_suffix=*/"1234"); } LoyaltyCard CreateLoyaltyCard2() { - return LoyaltyCard(/*loyalty_card_id=*/"loyalty_card_id_2", + return LoyaltyCard(/*loyalty_card_id=*/ValuableId("loyalty_card_id_2"), /*merchant_name=*/"Lidl", /*program_name=*/"CustomerCard", /*program_logo=*/GURL("https://empty.url.com"), /*unmasked_loyalty_card_suffix=*/"4321");
diff --git a/components/autofill/core/browser/ui/payments/local_card_migration_bubble_controller.h b/components/autofill/core/browser/ui/payments/local_card_migration_bubble_controller.h deleted file mode 100644 index a0f149b1..0000000 --- a/components/autofill/core/browser/ui/payments/local_card_migration_bubble_controller.h +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2018 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_UI_PAYMENTS_LOCAL_CARD_MIGRATION_BUBBLE_CONTROLLER_H_ -#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_LOCAL_CARD_MIGRATION_BUBBLE_CONTROLLER_H_ - -#include "components/autofill/core/browser/ui/payments/payments_ui_closed_reasons.h" - -namespace autofill { - -class LocalCardMigrationBubble; - -// Interface that exposes controller functionality to -// LocalCardMigrationBubble. The bubble is shown to offer user an option -// to upload credit cards stored in browser to Google Payments. -class LocalCardMigrationBubbleController { - public: - LocalCardMigrationBubbleController() = default; - - LocalCardMigrationBubbleController( - const LocalCardMigrationBubbleController&) = delete; - LocalCardMigrationBubbleController& operator=( - const LocalCardMigrationBubbleController&) = delete; - - virtual ~LocalCardMigrationBubbleController() = default; - - virtual void OnConfirmButtonClicked() = 0; - virtual void OnCancelButtonClicked() = 0; - virtual void OnBubbleClosed(PaymentsUiClosedReason closed_reason) = 0; -}; - -} // namespace autofill - -#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_LOCAL_CARD_MIGRATION_BUBBLE_CONTROLLER_H_
diff --git a/components/autofill/core/browser/ui/payments/local_card_migration_dialog_controller.h b/components/autofill/core/browser/ui/payments/local_card_migration_dialog_controller.h deleted file mode 100644 index 88d65e2..0000000 --- a/components/autofill/core/browser/ui/payments/local_card_migration_dialog_controller.h +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2018 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_UI_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_CONTROLLER_H_ -#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_CONTROLLER_H_ - -#include <memory> -#include <string> -#include <vector> - -#include "components/autofill/core/browser/payments/legal_message_line.h" -#include "url/gurl.h" - -namespace autofill { - -enum class LocalCardMigrationDialogState; -class MigratableCreditCard; - -// Interface that exposes controller functionality to local card migration -// dialog views. -class LocalCardMigrationDialogController { - public: - LocalCardMigrationDialogController() = default; - - LocalCardMigrationDialogController( - const LocalCardMigrationDialogController&) = delete; - LocalCardMigrationDialogController& operator=( - const LocalCardMigrationDialogController&) = delete; - - virtual ~LocalCardMigrationDialogController() = default; - - virtual LocalCardMigrationDialogState GetViewState() const = 0; - virtual const std::vector<MigratableCreditCard>& GetCardList() const = 0; - virtual const LegalMessageLines& GetLegalMessageLines() const = 0; - virtual const std::u16string& GetTipMessage() const = 0; - virtual const std::string& GetUserEmail() const = 0; - virtual void OnSaveButtonClicked( - const std::vector<std::string>& selected_cards_guids) = 0; - virtual void OnCancelButtonClicked() = 0; - virtual void OnDoneButtonClicked() = 0; - virtual void OnViewCardsButtonClicked() = 0; - virtual void OnLegalMessageLinkClicked(const GURL& url) = 0; - virtual void DeleteCard(const std::string& deleted_card_guid) = 0; - virtual void OnDialogClosed() = 0; - virtual bool AllCardsInvalid() const = 0; -}; - -} // namespace autofill - -#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_UI_PAYMENTS_LOCAL_CARD_MIGRATION_DIALOG_CONTROLLER_H_
diff --git a/components/autofill/core/browser/webdata/valuables/loyalty_card_sync_bridge.cc b/components/autofill/core/browser/webdata/valuables/loyalty_card_sync_bridge.cc index d95bb990..32060d6c 100644 --- a/components/autofill/core/browser/webdata/valuables/loyalty_card_sync_bridge.cc +++ b/components/autofill/core/browser/webdata/valuables/loyalty_card_sync_bridge.cc
@@ -146,7 +146,7 @@ std::unique_ptr<syncer::MutableDataBatch> LoyaltyCardSyncBridge::GetData() { auto batch = std::make_unique<syncer::MutableDataBatch>(); for (const LoyaltyCard& card : GetValuablesTable()->GetLoyaltyCards()) { - const std::string& id = card.id(); + const std::string& id = card.id().value(); batch->Put(id, CreateEntityDataFromLoyaltyCard(card)); } return batch;
diff --git a/components/autofill/core/browser/webdata/valuables/loyalty_card_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/valuables/loyalty_card_sync_bridge_unittest.cc index 991dee2..7a203b24 100644 --- a/components/autofill/core/browser/webdata/valuables/loyalty_card_sync_bridge_unittest.cc +++ b/components/autofill/core/browser/webdata/valuables/loyalty_card_sync_bridge_unittest.cc
@@ -40,8 +40,9 @@ constexpr char kInvalidId[] = ""; LoyaltyCard TestLoyaltyCard(std::string_view id) { - return LoyaltyCard(std::string(id), "merchant_name", "program_name", - GURL("http://foobar.com/logo.png"), "card_suffix"); + return LoyaltyCard(ValuableId(std::string(id)), "merchant_name", + "program_name", GURL("http://foobar.com/logo.png"), + "card_suffix"); } std::vector<LoyaltyCard> ExtractLoyaltyCardsFromDataBatch( @@ -78,8 +79,8 @@ ON_CALL(mock_processor(), IsTrackingMetadata).WillByDefault(Return(true)); syncer::EntityChangeList entity_data; for (const LoyaltyCard& card : loyalty_cards) { - entity_data.push_back( - syncer::EntityChange::CreateAdd(card.id(), CardToEntity(card))); + entity_data.push_back(syncer::EntityChange::CreateAdd( + card.id().value(), CardToEntity(card))); } // `MergeFullSyncData()` returns an error if it fails. return !bridge().MergeFullSyncData(bridge().CreateMetadataChangeList(),
diff --git a/components/autofill/core/browser/webdata/valuables/loyalty_card_sync_util.cc b/components/autofill/core/browser/webdata/valuables/loyalty_card_sync_util.cc index 375f9a19..8accd37 100644 --- a/components/autofill/core/browser/webdata/valuables/loyalty_card_sync_util.cc +++ b/components/autofill/core/browser/webdata/valuables/loyalty_card_sync_util.cc
@@ -16,7 +16,7 @@ const LoyaltyCard& card) { AutofillLoyaltyCardSpecifics specifics = sync_pb::AutofillLoyaltyCardSpecifics(); - specifics.set_id(card.id()); + specifics.set_id(card.id().value()); specifics.set_merchant_name(card.merchant_name()); specifics.set_program_name(card.program_name()); specifics.set_program_logo(card.program_logo().possibly_invalid_spec()); @@ -34,7 +34,7 @@ if (!AreAutofillLoyaltyCardSpecificsValid(specifics)) { return std::nullopt; } - return LoyaltyCard(specifics.id(), specifics.merchant_name(), + return LoyaltyCard(ValuableId(specifics.id()), specifics.merchant_name(), specifics.program_name(), GURL(specifics.program_logo()), specifics.loyalty_card_suffix()); }
diff --git a/components/autofill/core/browser/webdata/valuables/loyalty_card_sync_util_unittest.cc b/components/autofill/core/browser/webdata/valuables/loyalty_card_sync_util_unittest.cc index 350aaa7..e113e0e 100644 --- a/components/autofill/core/browser/webdata/valuables/loyalty_card_sync_util_unittest.cc +++ b/components/autofill/core/browser/webdata/valuables/loyalty_card_sync_util_unittest.cc
@@ -19,8 +19,9 @@ constexpr char kInvalidProgramLogo[] = "logo.png"; LoyaltyCard TestLoyaltyCard(std::string_view id = kId1) { - return LoyaltyCard(std::string(id), "merchant_name", "program_name", - GURL("http://foobar.com/logo.png"), "suffix"); + return LoyaltyCard(ValuableId(std::string(id)), "merchant_name", + "program_name", GURL("http://foobar.com/logo.png"), + "suffix"); } sync_pb::AutofillLoyaltyCardSpecifics TestSpecifics( @@ -45,7 +46,7 @@ sync_pb::AutofillLoyaltyCardSpecifics specifics = CreateSpecificsFromLoyaltyCard(card); - EXPECT_EQ(card.id(), specifics.id()); + EXPECT_EQ(card.id().value(), specifics.id()); EXPECT_EQ(card.merchant_name(), specifics.merchant_name()); EXPECT_EQ(card.program_name(), specifics.program_name()); EXPECT_EQ(card.program_logo(), specifics.program_logo()); @@ -61,7 +62,7 @@ entity_data->specifics.autofill_loyalty_card(); EXPECT_TRUE(entity_data->specifics.has_autofill_loyalty_card()); - EXPECT_EQ(card.id(), specifics.id()); + EXPECT_EQ(card.id().value(), specifics.id()); EXPECT_EQ(card.merchant_name(), specifics.merchant_name()); EXPECT_EQ(card.program_name(), specifics.program_name()); EXPECT_EQ(card.program_logo(), specifics.program_logo());
diff --git a/components/autofill/core/browser/webdata/valuables/valuables_table.cc b/components/autofill/core/browser/webdata/valuables/valuables_table.cc index 2806ef8..b09ce4e 100644 --- a/components/autofill/core/browser/webdata/valuables/valuables_table.cc +++ b/components/autofill/core/browser/webdata/valuables/valuables_table.cc
@@ -8,6 +8,7 @@ #include <string_view> #include "components/autofill/core/browser/data_model/valuables/loyalty_card.h" +#include "components/autofill/core/browser/data_model/valuables/valuable_types.h" #include "components/autofill/core/browser/webdata/autofill_table_utils.h" #include "components/webdata/common/web_database.h" #include "sql/database.h" @@ -30,7 +31,7 @@ // `kLoyaltyCardProgramLogo` and `kUnmaskedLoyaltyCardSuffix` in that order. // Constructs a `LoyaltyCard` from that data. std::optional<LoyaltyCard> LoyaltyCardFromStatement(sql::Statement& s) { - LoyaltyCard card(/*loyalty_card_id=*/s.ColumnString(0), + LoyaltyCard card(/*loyalty_card_id=*/ValuableId(s.ColumnString(0)), /*merchant_name=*/s.ColumnString(1), /*program_name=*/s.ColumnString(2), /*program_logo=*/GURL(s.ColumnStringView(3)), @@ -109,7 +110,7 @@ kLoyaltyCardProgramLogo, kUnmaskedLoyaltyCardSuffix}, /*or_replace=*/true); int index = 0; - query.BindString(index++, loyalty_card.id()); + query.BindString(index++, loyalty_card.id().value()); query.BindString(index++, loyalty_card.merchant_name()); query.BindString(index++, loyalty_card.program_name()); query.BindString(index++, loyalty_card.program_logo().spec()); @@ -118,21 +119,21 @@ } std::optional<LoyaltyCard> ValuablesTable::GetLoyaltyCardById( - std::string_view loyalty_card_id) const { + ValuableId loyalty_card_id) const { sql::Statement query; if (SelectByGuid( db(), query, kLoyaltyCardsTable, {kLoyaltyCardGuid, kLoyaltyCardMerchantName, kLoyaltyCardProgramName, kLoyaltyCardProgramLogo, kUnmaskedLoyaltyCardSuffix}, - loyalty_card_id)) { + loyalty_card_id.value())) { return LoyaltyCardFromStatement(query); } return std::nullopt; } -bool ValuablesTable::RemoveLoyaltyCard(std::string_view loyalty_card_id) { +bool ValuablesTable::RemoveLoyaltyCard(ValuableId loyalty_card_id) { return DeleteWhereColumnEq(db(), kLoyaltyCardsTable, kLoyaltyCardGuid, - loyalty_card_id); + loyalty_card_id.value()); } bool ValuablesTable::ClearLoyaltyCards() {
diff --git a/components/autofill/core/browser/webdata/valuables/valuables_table.h b/components/autofill/core/browser/webdata/valuables/valuables_table.h index 794798d..6ae5fe5c 100644 --- a/components/autofill/core/browser/webdata/valuables/valuables_table.h +++ b/components/autofill/core/browser/webdata/valuables/valuables_table.h
@@ -6,7 +6,6 @@ #define COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_VALUABLES_VALUABLES_TABLE_H_ #include <optional> -#include <string_view> #include <vector> #include "components/autofill/core/browser/data_model/valuables/loyalty_card.h" @@ -62,11 +61,11 @@ // `loyalty_card_id` as a unique identifier. Returns `std::nullopt` if there's // no loyalty card with `loyalty_card_id` in the database. std::optional<LoyaltyCard> GetLoyaltyCardById( - std::string_view loyalty_card_id) const; + ValuableId loyalty_card_id) const; // Removes the loyalty card from the database using `loyalty_card_id` as a // unique identifier. Returns `true` if the operation succeeded. - bool RemoveLoyaltyCard(std::string_view loyalty_card_id); + bool RemoveLoyaltyCard(ValuableId loyalty_card_id); // Removes all loyalty cards stored in the database. Returns `true` if the // operation succeeded.
diff --git a/components/autofill/core/browser/webdata/valuables/valuables_table_unittest.cc b/components/autofill/core/browser/webdata/valuables/valuables_table_unittest.cc index 6e89289..87a2f8f 100644 --- a/components/autofill/core/browser/webdata/valuables/valuables_table_unittest.cc +++ b/components/autofill/core/browser/webdata/valuables/valuables_table_unittest.cc
@@ -6,6 +6,7 @@ #include "base/files/scoped_temp_dir.h" #include "components/autofill/core/browser/data_model/valuables/loyalty_card.h" +#include "components/autofill/core/browser/data_model/valuables/valuable_types.h" #include "components/autofill/core/browser/test_utils/valuables_data_test_utils.h" #include "components/webdata/common/web_database.h" #include "testing/gmock/include/gmock/gmock.h" @@ -51,7 +52,8 @@ ASSERT_TRUE(valuables_table().AddOrUpdateLoyaltyCard(card2)); EXPECT_EQ(valuables_table().GetLoyaltyCardById(card1.id()), card1); EXPECT_EQ(valuables_table().GetLoyaltyCardById(card2.id()), card2); - EXPECT_EQ(valuables_table().GetLoyaltyCardById("invalid_id"), std::nullopt); + EXPECT_EQ(valuables_table().GetLoyaltyCardById(ValuableId("invalid_id")), + std::nullopt); } TEST_F(ValuablesTableTest, AddOrUpdateLoyaltyCard) { @@ -89,7 +91,7 @@ TEST_F(ValuablesTableTest, AddOrUpdateLoyaltyCard_EmptyLoyaltyCardId) { LoyaltyCard card1 = test::CreateLoyaltyCard(); - card1.set_id(""); + card1.set_id(ValuableId("")); EXPECT_FALSE(valuables_table().AddOrUpdateLoyaltyCard(card1)); EXPECT_THAT(valuables_table().GetLoyaltyCards(), IsEmpty());
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc index f8ee16c2..04f01c8 100644 --- a/components/autofill/core/common/autofill_features.cc +++ b/components/autofill/core/common/autofill_features.cc
@@ -80,6 +80,11 @@ &kAutofillAiServerModel, "autofill_ai_model_execution_timeout", base::Seconds(10)}; +// Whether AnnotatedPageContent is included in the request to the AutofillAI +// model. +const base::FeatureParam<bool> kAutofillAiServerModelSendPageContent{ + &kAutofillAiServerModel, "autofill_ai_model_send_apc", false}; + // Whether the page's full URL is included in the data sent to the model. const base::FeatureParam<bool> kAutofillAiServerModelSendPageUrl{ &kAutofillAiServerModel, "autofill_ai_model_send_page_url", false};
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h index cb2385c..b4aa662 100644 --- a/components/autofill/core/common/autofill_features.h +++ b/components/autofill/core/common/autofill_features.h
@@ -35,6 +35,8 @@ extern const base::FeatureParam<base::TimeDelta> kAutofillAiServerModelExecutionTimeout; COMPONENT_EXPORT(AUTOFILL) +extern const base::FeatureParam<bool> kAutofillAiServerModelSendPageContent; +COMPONENT_EXPORT(AUTOFILL) extern const base::FeatureParam<bool> kAutofillAiServerModelSendPageUrl; COMPONENT_EXPORT(AUTOFILL) extern const base::FeatureParam<bool> kAutofillAiServerModelUseCacheResults;
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc index 79fe0b7..291c135 100644 --- a/components/autofill/core/common/autofill_payments_features.cc +++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -14,11 +14,6 @@ base::FEATURE_ENABLED_BY_DEFAULT); #endif -// When enabled, local credit card migration flows will not be offered. -BASE_FEATURE(kAutofillDisableLocalCardMigration, - "AutofillDisableLocalCardMigration", - base::FEATURE_ENABLED_BY_DEFAULT); - // When enabled, card category benefits offered by BMO will be shown in Autofill // suggestions on the allowlisted merchant websites. BASE_FEATURE(kAutofillEnableAllowlistForBmoCardCategoryBenefits, @@ -93,12 +88,6 @@ "AutofillEnableCardInfoRuntimeRetrieval", base::FEATURE_DISABLED_BY_DEFAULT); -// When enabled, card product name (instead of issuer network) will be shown in -// Payments Autofill UI. -BASE_FEATURE(kAutofillEnableCardProductName, - "AutofillEnableCardProductName", - base::FEATURE_ENABLED_BY_DEFAULT); - // When enabled, we will store CVC for both local and server credit cards. This // will also allow the users to autofill their CVCs on checkout pages. BASE_FEATURE(kAutofillEnableCvcStorageAndFilling,
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h index 707f0fad..5f585156 100644 --- a/components/autofill/core/common/autofill_payments_features.h +++ b/components/autofill/core/common/autofill_payments_features.h
@@ -18,8 +18,6 @@ BASE_DECLARE_FEATURE(kAutofillDisableDefaultSaveCardFixFlowDetection); #endif COMPONENT_EXPORT(AUTOFILL) -BASE_DECLARE_FEATURE(kAutofillDisableLocalCardMigration); -COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillEnableAllowlistForBmoCardCategoryBenefits); COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillEnableAmountExtractionAllowlistDesktop); @@ -39,7 +37,6 @@ BASE_DECLARE_FEATURE(kAutofillEnableCardBenefitsIph); COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillEnableCardBenefitsSync); -COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillEnableCardProductName); COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillEnableCardInfoRuntimeRetrieval); COMPONENT_EXPORT(AUTOFILL)
diff --git a/components/autofill_payments_strings.grdp b/components/autofill_payments_strings.grdp index 9033734..ab83f52b 100644 --- a/components/autofill_payments_strings.grdp +++ b/components/autofill_payments_strings.grdp
@@ -236,76 +236,6 @@ Saving IBAN info </message> - <!-- Autofill Local card migration bubble or dialog --> - <if expr="not is_ios and not is_android"> - <message name="IDS_AUTOFILL_LOCAL_CARD_MIGRATION_ANIMATION_LABEL" desc="The text displayed in the migration pending animation in the omnibox. The animation will be triggered after the user consented to the migration offer."> - Saving cards... - </message> - <message name="IDS_AUTOFILL_LOCAL_CARD_MIGRATION_BUBBLE_TITLE" desc="The title text for a bubble that offers users to start the process of migrating local cards to cloud."> - Use your cards on all your devices? - </message> - <message name="IDS_AUTOFILL_LOCAL_CARD_MIGRATION_BUBBLE_BUTTON_LABEL" desc="The text in the OK button of a bubble that offers users to start the process of migration local cards to cloud."> - Continue - </message> - <message name="IDS_AUTOFILL_LOCAL_CARD_MIGRATION_BUBBLE_BODY_TEXT" desc="The body text for a bubble that offers users to start the process of migrating local cards to cloud."> - Right now, you have cards that can only be used on this device. Click Continue to review cards. - </message> - <message name="IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TITLE_OFFER" desc="The title text for a dialog that offers to migrate local cards into the cloud. - [ICU Syntax]"> - {NUM_CARDS, plural, - =1 {Save card in your Google Account} - other {Save cards in your Google Account}} - </message> - <message name="IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TITLE_DONE" desc="The title text for a dialog shown after the user accepts another dialog that offers to migrate local cards into the cloud and all cards are successfully migrated."> - You're all set! - </message> - <message name="IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TITLE_FIX" desc="The title text for a dialog shown after the user accepts another dialog that offers to migrate local cards into the cloud but there are errors with the cards that they need to address."> - Almost done - </message> - <message name="IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_CHECKBOX_UNCHECK_WARNING" desc="The warning text, after the user unchecks the checkbox, to indicate this card will still be saved on this device only, not to Google account."> - Saved on this device only - </message> - <message name="IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_OFFER" desc="The body text for a dialog that offers to migrate local cards into the cloud. [CHAR_LIMIT=NONE] [ICU Syntax]"> - {NUM_CARDS, plural, - =1 {This card and its billing address will be saved. You'll be able to use it when signed in to <ph name="USER_EMAIL">$1<ex>user@gmail.com</ex></ph>.} - other {These cards and their billing addresses will be saved. You'll be able to use them when signed in to <ph name="USER_EMAIL">$1<ex>user@gmail.com</ex></ph>.}} - </message> - <message name="IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_DONE" desc="The body text for a dialog shown after the user accepts another dialog that offers to migrate local cards into the cloud and all cards are successfully migrated. [ICU Syntax]"> - {NUM_CARDS, plural, - =1 {This card has been saved in your Google Account} - other {These cards have been saved in your Google Account}} - </message> - <message name="IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_ERROR" desc="The body text shown on a dialog when the user attempts to migrate their cards to Google Payments, but all migrations fail. [ICU Syntax]"> - {NUM_CARDS, plural, - =1 {This card can't be saved right now} - other {These cards can't be saved right now}} - </message> - <message name="IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_FIX" desc="The body text shown on a dialog after the user accepts another dialog that offers to migrate local cards into the cloud but there are errors with the cards that they need to address."> - Check the info below and delete any invalid cards - </message> - <message name="IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_INVALID_CARD_REMOVED" desc="The body text for a dialog shown after the user has deleted all invalid cards from browser local storage."> - The invalid cards have been removed - </message> - <message name="IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_BUTTON_LABEL_SAVE" desc="The text in the OK button of a dialog that offers to migrate local cards into the cloud."> - Save - </message> - <message name="IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_BUTTON_LABEL_CANCEL" desc="The text in the cancel button of a dialog that offers to migrate local cards into the cloud."> - Cancel - </message> - <message name="IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_BUTTON_LABEL_DONE" desc="The text in the OK button a dialog shown after the user accepts another dialog that offers to migrate local cards into the cloud."> - Done - </message> - <message name="IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_BUTTON_LABEL_VIEW_CARDS" desc="The text in the cancel button a dialog shown after the user accepts another dialog that offers to migrate local cards into the cloud."> - View cards - </message> - <message name="IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_LABEL_INVALID_CARDS" desc="The label text shown when a card is invalid and could not be migrated."> - Invalid - </message> - <message name="IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TRASH_CAN_BUTTON_TOOLTIP" desc="The tooltip for the trash can button in the card list that allows user to delete this particular credit card from Chrome."> - Remove card - </message> - </if> - <!-- Autofill error dialog related strings --> <message name="IDS_AUTOFILL_MASKED_SERVER_CARD_RISK_BASED_UNMASKING_ERROR_TITLE" desc="Text to be displayed as the title of the error dialog during credit card risk-based unmasking."> Something went wrong
diff --git a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_ANIMATION_LABEL.png.sha1 b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_ANIMATION_LABEL.png.sha1 deleted file mode 100644 index 5781e980..0000000 --- a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_ANIMATION_LABEL.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -586efa2ecee56f146aad85cce92bd41dc433b1e3 \ No newline at end of file
diff --git a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_LABEL_INVALID_CARDS.png.sha1 b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_LABEL_INVALID_CARDS.png.sha1 deleted file mode 100644 index 5b66ebde..0000000 --- a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_LABEL_INVALID_CARDS.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -e6b3aa3f9c7c002cb53adce75d1d6097ffe78809 \ No newline at end of file
diff --git a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_DONE.png.sha1 b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_DONE.png.sha1 deleted file mode 100644 index 33df952..0000000 --- a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_DONE.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -ec67b1d63d9d483ef8a3b5ddd07f8419c4377f8e \ No newline at end of file
diff --git a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_ERROR.png.sha1 b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_ERROR.png.sha1 deleted file mode 100644 index 145507b0..0000000 --- a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_ERROR.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -f525599d836186501897f0d1bd53da797ebf289e \ No newline at end of file
diff --git a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_INVALID_CARD_REMOVED.png.sha1 b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_INVALID_CARD_REMOVED.png.sha1 deleted file mode 100644 index 09cacec..0000000 --- a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_INVALID_CARD_REMOVED.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -350f61a737c0873e1443f2602afd68ae8ba63830 \ No newline at end of file
diff --git a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_OFFER.png.sha1 b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_OFFER.png.sha1 deleted file mode 100644 index 7f96622b..0000000 --- a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_MESSAGE_OFFER.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -d25c74bcff96c1e5c42f47503322f12e4313f14d \ No newline at end of file
diff --git a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TITLE_OFFER.png.sha1 b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TITLE_OFFER.png.sha1 deleted file mode 100644 index 7f96622b..0000000 --- a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TITLE_OFFER.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -d25c74bcff96c1e5c42f47503322f12e4313f14d \ No newline at end of file
diff --git a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TRASH_CAN_BUTTON_TOOLTIP.png.sha1 b/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TRASH_CAN_BUTTON_TOOLTIP.png.sha1 deleted file mode 100644 index 7cf6fe8..0000000 --- a/components/autofill_payments_strings_grdp/IDS_AUTOFILL_LOCAL_CARD_MIGRATION_DIALOG_TRASH_CAN_BUTTON_TOOLTIP.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -75df068d457ba4472fb15824d9d6644c0839ddeb \ No newline at end of file
diff --git a/components/browser_ui/edge_to_edge/android/java/src/org/chromium/components/browser_ui/edge_to_edge/layout/EdgeToEdgeLayoutCoordinator.java b/components/browser_ui/edge_to_edge/android/java/src/org/chromium/components/browser_ui/edge_to_edge/layout/EdgeToEdgeLayoutCoordinator.java index a9c819e..ae1d3c26 100644 --- a/components/browser_ui/edge_to_edge/android/java/src/org/chromium/components/browser_ui/edge_to_edge/layout/EdgeToEdgeLayoutCoordinator.java +++ b/components/browser_ui/edge_to_edge/android/java/src/org/chromium/components/browser_ui/edge_to_edge/layout/EdgeToEdgeLayoutCoordinator.java
@@ -7,6 +7,7 @@ import static org.chromium.build.NullUtil.assumeNonNull; import android.app.Activity; +import android.content.Context; import android.graphics.RectF; import android.os.Build; import android.util.DisplayMetrics; @@ -21,6 +22,8 @@ import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsCompat.Type; +import org.chromium.base.ContextUtils; +import org.chromium.base.Log; import org.chromium.build.annotations.EnsuresNonNull; import org.chromium.build.annotations.NullMarked; import org.chromium.build.annotations.Nullable; @@ -39,7 +42,8 @@ @NullMarked public class EdgeToEdgeLayoutCoordinator extends BaseSystemBarColorHelper implements WindowInsetsConsumer { - private final Activity mActivity; + private static final String TAG = "E2E_Layout"; + private final Context mContext; private final @Nullable InsetObserver mInsetObserver; private @Nullable EdgeToEdgeBaseLayout mView; private boolean mIsDebugging; @@ -47,11 +51,11 @@ /** * Construct the coordinator used to handle padding and color for the Edge to edge layout. * - * @param activity The base activity. + * @param context The Activity context. * @param insetObserver The inset observer of current window, if exists. */ - public EdgeToEdgeLayoutCoordinator(Activity activity, @Nullable InsetObserver insetObserver) { - mActivity = activity; + public EdgeToEdgeLayoutCoordinator(Context context, @Nullable InsetObserver insetObserver) { + mContext = context; mInsetObserver = insetObserver; } @@ -130,7 +134,7 @@ mView.setCaptionBarInsets(captionBarInsets); int paddingInsetTypes = Type.systemBars() + Type.ime(); - if (shouldPadDisplayCutout(windowInsets, mActivity)) { + if (shouldPadDisplayCutout(windowInsets, mContext)) { paddingInsetTypes += Type.displayCutout(); // Color display cutout padding to keep behaviour for Android 15-. mView.setDisplayCutoutTop(cutout.top > 0 ? cutout : Insets.NONE); @@ -163,7 +167,7 @@ mView = (EdgeToEdgeBaseLayout) - LayoutInflater.from(mActivity) + LayoutInflater.from(mContext) .inflate(R.layout.edge_to_edge_base_layout, null, false); if (mInsetObserver != null) { mInsetObserver.addInsetsConsumer( @@ -182,9 +186,15 @@ // Determine if padding is necessary according to WindowManager.LayoutParams. This is intended // to keep the behavior for Android 15-. // Ref: https://developer.android.com/develop/ui/views/layout/display-cutout - private static boolean shouldPadDisplayCutout(WindowInsetsCompat insets, Activity activity) { + private static boolean shouldPadDisplayCutout(WindowInsetsCompat insets, Context context) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P || insets == null) return true; + Activity activity = ContextUtils.activityFromContext(context); + if (activity == null) { + Log.w(TAG, "should not receive window insets in non-activity context."); + return false; + } + DisplayCutoutCompat cutout = insets.getDisplayCutout(); if (cutout == null) return false;
diff --git a/components/browser_ui/widget/android/BUILD.gn b/components/browser_ui/widget/android/BUILD.gn index 4857eb93..c262bea5 100644 --- a/components/browser_ui/widget/android/BUILD.gn +++ b/components/browser_ui/widget/android/BUILD.gn
@@ -163,11 +163,13 @@ "java/res/anim/image_tile_enter.xml", "java/res/anim/textbubble_in.xml", "java/res/anim/textbubble_out.xml", + "java/res/color-night/home_surface_ui_background_color.xml", "java/res/color/chip_background_color.xml", "java/res/color/chip_ripple_color.xml", "java/res/color/chip_state_layer_color.xml", "java/res/color/chip_stroke_color.xml", "java/res/color/chip_text_color.xml", + "java/res/color/home_surface_ui_background_color.xml", "java/res/color/menu_bg_color.xml", "java/res/color/menu_chip_background.xml", "java/res/drawable-hdpi/btn_delete_24dp.png",
diff --git a/components/browser_ui/widget/android/java/res/color-night/home_surface_ui_background_color.xml b/components/browser_ui/widget/android/java/res/color-night/home_surface_ui_background_color.xml new file mode 100644 index 0000000..89a51974 --- /dev/null +++ b/components/browser_ui/widget/android/java/res/color-night/home_surface_ui_background_color.xml
@@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +Copyright 2025 The Chromium Authors +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:color="?attr/colorSurfaceContainer"/> +</selector> \ No newline at end of file
diff --git a/components/browser_ui/widget/android/java/res/color/home_surface_ui_background_color.xml b/components/browser_ui/widget/android/java/res/color/home_surface_ui_background_color.xml new file mode 100644 index 0000000..465a419 --- /dev/null +++ b/components/browser_ui/widget/android/java/res/color/home_surface_ui_background_color.xml
@@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +Copyright 2025 The Chromium Authors +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:color="?attr/colorSurface"/> +</selector> \ No newline at end of file
diff --git a/components/browser_ui/widget/android/java/res/drawable/home_surface_ui_background.xml b/components/browser_ui/widget/android/java/res/drawable/home_surface_ui_background.xml index 67f189a8..2b19bf9a 100644 --- a/components/browser_ui/widget/android/java/res/drawable/home_surface_ui_background.xml +++ b/components/browser_ui/widget/android/java/res/drawable/home_surface_ui_background.xml
@@ -4,10 +4,8 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<org.chromium.components.browser_ui.widget.SurfaceColorDrawable - xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:shape="rectangle" - app:surfaceElevation="@dimen/home_surface_ui_background_color_elevation"> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <solid android:color="@color/home_surface_ui_background_color"/> <corners android:radius="@dimen/home_surface_ui_background_radius"/> -</org.chromium.components.browser_ui.widget.SurfaceColorDrawable> +</shape> \ No newline at end of file
diff --git a/components/browser_ui/widget/android/java/res/values-night/dimens.xml b/components/browser_ui/widget/android/java/res/values-night/dimens.xml index 14bf87ca..da04fc5 100644 --- a/components/browser_ui/widget/android/java/res/values-night/dimens.xml +++ b/components/browser_ui/widget/android/java/res/values-night/dimens.xml
@@ -17,7 +17,6 @@ <!-- New Tab Page --> <dimen name="home_surface_background_color_elevation">@dimen/default_elevation_0</dimen> <item name="home_surface_search_box_background_alpha" format="float" type="dimen">0.2</item> - <dimen name="home_surface_ui_background_color_elevation">@dimen/default_elevation_1</dimen> <!-- Single Tab module --> <dimen name="favicon_background_color_elevation">@dimen/default_elevation_2</dimen>
diff --git a/components/browser_ui/widget/android/java/res/values/dimens.xml b/components/browser_ui/widget/android/java/res/values/dimens.xml index 43b765e..995053c 100644 --- a/components/browser_ui/widget/android/java/res/values/dimens.xml +++ b/components/browser_ui/widget/android/java/res/values/dimens.xml
@@ -204,7 +204,6 @@ <!-- New Tab Page --> <dimen name="home_surface_background_color_elevation">@dimen/default_elevation_2</dimen> <item name="home_surface_search_box_background_alpha" format="float" type="dimen">0.15</item> - <dimen name="home_surface_ui_background_color_elevation">@dimen/default_elevation_0</dimen> <dimen name="home_surface_ui_background_radius">24dp</dimen> <dimen name="home_surface_search_box_background_radius">100dp</dimen>
diff --git a/components/commerce/core/internals/resources/BUILD.gn b/components/commerce/core/internals/resources/BUILD.gn index 28300dc0..d7225e0 100644 --- a/components/commerce/core/internals/resources/BUILD.gn +++ b/components/commerce/core/internals/resources/BUILD.gn
@@ -43,6 +43,7 @@ "$root_gen_dir/components/commerce/core/mojom/shopping_service.mojom-webui.ts", ] + ts_tsconfig_base = "//tools/typescript/tsconfig_base_lit_389737066.json" ts_deps = [ "//third_party/lit/v3_0:build_ts", "//ui/webui/resources/cr_components/commerce:build_ts",
diff --git a/components/commerce/core/internals/resources/eligibility_list.ts b/components/commerce/core/internals/resources/eligibility_list.ts index 59c755b8..d9d86783 100644 --- a/components/commerce/core/internals/resources/eligibility_list.ts +++ b/components/commerce/core/internals/resources/eligibility_list.ts
@@ -36,9 +36,9 @@ }; } - protected country_: string = ''; - protected details_: EligibilityDetail[] = []; - protected locale_: string = ''; + protected accessor country_: string = ''; + protected accessor details_: EligibilityDetail[] = []; + protected accessor locale_: string = ''; private commerceInternalsApi_: CommerceInternalsApiProxy = CommerceInternalsApiProxy.getInstance();
diff --git a/components/commerce/core/internals/resources/product_specifications_set_list.ts b/components/commerce/core/internals/resources/product_specifications_set_list.ts index 0ffc21b9..4071ac64 100644 --- a/components/commerce/core/internals/resources/product_specifications_set_list.ts +++ b/components/commerce/core/internals/resources/product_specifications_set_list.ts
@@ -28,7 +28,7 @@ }; } - protected sets_: ProductSpecificationsSet[] = []; + protected accessor sets_: ProductSpecificationsSet[] = []; private commerceInternalsApi_: CommerceInternalsApiProxy = CommerceInternalsApiProxy.getInstance();
diff --git a/components/commerce/core/internals/resources/product_viewer/app.ts b/components/commerce/core/internals/resources/product_viewer/app.ts index 9a4038f8..c7b49d2 100644 --- a/components/commerce/core/internals/resources/product_viewer/app.ts +++ b/components/commerce/core/internals/resources/product_viewer/app.ts
@@ -35,7 +35,7 @@ }; } - protected product_: ProductInfo|null = null; + protected accessor product_: ProductInfo|null = null; private commerceInternalsApi_: CommerceInternalsApiProxy = CommerceInternalsApiProxy.getInstance();
diff --git a/components/commerce/core/internals/resources/subscription_list.ts b/components/commerce/core/internals/resources/subscription_list.ts index 98d3cab..7b5a137b 100644 --- a/components/commerce/core/internals/resources/subscription_list.ts +++ b/components/commerce/core/internals/resources/subscription_list.ts
@@ -28,7 +28,7 @@ }; } - protected subscriptions_: Subscription[] = []; + protected accessor subscriptions_: Subscription[] = []; private commerceInternalsApi_: CommerceInternalsApiProxy = CommerceInternalsApiProxy.getInstance();
diff --git a/components/data_sharing/internal/data_sharing_network_loader_impl.cc b/components/data_sharing/internal/data_sharing_network_loader_impl.cc index 6f8220d7..514e4158 100644 --- a/components/data_sharing/internal/data_sharing_network_loader_impl.cc +++ b/components/data_sharing/internal/data_sharing_network_loader_impl.cc
@@ -85,7 +85,7 @@ } std::move(callback).Run( std::make_unique<DataSharingNetworkLoader::LoadResult>( - std::move(response->response), status)); + std::move(response->response), status, response->http_status_code)); } const net::NetworkTrafficAnnotationTag&
diff --git a/components/data_sharing/internal/data_sharing_network_loader_impl_unittest.cc b/components/data_sharing/internal/data_sharing_network_loader_impl_unittest.cc index 076692f..b6bceabf 100644 --- a/components/data_sharing/internal/data_sharing_network_loader_impl_unittest.cc +++ b/components/data_sharing/internal/data_sharing_network_loader_impl_unittest.cc
@@ -82,6 +82,7 @@ DataSharingNetworkLoader::NetworkLoaderStatus:: kTransientFailure); ASSERT_TRUE(response->result_bytes.empty()); + ASSERT_EQ(response->network_error_code, 400); run_loop->Quit(); }, &run_loop));
diff --git a/components/data_sharing/public/android/conversion_utils.cc b/components/data_sharing/public/android/conversion_utils.cc index 4b5a885..f093315 100644 --- a/components/data_sharing/public/android/conversion_utils.cc +++ b/components/data_sharing/public/android/conversion_utils.cc
@@ -114,7 +114,7 @@ env, ToJavaByteArray(env, std::vector<uint8_t>(response->result_bytes.begin(), response->result_bytes.end())), - static_cast<int>(response->status)); + static_cast<int>(response->status), response->network_error_code); } } // namespace data_sharing::conversion
diff --git a/components/data_sharing/public/android/java/src/org/chromium/components/data_sharing/DataSharingNetworkResult.java b/components/data_sharing/public/android/java/src/org/chromium/components/data_sharing/DataSharingNetworkResult.java index d5bbe35..792faf2 100644 --- a/components/data_sharing/public/android/java/src/org/chromium/components/data_sharing/DataSharingNetworkResult.java +++ b/components/data_sharing/public/android/java/src/org/chromium/components/data_sharing/DataSharingNetworkResult.java
@@ -15,15 +15,19 @@ public class DataSharingNetworkResult { public final byte[] resultBytes; public final @NetworkLoaderStatus int status; + public final int networkErrorCode; - DataSharingNetworkResult(byte[] resultBytes, @NetworkLoaderStatus int status) { + DataSharingNetworkResult(byte[] resultBytes, + @NetworkLoaderStatus int status, + int networkErrorCode) { this.resultBytes = resultBytes; this.status = status; + this.networkErrorCode = networkErrorCode; } @CalledByNative private static DataSharingNetworkResult createDataSharingNetworkResult( - byte[] resultBytes, @NetworkLoaderStatus int status) { - return new DataSharingNetworkResult(resultBytes, status); + byte[] resultBytes, @NetworkLoaderStatus int status, int networkErrorCode) { + return new DataSharingNetworkResult(resultBytes, status, networkErrorCode); } }
diff --git a/components/data_sharing/public/android/java/src/org/chromium/components/data_sharing/configs/DataSharingManageUiConfig.java b/components/data_sharing/public/android/java/src/org/chromium/components/data_sharing/configs/DataSharingManageUiConfig.java index c8875c6..8bb0dcc 100644 --- a/components/data_sharing/public/android/java/src/org/chromium/components/data_sharing/configs/DataSharingManageUiConfig.java +++ b/components/data_sharing/public/android/java/src/org/chromium/components/data_sharing/configs/DataSharingManageUiConfig.java
@@ -42,11 +42,6 @@ default void onMemberBlocked(GroupMember member) {} - default void onMemberRemovedAndStopSharingInitiated( - GroupMember member, GroupData groupData, Callback<Boolean> readyToStop) {} - - default void onMemberBlockedAndLeaveGroup(GroupMember member, GroupData groupData) {} - default void onLeaveGroup() {} default void getDataSharingUrl(GroupToken groupToken, Callback<String> url) {}
diff --git a/components/data_sharing/public/data_sharing_network_loader.cc b/components/data_sharing/public/data_sharing_network_loader.cc index f02f701f..8a005c62 100644 --- a/components/data_sharing/public/data_sharing_network_loader.cc +++ b/components/data_sharing/public/data_sharing_network_loader.cc
@@ -9,8 +9,11 @@ DataSharingNetworkLoader::LoadResult::LoadResult() = default; DataSharingNetworkLoader::LoadResult::LoadResult(std::string result_bytes, - NetworkLoaderStatus status) - : result_bytes(std::move(result_bytes)), status(status) {} + NetworkLoaderStatus status, + int network_error_code) + : result_bytes(std::move(result_bytes)), + status(status), + network_error_code(network_error_code) {} DataSharingNetworkLoader::LoadResult::~LoadResult() = default;
diff --git a/components/data_sharing/public/data_sharing_network_loader.h b/components/data_sharing/public/data_sharing_network_loader.h index 5764ad1..1a9f152 100644 --- a/components/data_sharing/public/data_sharing_network_loader.h +++ b/components/data_sharing/public/data_sharing_network_loader.h
@@ -50,11 +50,14 @@ struct LoadResult { LoadResult(); - LoadResult(std::string result_bytes, NetworkLoaderStatus status); + LoadResult(std::string result_bytes, + NetworkLoaderStatus status, + int network_error_code); ~LoadResult(); std::string result_bytes; NetworkLoaderStatus status; + int network_error_code; }; // Callback to return the network response to the caller.
diff --git a/components/download/resources/download_internals/BUILD.gn b/components/download/resources/download_internals/BUILD.gn index f55e4fa..af9e71d 100644 --- a/components/download/resources/download_internals/BUILD.gn +++ b/components/download/resources/download_internals/BUILD.gn
@@ -18,6 +18,7 @@ "download_internals_visuals.ts", ] + ts_tsconfig_base = "//tools/typescript/tsconfig_base_lit_389737066.json" ts_deps = [ "//third_party/lit/v3_0:build_ts", "//ui/webui/resources/js:build_ts",
diff --git a/components/headless/screen_info/BUILD.gn b/components/headless/screen_info/BUILD.gn index 0c26ab4b..f8bba70 100644 --- a/components/headless/screen_info/BUILD.gn +++ b/components/headless/screen_info/BUILD.gn
@@ -11,7 +11,6 @@ deps = [ "//base", "//third_party/re2", - "//ui/display", "//ui/gfx/geometry/", ] }
diff --git a/components/headless/screen_info/DEPS b/components/headless/screen_info/DEPS index 4f93239..20f6b13 100644 --- a/components/headless/screen_info/DEPS +++ b/components/headless/screen_info/DEPS
@@ -1,6 +1,5 @@ include_rules = [ "+base", "+third_party/re2/src/re2/re2.h", - "+ui/display", "+ui/gfx/geometry", ]
diff --git a/components/headless/screen_info/headless_screen_info.cc b/components/headless/screen_info/headless_screen_info.cc index 6b037f61..0cf2617c 100644 --- a/components/headless/screen_info/headless_screen_info.cc +++ b/components/headless/screen_info/headless_screen_info.cc
@@ -11,7 +11,6 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "third_party/re2/src/re2/re2.h" -#include "ui/display/display.h" using re2::RE2; @@ -70,6 +69,13 @@ return std::nullopt; } +// This is the same as display::Display::IsValidRotation(). It is replicated +// here to prevent dependency on //ui/display/ which is undesired because this +// file is intended to be included from there. +bool IsValidRotation(int degrees) { + return degrees == 0 || degrees == 90 || degrees == 180 || degrees == 270; +} + // Parse screen info parameter key value pair returning an error message or // an empty string if there is no error. std::string ParseScreenInfoParameter(std::string_view key, @@ -161,8 +167,7 @@ // rotation=0|90|180|270 if (key == kRotation) { int rotation; - if (!base::StringToInt(value, &rotation) || - !display::Display::IsValidRotation(rotation)) { + if (!base::StringToInt(value, &rotation) || !IsValidRotation(rotation)) { return kInvalidRotation + std::string(value); }
diff --git a/components/ntp_tiles/webui/resources/BUILD.gn b/components/ntp_tiles/webui/resources/BUILD.gn index cbec6868..7b51e4e 100644 --- a/components/ntp_tiles/webui/resources/BUILD.gn +++ b/components/ntp_tiles/webui/resources/BUILD.gn
@@ -16,6 +16,7 @@ ts_definitions = [ "//tools/typescript/definitions/chrome_send.d.ts" ] + ts_tsconfig_base = "//tools/typescript/tsconfig_base_lit_389737066.json" ts_deps = [ "//third_party/lit/v3_0:build_ts", "//ui/webui/resources/js:build_ts",
diff --git a/components/optimization_guide/internal b/components/optimization_guide/internal index be66ee9..70e09ab 160000 --- a/components/optimization_guide/internal +++ b/components/optimization_guide/internal
@@ -1 +1 @@ -Subproject commit be66ee9610e48fcfb3dba8dba2482af49d11f39a +Subproject commit 70e09ab5396ad41a1fa8996f6b6e9cde542301a1
diff --git a/components/optimization_guide/proto/features/forms_classifications.proto b/components/optimization_guide/proto/features/forms_classifications.proto index 327b22b..7720262 100644 --- a/components/optimization_guide/proto/features/forms_classifications.proto +++ b/components/optimization_guide/proto/features/forms_classifications.proto
@@ -32,6 +32,7 @@ ModelExecutionInfo model_execution_info = 4; } +// Next ID: 6 message AutofillAiTypeRequest { // The context of the page that the form is on. PageContext page_context = 1; @@ -46,7 +47,11 @@ // The page content extracted from the page, including form and field names, // types, surrounding text, and other relevant information. - PageContent page_content = 4; + // TODO(crbug.com/405474316): Remove this once the MES config no longer references it. + PageContent page_content = 4 [deprecated = true]; + + // The annotated page content of the page that the form is on. + AnnotatedPageContent annotated_page_content = 5; } message FormMedia { @@ -55,6 +60,7 @@ } // Next ID: 4 +// TODO(crbug.com/405474316): Remove this once the MES config no longer references it. message PageContent { // The form data extracted from the page, including form and field names, // types, and other relevant information. @@ -73,12 +79,14 @@ repeated FieldTypeResponse field_responses = 1; } +// Next ID: 6 message FieldTypeResponse { - // A globally unique identifier for the form field, passed from the client. - // Used to match the request field with the corresponding response field. - // This value is provided by the client and should remain consistent between - // request and response. - string field_global_id = 1; + // Do not use - use field_index instead. + string field_global_id = 1 [deprecated = true]; + + // The (zero-based) index of the field among those passed in the request that + // this prediction refers to. + int32 field_index = 5; // The predicted type for the field. int32 field_type = 2;
diff --git a/components/page_load_metrics/google/browser/gws_page_load_metrics_observer.cc b/components/page_load_metrics/google/browser/gws_page_load_metrics_observer.cc index 06db2c8..f8e8b99 100644 --- a/components/page_load_metrics/google/browser/gws_page_load_metrics_observer.cc +++ b/components/page_load_metrics/google/browser/gws_page_load_metrics_observer.cc
@@ -55,6 +55,8 @@ HISTOGRAM_PREFIX "NavigationTiming.NavigationStartToFirstLoaderCallback"; const char kHistogramGWSNavigationStartToOnComplete[] = HISTOGRAM_PREFIX "NavigationTiming.NavigationStartToOnComplete"; +const char kHistogramGWSInitializeStreamDelay[] = + HISTOGRAM_PREFIX "NavigationTiming.InitializeStreamDelay"; const char kHistogramGWSConnectTimingFirstRequestDomainLookupDelay[] = HISTOGRAM_PREFIX "ConnectTiming.FirstRequestDomainLookupDelay"; @@ -599,6 +601,8 @@ PAGE_LOAD_SHORT_HISTOGRAM( internal::kHistogramGWSConnectTimingFinalRequestSslDelay, timing.final_request_ssl_delay); + PAGE_LOAD_SHORT_HISTOGRAM(internal::kHistogramGWSInitializeStreamDelay, + timing.initialize_stream_delay); // Record latency trace events. RecordLatencyHitograms(timing.non_redirect_response_start_time);
diff --git a/components/password_manager/core/browser/password_manager_util_unittest.cc b/components/password_manager/core/browser/password_manager_util_unittest.cc index 6a3fd0c5..5e84739 100644 --- a/components/password_manager/core/browser/password_manager_util_unittest.cc +++ b/components/password_manager/core/browser/password_manager_util_unittest.cc
@@ -21,7 +21,6 @@ #include "components/autofill/core/browser/data_model/payments/credit_card.h" #include "components/autofill/core/browser/foundations/autofill_client.h" #include "components/autofill/core/browser/foundations/test_autofill_client.h" -#include "components/autofill/core/browser/payments/local_card_migration_manager.h" #include "components/autofill/core/browser/suggestions/suggestion.h" #include "components/autofill/core/browser/suggestions/suggestion_hiding_reason.h" #include "components/autofill/core/browser/suggestions/suggestion_type.h"
diff --git a/components/password_manager/core/browser/votes_uploader.cc b/components/password_manager/core/browser/votes_uploader.cc index f3b8ca96..15d87efd 100644 --- a/components/password_manager/core/browser/votes_uploader.cc +++ b/components/password_manager/core/browser/votes_uploader.cc
@@ -895,13 +895,12 @@ bool should_set_passwords_were_revealed) { // Annotate the form with the source language of the page. form.set_current_page_language(client_->GetPageLanguage()); - // Attach the Randomized Encoder. - form.set_randomized_encoder(RandomizedEncoder::Create(client_->GetPrefs())); std::vector<AutofillUploadContents> upload_contents = - autofill::EncodeUploadRequest(form, /*format_strings=*/{}, - available_field_types, login_form_signature, - /*observed_submission=*/true); + autofill::EncodeUploadRequest( + form, RandomizedEncoder::Create(client_->GetPrefs()).get(), + /*format_strings=*/{}, available_field_types, login_form_signature, + /*observed_submission=*/true); CHECK(!upload_contents.empty()); upload_contents[0].set_passwords_revealed(
diff --git a/components/policy/resources/templates/policies.yaml b/components/policy/resources/templates/policies.yaml index fd99dba0..3519956a 100644 --- a/components/policy/resources/templates/policies.yaml +++ b/components/policy/resources/templates/policies.yaml
@@ -1347,6 +1347,7 @@ 1346: GenAIInlineImageSettings 1347: UserSecuritySignalsReporting 1348: UserSecurityAuthenticatedReporting + 1349: HappyEyeballsV3Enabled atomic_groups: 1: Homepage
diff --git a/components/policy/resources/templates/policy_definitions/Network/HappyEyeballsV3Enabled.yaml b/components/policy/resources/templates/policy_definitions/Network/HappyEyeballsV3Enabled.yaml new file mode 100644 index 0000000..0b2d545 --- /dev/null +++ b/components/policy/resources/templates/policy_definitions/Network/HappyEyeballsV3Enabled.yaml
@@ -0,0 +1,33 @@ +caption: Use the <ph name="HAPPY_EYEBALLS_V3">Happy Eyeballs V3</ph> algorithm +desc: |- + This feature enables the <ph name="HAPPY_EYEBALLS_V3">Happy Eyeballs V3</ph> algorithm to make connection attempts. See https://datatracker.ietf.org/doc/draft-pauly-happy-happyeyeballs-v3 for details. + + Setting the policy to Enabled means <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will use the <ph name="HAPPY_EYEBALLS_V3">Happy Eyeballs V3</ph> algorithm for connection attempts. + + Setting the policy to Disabled turns off the <ph name="HAPPY_EYEBALLS_V3">Happy Eyeballs V3</ph> algorithm. + + Not setting the policy, <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> will turn on or off the <ph name="HAPPY_EYEBALLS_V3">Happy Eyeballs V3</ph> algorithm based on chrome://flags/#happy-eyeballs-v3. + + This policy supports dynamic refresh. + + This policy is a temporary measure and will be removed in future versions of <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>. +owners: +- bashi@chromium.org +- file://net/OWNERS +supported_on: +- android:136- +- chrome.*:136- +- chrome_os:136- +features: + dynamic_refresh: true + per_profile: false +type: main +schema: + type: boolean +items: +- caption: Using the <ph name="HAPPY_EYEBALLS_V3">Happy Eyeballs V3</ph> algorithm. + value: true +- caption: Do not use the <ph name="HAPPY_EYEBALLS_V3">Happy Eyeballs V3</ph> algorithm. + value: false +example_value: true +tags: []
diff --git a/components/policy/test/data/pref_mapping/HappyEyeballsV3Enabled.json b/components/policy/test/data/pref_mapping/HappyEyeballsV3Enabled.json new file mode 100644 index 0000000..af2f246 --- /dev/null +++ b/components/policy/test/data/pref_mapping/HappyEyeballsV3Enabled.json
@@ -0,0 +1,21 @@ +[ + { + "os": [ + "win", + "linux", + "mac", + "chromeos", + "android", + "fuchsia" + ], + "simple_policy_pref_mapping_test": { + "pref_name": "net.happy_eyeballs_v3_enabled", + "pref_location": "local_state", + "default_value": false, + "values_to_test": [ + true, + false + ] + } + } +]
diff --git a/components/printing/browser/print_to_pdf/pdf_print_utils.cc b/components/printing/browser/print_to_pdf/pdf_print_utils.cc index 0f0e217..ad0df87 100644 --- a/components/printing/browser/print_to_pdf/pdf_print_utils.cc +++ b/components/printing/browser/print_to_pdf/pdf_print_utils.cc
@@ -138,16 +138,16 @@ if (margin_bottom_in_inches < 0) return "bottom margin is negative"; - printing::PageMargins margins_in_points; - margins_in_points.left = - base::ClampFloor(margin_left_in_inches * printing::kPointsPerInch); - margins_in_points.right = - base::ClampFloor(margin_right_in_inches * printing::kPointsPerInch); - margins_in_points.top = - base::ClampFloor(margin_top_in_inches * printing::kPointsPerInch); - margins_in_points.bottom = - base::ClampFloor(margin_bottom_in_inches * printing::kPointsPerInch); - print_settings.SetCustomMargins(margins_in_points); + printing::PageMargins margins_in_microns; + margins_in_microns.left = + base::ClampFloor(margin_left_in_inches * printing::kMicronsPerInch); + margins_in_microns.right = + base::ClampFloor(margin_right_in_inches * printing::kMicronsPerInch); + margins_in_microns.top = + base::ClampFloor(margin_top_in_inches * printing::kMicronsPerInch); + margins_in_microns.bottom = + base::ClampFloor(margin_bottom_in_inches * printing::kMicronsPerInch); + print_settings.SetCustomMargins(margins_in_microns); double paper_width_in_inches = paper_width.value_or(printing::kLetterWidthInch);
diff --git a/components/printing/common/cloud_print_cdd_conversion_unittest.cc b/components/printing/common/cloud_print_cdd_conversion_unittest.cc index f70291a..26195c98 100644 --- a/components/printing/common/cloud_print_cdd_conversion_unittest.cc +++ b/components/printing/common/cloud_print_cdd_conversion_unittest.cc
@@ -16,6 +16,9 @@ namespace { +using testing::Eq; +using testing::Pointee; + constexpr char kKeyPrinter[] = "printer"; constexpr char kKeyVersion[] = "version"; constexpr char kValueVersion[] = "1.0"; @@ -295,7 +298,8 @@ caps_dict->size() != 2u) { return nullptr; } - base::ExpectDictStringValue(kValueVersion, *caps_dict, kKeyVersion); + EXPECT_THAT(caps_dict->FindString(kKeyVersion), + testing::Pointee(Eq(kValueVersion))); return caps_dict->FindDict(kKeyPrinter); } @@ -312,27 +316,27 @@ #else ASSERT_EQ(9u, printer_dict->size()); #endif // BUILDFLAG(IS_CHROMEOS) - base::ExpectDictValue(base::test::ParseJson(kExpectedCollateDefaultTrue), - *printer_dict, "collate"); - base::ExpectDictValue(base::test::ParseJson(kExpectedColor), *printer_dict, - "color"); - base::ExpectDictValue(base::test::ParseJson(kExpectedCopies), *printer_dict, - "copies"); - base::ExpectDictValue(base::test::ParseJson(kExpectedDpi), *printer_dict, - "dpi"); - base::ExpectDictValue(base::test::ParseJson(kExpectedDuplex), *printer_dict, - "duplex"); - base::ExpectDictValue(base::test::ParseJson(kExpectedMediaSize), - *printer_dict, "media_size"); - base::ExpectDictValue(base::test::ParseJson(kExpectedMediaType), - *printer_dict, "media_type"); - base::ExpectDictValue(base::test::ParseJson(kExpectedPageOrientation), - *printer_dict, "page_orientation"); - base::ExpectDictValue(base::test::ParseJson(kExpectedSupportedContentType), - *printer_dict, "supported_content_type"); + + EXPECT_THAT( + *printer_dict, + base::test::IsSupersetOfValue( + base::Value::Dict() + .Set("collate", + base::test::ParseJson(kExpectedCollateDefaultTrue)) + .Set("color", base::test::ParseJson(kExpectedColor)) + .Set("copies", base::test::ParseJson(kExpectedCopies)) + .Set("dpi", base::test::ParseJson(kExpectedDpi)) + .Set("duplex", base::test::ParseJson(kExpectedDuplex)) + .Set("media_size", base::test::ParseJson(kExpectedMediaSize)) + .Set("media_type", base::test::ParseJson(kExpectedMediaType)) + .Set("page_orientation", + base::test::ParseJson(kExpectedPageOrientation)) + .Set("supported_content_type", + base::test::ParseJson(kExpectedSupportedContentType)))); + #if BUILDFLAG(IS_CHROMEOS) - base::ExpectDictValue(base::test::ParseJson(kExpectedPinSupportedFalse), - *printer_dict, "pin"); + EXPECT_THAT(printer_dict->Find("pin"), + Pointee(base::test::IsJson(kExpectedPinSupportedFalse))); #endif // BUILDFLAG(IS_CHROMEOS) } @@ -367,8 +371,8 @@ #else ASSERT_EQ(9u, printer_dict->size()); #endif // BUILDFLAG(IS_CHROMEOS) - base::ExpectDictValue(base::test::ParseJson(kExpectedCollateDefaultFalse), - *printer_dict, "collate"); + EXPECT_THAT(printer_dict->Find("collate"), + Pointee(base::test::IsJson(kExpectedCollateDefaultFalse))); } TEST(CloudPrintCddConversionTest, WiderPaper) { @@ -390,8 +394,8 @@ #else ASSERT_EQ(9u, printer_dict->size()); #endif // BUILDFLAG(IS_CHROMEOS) - base::ExpectDictValue(base::test::ParseJson(kExpectedMediaSizeWithWiderPaper), - *printer_dict, "media_size"); + EXPECT_THAT(printer_dict->Find("media_size"), + Pointee(base::test::IsJson(kExpectedMediaSizeWithWiderPaper))); } #if BUILDFLAG(IS_CHROMEOS) @@ -417,10 +421,13 @@ ASSERT_TRUE(printer_dict); ASSERT_EQ(11u, printer_dict->size()); - base::ExpectDictValue(base::test::ParseJson(kExpectedPinSupportedTrue), - *printer_dict, "pin"); - base::ExpectDictValue(base::test::ParseJson(kExpectedAdvancedCapabilities), - *printer_dict, "vendor_capability"); + EXPECT_THAT( + *printer_dict, + base::test::IsSupersetOfValue( + base::Value::Dict() + .Set("pin", base::test::ParseJson(kExpectedPinSupportedTrue)) + .Set("vendor_capability", + base::test::ParseJson(kExpectedAdvancedCapabilities)))); } #endif // BUILDFLAG(IS_CHROMEOS) @@ -435,8 +442,8 @@ ASSERT_TRUE(printer_dict); ASSERT_EQ(10u, printer_dict->size()); - base::ExpectDictValue(base::test::ParseJson(kExpectedPageOutputQuality), - *printer_dict, "vendor_capability"); + EXPECT_THAT(printer_dict->Find("vendor_capability"), + Pointee(base::test::IsJson(kExpectedPageOutputQuality))); } TEST(CloudPrintCddConversionTest, PageOutputQualityNullDefaultQuality) { @@ -448,9 +455,9 @@ ASSERT_TRUE(printer_dict); ASSERT_EQ(10u, printer_dict->size()); - base::ExpectDictValue( - base::test::ParseJson(kExpectedPageOutputQualityNullDefault), - *printer_dict, "vendor_capability"); + EXPECT_THAT( + printer_dict->Find("vendor_capability"), + Pointee(base::test::IsJson(kExpectedPageOutputQualityNullDefault))); } #endif // BUILDFLAG(IS_WIN)
diff --git a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h index 3f29d9a5..09bb84f 100644 --- a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h +++ b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h
@@ -390,7 +390,7 @@ std::unique_ptr<CocoaWindowMoveLoop> window_move_loop_; ui::mojom::ModalType modal_type_ = ui::mojom::ModalType::kNone; bool is_translucent_window_ = false; - id __strong key_down_event_monitor_; + id __strong local_event_monitor_; raw_ptr<NativeWidgetNSWindowBridge> parent_ = nullptr; // Weak. If non-null, owns this.
diff --git a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm index 9e2d10f..5c0a531 100644 --- a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm +++ b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
@@ -57,6 +57,7 @@ #include "ui/display/display.h" #include "ui/display/screen.h" #include "ui/events/cocoa/cocoa_event_utils.h" +#include "ui/events/types/event_type.h" #include "ui/gfx/geometry/dip_util.h" #include "ui/gfx/geometry/size_conversions.h" #import "ui/gfx/mac/coordinate_conversion.h" @@ -376,7 +377,7 @@ NativeWidgetNSWindowBridge::~NativeWidgetNSWindowBridge() { SetLocalEventMonitorEnabled(false); - DCHECK(!key_down_event_monitor_); + DCHECK(!local_event_monitor_); GetPendingWindowTitleMap().erase(window_); // The delegate should be cleared already. Note this enforces the precondition // that -[NSWindow close] is invoked on the hosted window before the @@ -958,7 +959,7 @@ void NativeWidgetNSWindowBridge::SetLocalEventMonitorEnabled(bool enabled) { if (enabled) { // Create the event monitor if it does not exist yet. - if (key_down_event_monitor_) { + if (local_event_monitor_) { return; } @@ -972,20 +973,24 @@ std::unique_ptr<ui::Event> ui_event = ui::EventFromNative(base::apple::OwnedNSEvent(event)); bool event_handled = false; - weak_ptr->host_->DispatchMonitorEvent(std::move(ui_event), - &event_handled); + if (ui_event && ui_event->type() != ui::EventType::kUnknown) { + weak_ptr->host_->DispatchMonitorEvent(std::move(ui_event), + &event_handled); + } + return event_handled ? nil : event; }; - key_down_event_monitor_ = - [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskKeyDown + local_event_monitor_ = + [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskAny handler:block]; } else { // Destroy the event monitor if it exists. - if (!key_down_event_monitor_) + if (!local_event_monitor_) { return; + } - [NSEvent removeMonitor:key_down_event_monitor_]; - key_down_event_monitor_ = nil; + [NSEvent removeMonitor:local_event_monitor_]; + local_event_monitor_ = nil; } }
diff --git a/components/search_engines/search_engine_type.h b/components/search_engines/search_engine_type.h index 7f35681..9dff369c 100644 --- a/components/search_engines/search_engine_type.h +++ b/components/search_engines/search_engine_type.h
@@ -13,6 +13,7 @@ // // A Java counterpart will be generated for this enum. // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.search_engines +// LINT.IfChange(SearchEngineType) enum SearchEngineType { // Prepopulated engines. SEARCH_ENGINE_UNKNOWN = -1, @@ -97,6 +98,7 @@ SEARCH_ENGINE_MAX // Bounding value needed for UMA histogram macro. }; +// LINT.ThenChange(//tools/metrics/histograms/enums.xml:OmniboxSearchEngineType) // Enum to record the type of search engine a user used in keyword mode. This // should be kept aligned with the `OmniboxBuiltinEngineType` enum in enums.xml.
diff --git a/components/services/print_compositor/print_compositor_impl.cc b/components/services/print_compositor/print_compositor_impl.cc index 4ec2e6c..0671759f 100644 --- a/components/services/print_compositor/print_compositor_impl.cc +++ b/components/services/print_compositor/print_compositor_impl.cc
@@ -86,7 +86,7 @@ base::ReadOnlySharedMemoryMapping mapping = watermark_block->serialized_skpicture.Map(); if (!mapping.IsValid()) { - DLOG(ERROR) + LOG(ERROR) << "Error serializing the watermark block received from the browser"; return; } @@ -380,7 +380,7 @@ CompositePagesCallback callback) { base::ReadOnlySharedMemoryMapping mapping = serialized_content.Map(); if (!mapping.IsValid()) { - DLOG(ERROR) << "HandleCompositionRequest: Cannot map input."; + LOG(ERROR) << "HandleCompositionRequest: Cannot map input."; std::move(callback).Run(mojom::PrintCompositor::Status::kHandleMapError, base::ReadOnlySharedMemoryRegion()); return; @@ -435,7 +435,7 @@ SkMemoryStream stream(serialized_content.data(), serialized_content.size()); int page_count = SkMultiPictureDocument::ReadPageCount(&stream); if (!page_count) { - DLOG(ERROR) << "CompositePages: No page is read."; + LOG(ERROR) << "CompositePages: No page is read."; return mojom::PrintCompositor::Status::kContentFormatError; } @@ -444,7 +444,7 @@ DeserializationProcs(&subframes, &typefaces_, &images_); if (!SkMultiPictureDocument::Read(&stream, pages.data(), page_count, &procs)) { - DLOG(ERROR) << "CompositePages: Page reading failed."; + LOG(ERROR) << "CompositePages: Page reading failed."; return mojom::PrintCompositor::Status::kContentFormatError; } @@ -481,7 +481,7 @@ base::MappedReadOnlyRegion region_mapping = base::ReadOnlySharedMemoryRegion::Create(wstream.bytesWritten()); if (!region_mapping.IsValid()) { - DLOG(ERROR) << "CompositePages: Cannot create new shared memory region."; + LOG(ERROR) << "CompositePages: Cannot create new shared memory region."; return mojom::PrintCompositor::Status::kHandleMapError; } @@ -561,8 +561,8 @@ region = std::move(region_mapping.region); status = mojom::PrintCompositor::Status::kSuccess; } else { - DLOG(ERROR) << "FinishDocumentRequest: " - << "Cannot create new shared memory region."; + LOG(ERROR) << "FinishDocumentRequest: " + << "Cannot create new shared memory region."; status = mojom::PrintCompositor::Status::kHandleMapError; }
diff --git a/components/signin/core/browser/resources/BUILD.gn b/components/signin/core/browser/resources/BUILD.gn index e0e0abce..c795618d 100644 --- a/components/signin/core/browser/resources/BUILD.gn +++ b/components/signin/core/browser/resources/BUILD.gn
@@ -14,6 +14,7 @@ non_web_component_files = [ "signin_internals.ts" ] + ts_tsconfig_base = "//tools/typescript/tsconfig_base_lit_389737066.json" ts_deps = [ "//third_party/lit/v3_0:build_ts", "//ui/webui/resources/js:build_ts",
diff --git a/components/sync/service/resources/BUILD.gn b/components/sync/service/resources/BUILD.gn index fc416ceb..8df89f45 100644 --- a/components/sync/service/resources/BUILD.gn +++ b/components/sync/service/resources/BUILD.gn
@@ -31,6 +31,7 @@ "user_events.ts", ] + ts_tsconfig_base = "//tools/typescript/tsconfig_base_lit_389737066.json" ts_composite = true ts_deps = [ "//third_party/lit/v3_0:build_ts",
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc index 9de588f..26d7243 100644 --- a/components/viz/service/display/renderer_pixeltest.cc +++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -6598,6 +6598,12 @@ // Confirm that drawing a second trail completely removes the first trail. TEST_P(DelegatedInkWithPredictionTest, DrawTwoTrailsAndErase) { + if (is_skia_graphite()) { + // TODO(399640773): new Skia roll produces slightly different AA pixels. + // Skip this test until Skia is rolled into chrome. Then the expected pixels + // will be updated afterwards. + GTEST_SKIP(); + } // Numbers chosen arbitrarily. No points will be predicted, so a trail made of // 2 points will be drawn. const gfx::PointF kFirstPoint(140, 48);
diff --git a/components/webui/chrome_urls/resources/BUILD.gn b/components/webui/chrome_urls/resources/BUILD.gn index c6efbfd..fdf514b 100644 --- a/components/webui/chrome_urls/resources/BUILD.gn +++ b/components/webui/chrome_urls/resources/BUILD.gn
@@ -14,6 +14,7 @@ ] css_files = [ "app.css" ] + ts_tsconfig_base = "//tools/typescript/tsconfig_base_lit_389737066.json" ts_composite = true ts_deps = [ "//third_party/lit/v3_0:build_ts",
diff --git a/components/webui/chrome_urls/resources/app.ts b/components/webui/chrome_urls/resources/app.ts index c8a3316..50c1ec2 100644 --- a/components/webui/chrome_urls/resources/app.ts +++ b/components/webui/chrome_urls/resources/app.ts
@@ -46,11 +46,11 @@ }; } - protected debugPagesButtonDisabled_: boolean = false; - protected webuiUrlInfos_: WebuiUrlInfo[] = []; - protected internalUrlInfos_: WebuiUrlInfo[] = []; - protected commandUrls_: Url[] = []; - protected internalUisEnabled_: boolean = false; + protected accessor debugPagesButtonDisabled_: boolean = false; + protected accessor webuiUrlInfos_: WebuiUrlInfo[] = []; + protected accessor internalUrlInfos_: WebuiUrlInfo[] = []; + protected accessor commandUrls_: Url[] = []; + protected accessor internalUisEnabled_: boolean = false; protected tracker_: EventTracker = new EventTracker();
diff --git a/components/webui/flags/resources/BUILD.gn b/components/webui/flags/resources/BUILD.gn index b3b1e33..bbdc7d1 100644 --- a/components/webui/flags/resources/BUILD.gn +++ b/components/webui/flags/resources/BUILD.gn
@@ -22,6 +22,7 @@ "experiment.css", ] + ts_tsconfig_base = "//tools/typescript/tsconfig_base_lit_389737066.json" ts_composite = true ts_definitions = [ "//tools/typescript/definitions/chrome_send.d.ts" ] ts_deps = [
diff --git a/components/webui/flags/resources/app.ts b/components/webui/flags/resources/app.ts index 97152c96..62612a6e 100644 --- a/components/webui/flags/resources/app.ts +++ b/components/webui/flags/resources/app.ts
@@ -127,15 +127,15 @@ }; } - protected tabNames_: string[] = [ + protected accessor tabNames_: string[] = [ loadTimeData.getString('available'), // <if expr="not is_ios"> loadTimeData.getString('unavailable'), // </if> ]; - protected selectedTabIndex_: number = 0; + protected accessor selectedTabIndex_: number = 0; - protected data: ExperimentalFeaturesData = { + protected accessor data: ExperimentalFeaturesData = { supportedFeatures: [], // <if expr="not is_ios"> unsupportedFeatures: [], @@ -148,10 +148,10 @@ // </if> }; - protected defaultFeatures: Feature[] = []; - protected nonDefaultFeatures: Feature[] = []; - protected searching: boolean = false; - protected needsRestart: boolean = false; + protected accessor defaultFeatures: Feature[] = []; + protected accessor nonDefaultFeatures: Feature[] = []; + protected accessor searching: boolean = false; + protected accessor needsRestart: boolean = false; private announceStatusDelayMs: number = 100; private featuresResolver: PromiseResolver<void> = new PromiseResolver();
diff --git a/components/webui/flags/resources/experiment.ts b/components/webui/flags/resources/experiment.ts index c7281dae..463508f 100644 --- a/components/webui/flags/resources/experiment.ts +++ b/components/webui/flags/resources/experiment.ts
@@ -74,7 +74,7 @@ }; } - protected feature_: Feature = { + protected accessor feature_: Feature = { internal_name: '', name: '', description: '', @@ -84,21 +84,21 @@ }; // Whether the controls to change the experiment state should be hidden. - unsupported: boolean = false; + accessor unsupported: boolean = false; // Whether the currently selected value is the default value. - protected isDefault_: boolean = false; + protected accessor isDefault_: boolean = false; // Whether the description text is expanded. Only has an effect on narrow // widths (max-width: 480px). - protected expanded_: boolean = false; + protected accessor expanded_: boolean = false; // Whether search hits are currently displayed. When true, some DOM nodes are // replaced with cloned nodes whose textContent is not rendered by Lit, so // that the highlight algorithm can freely modify them. Lit does not play // nicely with manual DOM modifications and throws internal errors in // subsequent renders. - protected showingSearchHit_: boolean = false; + protected accessor showingSearchHit_: boolean = false; getRequiredElement<K extends keyof HTMLElementTagNameMap>(query: K): HTMLElementTagNameMap[K];
diff --git a/components/webui/version/resources/about_version.html b/components/webui/version/resources/about_version.html index 1243b0c..40c7cc5 100644 --- a/components/webui/version/resources/about_version.html +++ b/components/webui/version/resources/about_version.html
@@ -54,7 +54,7 @@ <tr><td class="label">$i18n{application_label}</td> <td class="version" id="version"> <span id="copy-content"> - <span>$i18n{version}</span> + <span>$i18n{version}$i18n{version_suffix}</span> (<span>$i18n{official}</span>) <span>$i18n{version_modifier}</span> <span>$i18n{version_processor_variation}</span>
diff --git a/components/webui/version/version_ui_constants.cc b/components/webui/version/version_ui_constants.cc index 1468177..7c9bd75 100644 --- a/components/webui/version/version_ui_constants.cc +++ b/components/webui/version/version_ui_constants.cc
@@ -88,6 +88,7 @@ const char kVariationsSeed[] = "variations_seed"; const char kVariationsSeedName[] = "variations_seed_name"; const char kVersion[] = "version"; +const char kVersionSuffix[] = "version_suffix"; const char kVersionModifier[] = "version_modifier"; const char kVersionProcessorVariation[] = "version_processor_variation";
diff --git a/components/webui/version/version_ui_constants.h b/components/webui/version/version_ui_constants.h index 86d7317..a3a92aa 100644 --- a/components/webui/version/version_ui_constants.h +++ b/components/webui/version/version_ui_constants.h
@@ -90,6 +90,7 @@ extern const char kVariationsSeed[]; extern const char kVariationsSeedName[]; extern const char kVersion[]; +extern const char kVersionSuffix[]; extern const char kVersionModifier[]; extern const char kVersionProcessorVariation[];
diff --git a/content/browser/ai/echo_ai_language_model.cc b/content/browser/ai/echo_ai_language_model.cc index a3e63283..fabeb95 100644 --- a/content/browser/ai/echo_ai_language_model.cc +++ b/content/browser/ai/echo_ai_language_model.cc
@@ -49,7 +49,7 @@ if (current_tokens_ > EchoAIManagerImpl::kMaxContextSizeInTokens - input.size()) { current_tokens_ = input.size(); - responder->OnContextOverflow(); + responder->OnQuotaOverflow(); } current_tokens_ += input.size(); responder->OnStreaming(kResponsePrefix, @@ -120,11 +120,11 @@ responder_set_.Clear(); } -void EchoAILanguageModel::CountPromptTokens( +void EchoAILanguageModel::MeasureInputUsage( const std::string& input, - mojo::PendingRemote<blink::mojom::AILanguageModelCountPromptTokensClient> + mojo::PendingRemote<blink::mojom::AILanguageModelMeasureInputUsageClient> client) { - mojo::Remote<blink::mojom::AILanguageModelCountPromptTokensClient>( + mojo::Remote<blink::mojom::AILanguageModelMeasureInputUsageClient>( std::move(client)) ->OnResult(input.size()); }
diff --git a/content/browser/ai/echo_ai_language_model.h b/content/browser/ai/echo_ai_language_model.h index 5bac3cd5..f81a112 100644 --- a/content/browser/ai/echo_ai_language_model.h +++ b/content/browser/ai/echo_ai_language_model.h
@@ -31,9 +31,9 @@ mojo::PendingRemote<blink::mojom::AIManagerCreateLanguageModelClient> client) override; void Destroy() override; - void CountPromptTokens( + void MeasureInputUsage( const std::string& input, - mojo::PendingRemote<blink::mojom::AILanguageModelCountPromptTokensClient> + mojo::PendingRemote<blink::mojom::AILanguageModelMeasureInputUsageClient> client) override; private:
diff --git a/content/browser/preloading/prefetch/prefetch_service.cc b/content/browser/preloading/prefetch/prefetch_service.cc index feb8e4c6..f9c06aa 100644 --- a/content/browser/preloading/prefetch/prefetch_service.cc +++ b/content/browser/preloading/prefetch/prefetch_service.cc
@@ -216,17 +216,31 @@ }(); // Normally PreloadingAttemptImpl::ShouldHoldback() eventually computes its - // `holdback_status_`, but we forcely set the status in two special cases + // `holdback_status_`, but we forcely set the status in some special cases // below, by calling PreloadingAttemptImpl::SetHoldbackStatus(). // As its comment describes, this is expected to be called only once. + // + // Note that, alternatively, determining holdback status can be done in + // triggers, e.g. in `PreloadingAttemptImpl::ctor()`. For more details, see + // https://crbug.com/406123867 if (devtools_client_exist) { // 1. When developers debug Speculation Rules Prefetch using DevTools, // always set status to kAllowed for developer experience. prefetch_container->preloading_attempt()->SetHoldbackStatus( PreloadingHoldbackStatus::kAllowed); + } else if (prefetch_container->IsLikelyAheadOfPrerender()) { + // 2. If PrefetchContainer is likely ahead of prerender, always set status + // to kAllowed as it is likely used for prerender. + // + // Note that we don't use `PrefetchContainer::overridden_holdback_status_` + // for this purpose because it can't handle a prefetch that was not ahead of + // prerender but another ahead of prerender one is migrated into it. We need + // to update migration if we'd like to do it. + prefetch_container->preloading_attempt()->SetHoldbackStatus( + PreloadingHoldbackStatus::kAllowed); } else if (prefetch_container->HasOverriddenHoldbackStatus()) { - // 2. If PrefetchContainer has custom overridden status, set that value. + // 3. If PrefetchContainer has custom overridden status, set that value. prefetch_container->preloading_attempt()->SetHoldbackStatus( prefetch_container->GetOverriddenHoldbackStatus()); }
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc index 715b755..b37c9a5b 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc
@@ -6888,6 +6888,14 @@ domain_lookup_delay; navigation_handle_timing_.final_request_connect_delay = connect_delay; navigation_handle_timing_.final_request_ssl_delay = ssl_delay; + + if (response_head_->load_timing_internal_info) { + navigation_handle_timing_.initialize_stream_delay = + response_head_->load_timing_internal_info->initialize_stream_delay; + // Reset `load_timing_internal_info` to make sure that isn't exposed. + response_head_->load_timing_internal_info.reset(); + } + final_receive_headers_end_time_ = response_head_->load_timing.receive_headers_end;
diff --git a/content/browser/renderer_host/subframe_history_navigation_throttle.cc b/content/browser/renderer_host/subframe_history_navigation_throttle.cc index 85377dac..2153c983 100644 --- a/content/browser/renderer_host/subframe_history_navigation_throttle.cc +++ b/content/browser/renderer_host/subframe_history_navigation_throttle.cc
@@ -44,10 +44,13 @@ } void SubframeHistoryNavigationThrottle::Resume() { - if (state_ == State::kDeferred) { - NavigationThrottle::Resume(); - } + const bool should_resume = state_ == State::kDeferred; state_ = State::kRunningAfterResumeSignal; + if (should_resume) { + NavigationThrottle::Resume(); + // `Resume()` can synchronously delete this navigation throttle, so no code + // after this call should reference the throttle instance. + } } void SubframeHistoryNavigationThrottle::Cancel() {
diff --git a/content/browser/resources/service_worker/BUILD.gn b/content/browser/resources/service_worker/BUILD.gn index 19e2237..d9282cf4 100644 --- a/content/browser/resources/service_worker/BUILD.gn +++ b/content/browser/resources/service_worker/BUILD.gn
@@ -14,8 +14,8 @@ non_web_component_files = [ "serviceworker_internals.ts" ] + ts_tsconfig_base = "//tools/typescript/tsconfig_base_lit_389737066.json" ts_definitions = [ "//tools/typescript/definitions/chrome_send.d.ts" ] - ts_deps = [ "//third_party/lit/v3_0:build_ts", "//ui/webui/resources/js:build_ts",
diff --git a/content/browser/resources/traces_internals/BUILD.gn b/content/browser/resources/traces_internals/BUILD.gn index 5c1b16ae..4a7256a1 100644 --- a/content/browser/resources/traces_internals/BUILD.gn +++ b/content/browser/resources/traces_internals/BUILD.gn
@@ -34,6 +34,7 @@ icons_html_files = [ "icons.html" ] html_to_wrapper_template = "detect" + ts_tsconfig_base = "//tools/typescript/tsconfig_base_lit_389737066.json" ts_deps = [ "//third_party/lit/v3_0:build_ts", "//ui/webui/resources/cr_elements:build_ts",
diff --git a/content/browser/resources/traces_internals/app.ts b/content/browser/resources/traces_internals/app.ts index 9beef6e..76002de 100644 --- a/content/browser/resources/traces_internals/app.ts +++ b/content/browser/resources/traces_internals/app.ts
@@ -49,8 +49,8 @@ path: 'scenarios', }, ]; - protected selected_: number = 0; - protected tabNames_: string[] = this.tabs.map(tab => tab.name); + protected accessor selected_: number = 0; + protected accessor tabNames_: string[] = this.tabs.map(tab => tab.name); override firstUpdated() { const router = CrRouter.getInstance();
diff --git a/content/browser/resources/traces_internals/trace_report.ts b/content/browser/resources/traces_internals/trace_report.ts index 7fd22715..6eda2ec 100644 --- a/content/browser/resources/traces_internals/trace_report.ts +++ b/content/browser/resources/traces_internals/trace_report.ts
@@ -53,7 +53,7 @@ private traceReportProxy_: TraceReportBrowserProxy = TraceReportBrowserProxy.getInstance(); - protected trace: ClientTraceReport = { + protected accessor trace: ClientTraceReport = { // Dummy ClientTraceReport uuid: { high: 0n,
diff --git a/content/browser/resources/traces_internals/trace_report_list.ts b/content/browser/resources/traces_internals/trace_report_list.ts index 5c63420..febf8d3 100644 --- a/content/browser/resources/traces_internals/trace_report_list.ts +++ b/content/browser/resources/traces_internals/trace_report_list.ts
@@ -67,8 +67,8 @@ private traceReportProxy_: TraceReportBrowserProxy = TraceReportBrowserProxy.getInstance(); - protected traces_: ClientTraceReport[] = []; - protected isLoading_: boolean = false; + protected accessor traces_: ClientTraceReport[] = []; + protected accessor isLoading_: boolean = false; protected notification_?: Readonly<Notification>; override connectedCallback(): void {
diff --git a/content/browser/resources/traces_internals/tracing_scenarios_config.ts b/content/browser/resources/traces_internals/tracing_scenarios_config.ts index 18240a9..84d2b8c 100644 --- a/content/browser/resources/traces_internals/tracing_scenarios_config.ts +++ b/content/browser/resources/traces_internals/tracing_scenarios_config.ts
@@ -61,15 +61,15 @@ private traceReportProxy_: TraceReportBrowserProxy = TraceReportBrowserProxy.getInstance(); - protected presetConfig_: Config[] = []; - protected fieldConfig_: Config[] = []; - protected isEdited_: boolean = false; - protected isLoading_: boolean = false; - protected privacyFilterEnabled_: boolean = false; - protected toastMessage_: string = ''; + protected accessor presetConfig_: Config[] = []; + protected accessor fieldConfig_: Config[] = []; + protected accessor isEdited_: boolean = false; + protected accessor isLoading_: boolean = false; + protected accessor privacyFilterEnabled_: boolean = false; + protected accessor toastMessage_: string = ''; // <if expr="is_win"> - protected tracingServiceSupported_: boolean = false; - protected tracingServiceRegistered_: boolean = false; + protected accessor tracingServiceSupported_: boolean = false; + protected accessor tracingServiceRegistered_: boolean = false; protected securityShieldIconUrl_: string = ''; // </if>
diff --git a/content/public/browser/navigation_handle_timing.h b/content/public/browser/navigation_handle_timing.h index 304817d..46d35c9b 100644 --- a/content/public/browser/navigation_handle_timing.h +++ b/content/public/browser/navigation_handle_timing.h
@@ -141,6 +141,9 @@ base::TimeDelta final_request_domain_lookup_delay; base::TimeDelta final_request_connect_delay; base::TimeDelta final_request_ssl_delay; + + // InitializeStream related delay information. + base::TimeDelta initialize_stream_delay; }; } // namespace content
diff --git a/content/public/test/network_service_test_helper.cc b/content/public/test/network_service_test_helper.cc index 589bd4e..bcdffbd 100644 --- a/content/public/test/network_service_test_helper.cc +++ b/content/public/test/network_service_test_helper.cc
@@ -802,6 +802,14 @@ } #endif // BUILDFLAG(IS_WIN) + void IsHappyEyeballsV3Enabled( + IsHappyEyeballsV3EnabledCallback callback) override { + const bool enabled = network::NetworkService::GetNetworkServiceForTesting() + ->host_resolver_manager() + ->IsHappyEyeballsV3Enabled(); + std::move(callback).Run(enabled); + } + private: void OnMemoryPressure( base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
diff --git a/content/renderer/media/renderer_webaudiodevice_impl.cc b/content/renderer/media/renderer_webaudiodevice_impl.cc index 725bfa9..aa02f35 100644 --- a/content/renderer/media/renderer_webaudiodevice_impl.cc +++ b/content/renderer/media/renderer_webaudiodevice_impl.cc
@@ -6,6 +6,7 @@ #include <stddef.h> +#include <algorithm> #include <memory> #include <string> @@ -52,6 +53,9 @@ namespace { +using ::media::limits::kMaxWebAudioBufferSize; +using ::media::limits::kMinWebAudioBufferSize; + blink::WebAudioDeviceSourceType GetLatencyHintSourceType( WebAudioLatencyHint::AudioContextLatencyCategory latency_category) { switch (latency_category) { @@ -69,35 +73,6 @@ NOTREACHED(); } -int GetOutputBufferSize(const blink::WebAudioLatencyHint& latency_hint, - const media::AudioParameters& hardware_params) { - const media::AudioParameters::HardwareCapabilities hardware_capabilities = - hardware_params.hardware_capabilities().value_or( - media::AudioParameters::HardwareCapabilities()); - - // Adjust output buffer size according to the latency requirement. - switch (latency_hint.Category()) { - case WebAudioLatencyHint::kCategoryInteractive: - return media::AudioLatency::GetInteractiveBufferSize( - hardware_params.frames_per_buffer()); - case WebAudioLatencyHint::kCategoryBalanced: - return media::AudioLatency::GetRtcBufferSize( - hardware_params.sample_rate(), hardware_params.frames_per_buffer()); - case WebAudioLatencyHint::kCategoryPlayback: - return media::AudioLatency::GetHighLatencyBufferSize( - hardware_params.sample_rate(), hardware_params.frames_per_buffer()); - case WebAudioLatencyHint::kCategoryExact: - return media::AudioLatency::GetExactBufferSize( - base::Seconds(latency_hint.Seconds()), hardware_params.sample_rate(), - hardware_params.frames_per_buffer(), - hardware_capabilities.min_frames_per_buffer, - hardware_capabilities.max_frames_per_buffer, - media::limits::kMaxWebAudioBufferSize); - case WebAudioLatencyHint::kLastValue: - NOTREACHED(); - } - NOTREACHED(); -} media::AudioParameters GetOutputDeviceParameters( const blink::LocalFrameToken& frame_token, @@ -119,6 +94,7 @@ const WebAudioSinkDescriptor& sink_descriptor, int number_of_output_channels, const blink::WebAudioLatencyHint& latency_hint, + std::optional<float> context_sample_rate, media::AudioRendererSink::RenderCallback* callback) { // The `number_of_output_channels` does not manifest the actual channel // layout of the audio output device. We use the best guess to the channel @@ -134,14 +110,85 @@ return std::unique_ptr<RendererWebAudioDeviceImpl>( new RendererWebAudioDeviceImpl( sink_descriptor, {layout, number_of_output_channels}, latency_hint, - callback, base::BindOnce(&GetOutputDeviceParameters), + context_sample_rate, callback, + base::BindOnce(&GetOutputDeviceParameters), base::BindRepeating(&GetNullAudioSink))); } +int RendererWebAudioDeviceImpl::GetOutputBufferSize( + const blink::WebAudioLatencyHint& latency_hint, + int resolved_context_sample_rate, + const media::AudioParameters& hardware_params) { + const media::AudioParameters::HardwareCapabilities hardware_capabilities = + hardware_params.hardware_capabilities().value_or( + media::AudioParameters::HardwareCapabilities()); + + const float scale_factor = static_cast<float>(resolved_context_sample_rate) / + hardware_params.sample_rate(); + + int min_hardware_buffer_size = hardware_capabilities.min_frames_per_buffer; + int max_hardware_buffer_size = hardware_capabilities.max_frames_per_buffer; + + // The hardware may not provide explicit buffer size limits. In such cases, + // we fall back to predefined minimum and maximum buffer sizes. Additionally, + // hardware-provided limits are defined at the hardware's default sample rate. + // We must scale these limits to the context's sample rate, as subsequent + // buffer size calculations rely on the context sample rate. + int min_buffer_size = kMinWebAudioBufferSize; + if (min_hardware_buffer_size != 0) { + min_buffer_size = std::max( + kMinWebAudioBufferSize, + static_cast<int>(std::ceil(min_hardware_buffer_size * scale_factor))); + } + + int max_buffer_size = kMaxWebAudioBufferSize; + if (max_hardware_buffer_size != 0) { + max_buffer_size = std::min( + kMaxWebAudioBufferSize, + static_cast<int>(std::ceil(max_hardware_buffer_size * scale_factor))); + } + // Ensure that the `min_buffer_size` does not exceed `max_buffer_size`. + // This can occur when a small scale_factor leads to inverted limits after + // scaling and clamping. + max_buffer_size = std::max(min_buffer_size, max_buffer_size); + + // Scale default buffer size to context rate. buffer size calculations for + // each latency hint now use the context rate (instead of hardware rate). + // Scaling ensures the calculated buffer size corresponds to the desired + // callback interval at the context rate. + int scaled_default_buffer_size = static_cast<int>( + std::ceil(hardware_params.frames_per_buffer() * scale_factor)); + + // Clamp the scaled default buffer size to the valid range. + scaled_default_buffer_size = + std::clamp(scaled_default_buffer_size, min_buffer_size, max_buffer_size); + + switch (latency_hint.Category()) { + case WebAudioLatencyHint::kCategoryInteractive: + return media::AudioLatency::GetInteractiveBufferSize( + scaled_default_buffer_size); + case WebAudioLatencyHint::kCategoryBalanced: + return media::AudioLatency::GetRtcBufferSize(resolved_context_sample_rate, + scaled_default_buffer_size); + case WebAudioLatencyHint::kCategoryPlayback: + return media::AudioLatency::GetHighLatencyBufferSize( + resolved_context_sample_rate, scaled_default_buffer_size); + case WebAudioLatencyHint::kCategoryExact: + return media::AudioLatency::GetExactBufferSize( + base::Seconds(latency_hint.Seconds()), resolved_context_sample_rate, + scaled_default_buffer_size, min_buffer_size, max_buffer_size, + kMaxWebAudioBufferSize); + case WebAudioLatencyHint::kLastValue: + NOTREACHED(); + } + NOTREACHED(); +} + RendererWebAudioDeviceImpl::RendererWebAudioDeviceImpl( const WebAudioSinkDescriptor& sink_descriptor, media::ChannelLayoutConfig layout_config, const blink::WebAudioLatencyHint& latency_hint, + std::optional<float> context_sample_rate, media::AudioRendererSink::RenderCallback* callback, OutputDeviceParamsCallback device_params_cb, CreateSilentSinkCallback create_silent_sink_cb) @@ -196,13 +243,26 @@ "%s => (hardware_params=[%s])", __func__, original_sink_params_.AsHumanReadableString().c_str())); - const int output_buffer_size = - GetOutputBufferSize(latency_hint_, original_sink_params_); + // If the 'WebAudioRemoveAudioDestinationResampler' feature is enabled and + // a context sample rate is provided, use the provided context sample rate. + // Otherwise, fall back to the use default hardware sample rate to create + // sink. + int resolved_context_sample_rate; + if (base::FeatureList::IsEnabled( + blink::features::kWebAudioRemoveAudioDestinationResampler) && + context_sample_rate.has_value()) { + resolved_context_sample_rate = *context_sample_rate; + } else { + resolved_context_sample_rate = original_sink_params_.sample_rate(); + } + + const int output_buffer_size = GetOutputBufferSize( + latency_hint_, resolved_context_sample_rate, original_sink_params_); + DCHECK_NE(0, output_buffer_size); current_sink_params_.Reset(original_sink_params_.format(), layout_config, - original_sink_params_.sample_rate(), - output_buffer_size); + resolved_context_sample_rate, output_buffer_size); // Specify the latency info to be passed to the browser side. current_sink_params_.set_latency_tag(AudioDeviceFactory::GetSourceLatencyType(
diff --git a/content/renderer/media/renderer_webaudiodevice_impl.h b/content/renderer/media/renderer_webaudiodevice_impl.h index 9ba471c..29cc117 100644 --- a/content/renderer/media/renderer_webaudiodevice_impl.h +++ b/content/renderer/media/renderer_webaudiodevice_impl.h
@@ -49,7 +49,11 @@ const blink::WebAudioSinkDescriptor& sink_descriptor, int number_of_output_channels, const blink::WebAudioLatencyHint& latency_hint, + std::optional<float> context_sample_rate, media::AudioRendererSink::RenderCallback* webaudio_callback); + static int GetOutputBufferSize(const blink::WebAudioLatencyHint& latency_hint, + int resolved_context_sample_rate, + const media::AudioParameters& hardware_params); // blink::WebAudioDevice implementation. void Start() override; @@ -104,6 +108,7 @@ const blink::WebAudioSinkDescriptor& sink_descriptor, media::ChannelLayoutConfig layout_config, const blink::WebAudioLatencyHint& latency_hint, + std::optional<float> context_sample_rate, media::AudioRendererSink::RenderCallback* webaudio_callback, OutputDeviceParamsCallback device_params_cb, CreateSilentSinkCallback create_silent_sink_cb);
diff --git a/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc b/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc index df9b2c58..b91550d0 100644 --- a/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc +++ b/content/renderer/media/renderer_webaudiodevice_impl_unittest.cc
@@ -10,6 +10,7 @@ #include "base/memory/raw_ptr.h" #include "base/strings/stringprintf.h" #include "base/task/sequenced_task_runner.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "build/build_config.h" #include "media/base/audio_capturer_source.h" @@ -19,17 +20,20 @@ #include "media/base/output_device_info.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/tokens/tokens.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/public/web/modules/media/audio/audio_device_factory.h" -using ::testing::_; -using ::testing::InSequence; - namespace content { namespace { +using ::media::limits::kMaxWebAudioBufferSize; +using ::media::limits::kMinWebAudioBufferSize; +using ::testing::_; +using ::testing::InSequence; + class MockAudioRendererSink : public media::AudioRendererSink { public: explicit MockAudioRendererSink() = default; @@ -80,12 +84,14 @@ const blink::WebAudioSinkDescriptor& sink_descriptor, media::ChannelLayoutConfig layout_config, const blink::WebAudioLatencyHint& latency_hint, + std::optional<float> context_sample_rate, media::AudioRendererSink::RenderCallback* callback, CreateSilentSinkCallback silent_sink_callback) : RendererWebAudioDeviceImpl( sink_descriptor, layout_config, latency_hint, + context_sample_rate, callback, base::BindOnce(&MockGetOutputDeviceParameters), std::move(silent_sink_callback)) {} @@ -122,7 +128,8 @@ blink::WebAudioSinkDescriptor sink_descriptor( blink::WebString::FromUTF8(std::string()), kFrameToken); webaudio_device_ = std::make_unique<RendererWebAudioDeviceImplUnderTest>( - sink_descriptor, media::ChannelLayoutConfig::Mono(), latencyHint, this, + sink_descriptor, media::ChannelLayoutConfig::Mono(), latencyHint, + context_sample_rate_, this, base::BindRepeating( &RendererWebAudioDeviceImplTest::CreateMockSilentSink, // Guaranteed to be valid because |this| owns |webaudio_device_| and @@ -139,7 +146,7 @@ sink_descriptor, layout_config, blink::WebAudioLatencyHint( blink::WebAudioLatencyHint::kCategoryInteractive), - this, + context_sample_rate_, this, base::BindRepeating( &RendererWebAudioDeviceImplTest::CreateMockSilentSink, // Guaranteed to be valid because |this| owns |webaudio_device_| and @@ -154,7 +161,7 @@ sink_descriptor, media::ChannelLayoutConfig::Mono(), blink::WebAudioLatencyHint( blink::WebAudioLatencyHint::kCategoryInteractive), - this, + context_sample_rate_, this, base::BindRepeating( &RendererWebAudioDeviceImplTest::CreateMockSilentSink, // Guaranteed to be valid because |this| owns |webaudio_device_| and @@ -176,15 +183,176 @@ std::unique_ptr<RendererWebAudioDeviceImpl> webaudio_device_; base::test::SingleThreadTaskEnvironment task_environment_; scoped_refptr<MockAudioRendererSink> mock_audio_renderer_sink_; + std::optional<float> context_sample_rate_; }; +class RendererWebAudioDeviceImplBufferSizeTest : public ::testing::Test { + protected: + static constexpr int kHardwareSampleRate48k = 48000; + static constexpr int kHardwareBufferSize48k = 480; + static constexpr int kHardwareSampleRate44k = 44100; + static constexpr int kHardwareBufferSize44k = 441; + base::test::ScopedFeatureList feature_list_; +}; + +// When the kWebAudioRemoveAudioDestinationResampler +// feature is disabled, the GetOutputBufferSize method returns the default +// hardware buffer size, regardless of the context sample rate. +TEST_F(RendererWebAudioDeviceImplBufferSizeTest, + InteractiveLatency_FeatureDisabled_UsesDefaultBufferSize) { + feature_list_.InitAndDisableFeature( + blink::features::kWebAudioRemoveAudioDestinationResampler); + blink::WebAudioLatencyHint latency_hint( + blink::WebAudioLatencyHint::kCategoryInteractive); + media::AudioParameters hardware_params( + media::AudioParameters::AUDIO_PCM_LOW_LATENCY, + media::ChannelLayoutConfig::Stereo(), kHardwareSampleRate48k, + kHardwareBufferSize48k); + + // When feature is disabled, we ensure the context_sample_rate is using + // default hardware sample rate before calling + // `RendererWebAudioDeviceImpl::GetOutputBufferSize`. + int context_sample_rate = kHardwareSampleRate48k; + int output_buffer_size = RendererWebAudioDeviceImpl::GetOutputBufferSize( + latency_hint, context_sample_rate, hardware_params); + EXPECT_EQ(output_buffer_size, 480); +} + +// When the kWebAudioRemoveAudioDestinationResampler +// feature is enabled and the context sample rate matches the hardware sample +// rate, the GetOutputBufferSize method returns the default hardware buffer +// size. +TEST_F(RendererWebAudioDeviceImplBufferSizeTest, + InteractiveLatency_SameSampleRate_ReturnsDefaultBufferSize) { + feature_list_.InitAndEnableFeature( + blink::features::kWebAudioRemoveAudioDestinationResampler); + blink::WebAudioLatencyHint latency_hint( + blink::WebAudioLatencyHint::kCategoryInteractive); + media::AudioParameters hardware_params( + media::AudioParameters::AUDIO_PCM_LOW_LATENCY, + media::ChannelLayoutConfig::Stereo(), kHardwareSampleRate48k, + kHardwareBufferSize48k); + + int context_sample_rate = 48000; + int output_buffer_size = RendererWebAudioDeviceImpl::GetOutputBufferSize( + latency_hint, context_sample_rate, hardware_params); + EXPECT_EQ(output_buffer_size, 480); +} + +// When the kWebAudioRemoveAudioDestinationResampler +// feature is enabled and the context sample rate is significantly lower than +// the hardware sample rate, the GetOutputBufferSize method returns the minimum +// allowed buffer size (kMinWebAudioBufferSize). This ensures that the scaled +// buffer size is capped at the minimum. +TEST_F(RendererWebAudioDeviceImplBufferSizeTest, + InteractiveLatency_LowSampleRate_CapsAtMinBufferSize) { + feature_list_.InitAndEnableFeature( + blink::features::kWebAudioRemoveAudioDestinationResampler); + blink::WebAudioLatencyHint latency_hint( + blink::WebAudioLatencyHint::kCategoryInteractive); + media::AudioParameters hardware_params( + media::AudioParameters::AUDIO_PCM_LOW_LATENCY, + media::ChannelLayoutConfig::Stereo(), kHardwareSampleRate48k, + kHardwareBufferSize48k); + + int context_sample_rate = 8000; + int output_buffer_size = RendererWebAudioDeviceImpl::GetOutputBufferSize( + latency_hint, context_sample_rate, hardware_params); + EXPECT_EQ(output_buffer_size, kMinWebAudioBufferSize); +} + +// When the kWebAudioRemoveAudioDestinationResampler +// feature is enabled and the context sample rate is higher than the hardware +// sample rate, the GetOutputBufferSize method correctly scales the buffer size. +TEST_F(RendererWebAudioDeviceImplBufferSizeTest, + InteractiveLatency_HighSampleRate_ScalesBufferSize) { + feature_list_.InitAndEnableFeature( + blink::features::kWebAudioRemoveAudioDestinationResampler); + blink::WebAudioLatencyHint latency_hint( + blink::WebAudioLatencyHint::kCategoryInteractive); + media::AudioParameters hardware_params( + media::AudioParameters::AUDIO_PCM_LOW_LATENCY, + media::ChannelLayoutConfig::Stereo(), kHardwareSampleRate48k, + kHardwareBufferSize48k); + + int context_sample_rate = 768000; + int output_buffer_size = RendererWebAudioDeviceImpl::GetOutputBufferSize( + latency_hint, context_sample_rate, hardware_params); + EXPECT_EQ(output_buffer_size, 7680); +} + +// When the kWebAudioRemoveAudioDestinationResampler feature is enabled and the +// context sample rate is slightly higher than the hardware sample rate, the +// GetOutputBufferSize method correctly scales the buffer size, demonstrating +// accurate rounding behavior. +TEST_F(RendererWebAudioDeviceImplBufferSizeTest, + InteractiveLatency_CloseSampleRate_ScalesBufferSize) { + feature_list_.InitAndEnableFeature( + blink::features::kWebAudioRemoveAudioDestinationResampler); + blink::WebAudioLatencyHint latency_hint( + blink::WebAudioLatencyHint::kCategoryInteractive); + media::AudioParameters hardware_params( + media::AudioParameters::AUDIO_PCM_LOW_LATENCY, + media::ChannelLayoutConfig::Stereo(), kHardwareSampleRate48k, + kHardwareBufferSize48k); + + int context_sample_rate = 48001; + int output_buffer_size = RendererWebAudioDeviceImpl::GetOutputBufferSize( + latency_hint, context_sample_rate, hardware_params); + EXPECT_EQ(output_buffer_size, 481); +} + +// When the kWebAudioRemoveAudioDestinationResampler feature is enabled and the +// context sample rate is slightly higher than the hardware sample rate, with +// different hardware parameters, the GetOutputBufferSize method correctly +// scales the buffer size, demonstrating general rounding and scaling behavior +// with various hardware configurations. +TEST_F(RendererWebAudioDeviceImplBufferSizeTest, + InteractiveLatency_CloseSampleRate2_ScalesBufferSize) { + feature_list_.InitAndEnableFeature( + blink::features::kWebAudioRemoveAudioDestinationResampler); + blink::WebAudioLatencyHint latency_hint( + blink::WebAudioLatencyHint::kCategoryInteractive); + media::AudioParameters hardware_params( + media::AudioParameters::AUDIO_PCM_LOW_LATENCY, + media::ChannelLayoutConfig::Stereo(), kHardwareSampleRate44k, + kHardwareBufferSize44k); + + int context_sample_rate = 48000; + int output_buffer_size = RendererWebAudioDeviceImpl::GetOutputBufferSize( + latency_hint, context_sample_rate, hardware_params); + EXPECT_EQ(output_buffer_size, 481); +} + +// When the kWebAudioRemoveAudioDestinationResampler +// feature is enabled and the context sample rate is extremely high (potentially +// unsupported), the GetOutputBufferSize method caps the scaled buffer size at +// the maximum allowed buffer size (kMaxWebAudioBufferSize). +TEST_F(RendererWebAudioDeviceImplBufferSizeTest, + InteractiveLatency_VeryHighSampleRate_CapsAtMaxBufferSize) { + feature_list_.InitAndEnableFeature( + blink::features::kWebAudioRemoveAudioDestinationResampler); + blink::WebAudioLatencyHint latency_hint( + blink::WebAudioLatencyHint::kCategoryInteractive); + media::AudioParameters hardware_params( + media::AudioParameters::AUDIO_PCM_LOW_LATENCY, + media::ChannelLayoutConfig::Stereo(), kHardwareSampleRate48k, + kHardwareBufferSize48k); + + int context_sample_rate = 999000; + int output_buffer_size = RendererWebAudioDeviceImpl::GetOutputBufferSize( + latency_hint, context_sample_rate, hardware_params); + EXPECT_EQ(output_buffer_size, kMaxWebAudioBufferSize); +} + TEST_F(RendererWebAudioDeviceImplTest, ChannelLayout) { for (int ch = 1; ch < static_cast<int>(media::limits::kMaxChannels); ++ch) { SCOPED_TRACE(base::StringPrintf("ch == %d", ch)); media::ChannelLayout layout = media::GuessChannelLayout(ch); - if (layout == media::CHANNEL_LAYOUT_UNSUPPORTED) + if (layout == media::CHANNEL_LAYOUT_UNSUPPORTED) { layout = media::CHANNEL_LAYOUT_DISCRETE; + } SetupDevice({layout, ch}); media::AudioParameters sink_params = @@ -195,86 +363,6 @@ } } -TEST_F(RendererWebAudioDeviceImplTest, TestLatencyHintValues) { - blink::WebAudioLatencyHint interactiveLatencyHint( - blink::WebAudioLatencyHint::kCategoryInteractive); - int interactiveBufferSize = - media::AudioLatency::GetInteractiveBufferSize(kHardwareBufferSize); - SetupDevice(interactiveLatencyHint); - - EXPECT_EQ(webaudio_device_->SampleRate(), kHardwareSampleRate); - EXPECT_EQ(webaudio_device_->FramesPerBuffer(), interactiveBufferSize); - - webaudio_device_->Start(); - EXPECT_EQ(webaudio_device_->SampleRate(), kHardwareSampleRate); - EXPECT_EQ(webaudio_device_->FramesPerBuffer(), interactiveBufferSize); - - webaudio_device_->Stop(); - EXPECT_EQ(webaudio_device_->SampleRate(), kHardwareSampleRate); - EXPECT_EQ(webaudio_device_->FramesPerBuffer(), interactiveBufferSize); - - webaudio_device_->Start(); - EXPECT_EQ(webaudio_device_->SampleRate(), kHardwareSampleRate); - EXPECT_EQ(webaudio_device_->FramesPerBuffer(), interactiveBufferSize); - - webaudio_device_->Stop(); - EXPECT_EQ(webaudio_device_->SampleRate(), kHardwareSampleRate); - EXPECT_EQ(webaudio_device_->FramesPerBuffer(), interactiveBufferSize); - - blink::WebAudioLatencyHint balancedLatencyHint( - blink::WebAudioLatencyHint::kCategoryBalanced); - int balancedBufferSize = media::AudioLatency::GetRtcBufferSize( - kHardwareSampleRate, kHardwareBufferSize); - SetupDevice(balancedLatencyHint); - - EXPECT_EQ(webaudio_device_->SampleRate(), kHardwareSampleRate); - EXPECT_EQ(webaudio_device_->FramesPerBuffer(), balancedBufferSize); - - webaudio_device_->Start(); - EXPECT_EQ(webaudio_device_->SampleRate(), kHardwareSampleRate); - EXPECT_EQ(webaudio_device_->FramesPerBuffer(), balancedBufferSize); - - webaudio_device_->Stop(); - EXPECT_EQ(webaudio_device_->SampleRate(), kHardwareSampleRate); - EXPECT_EQ(webaudio_device_->FramesPerBuffer(), balancedBufferSize); - - webaudio_device_->Start(); - EXPECT_EQ(webaudio_device_->SampleRate(), kHardwareSampleRate); - EXPECT_EQ(webaudio_device_->FramesPerBuffer(), balancedBufferSize); - - webaudio_device_->Stop(); - EXPECT_EQ(webaudio_device_->SampleRate(), kHardwareSampleRate); - EXPECT_EQ(webaudio_device_->FramesPerBuffer(), balancedBufferSize); - - blink::WebAudioLatencyHint playbackLatencyHint( - blink::WebAudioLatencyHint::kCategoryPlayback); - int playbackBufferSize = media::AudioLatency::GetHighLatencyBufferSize( - kHardwareSampleRate, kHardwareBufferSize); - SetupDevice(playbackLatencyHint); - - EXPECT_EQ(webaudio_device_->SampleRate(), kHardwareSampleRate); - EXPECT_EQ(webaudio_device_->FramesPerBuffer(), playbackBufferSize); - - webaudio_device_->Start(); - EXPECT_EQ(webaudio_device_->SampleRate(), kHardwareSampleRate); - EXPECT_EQ(webaudio_device_->FramesPerBuffer(), playbackBufferSize); - - webaudio_device_->Stop(); - EXPECT_EQ(webaudio_device_->SampleRate(), kHardwareSampleRate); - EXPECT_EQ(webaudio_device_->FramesPerBuffer(), playbackBufferSize); - - webaudio_device_->Start(); - EXPECT_EQ(webaudio_device_->SampleRate(), kHardwareSampleRate); - EXPECT_EQ(webaudio_device_->FramesPerBuffer(), playbackBufferSize); - - webaudio_device_->Stop(); - EXPECT_EQ(webaudio_device_->SampleRate(), kHardwareSampleRate); - EXPECT_EQ(webaudio_device_->FramesPerBuffer(), playbackBufferSize); - - EXPECT_GE(playbackBufferSize, balancedBufferSize); - EXPECT_GE(balancedBufferSize, interactiveBufferSize); -} - TEST_F(RendererWebAudioDeviceImplTest, NullSink_RenderWorks) { { InSequence s; @@ -504,4 +592,73 @@ webaudio_device_->Start(); webaudio_device_->Stop(); } + +class RendererWebAudioDeviceImplLatencyAndSampleRateTest + : public RendererWebAudioDeviceImplTest, + public testing::WithParamInterface< + std::tuple<blink::WebAudioLatencyHint::AudioContextLatencyCategory, + int>> { + protected: + void SetUp() override { + if (std::get<0>(GetParam()) == blink::WebAudioLatencyHint::kCategoryExact) { + // Simulate a 10ms exact latency. + test_latency_hint_ = blink::WebAudioLatencyHint(/*seconds=*/0.01); + } else { + test_latency_hint_ = blink::WebAudioLatencyHint(std::get<0>(GetParam())); + } + + int sample_rate = std::get<1>(GetParam()); + // sample_rate == 0 means no context_sample_rate is specified. + if (sample_rate != 0) { + context_sample_rate_ = static_cast<float>(sample_rate); + } + + feature_list_.InitAndEnableFeature( + blink::features::kWebAudioRemoveAudioDestinationResampler); + } + + protected: + blink::WebAudioLatencyHint test_latency_hint_{ + blink::WebAudioLatencyHint::kCategoryInteractive}; + + private: + base::test::ScopedFeatureList feature_list_; +}; + +TEST_P(RendererWebAudioDeviceImplLatencyAndSampleRateTest, + TestLatencyHintValues) { + int context_sample_rate = context_sample_rate_.value_or(kHardwareSampleRate); + media::AudioParameters hardware_params( + media::AudioParameters::AUDIO_PCM_LOW_LATENCY, + media::ChannelLayoutConfig::Stereo(), kHardwareSampleRate, + kHardwareBufferSize); + int expected_buffer_size = RendererWebAudioDeviceImpl::GetOutputBufferSize( + test_latency_hint_, context_sample_rate, hardware_params); + + SetupDevice(test_latency_hint_); + + EXPECT_EQ(webaudio_device_->SampleRate(), context_sample_rate); + EXPECT_EQ(webaudio_device_->FramesPerBuffer(), expected_buffer_size); + + webaudio_device_->Start(); + EXPECT_EQ(webaudio_device_->SampleRate(), context_sample_rate); + EXPECT_EQ(webaudio_device_->FramesPerBuffer(), expected_buffer_size); + + webaudio_device_->Stop(); + EXPECT_EQ(webaudio_device_->SampleRate(), context_sample_rate); + EXPECT_EQ(webaudio_device_->FramesPerBuffer(), expected_buffer_size); +} + +INSTANTIATE_TEST_SUITE_P( + All, + RendererWebAudioDeviceImplLatencyAndSampleRateTest, + testing::Combine( + + testing::Values(blink::WebAudioLatencyHint::kCategoryInteractive, + blink::WebAudioLatencyHint::kCategoryBalanced, + blink::WebAudioLatencyHint::kCategoryPlayback, + blink::WebAudioLatencyHint::kCategoryExact), + // User provided sample rate; 0 means no sample rate provided. + testing::Values(0, 16000, 44100, 48000, 96000))); + } // namespace content
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index 7432b46..ac71ba10 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -512,9 +512,11 @@ const WebAudioSinkDescriptor& sink_descriptor, unsigned number_of_output_channels, const blink::WebAudioLatencyHint& latency_hint, + std::optional<float> context_sample_rate, media::AudioRendererSink::RenderCallback* callback) { return RendererWebAudioDeviceImpl::Create( - sink_descriptor, number_of_output_channels, latency_hint, callback); + sink_descriptor, number_of_output_channels, latency_hint, + context_sample_rate, callback); } bool RendererBlinkPlatformImpl::DecodeAudioFileData(
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h index b6d525fb..a3aaa495 100644 --- a/content/renderer/renderer_blink_platform_impl.h +++ b/content/renderer/renderer_blink_platform_impl.h
@@ -135,6 +135,7 @@ const blink::WebAudioSinkDescriptor& sink_descriptor, unsigned number_of_output_channels, const blink::WebAudioLatencyHint& latency_hint, + std::optional<float> context_sample_rate, media::AudioRendererSink::RenderCallback* callback) override; bool DecodeAudioFileData(blink::WebAudioBus* destination_bus, const char* audio_file_data,
diff --git a/docs/how_to_add_your_feature_flag.md b/docs/how_to_add_your_feature_flag.md index ff38daa..e75bb17d 100644 --- a/docs/how_to_add_your_feature_flag.md +++ b/docs/how_to_add_your_feature_flag.md
@@ -105,7 +105,7 @@ You have to modify these five files in total. -* [chrome/browser/about_flags.cc](https://cs.chromium.org/chromium/src/chrome/browser/about_flags.cc) (Add your changes at the bottom of the list) +* [chrome/browser/about_flags.cc](https://cs.chromium.org/chromium/src/chrome/browser/about_flags.cc) (Add your changes at the bottom of the list, search for "Add new entries above this line.") * [chrome/browser/flag_descriptions.cc](https://cs.chromium.org/chromium/src/chrome/browser/flag_descriptions.cc) (Features should be alphabetically sorted) * [chrome/browser/flag_descriptions.h](https://cs.chromium.org/chromium/src/chrome/browser/flag_descriptions.h) (Features should be alphabetically sorted) * [tools/metrics/histograms/enums.xml](https://cs.chromium.org/chromium/src/tools/metrics/histograms/enums.xml)
diff --git a/docs/webui/optimizing_web_uis.md b/docs/webui/optimizing_web_uis.md index 3a6ef90..302ff78fa 100644 --- a/docs/webui/optimizing_web_uis.md +++ b/docs/webui/optimizing_web_uis.md
@@ -5,7 +5,7 @@ In order to build with a fast configuration, try setting these options in your GN args: -``` +```python optimize_webui = true is_debug = false ```
diff --git a/docs/webui/testing_webui.md b/docs/webui/testing_webui.md index 8b567e40..c2de29ac 100644 --- a/docs/webui/testing_webui.md +++ b/docs/webui/testing_webui.md
@@ -71,11 +71,10 @@ // Necessary if you have features (or the UI itself) behind a feature flag. base::test::ScopedFeatureList scoped_feature_list_{foo_bar::kSomeNewFeature}; }; - ``` Note: If testing a `chrome-untrusted://` UI, also call: -``` +```c++ set_test_loader_scheme(content::kChromeUIUntrustedScheme); ``` in the constructor. @@ -89,7 +88,6 @@ // Run all Mocha test suites found in app_test RunTest("foo_bar/app_test.js", "mocha.run();"); } - ``` Should you write a large number of tests in a single file (e.g., for one particular custom element), it may be necessary to run different suites or @@ -205,7 +203,7 @@ To build your tests as part of the `browser_tests` target, add a BUILD.gn file in your folder: -``` +```python # chrome/test/data/webui/foo_bar/BUILD.gn import("../build_webui_tests.gni") @@ -239,7 +237,7 @@ You then need to hook up the targets generated by this file, and list your browsertest.cc source file, in `chrome/test/data/webui/BUILD.gn`: -``` +```python # chrome/test/data/webui/BUILD.gn source_set("browser_tests") { @@ -282,8 +280,8 @@ # Conditionally added (e.g. platform-specific) grdps and deps go here } - ``` + ### Unusual Test Setups Some UIs may need to rely on loading a particular URL, such that using the default `chrome://foo-bar/test_loader.html` URL that is used to dynamically
diff --git a/docs/webui/trusted_types_on_webui.md b/docs/webui/trusted_types_on_webui.md index 21dfcb6f..d57ab0d9 100644 --- a/docs/webui/trusted_types_on_webui.md +++ b/docs/webui/trusted_types_on_webui.md
@@ -25,7 +25,7 @@ should have an if statement to check the Trusted Types support before using methods/properties under `window.trustedTypes` :** -``` +```ts if (window.trustedTypes) { // Trusted Types is supported, let's use Trusted Types 😎 elem.innerHTML = trustedTypes.emptyHTML; @@ -39,7 +39,7 @@ Example code: -``` +```ts document.body.innerHTML = ''; ``` @@ -47,7 +47,7 @@ a dangerous sink is not a Trusted Type. This can be converted to: -``` +```ts document.body.innerHTML = trustedTypes.emptyHTML; ``` @@ -57,13 +57,13 @@ Example code: -``` +```ts document.body.innerHTML = 'Hello Guest!'; ``` Because this is just a text assignment, this can be converted to: -``` +```ts document.body.textContent = 'Hello Guest!'; ``` @@ -73,14 +73,14 @@ Example code: -``` +```ts document.body.innerHTML = '<div><p>' + loadTimeData.getString('foo') + '</p> </div>'; ``` This can be converted by adding _template_ element to HTML file: -``` +```html <template id="foo-template"> <div> <p></p> @@ -90,7 +90,7 @@ And then adding following JS code to JS file: -``` +```ts // body might already have some contents, so let's clear those first 😊 document.body.innerHTML = trustedTypes.emptyHTML; @@ -105,13 +105,13 @@ JS libraries), you can use DOM APIs. Example code: -``` +```ts document.body.innerHTML += '<p>' + loadTimeData.getString('foo') + '</p>'; ``` And then adding following JS code to JS file: -``` +```ts const p = document.createElement('p'); p.textContent = loadTimeData.getString('foo'); document.body.appendChild(p); @@ -124,7 +124,7 @@ (https://web.dev/trusted-types/#create-a-trusted-type-policy). Example code: -``` +```ts document.body.innerHTML = '<div class="tree-row">' + '<span class="expand-icon"></span>' + '<span class="tree-label-icon"></span>' + @@ -135,7 +135,7 @@ This can be converted to: -``` +```ts const htmlString = '<div class="tree-row">' + '<span class="expand-icon"></span>' + '<span class="tree-label-icon"></span>' + @@ -155,7 +155,7 @@ Trusted Type policy (created above in `trustedTypes.createPolicy`) in the CSP header. -``` +```c++ source->OverrideContentSecurityPolicy( network::mojom::CSPDirectiveName::TrustedTypes, "trusted-types foo-static;"); @@ -165,7 +165,7 @@ Example code: -``` +```ts const script = document.createElement('script'); script.src = 'chrome://resources/foo.js'; document.body.appendChild(script); @@ -173,7 +173,7 @@ This can be converted to: -``` +```ts const staticUrlPolicy = trustedTypes.createPolicy( 'foo-js-static', {createScriptURL: () => 'chrome://resources/foo.js'}); @@ -189,7 +189,7 @@ Trusted Type policy (created above in `trustedTypes.createPolicy`) in the CSP header. -``` +```c++ source->OverrideContentSecurityPolicy( network::mojom::CSPDirectiveName::TrustedTypes, "trusted-types foo-js-static;"); @@ -200,7 +200,7 @@ In case there is no way to support Trusted Types in a WebUI page, you can disable Trusted Types with following code: -``` +```c++ source->DisableTrustedTypesCSP(); ```
diff --git a/docs/webui/webui_build_configuration.md b/docs/webui/webui_build_configuration.md index 77b8146..31c7cf8 100644 --- a/docs/webui/webui_build_configuration.md +++ b/docs/webui/webui_build_configuration.md
@@ -72,7 +72,7 @@ ``` #### **Example** -``` +```python import("//tools/polymer/html_to_wrapper.gni") import("//tools/polymer/css_to_wrapper.gni") @@ -115,7 +115,7 @@ conditional expressions. ``` #### **Example:** -``` +```python import("//tools/grit/preprocess_if_expr.gni") # Preprocesses "my_web_component.html.ts" and my_style_module.css.ts in @@ -223,7 +223,7 @@ #### **Example** -``` +```python import("//tools/typescript/ts_library.gni") # Compiles and outputs my_webui.js, my_web_component.js and @@ -362,7 +362,7 @@ ``` #### **Example** -``` +```python import("//ui/webui/resources/tools/bundle_js.gni") import ("//chrome/common/features.gni") @@ -406,7 +406,7 @@ ``` #### **Example** -``` +```python import("//ui/webui/resources/tools/minify_js.gni") import ("//chrome/common/features.gni") @@ -444,7 +444,7 @@ ``` #### **Example** -``` +```python import("//ui/webui/resources/tools/generate_code_cache.gni") import ("//chrome/common/features.gni") @@ -497,7 +497,7 @@ ``` #### **Example** -``` +```python import("//ui/webui/resources/tools/generate_grd.gni") generate_grd("build_grd") { @@ -539,7 +539,7 @@ ``` #### **Example** -``` +```python import("//tools/grit/grit_rule.gni") grit("resources") { @@ -715,7 +715,7 @@ ``` #### **Example** -``` +```python import("//ui/webui/resources/tools/build_webui.gni") build_webui("build") { @@ -821,7 +821,7 @@ ``` #### **Example** -``` +```python import("//chrome/test/data/webui/settings/tools/build_webui_tests.gni") build_webui_tests("build") { @@ -862,7 +862,7 @@ ``` #### **BUILD.gn file** -``` +```python import("//chrome/common/features.gni") import("//tools/grit/grit_rule.gni") import("//tools/typescript/ts_library.gni") @@ -915,7 +915,7 @@ ``` #### **BUILD.gn file** -``` +```python import("//chrome/common/features.gni") import("//tools/grit/grit_rule.gni") import("//tools/typescript/ts_library.gni")
diff --git a/docs/webui/webui_code_sharing.md b/docs/webui/webui_code_sharing.md index 00972017..4836eec 100644 --- a/docs/webui/webui_code_sharing.md +++ b/docs/webui/webui_code_sharing.md
@@ -124,7 +124,7 @@ targets that depend on the new shared library. This is best demonstrated with an example: -``` +```python build_webui("build_my_webui") { grd_prefix = "my_webui" # Other params here
diff --git a/docs/webui/webui_explainer.md b/docs/webui/webui_explainer.md index e92b0cb0..6b02054 100644 --- a/docs/webui/webui_explainer.md +++ b/docs/webui/webui_explainer.md
@@ -512,7 +512,7 @@ follows: **chrome/browser/ui/webui/donuts/BUILD.gn** -``` +```python import("//mojo/public/tools/bindings/mojom.gni") mojom("mojo_bindings") { @@ -673,7 +673,7 @@ `build_webui()`: **chrome/browser/resources/donuts/BUILD.gn** -``` +```python import("//ui/webui/resources/tools/build_webui.gni") build_webui("build") { @@ -743,7 +743,7 @@ response from the browser. **chrome/browser/resources/donuts/donuts.ts** -```js +```ts import {BrowserProxyImpl} from './browser_proxy.js'; let numDonutsBaked: number = 0; @@ -864,7 +864,7 @@ This works by crafting a string to be evaluated in the renderer. Any arguments to the call are serialized to JSON and the parameter list is wrapped with -``` +```c++ // See WebUI::GetJavascriptCall() for specifics: "functionCallName(" + argumentsAsJson + ")" ```
diff --git a/docs/webui/webui_in_chrome.md b/docs/webui/webui_in_chrome.md index 8b4e887..8bc25ec7 100644 --- a/docs/webui/webui_in_chrome.md +++ b/docs/webui/webui_in_chrome.md
@@ -73,7 +73,7 @@ ``` `chrome/browser/resources/hello_world/app.html.ts` -```js +```ts // 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. @@ -89,7 +89,7 @@ ``` `chrome/browser/resources/hello_world/app.ts` -```js +```ts import './strings.m.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; @@ -517,7 +517,7 @@ It is suggested to turn off any optimizations during WebUI development by adding the following in the args.gn file: -``` +```py optimize_webui = false ``` @@ -541,7 +541,7 @@ flow, follow the steps below: **Step 1:** Add the following in your args.gn file and build the `chrome` target. -``` +```py optimize_webui = false # explained in previous section load_webui_from_disk = true ```
diff --git a/docs/webui/webui_using_lit.md b/docs/webui/webui_using_lit.md index 68eae44..2d694f6 100644 --- a/docs/webui/webui_using_lit.md +++ b/docs/webui/webui_using_lit.md
@@ -84,7 +84,7 @@ This is also demonstrated in the example below. Suppose the Lit child has a property with `notify: true` as follows: -``` +```ts static override get properties() { return { foo: { @@ -97,14 +97,14 @@ This property is also bound to a parent element that listens for the `-changed` event as follows: -``` +```html <foo-child ?foo="${this.foo_}" on-foo-changed="${this.onFooChanged_}"> </foo-child> <demo-child id="demo"></demo-child> ``` The parent TypeScript code could look like this: -``` +```ts static override get properties() { return { foo_: {type: Boolean}, @@ -148,7 +148,7 @@ have an empty `<select>` displayed at startup. `.html.ts` file with `<select>` bug: -``` +```html <select .value="${this.mySelectValue}" @change="${this.onSelectChange_}"> <option value="${MyEnum.FIRST}">Option 1</option> <option value="${MyEnum.SECOND}">Option 2</option> @@ -157,7 +157,7 @@ Corresponding `.ts`. Note that the bug manifests even though `mySelectValue` is being initialized to a valid option. -``` +```ts static get properties() { return { mySelectValue: {type: String}, @@ -175,7 +175,7 @@ attribute on each `<option>`, i.e.: `.html.ts` file: -``` +```html <select @change="${this.onSelectChange_}"> <option value="${MyEnum.FIRST}" ?selected="${this.isSelected_(MyEnum.FIRST)}"> @@ -189,7 +189,7 @@ ``` Corresponding `.ts` file: -``` +```ts static get properties() { return { mySelectValue: {type: String}, @@ -313,7 +313,7 @@ *** Example `.ts` file: -``` +```ts // 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. @@ -371,7 +371,7 @@ ``` Example CSS file: -``` +```css /* 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. */ @@ -406,7 +406,7 @@ *** Example `.html.ts `file: -``` +```ts // 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. @@ -425,7 +425,7 @@ ``` `BUILD.gn` file configuration: -``` +```python build_webui("build") { … # Use non_web_component_files since the .html.ts file is checked in. @@ -493,12 +493,12 @@ without specifying parameters. An example of this follows. Polymer HTML template snippet: -``` +```html <cr-button hidden="[[hideButton_]]">Click Me</cr-button> ``` In the Polymer element definition: -``` +```ts static get properties() { return { loading: Boolean, @@ -519,12 +519,12 @@ This could be rewritten in Lit, omitting the `hideButton_` property entirely. Equivalent Lit HTML template snippet: -``` +```html <cr-button ?hidden="${this.computeHideButton_()}">Click Me</cr-button> ``` Equivalent Lit element definition: -``` +```ts static get properties() { return { loading: {type: Boolean}, @@ -543,7 +543,7 @@ attributes, or are needed for other internal logic, they can be computed in the `willUpdate()` lifecycle callback when the properties that they depend on change as in the following example: -``` +```ts override willUpdate(changedProperties: PropertyValues<this>) { super.willUpdate(changedProperties); @@ -567,7 +567,7 @@ than triggering a second round of updates. Consider the following Polymer code, with a complex observer: -``` +```ts static get properties() { return { max: Number, @@ -591,7 +591,7 @@ The Lit migrated code would look as follows, with the observer code split into `willUpdate()` and `updated()` based on whether it accesses the DOM: -``` +```ts static override get properties() { return { max: {type: Number}, @@ -630,7 +630,7 @@ `cr-toolbar`: Polymer `cr_toolbar.html`: -``` +```html <div id="content"> <template is="dom-if" if="[[showMenu]]" restamp> <cr-icon-button id="menuButton" class="no-overlap" @@ -642,7 +642,7 @@ ``` Lit `cr_toolbar.html.ts`: -``` +```html <div id="content"> ${this.showMenu ? html` <cr-icon-button id="menuButton" class="no-overlap" @@ -677,7 +677,7 @@ fire events, as seen in the example that follows. From the Polymer element template: -``` +```html <template is="dom-repeat" items="[[listItems]]"> <div class="item-container [[getSelectedClass_(item, selectedItem)]]"> <cr-button id="[[getItemId_(index)]]" on-click="onItemClick_"> @@ -688,7 +688,7 @@ ``` From the Polymer element definition: -``` +```ts private getItemId_(index: number): string { return 'listItemId' + index; } @@ -709,7 +709,7 @@ ``` Lit template: -``` +```ts ${this.listItems.map((item, index) => html` <div class="item-container ${this.getSelectedClass_(item)}"> <cr-button id="${this.getItemId_(index)}" @@ -725,7 +725,7 @@ *** From the Lit element definition file: -``` +```ts protected getItemId_(index: number): string { return 'listItemId' + index; } @@ -763,7 +763,7 @@ composition, follows. From the Polymer `.html` template: -``` +```html <div class="folder-and-count"> <template is="dom-if" if="[[shouldShowFolderImages_(size)]]" restamp> <template is="dom-repeat" items="[[imageUrls]]" @@ -778,7 +778,7 @@ ``` From the Polymer element definition: -``` +```ts private shouldShowImageUrl_(_url: string, index: number) { return index <= 1; } @@ -798,7 +798,7 @@ ``` From the Lit `.html.ts` template file: -``` +```ts import {html} from '//resources/lit/v3_0/lit.rollup.js'; import type {CrUrlListItemElement} from './cr_url_list_item.js'; @@ -842,7 +842,7 @@ ``` From the Lit element definition: -``` +```ts protected getDisplayedCount_(): string { if (this.count && this.count > 999) { // The square to display the count only fits 3 characters. @@ -891,7 +891,7 @@ their height has changed. See example below: From the `list_parent.html` template (`iron-list` client so must be Polymer) -``` +```html <iron-list id="list" items="[[listItems_]]" as="item"> <template> <custom-item description="[[item.description]]" name="[[item.name]]" @@ -902,7 +902,7 @@ ``` From the child `custom_item.html.ts` template: -``` +```html <div class="name">${this.name}</div> <div class="description" ?hidden="${!this.description}"> ${this.description} @@ -916,7 +916,7 @@ fire `iron-resize` in `updated()` if its `description` property changes. From `custom_item.ts`: -``` +```ts override updated(changedProperties: PropertyValues<this>) { super.updated(changedProperties); if (changedProperties.has('description')) { @@ -929,7 +929,7 @@ ### Testing A large number of unit tests do something like the following: -``` +```ts // Validate that the input is disabled when invalid is set. myTestElement.invalid = true; assertTrue(myTestElement.$.input.disabled); @@ -948,7 +948,7 @@ render cycle). Updated example: -``` +```ts // Validate that the input is disabled when invalid is set. myTestElement.invalid = true; await microtasksFinished();
diff --git a/extensions/browser/policy_check.cc b/extensions/browser/policy_check.cc index 39a5cdb..0c19d31 100644 --- a/extensions/browser/policy_check.cc +++ b/extensions/browser/policy_check.cc
@@ -18,11 +18,15 @@ void PolicyCheck::Start(ResultCallback callback) { Errors errors; +// TODO(crbug.com/394876083): Enable the management policy on android +// (currently management_policy() returns nullptr). +#if BUILDFLAG(ENABLE_EXTENSIONS) if (!ExtensionSystem::Get(context_)->management_policy()->UserMayInstall( extension(), &error_)) { DCHECK(!error_.empty()); errors.insert(Error::kDisallowedByPolicy); } +#endif // BUILDFLAG(ENABLE_EXTENSIONS) std::move(callback).Run(errors); }
diff --git a/extensions/browser/policy_check_unittest.cc b/extensions/browser/policy_check_unittest.cc index 367c942..c46722e6 100644 --- a/extensions/browser/policy_check_unittest.cc +++ b/extensions/browser/policy_check_unittest.cc
@@ -109,9 +109,13 @@ PolicyCheck policy_check(browser_context(), extension_); runner_.Run(&policy_check); EXPECT_TRUE(runner_.called()); +// TODO(crbug.com/394876083): Enable the management policy on android and +// remove the if-def. +#if !BUILDFLAG(IS_ANDROID) EXPECT_THAT(runner_.errors(), testing::UnorderedElementsAre( PreloadCheck::Error::kDisallowedByPolicy)); EXPECT_EQ(kDummyPolicyError, policy_check.GetErrorMessage()); +#endif // !BUILDFLAG(IS_ANDROID) } } // namespace extensions
diff --git a/gpu/command_buffer/tests/gl_angle_shader_pixel_local_storage_unittest.cc b/gpu/command_buffer/tests/gl_angle_shader_pixel_local_storage_unittest.cc index bdc15c7..2f4eb33e 100644 --- a/gpu/command_buffer/tests/gl_angle_shader_pixel_local_storage_unittest.cc +++ b/gpu/command_buffer/tests/gl_angle_shader_pixel_local_storage_unittest.cc
@@ -111,9 +111,8 @@ // marshalled properly over the command buffer. Thorough testing of these // commands is done in angle_end2end_tests. -// TODO(anglebug.com/40096838): debug and re-enable this test. TEST_F(ANGLEShaderPixelLocalStorageTest, - DISABLED_GetFramebufferPixelLocalStorageParameter) { + GetFramebufferPixelLocalStorageParameter) { if (!gl_.IsInitialized() || !GLTestHelper::HasExtension("GL_ANGLE_shader_pixel_local_storage")) { return;
diff --git a/gpu/config/gpu_finch_features.cc b/gpu/config/gpu_finch_features.cc index b4566140..33ca8c9 100644 --- a/gpu/config/gpu_finch_features.cc +++ b/gpu/config/gpu_finch_features.cc
@@ -849,7 +849,7 @@ "ANGLEPerContextBlobCache", base::FEATURE_DISABLED_BY_DEFAULT); -#if BUILDFLAG(IS_MAC) +#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_IOS) BASE_FEATURE(kMacSupportMultiThreading, "SupportMacMultiThreading", base::FEATURE_DISABLED_BY_DEFAULT);
diff --git "a/infra/config/generated/builders/ci/Linux Builder \050dbg\051/targets/chromium.linux.json" "b/infra/config/generated/builders/ci/Linux Builder \050dbg\051/targets/chromium.linux.json" index 042a0ed..f818c6b 100644 --- "a/infra/config/generated/builders/ci/Linux Builder \050dbg\051/targets/chromium.linux.json" +++ "b/infra/config/generated/builders/ci/Linux Builder \050dbg\051/targets/chromium.linux.json"
@@ -193,7 +193,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 32 + "shards": 48 }, "test": "browser_tests", "test_id_prefix": "ninja://chrome/test:browser_tests/" @@ -324,7 +324,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 8 + "shards": 12 }, "test": "content_browsertests", "test_id_prefix": "ninja://content/test:content_browsertests/"
diff --git "a/infra/config/generated/builders/ci/Linux Tests \050dbg\051\0501\051/targets/chromium.linux.json" "b/infra/config/generated/builders/ci/Linux Tests \050dbg\051\0501\051/targets/chromium.linux.json" index 8a8b8db..c83ba6b 100644 --- "a/infra/config/generated/builders/ci/Linux Tests \050dbg\051\0501\051/targets/chromium.linux.json" +++ "b/infra/config/generated/builders/ci/Linux Tests \050dbg\051\0501\051/targets/chromium.linux.json"
@@ -188,7 +188,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 32 + "shards": 48 }, "test": "browser_tests", "test_id_prefix": "ninja://chrome/test:browser_tests/" @@ -319,7 +319,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 8 + "shards": 12 }, "test": "content_browsertests", "test_id_prefix": "ninja://content/test:content_browsertests/"
diff --git a/infra/config/generated/builders/try/linux_chromium_compile_dbg_ng/targets/chromium.linux.json b/infra/config/generated/builders/try/linux_chromium_compile_dbg_ng/targets/chromium.linux.json index 042a0ed..f818c6b 100644 --- a/infra/config/generated/builders/try/linux_chromium_compile_dbg_ng/targets/chromium.linux.json +++ b/infra/config/generated/builders/try/linux_chromium_compile_dbg_ng/targets/chromium.linux.json
@@ -193,7 +193,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 32 + "shards": 48 }, "test": "browser_tests", "test_id_prefix": "ninja://chrome/test:browser_tests/" @@ -324,7 +324,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 8 + "shards": 12 }, "test": "content_browsertests", "test_id_prefix": "ninja://content/test:content_browsertests/"
diff --git a/infra/config/generated/builders/try/linux_chromium_dbg_ng/targets/chromium.linux.json b/infra/config/generated/builders/try/linux_chromium_dbg_ng/targets/chromium.linux.json index 042a0ed..f818c6b 100644 --- a/infra/config/generated/builders/try/linux_chromium_dbg_ng/targets/chromium.linux.json +++ b/infra/config/generated/builders/try/linux_chromium_dbg_ng/targets/chromium.linux.json
@@ -193,7 +193,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 32 + "shards": 48 }, "test": "browser_tests", "test_id_prefix": "ninja://chrome/test:browser_tests/" @@ -324,7 +324,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 8 + "shards": 12 }, "test": "content_browsertests", "test_id_prefix": "ninja://content/test:content_browsertests/"
diff --git a/infra/config/subprojects/chromium/ci/chromium.linux.star b/infra/config/subprojects/chromium/ci/chromium.linux.star index dd159a8..3537f104 100644 --- a/infra/config/subprojects/chromium/ci/chromium.linux.star +++ b/infra/config/subprojects/chromium/ci/chromium.linux.star
@@ -599,8 +599,16 @@ # crbug.com/1066161 # crbug.com/1459645 # crbug.com/1508286 + # crbug.com/404871436 swarming = targets.swarming( - shards = 32, + shards = 48, + ), + ), + "content_browsertests": targets.mixin( + # crbug.com/1508286 + # crbug.com/404871436 + swarming = targets.swarming( + shards = 12, ), ), "interactive_ui_tests": targets.mixin(
diff --git a/internal b/internal index a507347..466f90c 160000 --- a/internal +++ b/internal
@@ -1 +1 @@ -Subproject commit a5073472b181d28117915f910995dccc7a57cac5 +Subproject commit 466f90ca70623f51b82c63cb869b22ba4fe26de1
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 08baeb9..58f94ac 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -6000,13 +6000,13 @@ <message name="IDS_IOS_SIGNIN_PROMO_RECENT_TABS_WITH_UNITY" desc="Text to inform the user that they can sign in and sync to get tabs shared between devices. [iOS only]"> To get your tabs from your other devices, turn on sync. </message> - <message name="IDS_IOS_SIGNIN_PROMO_REVIEW_BOOKMARKS_SETTINGS" desc="This string is on a promo intended to promote reviewing the user's Google Account settings page to enable bookmarks toggle. It appears on the Bookmarks page when the user is signed in not syncing."> + <message name="IDS_IOS_SIGNIN_PROMO_REVIEW_BOOKMARKS_SETTINGS" desc="This string is on a promo intended to promote reviewing the user's Google Account settings page to enable bookmarks toggle. It appears on the Bookmarks page when the user is signed in."> To get your bookmarks on all your devices, turn on “Bookmarks” in settings. </message> - <message name="IDS_IOS_SIGNIN_PROMO_REVIEW_READING_LIST_SETTINGS" desc="This string is on a promo intended to promote reviewing the user's Google Account settings page to enable reading list toggle. It appears on the Reading List page when the user is signed in not syncing."> + <message name="IDS_IOS_SIGNIN_PROMO_REVIEW_READING_LIST_SETTINGS" desc="This string is on a promo intended to promote reviewing the user's Google Account settings page to enable reading list toggle. It appears on the Reading List page when the user is signed in."> To get your reading list on all your devices, turn on “Reading List” in settings. </message> - <message name="IDS_IOS_SIGNIN_PROMO_REVIEW_SETTINGS_BUTTON" desc="This string is on a promo button intended to promote reviewing the user's Google Account settings page to enable the type toggle. It appears on the Bookmarks or Reading List page when the user is signed in not syncing."> + <message name="IDS_IOS_SIGNIN_PROMO_REVIEW_SETTINGS_BUTTON" desc="This string is on a promo button intended to promote reviewing the user's Google Account settings page to enable the type toggle. It appears on the Bookmarks or Reading List page when the user is signed in."> Open settings </message> <message name="IDS_IOS_SIGNIN_PROMO_SIGNIN_WITH_UNO" desc="Button that the user can press if they want to sign-in in the browser. [iOS only]">
diff --git a/ios/chrome/browser/authentication/ui_bundled/authentication_ui_util.h b/ios/chrome/browser/authentication/ui_bundled/authentication_ui_util.h index 15d2409..c81da917 100644 --- a/ios/chrome/browser/authentication/ui_bundled/authentication_ui_util.h +++ b/ios/chrome/browser/authentication/ui_bundled/authentication_ui_util.h
@@ -36,7 +36,7 @@ SignoutActionSheetCoordinatorResultKeepOnDevice, }; -// Enum to describe all 3 cases for a user being signed-in and syncing. +// Enum to describe all 3 cases for a user being signed-in. enum class SignedInUserState { // Sign-in with UNO. The sign-out needs to ask confirmation to sign out only // if there are unsaved data. When signed out, a snackbar needs to be
diff --git a/ios/chrome/browser/authentication/ui_bundled/signin/forced_signin/forced_signin_egtest.mm b/ios/chrome/browser/authentication/ui_bundled/signin/forced_signin/forced_signin_egtest.mm index d5c70f23..394ef315 100644 --- a/ios/chrome/browser/authentication/ui_bundled/signin/forced_signin/forced_signin_egtest.mm +++ b/ios/chrome/browser/authentication/ui_bundled/signin/forced_signin/forced_signin_egtest.mm
@@ -417,7 +417,7 @@ FakeSystemIdentity* fakeIdentity1 = [FakeSystemIdentity fakeIdentity1]; [SigninEarlGrey addFakeIdentity:fakeIdentity1]; - // Sign in account without enabling sync. + // Sign in account. WaitForForcedSigninScreenAndSignin(fakeIdentity1); // Make sure the forced sign-in screen isn't shown. @@ -437,7 +437,7 @@ FakeSystemIdentity* fakeIdentity1 = [FakeSystemIdentity fakeIdentity1]; [SigninEarlGrey addFakeIdentity:fakeIdentity1]; - // Sign in account without enabling sync. + // Sign in account. WaitForForcedSigninScreenAndSignin(fakeIdentity1); // Make sure the forced sign-in screen isn't shown. @@ -483,7 +483,7 @@ FakeSystemIdentity* fakeIdentity1 = [FakeSystemIdentity fakeIdentity1]; [SigninEarlGrey addFakeIdentity:fakeIdentity1]; - // Sign in account without enabling sync. + // Sign in account. WaitForForcedSigninScreenAndSignin(fakeIdentity1); // Make sure the forced sign-in screen isn't shown. @@ -698,7 +698,7 @@ GREYAssertFalse([ChromeEarlGrey isLoading], @"Page should not have been loaded yet"); - // Sign in account without enabling sync. + // Sign in account. WaitForForcedSigninScreenAndSignin(fakeIdentity1); // Make sure the forced sign-in screen isn't shown because it should have @@ -752,7 +752,7 @@ // enabled and the browser is signed out. [ChromeEarlGrey waitForMatcher:GetForcedSigninScreenMatcher()]; - // Sign in account without enabling sync. + // Sign in account. WaitForForcedSigninScreenAndSignin(fakeIdentity); // Make sure the forced sign-in screen isn't shown because it should have
diff --git a/ios/chrome/browser/authentication/ui_bundled/signin/signin_coordinator_egtest.mm b/ios/chrome/browser/authentication/ui_bundled/signin/signin_coordinator_egtest.mm index db3b882..1077a661 100644 --- a/ios/chrome/browser/authentication/ui_bundled/signin/signin_coordinator_egtest.mm +++ b/ios/chrome/browser/authentication/ui_bundled/signin/signin_coordinator_egtest.mm
@@ -757,7 +757,7 @@ [SigninEarlGreyUI assertFakeAddAccountMenuDisplayed]; } -// Tests that a signed-out user can open "Sign in and sync" screen from the NTP. +// Tests that a signed-out user can open the "Sign in" screen from the NTP. - (void)testOpenSignInFromNTP { // Select the identity disc particle. [[EarlGrey selectElementWithMatcher:
diff --git a/ios/chrome/browser/authentication/ui_bundled/signin_earl_grey_app_interface.mm b/ios/chrome/browser/authentication/ui_bundled/signin_earl_grey_app_interface.mm index c535619..4d19250 100644 --- a/ios/chrome/browser/authentication/ui_bundled/signin_earl_grey_app_interface.mm +++ b/ios/chrome/browser/authentication/ui_bundled/signin_earl_grey_app_interface.mm
@@ -191,7 +191,7 @@ } + (void)signInWithoutHistorySyncWithFakeIdentity:(FakeSystemIdentity*)identity { - chrome_test_util::SignInWithoutSync(identity); + chrome_test_util::SignIn(identity); } + (void)triggerReauthDialogWithFakeIdentity:(FakeSystemIdentity*)identity {
diff --git a/ios/chrome/browser/authentication/ui_bundled/signin_promo_view_mediator.h b/ios/chrome/browser/authentication/ui_bundled/signin_promo_view_mediator.h index 4123cbb9..7580f436 100644 --- a/ios/chrome/browser/authentication/ui_bundled/signin_promo_view_mediator.h +++ b/ios/chrome/browser/authentication/ui_bundled/signin_promo_view_mediator.h
@@ -84,8 +84,8 @@ // (in that case the button opens a dialog to add an account instead). // When the user is signed-out and has accounts on the device, this is the // default identity. -// when the user is signed-in and not syncing, this is the signed-in identity -// (not necessarily the default one). +// When the user is signed-in, this is the signed-in identity (not necessarily +// the default one). @property(nonatomic, strong, readonly) id<SystemIdentity> displayedIdentity; // Sign-in promo view state. kNeverVisible by default.
diff --git a/ios/chrome/browser/autofill/ui_bundled/manual_fill/password_view_controller_egtest.mm b/ios/chrome/browser/autofill/ui_bundled/manual_fill/password_view_controller_egtest.mm index 9ecbf4e..3834e86 100644 --- a/ios/chrome/browser/autofill/ui_bundled/manual_fill/password_view_controller_egtest.mm +++ b/ios/chrome/browser/autofill/ui_bundled/manual_fill/password_view_controller_egtest.mm
@@ -1004,8 +1004,8 @@ [ChromeEarlGrey waitForJavaScriptCondition:javaScriptCondition]; } -// Tests password generation on manual fallback for signed in not syncing users. -- (void)testPasswordGenerationOnManualFallbackSignedInNotSyncingAccount { +// Tests password generation on manual fallback for signed in users. +- (void)testPasswordGenerationOnManualFallbackSignedInAccount { [SigninEarlGreyUI signinWithFakeIdentity:[FakeSystemIdentity fakeIdentity1]]; [ChromeEarlGrey waitForSyncTransportStateActiveWithTimeout:base::Seconds(10)]; @@ -1027,18 +1027,17 @@ performAction:grey_tap()]; } -// Tests password generation on manual fallback not showing for signed in not -// syncing users with Passwords toggle in account settings disbaled. +// Tests password generation on manual fallback not showing for signed in users +// with Passwords toggle in account settings disabled. // TODO(crbug.com/371189341): Test fails on device. #if TARGET_IPHONE_SIMULATOR -#define MAYBE_testPasswordGenerationFallbackSignedInNotSyncingPasswordsDisabled \ - testPasswordGenerationFallbackSignedInNotSyncingPasswordsDisabled +#define MAYBE_testPasswordGenerationFallbackSignedInPasswordsDisabled \ + testPasswordGenerationFallbackSignedInPasswordsDisabled #else -#define MAYBE_testPasswordGenerationFallbackSignedInNotSyncingPasswordsDisabled \ - DISABLED_testPasswordGenerationFallbackSignedInNotSyncingPasswordsDisabled +#define MAYBE_testPasswordGenerationFallbackSignedInPasswordsDisabled \ + DISABLED_testPasswordGenerationFallbackSignedInPasswordsDisabled #endif -- (void) - MAYBE_testPasswordGenerationFallbackSignedInNotSyncingPasswordsDisabled { +- (void)MAYBE_testPasswordGenerationFallbackSignedInPasswordsDisabled { [SigninEarlGreyUI signinWithFakeIdentity:[FakeSystemIdentity fakeIdentity1]]; [ChromeEarlGrey waitForSyncTransportStateActiveWithTimeout:base::Seconds(10)]; @@ -1065,17 +1064,17 @@ assertWithMatcher:grey_notVisible()]; } -// Tests password generation on manual fallback not showing for signed in not -// syncing users with encryption error. +// Tests password generation on manual fallback not showing for signed in users +// with encryption error. // TODO(crbug.com/371189341): Test fails on device. #if TARGET_IPHONE_SIMULATOR -#define MAYBE_testPasswordGenerationFallbackSignedInNotSyncingEncryptionError \ - testPasswordGenerationFallbackSignedInNotSyncingEncryptionError +#define MAYBE_testPasswordGenerationFallbackSignedInEncryptionError \ + testPasswordGenerationFallbackSignedInEncryptionError #else -#define MAYBE_testPasswordGenerationFallbackSignedInNotSyncingEncryptionError \ - DISABLED_testPasswordGenerationFallbackSignedInNotSyncingEncryptionError +#define MAYBE_testPasswordGenerationFallbackSignedInEncryptionError \ + DISABLED_testPasswordGenerationFallbackSignedInEncryptionError #endif -- (void)MAYBE_testPasswordGenerationFallbackSignedInNotSyncingEncryptionError { +- (void)MAYBE_testPasswordGenerationFallbackSignedInEncryptionError { // Encrypt synced data with a passphrase to enable passphrase encryption for // the signed in account. [ChromeEarlGrey addSyncPassphrase:kPassphrase];
diff --git a/ios/chrome/browser/collaboration/model/ios_collaboration_controller_delegate_unittest.mm b/ios/chrome/browser/collaboration/model/ios_collaboration_controller_delegate_unittest.mm index 4440077..452ae84ba 100644 --- a/ios/chrome/browser/collaboration/model/ios_collaboration_controller_delegate_unittest.mm +++ b/ios/chrome/browser/collaboration/model/ios_collaboration_controller_delegate_unittest.mm
@@ -431,7 +431,7 @@ delegate_->ShowAuthenticationUi(mock_callback.Get()); } -// Tests `ShowAuthenticationUi` when the user is SignedIn but not syncing. +// Tests `ShowAuthenticationUi` when the user is signed-in. TEST_F(IOSCollaborationControllerDelegateTest, ShowAuthenticationUiWithSignIn) { SignIn(); InitDelegate();
diff --git a/ios/chrome/browser/first_run/ui_bundled/first_run_without_search_engine_choice_egtest.mm b/ios/chrome/browser/first_run/ui_bundled/first_run_without_search_engine_choice_egtest.mm index d98cac4..15e10827 100644 --- a/ios/chrome/browser/first_run/ui_bundled/first_run_without_search_engine_choice_egtest.mm +++ b/ios/chrome/browser/first_run/ui_bundled/first_run_without_search_engine_choice_egtest.mm
@@ -445,8 +445,8 @@ performAction:grey_tap()]; } -// Tests forced sign-in policy, and refuse sync. -- (void)testForceSigninByPolicyWithoutSync { +// Tests forced sign-in policy, and refuse history sync. +- (void)testForceSigninByPolicyWithoutHistorySync { // Configure the policy to force sign-in. [self relaunchAppWithBrowserSigninMode:BrowserSigninMode::kForced]; FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1]; @@ -462,7 +462,7 @@ scrollViewIdentifier: kPromoStyleScrollViewAccessibilityIdentifier] performAction:grey_tap()]; - // Refuse sync. + // Refuse history sync. [[self elementInteractionWithGreyMatcher: chrome_test_util::PromoScreenSecondaryButtonMatcher() scrollViewIdentifier:
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 58e3961e..72ae8a0 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -1602,11 +1602,6 @@ commerce::flag_descriptions::kPriceInsightsHighPriceIosDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(commerce::kPriceInsightsHighPriceIos)}, - {"autofill-enable-card-product-name", - flag_descriptions::kAutofillEnableCardProductNameName, - flag_descriptions::kAutofillEnableCardProductNameDescription, - flags_ui::kOsIos, - FEATURE_VALUE_TYPE(autofill::features::kAutofillEnableCardProductName)}, {"enable-download-service-foreground-session", flag_descriptions::kDownloadServiceForegroundSessionName, flag_descriptions::kDownloadServiceForegroundSessionDescription,
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index 7e796372..5c45f9a 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -114,12 +114,6 @@ "When enabled, Autofill will use a new ranking formula to rank Autofill " "data model credit card suggestions."; -const char kAutofillEnableCardProductNameName[] = - "Enable showing card product name"; -const char kAutofillEnableCardProductNameDescription[] = - "When enabled, card product name (instead of issuer network) will be shown " - "in Payments UI."; - const char kAutofillEnableVerveCardSupportName[] = "Enable autofill support for Verve cards"; const char kAutofillEnableVerveCardSupportDescription[] =
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index 776d733..a8dcd32 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -75,9 +75,6 @@ extern const char kAutofillEnableRankingFormulaCreditCardsName[]; extern const char kAutofillEnableRankingFormulaCreditCardsDescription[]; -extern const char kAutofillEnableCardProductNameName[]; -extern const char kAutofillEnableCardProductNameDescription[]; - extern const char kAutofillEnableVerveCardSupportName[]; extern const char kAutofillEnableVerveCardSupportDescription[];
diff --git a/ios/chrome/browser/history/model/web_history_service_factory.cc b/ios/chrome/browser/history/model/web_history_service_factory.cc index b735fd80..1b7b009 100644 --- a/ios/chrome/browser/history/model/web_history_service_factory.cc +++ b/ios/chrome/browser/history/model/web_history_service_factory.cc
@@ -30,8 +30,7 @@ // static history::WebHistoryService* WebHistoryServiceFactory::GetForProfile( ProfileIOS* profile) { - // Ensure that the service is not instantiated or used if the user is not - // signed into sync, or if web history is not enabled. + // Ensure that the service is not instantiated if history sync is off. if (!IsHistorySyncEnabled(profile)) { return nullptr; }
diff --git a/ios/chrome/browser/metrics/model/ios_profile_session_durations_service.h b/ios/chrome/browser/metrics/model/ios_profile_session_durations_service.h index 55a9e29..f5aafff 100644 --- a/ios/chrome/browser/metrics/model/ios_profile_session_durations_service.h +++ b/ios/chrome/browser/metrics/model/ios_profile_session_durations_service.h
@@ -31,8 +31,8 @@ class MsbbSessionDurationsMetricsRecorder; } -// Tracks the active browsing time that the user spends signed in and/or syncing -// as fraction of their total browsing time. +// Tracks the active browsing time that the user spends signed in as fraction of +// their total browsing time. class IOSProfileSessionDurationsService : public KeyedService { public: // Callers must ensure that the parameters outlive this object.
diff --git a/ios/chrome/browser/metrics/model/ios_profile_session_durations_service_factory.mm b/ios/chrome/browser/metrics/model/ios_profile_session_durations_service_factory.mm index 8c8505f2..b2393b77 100644 --- a/ios/chrome/browser/metrics/model/ios_profile_session_durations_service_factory.mm +++ b/ios/chrome/browser/metrics/model/ios_profile_session_durations_service_factory.mm
@@ -29,9 +29,9 @@ } // Session time in incognito is counted towards the session time in the -// regular profile. That means that for a user that is signed in and syncing -// in their regular profile and that is browsing in incognito profile, -// Chromium will record the session time as being signed in and syncing. +// regular profile. That means that for a user that is signed in in their +// regular profile and that is browsing in incognito profile, +// Chromium will record the session time as being signed in. IOSProfileSessionDurationsServiceFactory:: IOSProfileSessionDurationsServiceFactory() : ProfileKeyedServiceFactoryIOS("IOSProfileSessionDurationsService",
diff --git a/ios/chrome/browser/passwords/model/password_controller_egtest.mm b/ios/chrome/browser/passwords/model/password_controller_egtest.mm index 2a5402c..9fdc652 100644 --- a/ios/chrome/browser/passwords/model/password_controller_egtest.mm +++ b/ios/chrome/browser/passwords/model/password_controller_egtest.mm
@@ -449,7 +449,7 @@ [ChromeEarlGrey waitForJavaScriptCondition:filledFieldCondition]; } -// Tests that password generation is offered for signed in not syncing users. +// Tests that password generation is offered for signed in users. - (void)testPasswordGenerationForSignedInAccount { [SigninEarlGrey signinAndWaitForSyncTransportStateActive:[FakeSystemIdentity fakeIdentity1]]; @@ -483,8 +483,8 @@ performAction:grey_tap()]; } -// Tests that password generation is not offered for signed in not syncing users -// with passwords toggle disabled. +// Tests that password generation is not offered for signed in users with +// passwords toggle disabled. // TODO(crbug.com/371189341): Test fails on device. #if TARGET_IPHONE_SIMULATOR #define MAYBE_testPasswordGenerationWhileSignedInWithPasswordsDisabled \ @@ -527,8 +527,8 @@ assertWithMatcher:grey_notVisible()]; } -// Tests that password generation is not offered for signed in not syncing users -// with an encryption error; missing passphrase. +// Tests that password generation is not offered for signed in users with an +// encryption error; missing passphrase. // TODO(crbug.com/371189341): Test fails on device. #if TARGET_IPHONE_SIMULATOR #define MAYBE_testPasswordGenerationWhileSignedInWithError \
diff --git a/ios/chrome/browser/reading_list/ui_bundled/reading_list_account_storage_egtest.mm b/ios/chrome/browser/reading_list/ui_bundled/reading_list_account_storage_egtest.mm index bd5917b..24a3bcc 100644 --- a/ios/chrome/browser/reading_list/ui_bundled/reading_list_account_storage_egtest.mm +++ b/ios/chrome/browser/reading_list/ui_bundled/reading_list_account_storage_egtest.mm
@@ -184,7 +184,7 @@ [[EarlGrey selectElementWithMatcher:SignedInSnackbar(fakeIdentity.userEmail)] performAction:grey_tap()]; - // Verify that the identity is signed-in without sync and the promo is hidden. + // Verify that the identity is signed-in and the promo is hidden. [SigninEarlGrey verifyPrimaryAccountWithEmail:fakeIdentity.userEmail consent:signin::ConsentLevel::kSignin]; [SigninEarlGreyUI verifySigninPromoNotVisible]; @@ -239,8 +239,7 @@ [[EarlGrey selectElementWithMatcher:IdentityCellMatcherForEmail( fakeIdentity2.userEmail)] performAction:grey_tap()]; - // Verify that the identity2 is signed-in without sync, and that the promo is - // hidden. + // Verify that the identity2 is signed-in and that the promo is hidden. [SigninEarlGrey verifyPrimaryAccountWithEmail:fakeIdentity2.userEmail consent:signin::ConsentLevel::kSignin]; [SigninEarlGreyUI verifySigninPromoNotVisible];
diff --git a/ios/chrome/browser/recent_tabs/ui_bundled/recent_tabs_table_view_controller.mm b/ios/chrome/browser/recent_tabs/ui_bundled/recent_tabs_table_view_controller.mm index 0ac9569..a6f59b2f 100644 --- a/ios/chrome/browser/recent_tabs/ui_bundled/recent_tabs_table_view_controller.mm +++ b/ios/chrome/browser/recent_tabs/ui_bundled/recent_tabs_table_view_controller.mm
@@ -1747,8 +1747,7 @@ // exist anymore. The mediator should not be removed each time the section // is removed since the section is replaced at each reload. // Metrics would be recorded too often. - // The other device section can be present even without the sync promo. This - // happens when sync is disabled. + // The other device section can be present even without the promo. [self.signinPromoViewMediator disconnect]; self.signinPromoViewMediator = nil; return;
diff --git a/ios/chrome/browser/safe_browsing/model/chrome_password_protection_service.h b/ios/chrome/browser/safe_browsing/model/chrome_password_protection_service.h index 105fb9be..019fd3a 100644 --- a/ios/chrome/browser/safe_browsing/model/chrome_password_protection_service.h +++ b/ios/chrome/browser/safe_browsing/model/chrome_password_protection_service.h
@@ -251,7 +251,7 @@ // Returns the GAIA-account-scoped PasswordStore associated with this // instance. The account password store contains passwords stored in the - // account and is accessible only when the user is signed in and non syncing. + // account and is accessible only when the user is signed in. password_manager::PasswordStoreInterface* GetAccountPasswordStore() const; // Gets prefs associated with `profile_`.
diff --git a/ios/chrome/browser/settings/ui_bundled/google_services/google_services_settings_egtest.mm b/ios/chrome/browser/settings/ui_bundled/google_services/google_services_settings_egtest.mm index 2289f588..26a4a04 100644 --- a/ios/chrome/browser/settings/ui_bundled/google_services/google_services_settings_egtest.mm +++ b/ios/chrome/browser/settings/ui_bundled/google_services/google_services_settings_egtest.mm
@@ -159,7 +159,7 @@ // Tests that disabling the "Allow Chrome sign-in" blocks the user from signing // in to Chrome through settings until it is re-enabled. - (void)testToggleAllowChromeSignin { - // User is signed-in and syncing. + // User is signed-in. FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1]; [SigninEarlGrey signinWithFakeIdentity:fakeIdentity]; [SigninEarlGrey verifySignedInWithFakeIdentity:fakeIdentity];
diff --git a/ios/chrome/browser/settings/ui_bundled/google_services/manage_accounts/legacy_accounts_table_egtest.mm b/ios/chrome/browser/settings/ui_bundled/google_services/manage_accounts/legacy_accounts_table_egtest.mm index 8fae733b..1d4590c 100644 --- a/ios/chrome/browser/settings/ui_bundled/google_services/manage_accounts/legacy_accounts_table_egtest.mm +++ b/ios/chrome/browser/settings/ui_bundled/google_services/manage_accounts/legacy_accounts_table_egtest.mm
@@ -468,8 +468,8 @@ [SigninEarlGrey verifySignedOut]; } -// Tests to sign out with a non managed account without syncing. -- (void)testSignOutWithNonManagedAccountFromNoneSyncingAccount { +// Tests to sign out with a non managed account. +- (void)testSignOutWithNonManagedAccount { FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1]; [SigninEarlGrey signinWithFakeIdentity:fakeIdentity]; @@ -488,8 +488,8 @@ [BookmarkEarlGreyUI verifyEmptyBackgroundIsAbsent]; } -// Tests to sign out with a managed account without syncing. -- (void)testSignOutWithManagedAccountFromNoneSyncingAccount { +// Tests to sign out with a managed account. +- (void)testSignOutWithManagedAccount { // Sign In `fakeManagedIdentity`. FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeManagedIdentity]; [SigninEarlGrey signinWithFakeIdentity:fakeIdentity];
diff --git a/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_constants.h b/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_constants.h index 3695449e..5181d1ae 100644 --- a/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_constants.h +++ b/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_constants.h
@@ -105,7 +105,7 @@ SyncNeedsTrustedVaultKeyErrorItemType, SyncTrustedVaultRecoverabilityDegradedErrorItemType, SyncDisabledByAdministratorErrorItemType, - // Indicates the errors related to the signed in not syncing account. + // Indicates the errors related to the signed in account. AccountErrorMessageItemType, // BatchUploadSectionIdentifier section. // Item for the batch upload button.
diff --git a/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_mediator.mm b/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_mediator.mm index b53cb26..db7eaf59 100644 --- a/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_mediator.mm +++ b/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_mediator.mm
@@ -481,7 +481,7 @@ // Creates the manage accounts and sign-out section. TableViewModel* model = self.consumer.tableViewModel; // The AdvancedSettingsSectionIdentifier does not exist when sync is disabled - // by administrator for a signed-in not syncing account. + // by administrator for a signed-in account. NSInteger previousSection = [model hasSectionForSectionIdentifier:AdvancedSettingsSectionIdentifier] ? [model @@ -1175,7 +1175,7 @@ } // Creates an error action button item to handle the indicated sync error type -// for signed in not syncing users. +// for signed in users. - (TableViewItem*)createSyncErrorButtonItemWithItemType:(NSInteger)itemType buttonLabelID:(int)buttonLabelID messageID:(int)messageID { @@ -1264,8 +1264,7 @@ if (type.value() == SyncDisabledByAdministratorErrorItemType) { self.syncErrorItem = [self createSyncDisabledByAdministratorErrorItem]; } else { - // For signed in not syncing users, the sync error item will be displayed as - // a button. + // For signed in users, the sync error item will be displayed as a button. self.syncErrorItem = [self createSyncErrorButtonItemWithItemType:type.value() buttonLabelID:GetAccountErrorUIInfo( @@ -1281,8 +1280,8 @@ if (type.value() != SyncDisabledByAdministratorErrorItemType) { [model insertSectionWithIdentifier:SyncErrorsSectionIdentifier atIndex:syncErrorSectionIndex]; - // For signed in not syncing users, the sync error item will be preceded - // by a descriptive message item. + // For signed in users, the sync error item will be preceded by a + // descriptive message item. [model addItem:[self createSyncErrorMessageItem:GetAccountErrorUIInfo( _syncService) .messageID]
diff --git a/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_mediator_unittest.mm b/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_mediator_unittest.mm index f602702..bf86550 100644 --- a/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_mediator_unittest.mm +++ b/ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_mediator_unittest.mm
@@ -157,10 +157,9 @@ [FakeSystemIdentity fakeIdentity1]; }; -// Tests that account types for a signed in not syncing account are showing -// correctly. +// Tests that account types for a signed in account are showing correctly. TEST_F(ManageSyncSettingsMediatorTest, - CheckAccountSwitchItemsForSignedInNotSyncingAccount) { + CheckAccountSwitchItemsForSignedInAccount) { CreateManageSyncSettingsMediator(); SimulateFirstSetupSyncOffWithSignedInAccount(); @@ -179,9 +178,9 @@ } // Tests that the sign out item exists in the ManageAndSignOutSectionIdentifier -// for a signed in not syncing account along with manage accounts items. +// for a signed in account along with manage accounts items. TEST_F(ManageSyncSettingsMediatorTest, - CheckSignOutSectionItemsForSignedInNotSyncingAccount) { + CheckSignOutSectionItemsForSignedInAccount) { CreateManageSyncSettingsMediator(); SimulateFirstSetupSyncOffWithSignedInAccount(); @@ -219,9 +218,8 @@ } // Tests that Sync errors display as a text button at the top of the page for a -// signed in not syncing account. -TEST_F(ManageSyncSettingsMediatorTest, - TestSyncErrorsForSignedInNotSyncingAccount) { +// signed in account. +TEST_F(ManageSyncSettingsMediatorTest, TestSyncErrorsForSignedInAccount) { CreateManageSyncSettingsMediator(); SimulateFirstSetupSyncOffWithSignedInAccount(); ON_CALL(*sync_service_mock_, GetUserActionableError())
diff --git a/ios/chrome/browser/settings/ui_bundled/password/password_details/BUILD.gn b/ios/chrome/browser/settings/ui_bundled/password/password_details/BUILD.gn index dfb57fd1..995b82c 100644 --- a/ios/chrome/browser/settings/ui_bundled/password/password_details/BUILD.gn +++ b/ios/chrome/browser/settings/ui_bundled/password/password_details/BUILD.gn
@@ -23,7 +23,6 @@ "//components/autofill/core/common", "//components/password_manager/core/browser:password_switches", "//components/password_manager/core/browser/form_parsing", - "//components/password_manager/core/browser/generation:core", "//components/password_manager/core/common", "//components/prefs", "//components/strings", @@ -97,7 +96,6 @@ "//ios/chrome/browser/settings/ui_bundled/autofill", "//ios/chrome/browser/settings/ui_bundled/cells", "//ios/chrome/browser/settings/ui_bundled/elements:enterprise_info_popover_view_controller", - "//ios/chrome/browser/settings/ui_bundled/password:features", "//ios/chrome/browser/settings/ui_bundled/password:password_constants", "//ios/chrome/browser/settings/ui_bundled/password/password_details/cells", "//ios/chrome/browser/shared/public/commands", @@ -141,7 +139,6 @@ "//components/password_manager/core/browser", "//components/password_manager/core/browser:password_form", "//components/password_manager/core/browser:test_support", - "//components/password_manager/core/browser/generation:core", "//components/sync/base", "//ios/chrome/app/strings", "//ios/chrome/browser/affiliations/model", @@ -149,7 +146,6 @@ "//ios/chrome/browser/passwords/model:store_factory", "//ios/chrome/browser/passwords/model/metrics", "//ios/chrome/browser/settings/ui_bundled/cells", - "//ios/chrome/browser/settings/ui_bundled/password:features", "//ios/chrome/browser/settings/ui_bundled/password/password_details/cells", "//ios/chrome/browser/settings/ui_bundled/password/password_settings:common", "//ios/chrome/browser/settings/ui_bundled/password/password_sharing:password_sharing_metrics",
diff --git a/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_details_consumer.h b/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_details_consumer.h index 130fd84a..085e95b 100644 --- a/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_details_consumer.h +++ b/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_details_consumer.h
@@ -6,7 +6,6 @@ #define IOS_CHROME_BROWSER_SETTINGS_UI_BUNDLED_PASSWORD_PASSWORD_DETAILS_ADD_PASSWORD_DETAILS_CONSUMER_H_ #import <Foundation/Foundation.h> -#import <UIKit/UIKit.h> // Sets the Add Password details for consumer. @protocol AddPasswordDetailsConsumer <NSObject> @@ -19,9 +18,6 @@ // completed. - (void)onDuplicateCheckCompletion:(BOOL)duplicateFound; -// Called when the user presses on tap suggest strong password. -- (void)didTapSuggestStrongPassword:(UIButton*)sender; - @end #endif // IOS_CHROME_BROWSER_SETTINGS_UI_BUNDLED_PASSWORD_PASSWORD_DETAILS_ADD_PASSWORD_DETAILS_CONSUMER_H_
diff --git a/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_mediator.mm b/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_mediator.mm index c2ae4ee..9775676e 100644 --- a/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_mediator.mm +++ b/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_mediator.mm
@@ -17,7 +17,6 @@ #import "base/task/thread_pool.h" #import "components/password_manager/core/browser/features/password_manager_features_util.h" #import "components/password_manager/core/browser/form_parsing/form_data_parser.h" -#import "components/password_manager/core/browser/generation/password_generator.h" #import "components/password_manager/core/browser/password_form.h" #import "components/password_manager/core/browser/password_manager_util.h" #import "components/password_manager/core/browser/password_sync_util.h" @@ -78,11 +77,7 @@ @end -@implementation AddPasswordMediator { - // Stores the last suggested password or nil if no password have - // been suggested. - NSString* _suggestedPassword; -} +@implementation AddPasswordMediator - (instancetype)initWithDelegate:(id<AddPasswordMediatorDelegate>)delegate passwordCheckManager:(IOSChromePasswordCheckManager*)manager @@ -144,7 +139,6 @@ std::string signonRealm = password_manager::GetSignonRealm(self.URL); credential.username = SysNSStringToUTF16(username); credential.password = SysNSStringToUTF16(password); - credential.note = SysNSStringToUTF16(note); credential.stored_in = { password_manager::features_util::IsAccountStorageEnabled(_prefService, @@ -216,19 +210,4 @@ return !base::Contains(hostname, '.'); } -- (BOOL)shouldShowSuggestPasswordItem { - // Only show the field `suggestPasswordItem` to user who are signed in and - // syncing password to their Google Account. - return password_manager::features_util::IsAccountStorageEnabled(_prefService, - _syncService); -} - -- (NSString*)generatePassword { - // The default spec is used to avoiding complicating the user flow. - autofill::PasswordRequirementsSpec defaultSpec; - _suggestedPassword = - base::SysUTF16ToNSString(autofill::GeneratePassword(defaultSpec)); - return _suggestedPassword; -} - @end
diff --git a/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_view_controller.mm b/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_view_controller.mm index 3801b80..bdced43 100644 --- a/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_view_controller.mm +++ b/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_view_controller.mm
@@ -10,20 +10,17 @@ #import "base/metrics/user_metrics_action.h" #import "base/strings/sys_string_conversions.h" #import "components/password_manager/core/browser/password_manager_metrics_util.h" -#import "components/password_manager/core/browser/password_requirements_service.h" #import "components/password_manager/core/common/password_manager_constants.h" #import "ios/chrome/browser/keyboard/ui_bundled/UIKeyCommand+Chrome.h" #import "ios/chrome/browser/settings/ui_bundled/cells/settings_image_detail_text_item.h" #import "ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_view_controller_delegate.h" #import "ios/chrome/browser/settings/ui_bundled/password/password_details/credential_details.h" #import "ios/chrome/browser/settings/ui_bundled/password/password_details/password_details_table_view_constants.h" -#import "ios/chrome/browser/settings/ui_bundled/password/password_manager_ui_features.h" #import "ios/chrome/browser/settings/ui_bundled/password/passwords_table_view_constants.h" #import "ios/chrome/browser/shared/ui/symbols/symbols.h" #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_link_header_footer_item.h" #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_multi_line_text_edit_item.h" #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_multi_line_text_edit_item_delegate.h" -#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_text_button_item.h" #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_text_edit_item.h" #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_text_edit_item_delegate.h" #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_text_item.h" @@ -54,7 +51,6 @@ ItemTypeWebsite = kItemTypeEnumZero, ItemTypeUsername, ItemTypePassword, - ItemTypeSuggestPassword, ItemTypeFooter, ItemTypeNote, ItemTypeDuplicateCredentialButton, @@ -71,57 +67,54 @@ @interface AddPasswordViewController () <TableViewTextEditItemDelegate, TableViewMultiLineTextEditItemDelegate> -// The text item related to the username value. -@property(nonatomic, strong) TableViewTextEditItem* usernameTextItem; +// Whether the password is shown in plain text form or in masked form. +@property(nonatomic, assign, getter=isPasswordShown) BOOL passwordShown; + // The text item related to the site value. @property(nonatomic, strong) TableViewTextEditItem* websiteTextItem; +// The text item related to the username value. +@property(nonatomic, strong) TableViewTextEditItem* usernameTextItem; + +// The text item related to the password value. +@property(nonatomic, strong) TableViewTextEditItem* passwordTextItem; + +// The text item related to the password note value. +@property(nonatomic, strong) TableViewMultiLineTextEditItem* noteTextItem; + +// The view used to anchor error alert which is shown for the username. This is +// image icon in the `usernameTextItem` cell. +@property(nonatomic, weak) UIView* usernameErrorAnchorView; + +// If YES, denotes that the credential with the same website/username +// combination already exists. Used when creating a new credential. +@property(nonatomic, assign) BOOL isDuplicatedCredential; + +// Denotes that the save button in the add credential view can be enabled after +// basic validation of data on all the fields. Does not account for whether the +// duplicate credential exists or not. +@property(nonatomic, assign) BOOL shouldEnableSave; + +// Yes, when the message for top-level domain missing is shown. +@property(nonatomic, assign) BOOL isTLDMissingMessageShown; + +// Yes, when the footer informing about the max note length is shown. +@property(nonatomic, assign) BOOL isNoteFooterShown; + +// Yes, when the note's length is less or equal than +// `password_manager::constants::kMaxPasswordNoteLength`. +@property(nonatomic, assign) BOOL isNoteValid; + +// The account where passwords are being saved to, or nil if passwords are only +// being saved locally. +@property(nonatomic, strong) NSString* accountSavingPasswords; + +// Stores the user current typed password. (Used for testing). +@property(nonatomic, strong) NSString* passwordForTesting; + @end -@implementation AddPasswordViewController { - // Whether the password is shown in plain text form or in masked form. - BOOL _passwordShown; - - // The text item related to the password value. - TableViewTextEditItem* _passwordTextItem; - - // The text item related to the suggest strong password value. - TableViewTextItem* _suggestPasswordTextItem; - - // The text item related to the password note value. - TableViewMultiLineTextEditItem* _noteTextItem; - - // The view used to anchor error alert which is shown for the username. This - // is image icon in the `usernameTextItem` cell. - UIView* _usernameErrorAnchorView; - - // If YES, denotes that the credential with the same website/username - // combination already exists. Used when creating a new credential. - BOOL _isDuplicatedCredential; - - // Denotes that the save button in the add credential view can be enabled - // after - // basic validation of data on all the fields. Does not account for whether - // the duplicate credential exists or not. - BOOL _shouldEnableSave; - - // Yes, when the message for top-level domain missing is shown. - BOOL _isTLDMissingMessageShown; - - // Yes, when the footer informing about the max note length is shown. - BOOL _isNoteFooterShown; - - // Yes, when the note's length is less or equal than - // `password_manager::constants::kMaxPasswordNoteLength`. - BOOL _isNoteValid; - - // The account where passwords are being saved to, or nil if passwords are - // only being saved locally. - NSString* _accountSavingPasswords; - - // Stores the user current typed password. (Used for testing). - NSString* _passwordForTesting; -} +@implementation AddPasswordViewController #pragma mark - ViewController Life Cycle. @@ -187,36 +180,27 @@ TableViewModel* model = self.tableViewModel; - _websiteTextItem = [self websiteItem]; + self.websiteTextItem = [self websiteItem]; [model addSectionWithIdentifier:SectionIdentifierSite]; - [model addItem:_websiteTextItem + [model addItem:self.websiteTextItem toSectionWithIdentifier:SectionIdentifierSite]; [model addSectionWithIdentifier:SectionIdentifierTLDFooter]; [model addSectionWithIdentifier:SectionIdentifierPassword]; - _usernameTextItem = [self usernameItem]; - [model addItem:_usernameTextItem + self.usernameTextItem = [self usernameItem]; + [model addItem:self.usernameTextItem toSectionWithIdentifier:SectionIdentifierPassword]; - _passwordTextItem = [self passwordItem]; - [model addItem:_passwordTextItem + self.passwordTextItem = [self passwordItem]; + [model addItem:self.passwordTextItem toSectionWithIdentifier:SectionIdentifierPassword]; - if (password_manager::features:: - IsSuggestStrongPasswordInAddPasswordEnabled()) { - if ([self.delegate shouldShowSuggestPasswordItem]) { - _suggestPasswordTextItem = [self suggestPasswordItem]; - [model addItem:_suggestPasswordTextItem - toSectionWithIdentifier:SectionIdentifierPassword]; - } - } - - _noteTextItem = [self noteItem]; - [model addItem:_noteTextItem + self.noteTextItem = [self noteItem]; + [model addItem:self.noteTextItem toSectionWithIdentifier:SectionIdentifierPassword]; [model addSectionWithIdentifier:SectionIdentifierNoteFooter]; @@ -293,17 +277,6 @@ return item; } -- (TableViewTextItem*)suggestPasswordItem { - // `TableViewTextItem` was chosen instead of `TableViewTextButtonItem` to - // avoid unwanted padding introduced by UIStackView. - TableViewTextItem* item = - [[TableViewTextItem alloc] initWithType:ItemTypeSuggestPassword]; - item.textColor = [UIColor colorNamed:kBlueColor]; - item.text = l10n_util::GetNSString( - IDS_IOS_CREDENTIAL_PROVIDER_NEW_PASSWORD_SUGGEST_STRONG_PASSWORD); - return item; -} - - (TableViewMultiLineTextEditItem*)noteItem { TableViewMultiLineTextEditItem* item = [[TableViewMultiLineTextEditItem alloc] initWithType:ItemTypeNote]; @@ -326,15 +299,16 @@ - (SettingsImageDetailTextItem*)duplicatePasswordMessageItem { SettingsImageDetailTextItem* item = [[SettingsImageDetailTextItem alloc] initWithType:ItemTypeDuplicateCredentialMessage]; - if (_usernameTextItem && [_usernameTextItem.textFieldValue length] > 0) { + if (self.usernameTextItem && + [self.usernameTextItem.textFieldValue length] > 0) { item.detailText = l10n_util::GetNSStringF( IDS_IOS_SETTINGS_PASSWORDS_DUPLICATE_SECTION_ALERT_DESCRIPTION, - base::SysNSStringToUTF16(_usernameTextItem.textFieldValue), - base::SysNSStringToUTF16(_websiteTextItem.textFieldValue)); + base::SysNSStringToUTF16(self.usernameTextItem.textFieldValue), + base::SysNSStringToUTF16(self.websiteTextItem.textFieldValue)); } else { item.detailText = l10n_util::GetNSStringF( IDS_IOS_SETTINGS_PASSWORDS_DUPLICATE_SECTION_ALERT_DESCRIPTION_WITHOUT_USERNAME, - base::SysNSStringToUTF16(_websiteTextItem.textFieldValue)); + base::SysNSStringToUTF16(self.websiteTextItem.textFieldValue)); } item.image = DefaultSymbolWithPointSize(kErrorCircleFillSymbol, kSymbolSize); item.imageViewTintColor = [UIColor colorNamed:kRedColor]; @@ -357,8 +331,8 @@ [[TableViewLinkHeaderFooterItem alloc] initWithType:ItemTypeFooter]; item.text = l10n_util::GetNSStringF( IDS_IOS_SETTINGS_PASSWORDS_MISSING_TLD_DESCRIPTION, - base::SysNSStringToUTF16( - [_websiteTextItem.textFieldValue stringByAppendingString:@".com"])); + base::SysNSStringToUTF16([self.websiteTextItem.textFieldValue + stringByAppendingString:@".com"])); return item; } @@ -373,10 +347,10 @@ } - (NSString*)footerText { - if (_accountSavingPasswords) { + if (self.accountSavingPasswords) { return l10n_util::GetNSStringF( IDS_IOS_SETTINGS_ADD_PASSWORD_FOOTER_BRANDED, - base::SysNSStringToUTF16(_accountSavingPasswords)); + base::SysNSStringToUTF16(self.accountSavingPasswords)); } return l10n_util::GetNSString(IDS_IOS_SAVE_PASSWORD_FOOTER_NOT_SYNCING); @@ -447,7 +421,7 @@ return 0; } if ((sectionIdentifier == SectionIdentifierPassword && - !_isDuplicatedCredential) || + !self.isDuplicatedCredential) || sectionIdentifier == SectionIdentifierDuplicate) { return 0; } @@ -496,14 +470,6 @@ cell.selectionStyle = UITableViewCellSelectionStyleNone; break; } - case ItemTypeSuggestPassword: { - UITapGestureRecognizer* tapRecognizer = [[UITapGestureRecognizer alloc] - initWithTarget:self - action:@selector(didTapSuggestStrongPassword:)]; - [cell addGestureRecognizer:tapRecognizer]; - cell.accessibilityTraits |= UIAccessibilityTraitButton; - break; - } case ItemTypeDuplicateCredentialMessage: case ItemTypeFooter: break; @@ -535,14 +501,13 @@ } - (void)onDuplicateCheckCompletion:(BOOL)duplicateFound { - if (duplicateFound == _isDuplicatedCredential) { + if (duplicateFound == self.isDuplicatedCredential) { return; } - _isDuplicatedCredential = duplicateFound; + self.isDuplicatedCredential = duplicateFound; [self toggleNavigationBarRightButtonItem]; - - __weak __typeof(self) weakSelf = self; + TableViewModel* model = self.tableViewModel; if (duplicateFound) { password_manager::metrics_util:: LogUserInteractionsWhenAddingCredentialFromSettings( @@ -551,13 +516,38 @@ kDuplicatedCredentialEntered); [self performBatchTableViewUpdates:^{ - [weakSelf updateTableViewWithDuplicatesFound:YES]; + NSUInteger passwordSectionIndex = [self.tableViewModel + sectionForSectionIdentifier:SectionIdentifierPassword]; + [model insertSectionWithIdentifier:SectionIdentifierDuplicate + atIndex:passwordSectionIndex + 1]; + [self.tableView + insertSections:[NSIndexSet + indexSetWithIndex:passwordSectionIndex + 1] + withRowAnimation:UITableViewRowAnimationTop]; + [model addItem:[self duplicatePasswordMessageItem] + toSectionWithIdentifier:SectionIdentifierDuplicate]; + [model addItem:[self duplicatePasswordViewButtonItem] + toSectionWithIdentifier:SectionIdentifierDuplicate]; + if (self.usernameTextItem && + [self.usernameTextItem.textFieldValue length] > 0) { + self.usernameTextItem.hasValidText = NO; + [self reconfigureCellsForItems:@[ self.usernameTextItem ]]; + } else { + self.websiteTextItem.hasValidText = NO; + [self reconfigureCellsForItems:@[ self.websiteTextItem ]]; + } } completion:nil]; } else { [self performBatchTableViewUpdates:^{ - [weakSelf updateTableViewWithDuplicatesFound:NO]; + [self removeSectionWithIdentifier:SectionIdentifierDuplicate + withRowAnimation:UITableViewRowAnimationTop]; + self.usernameTextItem.hasValidText = YES; + self.websiteTextItem.hasValidText = YES; + [self reconfigureCellsForItems:@[ + self.websiteTextItem, self.usernameTextItem + ]]; } completion:nil]; } @@ -567,19 +557,23 @@ - (void)tableViewItemDidBeginEditing:(TableViewTextEditItem*)tableViewItem { [self reconfigureCellsForItems:@[ - _websiteTextItem, _usernameTextItem, _passwordTextItem + self.websiteTextItem, self.usernameTextItem, self.passwordTextItem ]]; } - (void)tableViewItemDidChange:(TableViewTextEditItem*)tableViewItem { - if (tableViewItem == _websiteTextItem) { - [self.delegate setWebsiteURL:_websiteTextItem.textFieldValue]; - if (_isTLDMissingMessageShown) { - _isTLDMissingMessageShown = NO; - __weak __typeof(self) weakSelf = self; + if (tableViewItem == self.websiteTextItem) { + [self.delegate setWebsiteURL:self.websiteTextItem.textFieldValue]; + if (self.isTLDMissingMessageShown) { + self.isTLDMissingMessageShown = NO; [self performBatchTableViewUpdates:^{ - [weakSelf removeTLDFooter]; + [self.tableViewModel setFooter:nil + forSectionWithIdentifier:SectionIdentifierTLDFooter]; + NSUInteger index = [self.tableViewModel + sectionForSectionIdentifier:SectionIdentifierTLDFooter]; + [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:index] + withRowAnimation:UITableViewRowAnimationNone]; } completion:nil]; } @@ -588,44 +582,44 @@ BOOL siteValid = [self checkIfValidSite]; BOOL passwordValid = [self checkIfValidPassword]; - _shouldEnableSave = (siteValid && passwordValid && _isNoteValid); + self.shouldEnableSave = (siteValid && passwordValid && self.isNoteValid); [self toggleNavigationBarRightButtonItem]; - [self.delegate checkForDuplicates:_usernameTextItem.textFieldValue]; + [self.delegate checkForDuplicates:self.usernameTextItem.textFieldValue]; } - (void)tableViewItemDidEndEditing:(TableViewTextEditItem*)tableViewItem { - if (tableViewItem == _websiteTextItem) { - if (!_isDuplicatedCredential) { - _websiteTextItem.hasValidText = [self checkIfValidSite]; + if (tableViewItem == self.websiteTextItem) { + if (!self.isDuplicatedCredential) { + self.websiteTextItem.hasValidText = [self checkIfValidSite]; } - if ([_websiteTextItem.textFieldValue length] > 0 && + if ([self.websiteTextItem.textFieldValue length] > 0 && [self.delegate isTLDMissing]) { [self showTLDMissingSection]; - _websiteTextItem.hasValidText = NO; + self.websiteTextItem.hasValidText = NO; } - [self reconfigureCellsForItems:@[ _websiteTextItem ]]; - } else if (tableViewItem == _usernameTextItem) { - [self reconfigureCellsForItems:@[ _usernameTextItem ]]; - } else if (tableViewItem == _passwordTextItem) { - _passwordTextItem.hasValidText = [self checkIfValidPassword]; - [self reconfigureCellsForItems:@[ _passwordTextItem ]]; + [self reconfigureCellsForItems:@[ self.websiteTextItem ]]; + } else if (tableViewItem == self.usernameTextItem) { + [self reconfigureCellsForItems:@[ self.usernameTextItem ]]; + } else if (tableViewItem == self.passwordTextItem) { + self.passwordTextItem.hasValidText = [self checkIfValidPassword]; + [self reconfigureCellsForItems:@[ self.passwordTextItem ]]; } } #pragma mark - TableViewMultiLineTextEditItemDelegate - (void)textViewItemDidChange:(TableViewMultiLineTextEditItem*)tableViewItem { - DCHECK(tableViewItem == _noteTextItem); + DCHECK(tableViewItem == self.noteTextItem); // Update save button state based on the note's length and validity of other // input fields. BOOL noteValid = tableViewItem.text.length <= kMaxPasswordNoteLength; - if (_isNoteValid != noteValid) { - _isNoteValid = noteValid; + if (self.isNoteValid != noteValid) { + self.isNoteValid = noteValid; tableViewItem.validText = noteValid; - _shouldEnableSave = + self.shouldEnableSave = noteValid && [self checkIfValidSite] && [self checkIfValidPassword]; [self toggleNavigationBarRightButtonItem]; } @@ -642,12 +636,19 @@ // Update note footer based on the note's length. BOOL shouldDisplayNoteFooter = tableViewItem.text.length >= kMinNoteCharAmountForWarning; - if (_isNoteFooterShown != shouldDisplayNoteFooter) { - _isNoteFooterShown = shouldDisplayNoteFooter; - __weak __typeof(self) weakSelf = self; + if (self.isNoteFooterShown != shouldDisplayNoteFooter) { + self.isNoteFooterShown = shouldDisplayNoteFooter; [self performBatchTableViewUpdates:^{ - [weakSelf updateNoteFooterVisibility:shouldDisplayNoteFooter]; + [self.tableViewModel + setFooter:shouldDisplayNoteFooter + ? [self tooLongNoteMessageFooterItem] + : nil + forSectionWithIdentifier:SectionIdentifierNoteFooter]; + NSUInteger index = [self.tableViewModel + sectionForSectionIdentifier:SectionIdentifierNoteFooter]; + [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:index] + withRowAnimation:UITableViewRowAnimationNone]; } completion:nil]; } @@ -668,7 +669,7 @@ // Handles Save button tap on adding new credentials. - (void)didTapSaveButton:(id)sender { - if ([_websiteTextItem.textFieldValue length] > 0 && + if ([self.websiteTextItem.textFieldValue length] > 0 && [self.delegate isTLDMissing]) { [self showTLDMissingSection]; return; @@ -679,20 +680,15 @@ AddCredentialFromSettingsUserInteractions::kCredentialAdded); base::RecordAction( base::UserMetricsAction("MobilePasswordManagerAddPassword")); - if (_noteTextItem.text.length != 0) { + if (self.noteTextItem.text.length != 0) { password_manager::metrics_util::LogPasswordNoteActionInSettings( password_manager::metrics_util::PasswordNoteAction:: kNoteAddedInAddDialog); } - [self.delegate addPasswordViewController:self - didAddPasswordDetails:_usernameTextItem.textFieldValue - password:_passwordTextItem.textFieldValue - note:_noteTextItem.text]; -} -- (void)didTapSuggestStrongPassword:(UIButton*)sender { - _passwordTextItem.textFieldSecureTextEntry = NO; - [_passwordTextItem updateTextFieldValue:[self.delegate generatePassword]]; + didAddPasswordDetails:self.usernameTextItem.textFieldValue + password:self.passwordTextItem.textFieldValue + note:self.noteTextItem.text]; } #pragma mark - SettingsRootTableViewController @@ -714,7 +710,6 @@ case ItemTypeDuplicateCredentialButton: case ItemTypeFooter: case ItemTypeNote: - case ItemTypeSuggestPassword: return NO; }; } @@ -722,20 +717,21 @@ #pragma mark - Private - (BOOL)checkIfValidSite { - BOOL siteEmpty = [_websiteTextItem.textFieldValue length] == 0; - if (!siteEmpty && !_isTLDMissingMessageShown && !_isDuplicatedCredential) { - _websiteTextItem.hasValidText = YES; - [self reconfigureCellsForItems:@[ _websiteTextItem ]]; + BOOL siteEmpty = [self.websiteTextItem.textFieldValue length] == 0; + if (!siteEmpty && !self.isTLDMissingMessageShown && + !self.isDuplicatedCredential) { + self.websiteTextItem.hasValidText = YES; + [self reconfigureCellsForItems:@[ self.websiteTextItem ]]; } return !siteEmpty; } // Checks if the password is valid and updates item accordingly. - (BOOL)checkIfValidPassword { - BOOL passwordEmpty = [_passwordTextItem.textFieldValue length] == 0; + BOOL passwordEmpty = [self.passwordTextItem.textFieldValue length] == 0; if (!passwordEmpty) { - _passwordTextItem.hasValidText = YES; - [self reconfigureCellsForItems:@[ _passwordTextItem ]]; + self.passwordTextItem.hasValidText = YES; + [self reconfigureCellsForItems:@[ self.passwordTextItem ]]; } return !passwordEmpty; @@ -756,123 +752,60 @@ // Enables/Disables the right bar button item in the navigation bar. - (void)toggleNavigationBarRightButtonItem { self.navigationItem.rightBarButtonItem.enabled = - !_isDuplicatedCredential && _shouldEnableSave && - [self.delegate isURLValid] && !_isTLDMissingMessageShown; + !self.isDuplicatedCredential && self.shouldEnableSave && + [self.delegate isURLValid] && !self.isTLDMissingMessageShown; } // Shows the section with the error message for top-level domain missing. - (void)showTLDMissingSection { - if (_isTLDMissingMessageShown) { + if (self.isTLDMissingMessageShown) { return; } self.navigationItem.rightBarButtonItem.enabled = NO; - _isTLDMissingMessageShown = YES; - __weak __typeof(self) weakSelf = self; + self.isTLDMissingMessageShown = YES; [self performBatchTableViewUpdates:^{ - [weakSelf updateTLDMissingSectionCompletion]; + [self.tableViewModel setFooter:[self TLDMessageFooterItem] + forSectionWithIdentifier:SectionIdentifierTLDFooter]; + NSUInteger index = [self.tableViewModel + sectionForSectionIdentifier:SectionIdentifierTLDFooter]; + [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:index] + withRowAnimation:UITableViewRowAnimationNone]; } completion:nil]; } -- (BOOL)isPasswordShown { - return _passwordShown; -} - -// Updates the table view to show the TLD message. -- (void)updateTLDMissingSectionCompletion { - [self.tableViewModel setFooter:[self TLDMessageFooterItem] - forSectionWithIdentifier:SectionIdentifierTLDFooter]; - NSUInteger index = [self.tableViewModel - sectionForSectionIdentifier:SectionIdentifierTLDFooter]; - [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:index] - withRowAnimation:UITableViewRowAnimationNone]; -} - -// Updates the table view based on if a duplicate credentials was found. -- (void)updateTableViewWithDuplicatesFound:(BOOL)duplicateFound { - if (duplicateFound) { - TableViewModel* model = self.tableViewModel; - NSUInteger passwordSectionIndex = [self.tableViewModel - sectionForSectionIdentifier:SectionIdentifierPassword]; - [model insertSectionWithIdentifier:SectionIdentifierDuplicate - atIndex:passwordSectionIndex + 1]; - [self.tableView - insertSections:[NSIndexSet indexSetWithIndex:passwordSectionIndex + 1] - withRowAnimation:UITableViewRowAnimationTop]; - [model addItem:[self duplicatePasswordMessageItem] - toSectionWithIdentifier:SectionIdentifierDuplicate]; - [model addItem:[self duplicatePasswordViewButtonItem] - toSectionWithIdentifier:SectionIdentifierDuplicate]; - if (_usernameTextItem && [_usernameTextItem.textFieldValue length] > 0) { - _usernameTextItem.hasValidText = NO; - [self reconfigureCellsForItems:@[ _usernameTextItem ]]; - return; - } - _websiteTextItem.hasValidText = NO; - [self reconfigureCellsForItems:@[ _websiteTextItem ]]; - return; - } - [self removeSectionWithIdentifier:SectionIdentifierDuplicate - withRowAnimation:UITableViewRowAnimationTop]; - _usernameTextItem.hasValidText = YES; - _websiteTextItem.hasValidText = YES; - [self reconfigureCellsForItems:@[ _websiteTextItem, _usernameTextItem ]]; -} - -// Updates the visibility of the note footer in the table view. -- (void)updateNoteFooterVisibility:(BOOL)shouldDisplayNoteFooter { - [self.tableViewModel setFooter:shouldDisplayNoteFooter - ? [self tooLongNoteMessageFooterItem] - : nil - forSectionWithIdentifier:SectionIdentifierNoteFooter]; - NSUInteger index = [self.tableViewModel - sectionForSectionIdentifier:SectionIdentifierNoteFooter]; - [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:index] - withRowAnimation:UITableViewRowAnimationNone]; -} - -// Removes the footer associated with TLD. -- (void)removeTLDFooter { - [self.tableViewModel setFooter:nil - forSectionWithIdentifier:SectionIdentifierTLDFooter]; - NSUInteger index = [self.tableViewModel - sectionForSectionIdentifier:SectionIdentifierTLDFooter]; - [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:index] - withRowAnimation:UITableViewRowAnimationNone]; -} - #pragma mark - Actions // Called when the user tapped on the show/hide button near password. - (void)didTapShowHideButton:(UIButton*)buttonView { [self.tableView deselectRowAtIndexPath:self.tableView.indexPathForSelectedRow animated:NO]; - if (_passwordShown) { - _passwordShown = NO; - _passwordTextItem.textFieldSecureTextEntry = YES; + if (self.isPasswordShown) { + self.passwordShown = NO; + self.passwordTextItem.textFieldSecureTextEntry = YES; // Only change the textFieldValue for tests. - if (_passwordForTesting) { - _passwordTextItem.textFieldValue = kMaskedPassword; + if (self.passwordForTesting) { + self.passwordTextItem.textFieldValue = kMaskedPassword; } - _passwordTextItem.identifyingIcon = + self.passwordTextItem.identifyingIcon = DefaultSymbolWithPointSize(kShowActionSymbol, kSymbolSize); - _passwordTextItem.identifyingIconAccessibilityLabel = + self.passwordTextItem.identifyingIconAccessibilityLabel = l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_SHOW_BUTTON); - [self reconfigureCellsForItems:@[ _passwordTextItem ]]; + [self reconfigureCellsForItems:@[ self.passwordTextItem ]]; } else { - _passwordTextItem.textFieldSecureTextEntry = NO; - _passwordShown = YES; + self.passwordTextItem.textFieldSecureTextEntry = NO; + self.passwordShown = YES; // Only change the textFieldValue for tests. - if (_passwordForTesting) { - _passwordTextItem.textFieldValue = _passwordForTesting; + if (self.passwordForTesting) { + self.passwordTextItem.textFieldValue = self.passwordForTesting; } - _passwordTextItem.identifyingIcon = + self.passwordTextItem.identifyingIcon = DefaultSymbolWithPointSize(kHideActionSymbol, kSymbolSize); - _passwordTextItem.identifyingIconAccessibilityLabel = + self.passwordTextItem.identifyingIconAccessibilityLabel = l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_HIDE_BUTTON); - [self reconfigureCellsForItems:@[ _passwordTextItem ]]; + [self reconfigureCellsForItems:@[ self.passwordTextItem ]]; } } @@ -895,9 +828,9 @@ secondaryAttributedString:nil]; errorInfoPopover.popoverPresentationController.sourceView = - _usernameErrorAnchorView; + self.usernameErrorAnchorView; errorInfoPopover.popoverPresentationController.sourceRect = - _usernameErrorAnchorView.bounds; + self.usernameErrorAnchorView.bounds; errorInfoPopover.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny; [self presentViewController:errorInfoPopover animated:YES completion:nil]; @@ -907,12 +840,12 @@ - (void)setPassword:(NSString*)password { NSIndexPath* indexPath = - [self.tableViewModel indexPathForItem:_passwordTextItem]; + [self.tableViewModel indexPathForItem:self.passwordTextItem]; TableViewTextEditItem* item = static_cast<TableViewTextEditItem*>( [self.tableViewModel itemAtIndexPath:indexPath]); - _passwordForTesting = password; + self.passwordForTesting = password; item.textFieldValue = [self isPasswordShown] || self.tableView.editing - ? _passwordForTesting + ? self.passwordForTesting : kMaskedPassword; }
diff --git a/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_view_controller_delegate.h b/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_view_controller_delegate.h index e847688d..a8671139 100644 --- a/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_view_controller_delegate.h +++ b/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_view_controller_delegate.h
@@ -36,12 +36,6 @@ // Called to check if the url is missing the top-level domain. - (BOOL)isTLDMissing; -// Returns YES if the suggest strong password field should be shown. -- (BOOL)shouldShowSuggestPasswordItem; - -// Generates a strong password and returns it. -- (NSString*)generatePassword; - @end #endif // IOS_CHROME_BROWSER_SETTINGS_UI_BUNDLED_PASSWORD_PASSWORD_DETAILS_ADD_PASSWORD_VIEW_CONTROLLER_DELEGATE_H_
diff --git a/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_view_controller_unittest.mm b/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_view_controller_unittest.mm index 087dc39..a0d8a5b2 100644 --- a/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_view_controller_unittest.mm +++ b/ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_view_controller_unittest.mm
@@ -11,16 +11,12 @@ #import "base/strings/sys_string_conversions.h" #import "base/strings/utf_string_conversions.h" #import "base/test/metrics/histogram_tester.h" -#import "base/test/scoped_feature_list.h" -#import "components/password_manager/core/browser/generation/password_generator.h" #import "components/password_manager/core/browser/password_form.h" -#import "components/password_manager/core/browser/password_requirements_service.h" #import "components/password_manager/core/browser/ui/credential_ui_entry.h" #import "ios/chrome/browser/settings/ui_bundled/cells/settings_image_detail_text_item.h" #import "ios/chrome/browser/settings/ui_bundled/password/password_details/add_password_view_controller_delegate.h" #import "ios/chrome/browser/settings/ui_bundled/password/password_details/credential_details.h" #import "ios/chrome/browser/settings/ui_bundled/password/password_details/password_details_consumer.h" -#import "ios/chrome/browser/settings/ui_bundled/password/password_manager_ui_features.h" #import "ios/chrome/browser/shared/model/profile/test/test_profile_ios.h" #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_text_edit_item.h" #import "ios/chrome/browser/shared/ui/table_view/legacy_chrome_table_view_controller_test.h" @@ -53,8 +49,6 @@ // Whether `showExistingCredential` was called. @property(nonatomic) BOOL showExistingCredentialCalled; -@property(nonatomic, assign) NSString* suggestedPassword; - @end @implementation FakeAddPasswordDelegate @@ -86,18 +80,6 @@ return NO; } -- (BOOL)shouldShowSuggestPasswordItem { - return YES; -} - -- (NSString*)generatePassword { - // The default spec is used to avoiding complicating the user flow. - autofill::PasswordRequirementsSpec defaultSpec; - self.suggestedPassword = - base::SysUTF16ToNSString(autofill::GeneratePassword(defaultSpec)); - return self.suggestedPassword; -} - @end // Unit tests for PasswordIssuesTableViewController. @@ -254,39 +236,3 @@ // Validate the delegate was asked to show the existing credential. EXPECT_TRUE(delegate_.showExistingCredentialCalled); } - -// Tests for testing suggest strong password. -TEST_F(AddPasswordViewControllerTest, TestSuggestStrongPassword) { - // Enable flag `kSuggestStrongPasswordInAddPassword` for the test. - base::test::ScopedFeatureList scoped_feature_list; - std::vector<base::test::FeatureRef> enabled_features; - enabled_features.push_back( - password_manager::features::kSuggestStrongPasswordInAddPassword); - scoped_feature_list.InitWithFeatures(enabled_features, {}); - - AddPasswordViewController* passwords_controller = - static_cast<AddPasswordViewController*>(controller()); - [passwords_controller loadModel]; - - // Get the password cell. - NSIndexPath* password_index_path = [NSIndexPath indexPathForRow:1 - inSection:2]; - TableViewTextEditItem* password_cell = static_cast<TableViewTextEditItem*>( - GetTableViewItem(password_index_path.section, password_index_path.row)); - EXPECT_TRUE(password_cell); - - password_cell.textFieldValue = @""; - // Verify it's secure text entry initially. - EXPECT_TRUE(password_cell.textFieldSecureTextEntry); - - // Simulate tapping the suggest strong password cell. - [passwords_controller didTapSuggestStrongPassword:nil]; - - // Get the password cell again after suggestion to get the updated value. - NSString* suggested_password_value = password_cell.textFieldValue; - EXPECT_TRUE( - [suggested_password_value isEqualToString:delegate_.suggestedPassword]); - // Should not be masked password anymore. - EXPECT_FALSE(password_cell.textFieldSecureTextEntry); - EXPECT_FALSE([suggested_password_value isEqualToString:kMaskedPassword]); -}
diff --git a/ios/chrome/browser/settings/ui_bundled/settings_table_view_controller.mm b/ios/chrome/browser/settings/ui_bundled/settings_table_view_controller.mm index 5e90f57..ae019c3 100644 --- a/ios/chrome/browser/settings/ui_bundled/settings_table_view_controller.mm +++ b/ios/chrome/browser/settings/ui_bundled/settings_table_view_controller.mm
@@ -640,8 +640,7 @@ _hasRecordedSigninImpression = YES; } - // The user is signed-in and syncing, exit early since the promo is not - // required. + // The user is signed-in, exit early since the promo is not required. return; } @@ -1946,7 +1945,7 @@ // 5.) Not have their Safe Browsing preferences enterprise-managed. AuthenticationService* authService = AuthenticationServiceFactory::GetForProfile(_profile); - bool isSignedInAndSynced = + bool isSignedIn = authService->HasPrimaryIdentity(signin::ConsentLevel::kSignin); bool isDefaultBrowser = IsChromeLikelyDefaultBrowser(); bool isStandardProtectionEnabled = @@ -1957,9 +1956,8 @@ bool isEnterpriseManaged = safe_browsing::IsSafeBrowsingPolicyManaged(*_profile->GetPrefs()); - if (!isSignedInAndSynced || !isDefaultBrowser || - !isStandardProtectionEnabled || !triggerCriteriaMet || - isEnterpriseManaged) { + if (!isSignedIn || !isDefaultBrowser || !isStandardProtectionEnabled || + !triggerCriteriaMet || isEnterpriseManaged) { return NO; }
diff --git a/ios/chrome/browser/shared/ui/table_view/cells/table_view_text_edit_item.h b/ios/chrome/browser/shared/ui/table_view/cells/table_view_text_edit_item.h index eefdd00d..29c4c1b5f 100644 --- a/ios/chrome/browser/shared/ui/table_view/cells/table_view_text_edit_item.h +++ b/ios/chrome/browser/shared/ui/table_view/cells/table_view_text_edit_item.h
@@ -87,9 +87,6 @@ // Whether the aspect of the cell should mark the text as valid. - (void)setHasValidText:(BOOL)hasValidText; -// Updates the text field value and refreshes the cell. -- (void)updateTextFieldValue:(NSString*)textFieldValue; - @end // TableViewTextEditCell implements an TableViewCell subclass containing a label
diff --git a/ios/chrome/browser/shared/ui/table_view/cells/table_view_text_edit_item.mm b/ios/chrome/browser/shared/ui/table_view/cells/table_view_text_edit_item.mm index e572a911..ca0e765 100644 --- a/ios/chrome/browser/shared/ui/table_view/cells/table_view_text_edit_item.mm +++ b/ios/chrome/browser/shared/ui/table_view/cells/table_view_text_edit_item.mm
@@ -151,7 +151,8 @@ #pragma mark Actions - (void)textFieldChanged:(UITextField*)textField { - [self updateTextFieldValue:textField.text]; + self.textFieldValue = textField.text; + [self.delegate tableViewItemDidChange:self]; } - (void)textFieldBeginEditing:(UITextField*)textField { @@ -171,11 +172,6 @@ _hasValidText = hasValidText; } -- (void)updateTextFieldValue:(NSString*)textFieldValue { - _textFieldValue = textFieldValue; - [self.delegate tableViewItemDidChange:self]; -} - @end #pragma mark - TableViewTextEditCell
diff --git a/ios/chrome/browser/webui/ui_bundled/version_ui.mm b/ios/chrome/browser/webui/ui_bundled/version_ui.mm index 1866814..2e28ef58 100644 --- a/ios/chrome/browser/webui/ui_bundled/version_ui.mm +++ b/ios/chrome/browser/webui/ui_bundled/version_ui.mm
@@ -53,6 +53,9 @@ html_source->AddString(version_ui::kOSType, std::string(version_info::GetOSType())); + // Always empty on iOS. + html_source->AddString(version_ui::kVersionSuffix, std::string()); + html_source->AddLocalizedString(version_ui::kCompany, IDS_IOS_ABOUT_VERSION_COMPANY_NAME); html_source->AddLocalizedString(version_ui::kCopyLabel,
diff --git a/ios/chrome/test/app/signin_test_util.h b/ios/chrome/test/app/signin_test_util.h index 1bdcefc..4cee496 100644 --- a/ios/chrome/test/app/signin_test_util.h +++ b/ios/chrome/test/app/signin_test_util.h
@@ -32,9 +32,8 @@ // and resets kIosBookmarkPromoAlreadySeen flag for bookmarks. void ResetSigninPromoPreferences(); -// Revokes the Sync consent of the primary account. The user will be in the -// signed-in state. -void SignInWithoutSync(id<SystemIdentity> identity); +// The user will be in the signed-in state. +void SignIn(id<SystemIdentity> identity); // Resets all preferences related to History Sync Opt-In. void ResetHistorySyncPreferencesForTesting();
diff --git a/ios/chrome/test/app/signin_test_util.mm b/ios/chrome/test/app/signin_test_util.mm index a1457a5..47c5829 100644 --- a/ios/chrome/test/app/signin_test_util.mm +++ b/ios/chrome/test/app/signin_test_util.mm
@@ -154,7 +154,7 @@ prefs->SetBoolean(prefs::kSigninShouldPromptForSigninAgain, false); } -void SignInWithoutSync(id<SystemIdentity> identity) { +void SignIn(id<SystemIdentity> identity) { Browser* browser = GetMainBrowser(); UIViewController* viewController = GetActiveViewController(); __block AuthenticationFlow* authenticationFlow = [[AuthenticationFlow alloc]
diff --git a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1 index 99670b3..8799903 100644 --- a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -ee4c593e361744e5abe7dddddb2725ead3f9c37b \ No newline at end of file +ec0a091bbdb49200a64162e8fc93fbd15cccd3e3 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1 b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1 index 3d318c07..47961f1 100644 --- a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1
@@ -1 +1 @@ -c12674289c62a567429c6e49b3a7f1f90de8dc76 \ No newline at end of file +1dee4211ab663df4143e82b5ba27c4b78693c61a \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 index 7213fbe3..b8867fc 100644 --- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -67835014c04ad4f5a25ed515dabb3f5a6cbf1a98 \ No newline at end of file +b7b4044d674fdbade0eeddbf458f4dfd21869de7 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1 index 5f4164d..5334795 100644 --- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1
@@ -1 +1 @@ -50df0a2376214bb6f8ec16d5ec3f994fd874dd78 \ No newline at end of file +1938e60f321e5d0af07e3f11d10a5a56059f7050 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 index cdc552e..ce1b556 100644 --- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -0d4f33b2de293fc26f588ddaf7b4bb3c20920681 \ No newline at end of file +c6c73d4a6724170d9b9eaee21367bbd55252b37a \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1 index 9f45005..2c1cafc 100644 --- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1
@@ -1 +1 @@ -3cb869fc852b2ec9c2dc110c1d037b5555540512 \ No newline at end of file +21934e789303c89997df253d436234a1be6deb89 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1 index 698ca489..381619f 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -a8685e9a5c3a507c449653f765808399b660588c \ No newline at end of file +d901610afad3b50638eb159eeb3afe74158a6852 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1 index 1f3fe22..c65121b 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -dfb6fd6b7cc340c5a04e5368f6df58da4a68767c \ No newline at end of file +49c518b9cc2d9ee8b282bb7c0499f410c23d47de \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1 index 36742b2..15e8bdb 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -0b1679139488e0192dd81ab00c12f67cb8e5c6c2 \ No newline at end of file +864c816ae2abb44645803db105305569080e2bc8 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1 index 357b3cc..cf8afbd 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -13bf3d9093222c20fa56cdb6bd17e06717dd3962 \ No newline at end of file +8623688661fabdeaaf85c8caf7cfe1a5c4f40972 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 index 0844b0cf..41008922 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -19796fd19cce4447700a7db0eb1be529360dc2cb \ No newline at end of file +15df9359d1495c76e5f339867b2245d4d1c26dc9 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1 index c0571f3..222f3d2 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -4584fe0e1b04d7f439af59e492220cbe9275dd4e \ No newline at end of file +eab4788731204cdefadbbea61e08466591465c10 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 index 466a9692..cb91ca26 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -11464058fff988b5871b5bbd13e46d71edff3f19 \ No newline at end of file +a5b2ad34cccb75be03539d1df4114a71d3817f57 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1 index 25072f5..e7404ee 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -a27166e2ea3c15c0309fbb97bcf66389f6395ea3 \ No newline at end of file +9f116aaebdc4d1ceef80417a73252ee2df99e60a \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 index ebf23fb..bca22b9 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -f7cdc8ea1c7d18a80aa0941bbee1696566e840cb \ No newline at end of file +9ee28bbaa19cab8eecfa90aad66d04f7b4a0590b \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1 index a969be8..f497db37 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -be35e25b644bae9b5c329404349983f10c7d2a50 \ No newline at end of file +297e40e057208d3cdcda533954990808acef94c4 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 index 36c0e68..309f4216 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -c0d035847c3da73915140dbfd6e946a43ead64cf \ No newline at end of file +24f8b5faa0afe232e3cbe8886c4b53cf2123bd99 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1 index 9414bb92..0b3d0ff 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -0a257aaef27ee37d6dd007481802c751e54aadf5 \ No newline at end of file +3611ae7fbcd68fbc194a32315a1e4df14a83286a \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 index 11d6a654..933bb9d 100644 --- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -53469b5f8510ff5a885e36648e1c5c273cd582c7 \ No newline at end of file +d917a120e2ffc060c1c60a994fb629a41714ea02 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 index 277960f1..0cfd29e 100644 --- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -e0bd1ee5a12ce6c35594913d7f348385ecdf767f \ No newline at end of file +6b04e1832c5fbc2cd8f9283044e52928faec294c \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 index 82864fd8..344806a 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -e5dbdbd044a35180905d5d03683ee1ec57d681ae \ No newline at end of file +4a287182cfef0d417030c3698c2b9811abce1838 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1 index 223402e6..cc143d99 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -b3fd2387d0f0a28c1e8943df8b2c5210453ca8c7 \ No newline at end of file +30aeef8ef2b824cc89453f1677304896283ff888 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 index c83961b..8460af16 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -c10690ef4a578506b9bee4c922a90fb3b0c019f9 \ No newline at end of file +e68982a57fc5bd03aaef58cff5a689e887c243b2 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1 index 7513429..99f2d12 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -8b74e22dd36aed95a0512f20cd6ca68b70125a82 \ No newline at end of file +931b35157cdafaedafbc10dd782bab6c603f109b \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 index 75d6b56..34772419 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -718d632aa23a8b127b78c1d3d920abe57330cf5c \ No newline at end of file +705b8c8d53df191098a252967fb0500ea2c79641 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1 index 7066b0d9..cfbad557 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -71afe03bb3f2648f290175b7cad7ed0855e21f4e \ No newline at end of file +621a8909ee0dde6626cda50e5e7d1b0af47698cd \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 index 0738417..36930d7 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -e714cdc01df8ac0a8a4df173c22f018b7ded47d9 \ No newline at end of file +512a292af1cfedb14ee470c81cdefc10d9544d6a \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1 index 7832669..37568201d 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -16aebe5befff603a49344c9cb0ff4a2931ae2471 \ No newline at end of file +590bc9009878691db3df73eb2f45ecb47189d140 \ No newline at end of file
diff --git a/media/base/limits.h b/media/base/limits.h index 7d19868..ae264335 100644 --- a/media/base/limits.h +++ b/media/base/limits.h
@@ -78,7 +78,8 @@ inline constexpr int kMaxAudioBufferSize = 8192; #endif -// Maximum buffer size supported by Web Audio. +// Minimum and maximum buffer size supported by Web Audio. +inline constexpr int kMinWebAudioBufferSize = 128; inline constexpr int kMaxWebAudioBufferSize = 8192; // Bounds for the number of threads used for software video decoding.
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 5e9e942..9e17b954 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -769,7 +769,7 @@ // Enable AV1 temporal layer encoding with HW encoder on ChromeOS. BASE_FEATURE(kVaapiAV1TemporalLayerHWEncoding, "VaapiAv1TemporalLayerEncoding", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); // Enable VP9 S-mode encoding with HW encoder for webrtc use case on ChromeOS. BASE_FEATURE(kVaapiVp9SModeHWEncoding, "VaapiVp9SModeHWEncoding",
diff --git a/media/gpu/test/video_encoder/video_encoder_test_environment.cc b/media/gpu/test/video_encoder/video_encoder_test_environment.cc index 64b8f13..bd1fecc 100644 --- a/media/gpu/test/video_encoder/video_encoder_test_environment.cc +++ b/media/gpu/test/video_encoder/video_encoder_test_environment.cc
@@ -294,11 +294,6 @@ media::kVaapiEnforceVideoMinMaxResolution); #endif -#if defined(ARCH_CPU_X86_FAMILY) && BUILDFLAG(IS_CHROMEOS) - // TODO(b/378401081): remove once enabled by default. - combined_enabled_features.push_back(media::kVaapiAV1TemporalLayerHWEncoding); -#endif - #if BUILDFLAG(IS_LINUX) && BUILDFLAG(USE_VAAPI) combined_enabled_features.push_back(media::kAcceleratedVideoEncodeLinux); #endif
diff --git a/media/gpu/windows/d3d12_video_encode_h264_delegate.cc b/media/gpu/windows/d3d12_video_encode_h264_delegate.cc index e0a04b14..fcff44d 100644 --- a/media/gpu/windows/d3d12_video_encode_h264_delegate.cc +++ b/media/gpu/windows/d3d12_video_encode_h264_delegate.cc
@@ -381,9 +381,11 @@ ? H264LevelIDCToD3D12VideoEncoderLevelsH264( config.h264_output_level.value()) : suggested_level; - if (h264_level_ >= D3D12_VIDEO_ENCODER_LEVELS_H264_3 && - config_support_h264.SupportFlags & - D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_H264_FLAG_ADAPTIVE_8x8_TRANSFORM_ENCODING_SUPPORT) { + // According to H.264 spec Annex A.2, only for high profile and above, that we + // can support adaptive 8x8 transform. + if (h264_profile_ >= D3D12_VIDEO_ENCODER_PROFILE_H264_HIGH && + (config_support_h264.SupportFlags & + D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_SUPPORT_H264_FLAG_ADAPTIVE_8x8_TRANSFORM_ENCODING_SUPPORT)) { codec_config_h264_.ConfigurationFlags |= D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_FLAG_USE_ADAPTIVE_8x8_TRANSFORM; } @@ -470,10 +472,11 @@ sps.pic_height_in_map_units_minus1 = (input_size_.Height + kMbSize - 1) / kMbSize - 1; sps.frame_mbs_only_flag = true; - sps.direct_8x8_inference_flag = static_cast<bool>( - codec_config_h264_.ConfigurationFlags & - D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_FLAG_USE_ADAPTIVE_8x8_TRANSFORM); - CHECK(sps.frame_mbs_only_flag || sps.direct_8x8_inference_flag); + // According to H.264 spec Table A-4, for level 3.0 and higher, + // direct_8x8_inference_flag should be equal to 1 for profiles that allow + // B-Frame. + sps.direct_8x8_inference_flag = + h264_level_ >= D3D12_VIDEO_ENCODER_LEVELS_H264_3; if (input_size_.Width % kMbSize != 0 || input_size_.Height % kMbSize != 0) { // Spec 7.4.2.1.1. Crop is in crop units, which is 2 pixels for 4:2:0. const int kCropUnitX = 2; @@ -504,7 +507,9 @@ // We don't use // D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_FLAG_USE_CONSTRAINED_INTRAPREDICTION // yet. So let constrained_intra_pred_flag be false by default. - pps.transform_8x8_mode_flag = sps.direct_8x8_inference_flag; + pps.transform_8x8_mode_flag = static_cast<bool>( + codec_config_h264_.ConfigurationFlags & + D3D12_VIDEO_ENCODER_CODEC_CONFIGURATION_H264_FLAG_USE_ADAPTIVE_8x8_TRANSFORM); return pps; }
diff --git a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc index 1d5e5602..273cb448 100644 --- a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc +++ b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
@@ -484,6 +484,14 @@ encoder_info_.requested_resolution_alignment = 2; encoder_info_.apply_alignment_to_all_simulcast_layers = true; encoder_info_.has_trusted_rate_controller = false; + if (codec_ == VideoCodec::kHEVC && vendor_ == DriverVendor::kIntel) { + // On Intel HEVC we trust the rate controller based on manual testing and + // because trusting it produces better results than not trusting it when + // track frame rate suddenly drops, this avoids encoder FPS dropping even + // more than the track FPS dropped, see https://crbug.com/402910373. This + // risks overshooting but that seems like less of a concern on Intel. + encoder_info_.has_trusted_rate_controller = true; + } DCHECK(encoder_info_.is_hardware_accelerated); DCHECK(encoder_info_.supports_native_handle); DCHECK(encoder_info_.reports_average_qp);
diff --git a/mojo/public/tools/bindings/mojom.gni b/mojo/public/tools/bindings/mojom.gni index 43bdbe7..dd2b928 100644 --- a/mojo/public/tools/bindings/mojom.gni +++ b/mojo/public/tools/bindings/mojom.gni
@@ -86,14 +86,10 @@ # ARC) we have to explicitly opt out there even when NaCl is enabled (and # consequently also when building for NaCl toolchains.) For this reason we # check |target_os| explicitly, as it's consistent across all toolchains. -# -# TODO(crbug.com/40118868): Remove !chromeos_is_browser_only once -# lacros-chrome switches to target_os="chromeos" enable_scrambled_message_ids = enable_mojom_message_id_scrambling && (is_mac || is_win || (is_linux && !is_castos) || - ((enable_nacl || is_nacl) && - (target_os != "chromeos" && !chromeos_is_browser_only))) + ((enable_nacl || is_nacl) && target_os != "chromeos")) _mojom_tools_root = "//mojo/public/tools" _mojom_library_root = "$_mojom_tools_root/mojom/mojom"
diff --git a/net/BUILD.gn b/net/BUILD.gn index 77c8845c..9b70bea 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -214,6 +214,8 @@ "base/load_states_list.h", "base/load_timing_info.cc", "base/load_timing_info.h", + "base/load_timing_internal_info.cc", + "base/load_timing_internal_info.h", "base/logging_network_change_observer.cc", "base/logging_network_change_observer.h", "base/lookup_string_in_fixed_set.cc",
diff --git a/net/base/load_timing_internal_info.cc b/net/base/load_timing_internal_info.cc new file mode 100644 index 0000000..900fe8c --- /dev/null +++ b/net/base/load_timing_internal_info.cc
@@ -0,0 +1,16 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/base/load_timing_internal_info.h" + +namespace net { + +LoadTimingInternalInfo::LoadTimingInternalInfo() = default; +LoadTimingInternalInfo::LoadTimingInternalInfo( + const LoadTimingInternalInfo& other) = default; +LoadTimingInternalInfo::~LoadTimingInternalInfo() = default; +bool LoadTimingInternalInfo::operator==( + const LoadTimingInternalInfo& other) const = default; + +} // namespace net
diff --git a/net/base/load_timing_internal_info.h b/net/base/load_timing_internal_info.h new file mode 100644 index 0000000..6680872e --- /dev/null +++ b/net/base/load_timing_internal_info.h
@@ -0,0 +1,31 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_BASE_LOAD_TIMING_INTERNAL_INFO_H_ +#define NET_BASE_LOAD_TIMING_INTERNAL_INFO_H_ + +#include <stdint.h> + +#include "base/time/time.h" +#include "net/base/net_export.h" + +namespace net { + +// Structure containing internal load timing information. This is similar to +// LoadTimingInfo, but contains extra information which shouldn't be exposed to +// the web. We use this structure for internal measurements. +struct NET_EXPORT LoadTimingInternalInfo { + LoadTimingInternalInfo(); + LoadTimingInternalInfo(const LoadTimingInternalInfo& other); + bool operator==(const LoadTimingInternalInfo& other) const; + ~LoadTimingInternalInfo(); + + // The time taken for HTTP stream initialization to finish if the + // initialization was blocked. + base::TimeDelta initialize_stream_delay; +}; + +} // namespace net + +#endif // NET_BASE_LOAD_TIMING_INTERNAL_INFO_H_
diff --git a/net/data/ssl/chrome_root_store/BUILD.gn b/net/data/ssl/chrome_root_store/BUILD.gn index 985b93a3..d782e4f 100644 --- a/net/data/ssl/chrome_root_store/BUILD.gn +++ b/net/data/ssl/chrome_root_store/BUILD.gn
@@ -18,6 +18,7 @@ args = [ "--root-store=" + rebase_path("root_store.textproto", root_build_dir), "--certs=" + rebase_path("root_store.certs", root_build_dir), + "--additional-certs=" + rebase_path("additional.certs", root_build_dir), "--write-cpp-root-store=" + rebase_path("${target_gen_dir}/chrome-root-store-inc.cc", root_build_dir),
diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc index 52169e7a..ae31aa9b 100644 --- a/net/http/http_cache_transaction.cc +++ b/net/http/http_cache_transaction.cc
@@ -565,6 +565,14 @@ return true; } +void HttpCache::Transaction::PopulateLoadTimingInternalInfo( + LoadTimingInternalInfo* load_timing_internal_info) const { + const HttpTransaction* transaction = GetOwnedOrMovedNetworkTransaction(); + if (transaction) { + transaction->PopulateLoadTimingInternalInfo(load_timing_internal_info); + } +} + bool HttpCache::Transaction::GetRemoteEndpoint(IPEndPoint* endpoint) const { const HttpTransaction* transaction = GetOwnedOrMovedNetworkTransaction(); if (transaction) {
diff --git a/net/http/http_cache_transaction.h b/net/http/http_cache_transaction.h index 9d422c6c..fe30b69 100644 --- a/net/http/http_cache_transaction.h +++ b/net/http/http_cache_transaction.h
@@ -152,6 +152,8 @@ LoadState GetLoadState() const override; void SetQuicServerInfo(QuicServerInfo* quic_server_info) override; bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; + void PopulateLoadTimingInternalInfo( + LoadTimingInternalInfo* load_timing_internal_info) const override; bool GetRemoteEndpoint(IPEndPoint* endpoint) const override; void PopulateNetErrorDetails(NetErrorDetails* details) const override; void SetPriority(RequestPriority priority) override;
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 0fe83e3..f5bc52d 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc
@@ -31,6 +31,7 @@ #include "net/base/io_buffer.h" #include "net/base/load_flags.h" #include "net/base/load_timing_info.h" +#include "net/base/load_timing_internal_info.h" #include "net/base/net_errors.h" #include "net/base/proxy_chain.h" #include "net/base/proxy_server.h" @@ -560,6 +561,16 @@ return true; } +void HttpNetworkTransaction::PopulateLoadTimingInternalInfo( + LoadTimingInternalInfo* load_timing_internal_info) const { + if (!initialize_stream_start_time_.is_null() && + !initialize_stream_end_time_.is_null()) { + CHECK_LE(initialize_stream_start_time_, initialize_stream_end_time_); + load_timing_internal_info->initialize_stream_delay = + initialize_stream_end_time_ - initialize_stream_start_time_; + } +} + bool HttpNetworkTransaction::GetRemoteEndpoint(IPEndPoint* endpoint) const { if (remote_endpoint_.address().empty()) return false; @@ -1009,7 +1020,7 @@ NetLogWithSourceToFlow(net_log_)); next_state_ = STATE_INIT_STREAM_COMPLETE; - base::TimeTicks now = base::TimeTicks::Now(); + initialize_stream_start_time_ = base::TimeTicks::Now(); int rv = stream_->InitializeStream(can_send_early_data_, priority_, net_log_, io_callback_); @@ -1017,7 +1028,7 @@ // completes. bool blocked = rv == ERR_IO_PENDING; if (blocked) { - blocked_initialize_stream_start_time_ = now; + blocked_initialize_stream_start_time_ = initialize_stream_start_time_; } base::UmaHistogramBoolean( base::StrCat({"Net.NetworkTransaction.InitializeStreamBlocked", @@ -1030,6 +1041,8 @@ int HttpNetworkTransaction::DoInitStreamComplete(int result) { TRACE_EVENT("net", "HttpNetworkTransaction::InitStreamComplete", NetLogWithSourceToFlow(net_log_), "result", result); + initialize_stream_end_time_ = base::TimeTicks::Now(); + // TODO(crbug.com/359404121): Remove this histogram after the investigation // completes. if (!blocked_initialize_stream_start_time_.is_null()) { @@ -1038,7 +1051,7 @@ {"Net.NetworkTransaction.InitializeStreamBlockTime", IsGoogleHostWithAlpnH3(url_.host()) ? "GoogleHost." : ".", NegotiatedProtocolToHistogramSuffix(negotiated_protocol_)}), - base::TimeTicks::Now() - blocked_initialize_stream_start_time_); + initialize_stream_end_time_ - blocked_initialize_stream_start_time_); } if (result != OK) {
diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h index fc959c73..1e2c86c 100644 --- a/net/http/http_network_transaction.h +++ b/net/http/http_network_transaction.h
@@ -85,6 +85,8 @@ LoadState GetLoadState() const override; void SetQuicServerInfo(QuicServerInfo* quic_server_info) override; bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; + void PopulateLoadTimingInternalInfo( + LoadTimingInternalInfo* load_timing_internal_info) const override; bool GetRemoteEndpoint(IPEndPoint* endpoint) const override; void PopulateNetErrorDetails(NetErrorDetails* details) const override; void SetPriority(RequestPriority priority) override; @@ -523,6 +525,10 @@ base::TimeTicks dns_resolution_start_time_override_; base::TimeTicks dns_resolution_end_time_override_; + // The time at which initialize stream started / ended. + base::TimeTicks initialize_stream_start_time_; + base::TimeTicks initialize_stream_end_time_; + base::TimeTicks blocked_initialize_stream_start_time_; base::TimeTicks blocked_generate_proxy_auth_token_start_time_; base::TimeTicks blocked_generate_server_auth_token_start_time_;
diff --git a/net/http/http_transaction.h b/net/http/http_transaction.h index bedbeb0..9fbc435 100644 --- a/net/http/http_transaction.h +++ b/net/http/http_transaction.h
@@ -27,6 +27,7 @@ class IOBuffer; struct TransportInfo; struct LoadTimingInfo; +struct LoadTimingInternalInfo; class NetLogWithSource; class QuicServerInfo; class SSLPrivateKey; @@ -175,6 +176,10 @@ // provide. virtual bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const = 0; + // Populates load timing internal info. + virtual void PopulateLoadTimingInternalInfo( + LoadTimingInternalInfo* load_timing_internal_info) const = 0; + // Gets the remote endpoint of the socket that the transaction's underlying // stream is using or did use, if any. Returns true and fills in |endpoint| // if it is available; returns false and leaves |endpoint| unchanged if it is
diff --git a/net/http/http_transaction_test_util.cc b/net/http/http_transaction_test_util.cc index fe14ec82..394b6a5 100644 --- a/net/http/http_transaction_test_util.cc +++ b/net/http/http_transaction_test_util.cc
@@ -25,6 +25,7 @@ #include "net/base/ip_endpoint.h" #include "net/base/load_flags.h" #include "net/base/load_timing_info.h" +#include "net/base/load_timing_internal_info.h" #include "net/base/net_errors.h" #include "net/base/network_isolation_key.h" #include "net/base/proxy_chain.h" @@ -487,6 +488,11 @@ return true; } +void MockNetworkTransaction::PopulateLoadTimingInternalInfo( + LoadTimingInternalInfo* load_timing_internal_info) const { + load_timing_internal_info->initialize_stream_delay = base::TimeDelta(); +} + bool MockNetworkTransaction::GetRemoteEndpoint(IPEndPoint* endpoint) const { *endpoint = IPEndPoint(IPAddress(127, 0, 0, 1), 80); return true;
diff --git a/net/http/http_transaction_test_util.h b/net/http/http_transaction_test_util.h index 55a0b03a..5368f617 100644 --- a/net/http/http_transaction_test_util.h +++ b/net/http/http_transaction_test_util.h
@@ -227,6 +227,9 @@ bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; + void PopulateLoadTimingInternalInfo( + LoadTimingInternalInfo* load_timing_internal_info) const override; + bool GetRemoteEndpoint(IPEndPoint* endpoint) const override; void SetPriority(RequestPriority priority) override;
diff --git a/net/shared_dictionary/shared_dictionary_network_transaction.cc b/net/shared_dictionary/shared_dictionary_network_transaction.cc index 279735a..1262d88 100644 --- a/net/shared_dictionary/shared_dictionary_network_transaction.cc +++ b/net/shared_dictionary/shared_dictionary_network_transaction.cc
@@ -433,6 +433,12 @@ return network_transaction_->GetLoadTimingInfo(load_timing_info); } +void SharedDictionaryNetworkTransaction::PopulateLoadTimingInternalInfo( + LoadTimingInternalInfo* load_timing_internal_info) const { + network_transaction_->PopulateLoadTimingInternalInfo( + load_timing_internal_info); +} + bool SharedDictionaryNetworkTransaction::GetRemoteEndpoint( IPEndPoint* endpoint) const { return network_transaction_->GetRemoteEndpoint(endpoint);
diff --git a/net/shared_dictionary/shared_dictionary_network_transaction.h b/net/shared_dictionary/shared_dictionary_network_transaction.h index 9f074a9..18332b7a 100644 --- a/net/shared_dictionary/shared_dictionary_network_transaction.h +++ b/net/shared_dictionary/shared_dictionary_network_transaction.h
@@ -25,6 +25,7 @@ namespace net { class SharedDictionary; class SourceStream; +struct LoadTimingInternalInfo; struct TransportInfo; // A `HttpTransaction` that decodes shared dictionary compression. @@ -75,6 +76,8 @@ LoadState GetLoadState() const override; void SetQuicServerInfo(QuicServerInfo* quic_server_info) override; bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; + void PopulateLoadTimingInternalInfo( + LoadTimingInternalInfo* load_timing_internal_info) const override; bool GetRemoteEndpoint(IPEndPoint* endpoint) const override; void PopulateNetErrorDetails(NetErrorDetails* details) const override; void SetPriority(RequestPriority priority) override;
diff --git a/net/third_party/quiche/src b/net/third_party/quiche/src index ac4ab42..feba540 160000 --- a/net/third_party/quiche/src +++ b/net/third_party/quiche/src
@@ -1 +1 @@ -Subproject commit ac4ab4297cbdcc10183a2c8d2ab4fd92fbc8fc70 +Subproject commit feba5402d20fa4f51c8f7e29ad6f031a650f485a
diff --git a/net/tools/root_store_tool/root_store_tool.cc b/net/tools/root_store_tool/root_store_tool.cc index d8e7204a..11b5692 100644 --- a/net/tools/root_store_tool/root_store_tool.cc +++ b/net/tools/root_store_tool/root_store_tool.cc
@@ -39,6 +39,7 @@ #include "third_party/protobuf/src/google/protobuf/text_format.h" using chrome_root_store::RootStore; +using chrome_root_store::TrustAnchor; namespace { @@ -85,9 +86,59 @@ return std::move(certs); } +// ReplaceTrustAnchors takes a repeated trust_anchors field from a proto and +// replaces certs identified by a SHA-256 hash with the full cert bytes, using +// the file found at certs_file_path to provide the full cert bytes. +bool ReplaceTrustAnchors( + google::protobuf::RepeatedPtrField<TrustAnchor>* trust_anchors, + const base::FilePath& certs_file_path) { + std::map<std::string, std::string> certs; + if (!certs_file_path.empty()) { + std::string certs_data; + if (!base::ReadFileToString(base::MakeAbsoluteFilePath(certs_file_path), + &certs_data)) { + LOG(ERROR) << "Could not read " << certs_file_path; + return false; + } + auto certs_opt = DecodeCerts(certs_data); + if (!certs_opt) { + LOG(ERROR) << "Could not decode " << certs_file_path; + return false; + } + certs = std::move(*certs_opt); + } + + // Replace the filenames with the actual certificate contents. + for (auto& anchor : *trust_anchors) { + if (anchor.certificate_case() != + chrome_root_store::TrustAnchor::kSha256Hex) { + continue; + } + + auto iter = certs.find(anchor.sha256_hex()); + if (iter == certs.end()) { + LOG(ERROR) << "Could not find certificate " << anchor.sha256_hex(); + return false; + } + + // Remove the certificate from `certs`. This both checks for duplicate + // certificates and allows us to check for unused certificates later. + anchor.set_der(std::move(iter->second)); + certs.erase(iter); + } + + if (!certs.empty()) { + LOG(ERROR) << "Unused certificate (SHA-256 hash " << certs.begin()->first + << ") in " << certs_file_path; + return false; + } + return true; +} + std::optional<RootStore> ReadTextRootStore( const base::FilePath& root_store_path, - const base::FilePath& certs_path) { + const base::FilePath& certs_path, + const base::FilePath& additional_certs_path) { std::string root_store_text; if (!base::ReadFileToString(base::MakeAbsoluteFilePath(root_store_path), &root_store_text)) { @@ -102,47 +153,15 @@ return std::nullopt; } - std::map<std::string, std::string> certs; - if (!certs_path.empty()) { - std::string certs_data; - if (!base::ReadFileToString(base::MakeAbsoluteFilePath(certs_path), - &certs_data)) { - LOG(ERROR) << "Could not read " << certs_path; - return std::nullopt; - } - auto certs_opt = DecodeCerts(certs_data); - if (!certs_opt) { - LOG(ERROR) << "Could not decode " << certs_path; - return std::nullopt; - } - certs = std::move(*certs_opt); - } - - // Replace the filenames with the actual certificate contents. - for (auto& anchor : *root_store.mutable_trust_anchors()) { - if (anchor.certificate_case() != - chrome_root_store::TrustAnchor::kSha256Hex) { - continue; - } - - auto iter = certs.find(anchor.sha256_hex()); - if (iter == certs.end()) { - LOG(ERROR) << "Could not find certificate " << anchor.sha256_hex(); - return std::nullopt; - } - - // Remove the certificate from `certs`. This both checks for duplicate - // certificates and allows us to check for unused certificates later. - anchor.set_der(std::move(iter->second)); - certs.erase(iter); - } - - if (!certs.empty()) { - LOG(ERROR) << "Unused certificate (SHA-256 hash " << certs.begin()->first - << ") in " << certs_path; + if (!ReplaceTrustAnchors(root_store.mutable_trust_anchors(), certs_path)) { + LOG(ERROR) << "Failed to process " << certs_path; return std::nullopt; } - + if (!ReplaceTrustAnchors(root_store.mutable_additional_certs(), + additional_certs_path)) { + LOG(ERROR) << "Failed to process " << additional_certs_path; + return std::nullopt; + } return std::move(root_store); } @@ -155,55 +174,49 @@ return base::StrCat({"\"", version_str, "\""}); } -// Returns true if file was correctly written, false otherwise. -bool WriteRootCppFile(const RootStore& root_store, - const base::FilePath cpp_path) { - // Root store should have at least one trust anchors. - CHECK_GT(root_store.trust_anchors_size(), 0); - +void WriteTrustAnchors( + const google::protobuf::RepeatedPtrField<TrustAnchor>& trust_anchors, + const std::string& cert_name_prefix, + std::string* string_to_write) { const std::string kNulloptString = "std::nullopt"; - std::string string_to_write = - "// This file is auto-generated, DO NOT EDIT.\n\n"; - - for (int i = 0; i < root_store.trust_anchors_size(); i++) { - const auto& anchor = root_store.trust_anchors(i); + for (int i = 0; i < trust_anchors.size(); i++) { + const auto& anchor = trust_anchors.Get(i); // Every trust anchor at this point should have a DER. CHECK(!anchor.der().empty()); std::string der = anchor.der(); - base::StringAppendF(&string_to_write, - "constexpr uint8_t kChromeRootCert%d[] = {", i); + base::StringAppendF(string_to_write, "constexpr uint8_t k%sCert%d[] = {", + cert_name_prefix, i); // Convert each character to hex representation, escaped. for (auto c : der) { - base::StringAppendF(&string_to_write, "0x%02xu,", - static_cast<uint8_t>(c)); + base::StringAppendF(string_to_write, "0x%02xu,", static_cast<uint8_t>(c)); } // End struct - string_to_write += "};\n"; + *string_to_write += "};\n"; if (anchor.constraints_size() > 0) { int constraint_num = 0; for (const auto& constraint : anchor.constraints()) { if (constraint.permitted_dns_names_size() > 0) { - base::StringAppendF(&string_to_write, + base::StringAppendF(string_to_write, "constexpr std::string_view " - "kChromeRootConstraint%dNames%d[] = {", - i, constraint_num); + "k%sConstraint%dNames%d[] = {", + cert_name_prefix, i, constraint_num); for (const auto& name : constraint.permitted_dns_names()) { - base::StringAppendF(&string_to_write, "\"%s\",", name); + base::StringAppendF(string_to_write, "\"%s\",", name); } - string_to_write += "};\n"; + *string_to_write += "};\n"; } constraint_num++; } - base::StringAppendF(&string_to_write, + base::StringAppendF(string_to_write, "constexpr StaticChromeRootCertConstraints " - "kChromeRootConstraints%d[] = {", - i); + "k%sConstraints%d[] = {", + cert_name_prefix, i); std::vector<std::string> constraint_strings; constraint_num = 0; @@ -232,7 +245,7 @@ if (constraint.permitted_dns_names_size() > 0) { constraint_params.push_back(base::StringPrintf( - "kChromeRootConstraint%dNames%d", i, constraint_num)); + "k%sConstraint%dNames%d", cert_name_prefix, i, constraint_num)); } else { constraint_params.push_back("{}"); } @@ -243,13 +256,27 @@ constraint_num++; } - string_to_write += base::JoinString(constraint_strings, ","); - string_to_write += "};\n"; + *string_to_write += base::JoinString(constraint_strings, ","); + *string_to_write += "};\n"; } } +} +// Returns true if file was correctly written, false otherwise. +bool WriteRootCppFile(const RootStore& root_store, + const base::FilePath cpp_path) { + // Root store should have at least one trust anchor. + CHECK_GT(root_store.trust_anchors_size(), 0); + + std::string string_to_write = + "// This file is auto-generated, DO NOT EDIT.\n\n"; + + WriteTrustAnchors(root_store.trust_anchors(), "ChromeRoot", &string_to_write); + WriteTrustAnchors(root_store.additional_certs(), "Additional", + &string_to_write); + + // Assemble list of trust anchors string_to_write += "constexpr ChromeRootCertInfo kChromeRootCertList[] = {\n"; - for (int i = 0; i < root_store.trust_anchors_size(); i++) { const auto& anchor = root_store.trust_anchors(i); base::StringAppendF(&string_to_write, " {kChromeRootCert%d, ", i); @@ -260,10 +287,30 @@ } string_to_write += "},\n"; } - string_to_write += "};"; + string_to_write += "};\n\n"; + + // Assemble list of QWAC issuers, which can come from both trust_anchors and + // additional_certs. + string_to_write += + "constexpr base::span<const uint8_t> kEutlRootCertList[] = {\n"; + for (int i = 0; i < root_store.trust_anchors_size(); i++) { + const auto& anchor = root_store.trust_anchors(i); + if (!anchor.eutl()) { + continue; + } + base::StringAppendF(&string_to_write, " kChromeRootCert%d,\n", i); + } + for (int i = 0; i < root_store.additional_certs_size(); i++) { + const auto& anchor = root_store.additional_certs(i); + if (!anchor.eutl()) { + continue; + } + base::StringAppendF(&string_to_write, " kAdditionalCert%d,\n", i); + } + string_to_write += "};\n\n"; base::StringAppendF(&string_to_write, - "\n\n\nstatic const int64_t kRootStoreVersion = %" PRId64 + "\nstatic const int64_t kRootStoreVersion = %" PRId64 ";\n", root_store.version_major()); if (!base::WriteFile(cpp_path, string_to_write)) { @@ -370,6 +417,8 @@ base::FilePath root_store_path = command_line.GetSwitchValuePath("root-store"); base::FilePath certs_path = command_line.GetSwitchValuePath("certs"); + base::FilePath additional_certs_path = + command_line.GetSwitchValuePath("additional-certs"); if ((proto_path.empty() && root_store_cpp_path.empty() && ev_roots_cpp_path.empty()) || @@ -377,6 +426,7 @@ std::cerr << "Usage: root_store_tool " << "--root-store=TEXTPROTO_FILE " << "[--certs=CERTS_FILE] " + << "[--additional-certs=ADDITIONAL_CERTS_FILE] " << "[--write-proto=PROTO_FILE] " << "[--write-cpp-root-store=CPP_FILE] " << "[--write-cpp-ev-roots=CPP_FILE] " << std::endl; @@ -384,7 +434,7 @@ } std::optional<RootStore> root_store = - ReadTextRootStore(root_store_path, certs_path); + ReadTextRootStore(root_store_path, certs_path, additional_certs_path); if (!root_store) { return 1; }
diff --git a/net/url_request/storage_access_status_cache.h b/net/url_request/storage_access_status_cache.h index e1dd1d4..6b81b2d 100644 --- a/net/url_request/storage_access_status_cache.h +++ b/net/url_request/storage_access_status_cache.h
@@ -39,22 +39,16 @@ // state is `FirstParty`. std::optional<net::cookie_util::StorageAccessStatus> GetStatusForThirdPartyContext() const { - CHECK(IsSet()); return base::OptionalFromPtr( std::get_if<net::cookie_util::StorageAccessStatus>(&state_)); } - bool IsSet() const { return !std::holds_alternative<Unset>(state_); } - private: - // `state_` variant used when the storage access status is not set. - struct Unset {}; - // `state_` variant used when the storage access status is not applicable // because the request is first-party. struct FirstParty {}; - std::variant<Unset, FirstParty, net::cookie_util::StorageAccessStatus> state_; + std::variant<FirstParty, net::cookie_util::StorageAccessStatus> state_; }; } // namespace net
diff --git a/net/url_request/storage_access_status_cache_unittest.cc b/net/url_request/storage_access_status_cache_unittest.cc index ff9d293..8b170d9c 100644 --- a/net/url_request/storage_access_status_cache_unittest.cc +++ b/net/url_request/storage_access_status_cache_unittest.cc
@@ -13,20 +13,18 @@ TEST(StorageAccessStatusTest, DefaultConstructor) { StorageAccessStatusCache status; - EXPECT_FALSE(status.IsSet()); + EXPECT_EQ(status.GetStatusForThirdPartyContext(), std::nullopt); } TEST(StorageAccessStatusTest, ConstructorWithValue) { StorageAccessStatusCache status( net::cookie_util::StorageAccessStatus::kActive); - ASSERT_TRUE(status.IsSet()); EXPECT_EQ(status.GetStatusForThirdPartyContext(), std::make_optional(net::cookie_util::StorageAccessStatus::kActive)); } TEST(StorageAccessStatusTest, ConstructorWithNullopt) { StorageAccessStatusCache status(std::nullopt); - ASSERT_TRUE(status.IsSet()); EXPECT_EQ(status.GetStatusForThirdPartyContext(), std::nullopt); } @@ -38,15 +36,7 @@ TEST(StorageAccessStatusTest, EqualityOperatorWithoutValue) { StorageAccessStatusCache status; - EXPECT_DEATH_IF_SUPPORTED( - EXPECT_NE(status, cookie_util::StorageAccessStatus::kNone), - "Check failed"); -} - -TEST(StorageAccessStatusTest, GetStatusForThirdPartyContext_Unset) { - StorageAccessStatusCache status; - EXPECT_DEATH_IF_SUPPORTED(status.GetStatusForThirdPartyContext(), - "Check failed"); + EXPECT_NE(status, cookie_util::StorageAccessStatus::kNone); } } // namespace
diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc index 4c48b8f..5608dca 100644 --- a/net/url_request/url_request.cc +++ b/net/url_request/url_request.cc
@@ -417,6 +417,10 @@ *load_timing_info = load_timing_info_; } +LoadTimingInternalInfo URLRequest::GetLoadTimingInternalInfo() const { + return load_timing_internal_info_; +} + void URLRequest::PopulateNetErrorDetails(NetErrorDetails* details) const { if (!job_) return; @@ -1023,6 +1027,8 @@ load_timing_info_.request_start_time = response_info_.request_time; load_timing_info_.request_start = base::TimeTicks::Now(); + load_timing_internal_info_ = LoadTimingInternalInfo(); + status_ = OK; is_pending_ = false; proxy_chain_ = ProxyChain(); @@ -1254,6 +1260,8 @@ load_timing_info_.request_start_time = request_start_time; ConvertRealLoadTimesToBlockingTimes(&load_timing_info_); + + job_->PopulateLoadTimingInternalInfo(&load_timing_internal_info_); } }
diff --git a/net/url_request/url_request.h b/net/url_request/url_request.h index 4b58b6b..a4de3ba 100644 --- a/net/url_request/url_request.h +++ b/net/url_request/url_request.h
@@ -29,6 +29,7 @@ #include "net/base/load_flags.h" #include "net/base/load_states.h" #include "net/base/load_timing_info.h" +#include "net/base/load_timing_internal_info.h" #include "net/base/net_error_details.h" #include "net/base/net_errors.h" #include "net/base/net_export.h" @@ -557,6 +558,10 @@ // non-cached HTTP responses. void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const; + // Gets load timing internal information. Events that have not yet + // occurred are left uninitialized. + LoadTimingInternalInfo GetLoadTimingInternalInfo() const; + // Gets the networkd error details of the most recent origin that the network // stack makes the request to. void PopulateNetErrorDetails(NetErrorDetails* details) const; @@ -1165,6 +1170,9 @@ // populated during Start(), and the rest are populated in OnResponseReceived. LoadTimingInfo load_timing_info_; + // Internal load timing information that is not exposed to the web. + LoadTimingInternalInfo load_timing_internal_info_; + // The proxy chain used for this request, if any. ProxyChain proxy_chain_;
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index 8c1eea6..089d8a3 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc
@@ -1478,6 +1478,13 @@ load_timing_info->receive_headers_end = receive_headers_end_; } +void URLRequestHttpJob::PopulateLoadTimingInternalInfo( + LoadTimingInternalInfo* load_timing_internal_info) const { + if (transaction_) { + transaction_->PopulateLoadTimingInternalInfo(load_timing_internal_info); + } +} + bool URLRequestHttpJob::GetTransactionRemoteEndpoint( IPEndPoint* endpoint) const { if (!transaction_)
diff --git a/net/url_request/url_request_http_job.h b/net/url_request/url_request_http_job.h index ceb5344..d4650b7 100644 --- a/net/url_request/url_request_http_job.h +++ b/net/url_request/url_request_http_job.h
@@ -40,6 +40,7 @@ class HttpUserAgentSettings; class SSLPrivateKey; struct TransportInfo; +struct LoadTimingInternalInfo; class UploadDataStream; // A URLRequestJob subclass that is built on top of HttpTransaction. It @@ -173,6 +174,8 @@ bool GetCharset(std::string* charset) override; void GetResponseInfo(HttpResponseInfo* info) override; void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; + void PopulateLoadTimingInternalInfo( + LoadTimingInternalInfo* load_timing_internal_info) const override; bool GetTransactionRemoteEndpoint(IPEndPoint* endpoint) const override; int GetResponseCode() const override; void PopulateNetErrorDetails(NetErrorDetails* details) const override;
diff --git a/net/url_request/url_request_job.cc b/net/url_request/url_request_job.cc index 746d983..1424e6d 100644 --- a/net/url_request/url_request_job.cc +++ b/net/url_request/url_request_job.cc
@@ -158,6 +158,11 @@ // Only certain request types return more than just request start times. } +void URLRequestJob::PopulateLoadTimingInternalInfo( + LoadTimingInternalInfo* load_timing_internal_info) const { + // Only certain request types populate LoadTimingInternalInfo. +} + bool URLRequestJob::GetTransactionRemoteEndpoint(IPEndPoint* endpoint) const { return false; }
diff --git a/net/url_request/url_request_job.h b/net/url_request/url_request_job.h index c442a90..3c76d62f 100644 --- a/net/url_request/url_request_job.h +++ b/net/url_request/url_request_job.h
@@ -136,6 +136,10 @@ // for more information on the difference. virtual void GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const; + // Populates load timing internal information. + virtual void PopulateLoadTimingInternalInfo( + LoadTimingInternalInfo* load_timing_internal_info) const; + // Gets the remote endpoint that the network stack is currently fetching the // URL from. Returns true and fills in |endpoint| if it is available; returns // false and leaves |endpoint| unchanged if it is unavailable.
diff --git a/pdf/pdf_view_web_plugin.cc b/pdf/pdf_view_web_plugin.cc index 0b3975d..897e113 100644 --- a/pdf/pdf_view_web_plugin.cc +++ b/pdf/pdf_view_web_plugin.cc
@@ -165,6 +165,9 @@ // A different negative value to differentiate itself from `kCompletePDFIndex`. constexpr int kInvalidPDFIndex = -2; +// Get save data from plugin in maximum 16 MB blocks. +constexpr uint32_t kMaxSaveBufferSize = 16 * 1000 * 1000; + // Enumeration of pinch states. // This should match PinchPhase enum in // chrome/browser/resources/pdf/viewport.ts. @@ -267,6 +270,17 @@ return size > 0 && size <= PdfViewWebPlugin::kMaximumSavedFileSize; } +base::Value::Dict CreateSaveDataBlockMessage( + const std::string& token, + PdfViewWebPlugin::SaveDataBlock data) { + base::Value::Dict message; + message.Set("type", "saveDataBlock"); + message.Set("token", token); + message.Set("dataToSave", std::move(data.block)); + message.Set("totalFileSize", base::checked_cast<int>(data.total_file_size)); + return message; +} + } // namespace #if BUILDFLAG(ENABLE_PDF_INK2) @@ -407,6 +421,13 @@ }; #endif // BUILDFLAG(ENABLE_PDF_INK2) +PdfViewWebPlugin::SaveDataBlock::SaveDataBlock() = default; +PdfViewWebPlugin::SaveDataBlock::SaveDataBlock( + PdfViewWebPlugin::SaveDataBlock&& other) noexcept = default; +PdfViewWebPlugin::SaveDataBlock& PdfViewWebPlugin::SaveDataBlock::operator=( + PdfViewWebPlugin::SaveDataBlock&&) noexcept = default; +PdfViewWebPlugin::SaveDataBlock::~SaveDataBlock() = default; + std::unique_ptr<PDFiumEngine> PdfViewWebPlugin::Client::CreateEngine( PDFiumEngineClient* client, PDFiumFormFiller::ScriptOption script_option) { @@ -423,7 +444,8 @@ ink_module_client_(MaybeCreatePdfInkModuleClient(*this)), ink_module_(MaybeCreatePdfInkModule(ink_module_client_.get())), #endif - initial_params_(std::move(params)) { + initial_params_(std::move(params)), + max_save_buffer_size_(kMaxSaveBufferSize) { DCHECK(pdf_host_); pdf_host_->SetListener(listener_receiver_.BindNewPipeAndPassRemote()); } @@ -1625,12 +1647,18 @@ &PdfViewWebPlugin::HandleGetPageBoundingBoxMessage}, {"getPasswordComplete", &PdfViewWebPlugin::HandleGetPasswordCompleteMessage}, + {"getSaveDataBlock", + &PdfViewWebPlugin::HandleGetSaveDataBlockMessage}, {"getSelectedText", &PdfViewWebPlugin::HandleGetSelectedTextMessage}, + {"getSuggestedFileName", + &PdfViewWebPlugin::HandleGetSuggestedFileName}, {"getThumbnail", &PdfViewWebPlugin::HandleGetThumbnailMessage}, {"highlightTextFragments", &PdfViewWebPlugin::HandleHighlightTextFragmentsMessage}, {"print", &PdfViewWebPlugin::HandlePrintMessage}, {"loadPreviewPage", &PdfViewWebPlugin::HandleLoadPreviewPageMessage}, + {"releaseSaveInBlockBuffers", + &PdfViewWebPlugin::HandleReleaseSaveInBlockBuffers}, {"resetPrintPreviewMode", &PdfViewWebPlugin::HandleResetPrintPreviewModeMessage}, {"rotateClockwise", &PdfViewWebPlugin::HandleRotateClockwiseMessage}, @@ -1726,6 +1754,26 @@ client_->PostMessage(std::move(reply)); } +void PdfViewWebPlugin::HandleGetSaveDataBlockMessage( + const base::Value::Dict& message) { + const std::string& token = *message.FindString("token"); + SaveRequestType request_type = + static_cast<SaveRequestType>(message.FindInt("saveRequestType").value()); + uint32_t offset = static_cast<uint32_t>(message.FindInt("offset").value()); + uint32_t block_size = + static_cast<uint32_t>(message.FindInt("blockSize").value()); + + client_->PostMessage(CreateSaveDataBlockMessage( + token, SaveBlockToBuffer(request_type, offset, block_size))); +} + +void PdfViewWebPlugin::HandleGetSuggestedFileName( + const base::Value::Dict& message) { + base::Value::Dict reply = PrepareReplyMessage(message); + reply.Set("fileName", GetFileNameForSaveFromUrl(url_)); + client_->PostMessage(std::move(reply)); +} + void PdfViewWebPlugin::HandleGetThumbnailMessage( const base::Value::Dict& message) { const int page_index = message.FindInt("pageIndex").value(); @@ -2024,7 +2072,7 @@ uint32_t length = engine_->GetLoadedByteSize(); if (IsSaveDataSizeValid(length)) { base::Value::BlobStorage data(length); - if (engine_->ReadLoadedBytes(data)) { + if (engine_->ReadLoadedBytes(0, data)) { data_to_save = base::Value(std::move(data)); } } @@ -2037,6 +2085,73 @@ client_->PostMessage(std::move(message)); } +uint32_t PdfViewWebPlugin::VerifyParamsAndGetSaveBlockSize( + uint32_t total_file_size, + uint32_t offset, + uint32_t block_size) { + if (block_size) { + // Block size should be less than max threshold. + CHECK_LE(block_size, max_save_buffer_size_); + } else { + // `block_size` is allowed to be 0 only when offset is 0 since the caller + // may not know the total file size at that point. + CHECK(!offset); + } + CHECK_LT(offset, total_file_size); + if (block_size) { + CHECK_LE(block_size, total_file_size - offset); + } else { + block_size = std::min(max_save_buffer_size_, total_file_size); + } + return block_size; +} + +PdfViewWebPlugin::SaveDataBlock PdfViewWebPlugin::SaveBlockToBuffer( + SaveRequestType request_type, + uint32_t offset, + uint32_t block_size) { + engine_->KillFormFocus(); + + SaveDataBlock result; + if (request_type == SaveRequestType::kOriginal) { + // This function does not handle files larger than INT_MAX. + if (engine_->GetLoadedByteSize() <= static_cast<uint32_t>(INT_MAX)) { + result.total_file_size = engine_->GetLoadedByteSize(); + block_size = VerifyParamsAndGetSaveBlockSize(result.total_file_size, + offset, block_size); + result.block.resize(block_size); + if (!engine_->ReadLoadedBytes(offset, result.block)) { + result.block.resize(0); + } + } + return result; + } + + if (offset == 0) { + save_data_buffer_ = engine_->GetSaveData(); + // This function does not handle files larger than INT_MAX. + if (save_data_buffer_.size() > static_cast<uint32_t>(INT_MAX)) { + ReleaseSaveBuffer(); + } + } else { + CHECK(save_data_buffer_.size()); + } + if (save_data_buffer_.size()) { + result.total_file_size = static_cast<uint32_t>(save_data_buffer_.size()); + block_size = VerifyParamsAndGetSaveBlockSize(result.total_file_size, offset, + block_size); + result.block.resize(block_size); + base::span(result.block) + .copy_from(base::span(save_data_buffer_).subspan(offset, block_size)); + // Drop the buffer if everything is returned. + if (offset + block_size == result.total_file_size) { + ReleaseSaveBuffer(); + } + } + + return result; +} + void PdfViewWebPlugin::SaveToFile(const std::string& token) { engine_->KillFormFocus(); @@ -2048,6 +2163,11 @@ pdf_host_->SaveUrlAs(GURL(url_), network::mojom::ReferrerPolicy::kDefault); } +void PdfViewWebPlugin::ReleaseSaveBuffer() { + std::vector<uint8_t> empty; + save_data_buffer_.swap(empty); +} + void PdfViewWebPlugin::SetPluginCanSave(bool can_save) { if (plugin_can_save_ == can_save) { return; @@ -2626,6 +2746,11 @@ client_->PostMessage(std::move(message)); } +void PdfViewWebPlugin::HandleReleaseSaveInBlockBuffers( + const base::Value::Dict& /*message*/) { + ReleaseSaveBuffer(); +} + void PdfViewWebPlugin::HandleResetPrintPreviewModeMessage( const base::Value::Dict& message) { const std::string& url = *message.FindString("url");
diff --git a/pdf/pdf_view_web_plugin.h b/pdf/pdf_view_web_plugin.h index 83d4e42..d5c3c4d 100644 --- a/pdf/pdf_view_web_plugin.h +++ b/pdf/pdf_view_web_plugin.h
@@ -258,6 +258,16 @@ #endif }; + struct SaveDataBlock { + SaveDataBlock(); + SaveDataBlock(SaveDataBlock&& other) noexcept; + SaveDataBlock& operator=(SaveDataBlock&&) noexcept; + ~SaveDataBlock(); + + std::vector<uint8_t> block; + uint32_t total_file_size = 0; + }; + PdfViewWebPlugin(std::unique_ptr<Client> client, mojo::AssociatedRemote<pdf::mojom::PdfHost> pdf_host, blink::WebPluginParams params); @@ -488,6 +498,14 @@ } #endif // BUILDFLAG(ENABLE_PDF_INK2) + void SetMaxSaveBufferSizeForTesting(uint32_t max_save_buffer_size) { + max_save_buffer_size_ = max_save_buffer_size; + } + + bool IsSaveDataBufferEmptyForTesting() const { + return save_data_buffer_.empty(); + } + private: // Callback that runs after `LoadUrl()`. The `loader` is the loader used to // load the URL, and `result` is the result code for the load. @@ -552,10 +570,13 @@ void HandleGetNamedDestinationMessage(const base::Value::Dict& message); void HandleGetPageBoundingBoxMessage(const base::Value::Dict& message); void HandleGetPasswordCompleteMessage(const base::Value::Dict& message); + void HandleGetSaveDataBlockMessage(const base::Value::Dict& message); void HandleGetSelectedTextMessage(const base::Value::Dict& message); + void HandleGetSuggestedFileName(const base::Value::Dict& message); void HandleGetThumbnailMessage(const base::Value::Dict& message); void HandleHighlightTextFragmentsMessage(const base::Value::Dict& message); void HandlePrintMessage(const base::Value::Dict& /*message*/); + void HandleReleaseSaveInBlockBuffers(const base::Value::Dict& /*message*/); void HandleRotateClockwiseMessage(const base::Value::Dict& /*message*/); void HandleRotateCounterclockwiseMessage( const base::Value::Dict& /*message*/); @@ -571,6 +592,26 @@ void SaveToBuffer(SaveRequestType request_type, const std::string& token); void SaveToFile(const std::string& token); + // Returns `block_size` bytes to save the PDF with `request_type`, starting + // from location `offset`. Since the caller may not know the exact file size, + // the first request (when `offset` is 0) can be called with `block_size` 0 + // and in that case, the entire file data, capped at 16MB limit is returned. + // The function also returns the total file size. + // Note that it only handles files less than INT_MAX size, and if the file is + // larger than that, it returns 0 as file size and no data. + SaveDataBlock SaveBlockToBuffer(SaveRequestType request_type, + uint32_t offset, + uint32_t block_size); + + // For a call to `SaveBlockToBuffer`, ensures `offset` and `block_size` have + // expected values and returns the effective `block_size`. + uint32_t VerifyParamsAndGetSaveBlockSize(uint32_t total_file_size, + uint32_t offset, + uint32_t block_size); + + // Release buffered data for saving. + void ReleaseSaveBuffer(); + // Sets whether the plugin can and should handle the save by using `pdf_host_` // to notify the browser. Prevents duplicate notifications to the browser if // the state has not changed. @@ -946,6 +987,16 @@ // Queue of available preview pages to load next. base::queue<PreviewPageInfo> preview_pages_info_; + // Buffer for saving data by Web UI. + // `SaveBlockToBuffer` allocates this variable when WebUI requests saving the + // PDF by getting the content in blocks, and the content needs to be buffered + // during the save process. It is released when saving is finished or + // canceled. + std::vector<uint8_t> save_data_buffer_; + + // Maximum size of save data in each block. + uint32_t max_save_buffer_size_; + #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) bool show_searchify_in_progress_ = false;
diff --git a/pdf/pdf_view_web_plugin_unittest.cc b/pdf/pdf_view_web_plugin_unittest.cc index 13d787ec..ca4dd3b 100644 --- a/pdf/pdf_view_web_plugin_unittest.cc +++ b/pdf/pdf_view_web_plugin_unittest.cc
@@ -2293,6 +2293,135 @@ })")); } +class PdfViewWebPluginSaveInBlocksTest : public PdfViewWebPluginTest { + protected: + base::Value::Dict CreateRequest( + PdfViewWebPlugin::SaveRequestType request_type, + uint32_t offset, + uint32_t block_size, + std::string token) { + base::Value::Dict dict; + dict.Set("type", "getSaveDataBlock"); + dict.Set("saveRequestType", static_cast<int>(request_type)); + dict.Set("offset", static_cast<int>(offset)); + dict.Set("blockSize", static_cast<int>(block_size)); + dict.Set("token", token); + return dict; + } + + void ExpectResponse(base::span<const uint8_t> data, + uint32_t offset, + uint32_t block_size, + std::string token) { + base::Value value(base::Value::Type::DICT); + value.GetDict().Set("type", "saveDataBlock"); + value.GetDict().Set("token", token); + value.GetDict().Set("dataToSave", + base::Value(data.subspan(offset, block_size))); + value.GetDict().Set("totalFileSize", + base::Value(static_cast<int>(data.size()))); + EXPECT_CALL(*client_ptr_, PostMessage(base::test::IsJson(value))); + } + + void SetUpClient() override { + // Ignore non - "saveDataBlock" `PdfViewWebPlugin::Client::PostMessage()` + // calls. + EXPECT_CALL(*client_ptr_, PostMessage) + .WillRepeatedly([](const base::Value::Dict& message) { + EXPECT_NE("saveDataBlock", *message.FindString("type")); + }); + } +}; + +TEST_F(PdfViewWebPluginSaveInBlocksTest, GetSuggestedFileName) { + EXPECT_CALL(*client_ptr_, PostMessage(base::test::IsJson(R"({ + "type": "getSuggestedFileNameReply", + "messageId": "foo", + "fileName": "example.pdf", + })"))); + + plugin_->OnMessage(ParseMessage(R"({ + "type": "getSuggestedFileName", + "messageId": "foo", + })")); + + pdf_receiver_.FlushForTesting(); +} + +TEST_F(PdfViewWebPluginSaveInBlocksTest, OriginalInOneBlock) { + base::span data(TestPDFiumEngine::kLoadedData); + ExpectResponse(data, 0, data.size(), "token-1"); + plugin_->OnMessage(CreateRequest(PdfViewWebPlugin::SaveRequestType::kOriginal, + 0, 0, "token-1")); + EXPECT_TRUE(plugin_->IsSaveDataBufferEmptyForTesting()); + pdf_receiver_.FlushForTesting(); +} + +TEST_F(PdfViewWebPluginSaveInBlocksTest, OriginalInMulipleBlocks) { + plugin_->SetMaxSaveBufferSizeForTesting(3); + + base::span data(TestPDFiumEngine::kLoadedData); + ASSERT_GT(data.size(), 3u); + ExpectResponse(data, 0, 3, "token-1"); + ExpectResponse(data, 3, data.size() - 3, "token-2"); + plugin_->OnMessage(CreateRequest(PdfViewWebPlugin::SaveRequestType::kOriginal, + 0, 0, "token-1")); + EXPECT_TRUE(plugin_->IsSaveDataBufferEmptyForTesting()); + plugin_->OnMessage(CreateRequest(PdfViewWebPlugin::SaveRequestType::kOriginal, + 3, data.size() - 3, "token-2")); + EXPECT_TRUE(plugin_->IsSaveDataBufferEmptyForTesting()); + pdf_receiver_.FlushForTesting(); +} + +TEST_F(PdfViewWebPluginSaveInBlocksTest, EditedInOneBlock) { + plugin_->EnteredEditMode(); + + base::span data(TestPDFiumEngine::kSaveData); + ExpectResponse(data, 0, data.size(), "token-1"); + plugin_->OnMessage(CreateRequest(PdfViewWebPlugin::SaveRequestType::kEdited, + 0, 0, "token-1")); + EXPECT_TRUE(plugin_->IsSaveDataBufferEmptyForTesting()); + pdf_receiver_.FlushForTesting(); +} + +TEST_F(PdfViewWebPluginSaveInBlocksTest, EditedInMultipleBlock) { + plugin_->EnteredEditMode(); + plugin_->SetMaxSaveBufferSizeForTesting(2); + + base::span data(TestPDFiumEngine::kSaveData); + ASSERT_GT(data.size(), 2u); + ExpectResponse(data, 0, 2, "token-1"); + ExpectResponse(data, 2, data.size() - 2, "token-2"); + + plugin_->OnMessage(CreateRequest(PdfViewWebPlugin::SaveRequestType::kEdited, + 0, 0, "token-1")); + EXPECT_FALSE(plugin_->IsSaveDataBufferEmptyForTesting()); + plugin_->OnMessage(CreateRequest(PdfViewWebPlugin::SaveRequestType::kEdited, + 2, data.size() - 2, "token-2")); + EXPECT_TRUE(plugin_->IsSaveDataBufferEmptyForTesting()); + pdf_receiver_.FlushForTesting(); +} + +TEST_F(PdfViewWebPluginSaveInBlocksTest, ReleaseSaveBuffer) { + plugin_->EnteredEditMode(); + plugin_->SetMaxSaveBufferSizeForTesting(2); + + base::span data(TestPDFiumEngine::kSaveData); + ASSERT_GT(data.size(), 2u); + ExpectResponse(data, 0, 2, "token-1"); + + plugin_->OnMessage(CreateRequest(PdfViewWebPlugin::SaveRequestType::kEdited, + 0, 0, "token-1")); + EXPECT_FALSE(plugin_->IsSaveDataBufferEmptyForTesting()); + + base::Value::Dict message; + message.Set("type", "releaseSaveInBlockBuffers"); + plugin_->OnMessage(message); + EXPECT_TRUE(plugin_->IsSaveDataBufferEmptyForTesting()); + + pdf_receiver_.FlushForTesting(); +} + class PdfViewWebPluginSubmitFormTest : public PdfViewWebPluginWithoutInitializeTest { protected:
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc index c5e96635..77ade2d7 100644 --- a/pdf/pdfium/pdfium_engine.cc +++ b/pdf/pdfium/pdfium_engine.cc
@@ -1258,8 +1258,9 @@ return doc_loader_->GetDocumentSize(); } -bool PDFiumEngine::ReadLoadedBytes(base::span<uint8_t> buffer) { - return doc_loader_->GetBlock(0, buffer.size(), buffer.data()); +bool PDFiumEngine::ReadLoadedBytes(uint32_t offset, + base::span<uint8_t> buffer) { + return doc_loader_->GetBlock(offset, buffer.size(), buffer.data()); } void PDFiumEngine::SetFormSelectedText(FPDF_FORMHANDLE form_handle,
diff --git a/pdf/pdfium/pdfium_engine.h b/pdf/pdfium/pdfium_engine.h index e4cc849..c578b64 100644 --- a/pdf/pdfium/pdfium_engine.h +++ b/pdf/pdfium/pdfium_engine.h
@@ -377,12 +377,12 @@ virtual uint32_t GetLoadedByteSize(); - // Copies data from `doc_loader_` into `buffer`. + // Copies data from `doc_loader_` into `buffer` starting from `offset`. // - `buffer` is completely filled, so its size should be less than or equal - // to GetLoadedByteSize(). + // to GetLoadedByteSize() - `offset`. // // Returns true on success and writes into `buffer. Returns false on failure. - virtual bool ReadLoadedBytes(base::span<uint8_t> buffer); + virtual bool ReadLoadedBytes(uint32_t offset, base::span<uint8_t> buffer); // Requests rendering the page at `page_index` as a thumbnail at a given // `device_pixel_ratio`. Runs `send_callback` with the rendered thumbnail.
diff --git a/pdf/test/test_pdfium_engine.cc b/pdf/test/test_pdfium_engine.cc index 9635c5e..8198030 100644 --- a/pdf/test/test_pdfium_engine.cc +++ b/pdf/test/test_pdfium_engine.cc
@@ -53,8 +53,9 @@ return sizeof(kLoadedData); } -bool TestPDFiumEngine::ReadLoadedBytes(base::span<uint8_t> buffer) { - buffer.copy_from(base::span(kLoadedData).first(buffer.size())); +bool TestPDFiumEngine::ReadLoadedBytes(uint32_t offset, + base::span<uint8_t> buffer) { + buffer.copy_from(base::span(kLoadedData).subspan(offset, buffer.size())); return true; }
diff --git a/pdf/test/test_pdfium_engine.h b/pdf/test/test_pdfium_engine.h index 503ac04..72faa7c 100644 --- a/pdf/test/test_pdfium_engine.h +++ b/pdf/test/test_pdfium_engine.h
@@ -102,7 +102,7 @@ uint32_t GetLoadedByteSize() override; - bool ReadLoadedBytes(base::span<uint8_t> buffer) override; + bool ReadLoadedBytes(uint32_t offset, base::span<uint8_t> buffer) override; MOCK_METHOD(void, RequestThumbnail,
diff --git a/printing/mojom/printing_context.mojom b/printing/mojom/printing_context.mojom index 7e29a43..d76cc80 100644 --- a/printing/mojom/printing_context.mojom +++ b/printing/mojom/printing_context.mojom
@@ -65,7 +65,7 @@ PrinterLanguageType printer_language_type; bool is_modifiable; - PageMargins requested_custom_margins_in_points; + PageMargins requested_custom_margins_in_microns; int32 pages_per_sheet; [EnableIf=is_chromeos|is_linux]
diff --git a/printing/mojom/printing_context_mojom_traits.cc b/printing/mojom/printing_context_mojom_traits.cc index f6c58fd..8a34c26 100644 --- a/printing/mojom/printing_context_mojom_traits.cc +++ b/printing/mojom/printing_context_mojom_traits.cc
@@ -155,8 +155,9 @@ // so only want to apply this if the type was for `kCustomMargins`. if (data.margin_type() == printing::mojom::MarginType::kCustomMargins) { printing::PageMargins requested_margins; - if (!data.ReadRequestedCustomMarginsInPoints(&requested_margins)) + if (!data.ReadRequestedCustomMarginsInMicrons(&requested_margins)) { return false; + } out->SetCustomMargins(requested_margins); }
diff --git a/printing/mojom/printing_context_mojom_traits.h b/printing/mojom/printing_context_mojom_traits.h index 003c9c8..38a753d 100644 --- a/printing/mojom/printing_context_mojom_traits.h +++ b/printing/mojom/printing_context_mojom_traits.h
@@ -158,9 +158,9 @@ static bool is_modifiable(const printing::PrintSettings& s) { return s.is_modifiable(); } - static const printing::PageMargins& requested_custom_margins_in_points( + static const printing::PageMargins& requested_custom_margins_in_microns( const printing::PrintSettings& s) { - return s.requested_custom_margins_in_points(); + return s.requested_custom_margins_in_microns(); } static int32_t pages_per_sheet(const printing::PrintSettings& s) { return s.pages_per_sheet();
diff --git a/printing/mojom/printing_context_mojom_traits_unittest.cc b/printing/mojom/printing_context_mojom_traits_unittest.cc index 35039122b..316a8f2 100644 --- a/printing/mojom/printing_context_mojom_traits_unittest.cc +++ b/printing/mojom/printing_context_mojom_traits_unittest.cc
@@ -107,12 +107,14 @@ const PrintSettings::RequestedMedia kPrintSettingsRequestedMedia{ /*size_microns=*/gfx::Size(/*width=*/215900, /*height=*/279400), /*vendor_id=*/"vendor"}; -const PageMargins kPrintSettingsCustomMarginsInPoints(/*header=*/10, - /*footer=*/15, - /*left=*/20, - /*right=*/25, - /*top=*/30, - /*bottom=*/35); + +// Converted from points to microns (1 point = 352.7778 microns) +const PageMargins kPrintSettingsCustomMarginsInMicrons(/*header=*/3528, + /*footer=*/5292, + /*left=*/7056, + /*right=*/8819, + /*top=*/10583, + /*bottom=*/12347); #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) PrintSettings::AdvancedSettings GenerateSampleAdvancedSettings() { @@ -272,7 +274,7 @@ settings.set_rasterize_pdf(kPrintSettingsRasterizePdf2); settings.SetOrientation(kPrintSettingsLandscape2); - settings.SetCustomMargins(kPrintSettingsCustomMarginsInPoints); + settings.SetCustomMargins(kPrintSettingsCustomMarginsInMicrons); #if BUILDFLAG(IS_WIN) settings.set_printer_language_type(kPrintSettingsPrinterLanguageType2); @@ -540,7 +542,7 @@ // Since `kPrintSettingsMarginType1` is not `kCustomMargins` then expect the // custom margins to be default values. - EXPECT_TRUE(PageMarginsEqual(output.requested_custom_margins_in_points(), + EXPECT_TRUE(PageMarginsEqual(output.requested_custom_margins_in_microns(), PageMargins())); EXPECT_EQ(output.pages_per_sheet(), kPrintSettingsPagesPerSheet1); @@ -594,8 +596,8 @@ #endif EXPECT_EQ(output.is_modifiable(), kPrintSettingsModifiable2); - EXPECT_TRUE(PageMarginsEqual(output.requested_custom_margins_in_points(), - kPrintSettingsCustomMarginsInPoints)); + EXPECT_TRUE(PageMarginsEqual(output.requested_custom_margins_in_microns(), + kPrintSettingsCustomMarginsInMicrons)); EXPECT_EQ(output.pages_per_sheet(), kPrintSettingsPagesPerSheet2); #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
diff --git a/printing/print_settings.cc b/printing/print_settings.cc index 2471cde..928df71 100644 --- a/printing/print_settings.cc +++ b/printing/print_settings.cc
@@ -347,7 +347,7 @@ #if BUILDFLAG(IS_WIN) printer_language_type_, #endif - is_modifiable_, requested_custom_margins_in_points_, + is_modifiable_, requested_custom_margins_in_microns_, pages_per_sheet_ #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) , @@ -371,7 +371,7 @@ other.printer_language_type_, #endif other.is_modifiable_, - other.requested_custom_margins_in_points_, + other.requested_custom_margins_in_microns_, other.pages_per_sheet_ #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) , @@ -484,14 +484,14 @@ case mojom::MarginType::kCustomMargins: { margins.header = 0; margins.footer = 0; - margins.top = ConvertUnit(requested_custom_margins_in_points_.top, - kPointsPerInch, units_per_inch); - margins.bottom = ConvertUnit(requested_custom_margins_in_points_.bottom, - kPointsPerInch, units_per_inch); - margins.left = ConvertUnit(requested_custom_margins_in_points_.left, - kPointsPerInch, units_per_inch); - margins.right = ConvertUnit(requested_custom_margins_in_points_.right, - kPointsPerInch, units_per_inch); + margins.top = ConvertUnit(requested_custom_margins_in_microns_.top, + kMicronsPerInch, units_per_inch); + margins.bottom = ConvertUnit(requested_custom_margins_in_microns_.bottom, + kMicronsPerInch, units_per_inch); + margins.left = ConvertUnit(requested_custom_margins_in_microns_.left, + kMicronsPerInch, units_per_inch); + margins.right = ConvertUnit(requested_custom_margins_in_microns_.right, + kMicronsPerInch, units_per_inch); break; } default: { @@ -541,8 +541,8 @@ #endif void PrintSettings::SetCustomMargins( - const PageMargins& requested_margins_in_points) { - requested_custom_margins_in_points_ = requested_margins_in_points; + const PageMargins& requested_margins_in_microns) { + requested_custom_margins_in_microns_ = requested_margins_in_microns; margin_type_ = mojom::MarginType::kCustomMargins; }
diff --git a/printing/print_settings.h b/printing/print_settings.h index 8d71020..d60cb909 100644 --- a/printing/print_settings.h +++ b/printing/print_settings.h
@@ -115,9 +115,9 @@ // Reinitialize the settings to the default values. void Clear(); - void SetCustomMargins(const PageMargins& requested_margins_in_points); - const PageMargins& requested_custom_margins_in_points() const { - return requested_custom_margins_in_points_; + void SetCustomMargins(const PageMargins& requested_margins_in_microns); + const PageMargins& requested_custom_margins_in_microns() const { + return requested_custom_margins_in_microns_; } void set_margin_type(mojom::MarginType margin_type) { margin_type_ = margin_type; @@ -424,7 +424,7 @@ bool is_modifiable_; // If margin type is custom, this is what was requested. - PageMargins requested_custom_margins_in_points_; + PageMargins requested_custom_margins_in_microns_; // Number of pages per sheet. int pages_per_sheet_;
diff --git a/printing/print_settings_conversion.cc b/printing/print_settings_conversion.cc index 974fc61..3ca33218 100644 --- a/printing/print_settings_conversion.cc +++ b/printing/print_settings_conversion.cc
@@ -42,16 +42,22 @@ // Note: If this code crashes, then the caller has passed in invalid `settings`. // Fix the caller, instead of trying to avoid the crash here. PageMargins GetCustomMarginsFromJobSettings(const base::Value::Dict& settings) { - PageMargins margins_in_points; + PageMargins margins_in_microns; const base::Value::Dict* custom_margins = settings.FindDict(kSettingMarginsCustom); - margins_in_points.top = custom_margins->FindInt(kSettingMarginTop).value(); - margins_in_points.bottom = - custom_margins->FindInt(kSettingMarginBottom).value(); - margins_in_points.left = custom_margins->FindInt(kSettingMarginLeft).value(); - margins_in_points.right = - custom_margins->FindInt(kSettingMarginRight).value(); - return margins_in_points; + margins_in_microns.top = + ConvertUnit(custom_margins->FindInt(kSettingMarginTop).value(), + kPointsPerInch, kMicronsPerInch); + margins_in_microns.bottom = + ConvertUnit(custom_margins->FindInt(kSettingMarginBottom).value(), + kPointsPerInch, kMicronsPerInch); + margins_in_microns.left = + ConvertUnit(custom_margins->FindInt(kSettingMarginLeft).value(), + kPointsPerInch, kMicronsPerInch); + margins_in_microns.right = + ConvertUnit(custom_margins->FindInt(kSettingMarginRight).value(), + kPointsPerInch, kMicronsPerInch); + return margins_in_microns; } void SetMarginsToJobSettings(const std::string& json_path, @@ -388,8 +394,9 @@ SetSizeToJobSettings("media_size", settings.requested_media().size_microns, debug); - SetMarginsToJobSettings("requested_custom_margins_in_points", - settings.requested_custom_margins_in_points(), debug); + SetMarginsToJobSettings("requested_custom_margins_in_microns", + settings.requested_custom_margins_in_microns(), + debug); const PageSetup& page_setup = settings.page_setup_device_units(); SetMarginsToJobSettings("effective_margins", page_setup.effective_margins(), debug);
diff --git a/printing/print_settings_unittest.cc b/printing/print_settings_unittest.cc index 9e8ea34..a0f71b2 100644 --- a/printing/print_settings_unittest.cc +++ b/printing/print_settings_unittest.cc
@@ -9,6 +9,7 @@ #include "build/chromeos_buildflags.h" #include "printing/buildflags/buildflags.h" #include "printing/mojom/print.mojom.h" +#include "printing/units.h" #include "testing/gtest/include/gtest/gtest.h" namespace printing { @@ -68,4 +69,77 @@ } #endif // BUILDFLAG(USE_CUPS_IPP) +TEST(PrintSettingsTest, SetPrinterPrintableArea) { + static constexpr gfx::Size kPhysicalSizeDeviceUnits(600, 800); + static constexpr gfx::Rect kPrintableAreaDeviceUnits(50, 50, 500, 700); + + struct TestCase { + int dpi; + PageMargins margins; + mojom::MarginType expected_margin_type; + } static const kTestCases[] = { + { + 300, + PageMargins(), + mojom::MarginType::kDefaultMargins, + }, + {250, PageMargins(0, 0, 10000, 10000, 5000, 5000), + mojom::MarginType::kCustomMargins}, + {426, PageMargins(0, 0, 20000, 20000, 25400, 25400), + mojom::MarginType::kCustomMargins}, + {300, PageMargins(0, 0, 10000, 20000, 5000, 15000), + mojom::MarginType::kCustomMargins}}; + + for (const auto& test_case : kTestCases) { + PrintSettings settings; + settings.set_dpi(test_case.dpi); + + if (test_case.expected_margin_type == mojom::MarginType::kCustomMargins) { + settings.SetCustomMargins(test_case.margins); + } + + settings.SetPrinterPrintableArea(kPhysicalSizeDeviceUnits, + kPrintableAreaDeviceUnits, + /*landscape_needs_flip=*/false); + + EXPECT_EQ(test_case.expected_margin_type, settings.margin_type()); + EXPECT_EQ(test_case.margins.top, + settings.requested_custom_margins_in_microns().top); + EXPECT_EQ(test_case.margins.bottom, + settings.requested_custom_margins_in_microns().bottom); + EXPECT_EQ(test_case.margins.left, + settings.requested_custom_margins_in_microns().left); + EXPECT_EQ(test_case.margins.right, + settings.requested_custom_margins_in_microns().right); + + const PageSetup& page_setup = settings.page_setup_device_units(); + + if (test_case.expected_margin_type == mojom::MarginType::kDefaultMargins) { +#if BUILDFLAG(IS_MAC) + EXPECT_EQ(PageMargins(50, 50, 50, 50, 50, 50), + page_setup.effective_margins()); +#else + EXPECT_EQ(PageMargins(50, 50, 118, 118, 118, 118), + page_setup.effective_margins()); +#endif + } else if (test_case.expected_margin_type == + mojom::MarginType::kCustomMargins) { + const int device_units_per_inch = settings.device_units_per_inch(); + PageMargins expected_custom_margins; + expected_custom_margins.header = 0; + expected_custom_margins.footer = 0; + expected_custom_margins.top = ConvertUnit( + test_case.margins.top, kMicronsPerInch, device_units_per_inch); + expected_custom_margins.bottom = ConvertUnit( + test_case.margins.bottom, kMicronsPerInch, device_units_per_inch); + expected_custom_margins.left = ConvertUnit( + test_case.margins.left, kMicronsPerInch, device_units_per_inch); + expected_custom_margins.right = ConvertUnit( + test_case.margins.right, kMicronsPerInch, device_units_per_inch); + + EXPECT_EQ(expected_custom_margins, page_setup.effective_margins()); + } + } +} + } // namespace printing
diff --git a/services/device/geolocation/geolocation_service_unittest.cc b/services/device/geolocation/geolocation_service_unittest.cc index 1a3cfe3..824b114 100644 --- a/services/device/geolocation/geolocation_service_unittest.cc +++ b/services/device/geolocation/geolocation_service_unittest.cc
@@ -88,6 +88,9 @@ mojo::Remote<mojom::GeolocationControl> geolocation_control_; mojo::Remote<mojom::GeolocationContext> geolocation_context_; mojo::Remote<mojom::Geolocation> geolocation_; +#if BUILDFLAG(IS_MAC) + base::test::ScopedFeatureList scoped_feature_list_; +#endif // BUILDFLAG(IS_MAC) }; #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) @@ -103,6 +106,15 @@ LocationSystemPermissionStatus::kAllowed); #endif +// crrev.com/c/6378263 enabled the platform location provider by default on +// macOS. This explicit feature flag configuration ensures network location +// provider tests remain unaffected. +#if BUILDFLAG(IS_MAC) + scoped_feature_list_.InitAndEnableFeatureWithParameters( + features::kLocationProviderManager, + {{"LocationProviderManagerMode", "NetworkOnly"}}); +#endif // BUILDFLAG(IS_MAC) + base::RunLoop loop; test_url_loader_factory_.SetInterceptor(base::BindLambdaForTesting( [&loop](const network::ResourceRequest& request) {
diff --git a/services/device/geolocation/location_provider_manager_unittest.cc b/services/device/geolocation/location_provider_manager_unittest.cc index e6566952..f4b76de2 100644 --- a/services/device/geolocation/location_provider_manager_unittest.cc +++ b/services/device/geolocation/location_provider_manager_unittest.cc
@@ -237,6 +237,8 @@ // Tests basic operation (valid position and error position update) for network // location provider. TEST_F(GeolocationLocationProviderManagerTest, NetworkOnly) { + ASSERT_TRUE( + SetExperimentMode(mojom::LocationProviderManagerMode::kNetworkOnly)); InitializeLocationProviderManager(base::BindRepeating(&NullLocationProvider), url_loader_factory_); ASSERT_TRUE(location_provider_manager_); @@ -363,9 +365,11 @@ } #if !BUILDFLAG(IS_ANDROID) -// Tests flipping from Low to High accuracy mode as requested by a location -// observer. +// When in kNetworkOnly mode, test flipping from Low to High accuracy mode as +// requested by a location observer. TEST_F(GeolocationLocationProviderManagerTest, SetObserverOptions) { + ASSERT_TRUE( + SetExperimentMode(mojom::LocationProviderManagerMode::kNetworkOnly)); InitializeLocationProviderManager(base::BindRepeating(&NullLocationProvider), url_loader_factory_); location_provider_manager_->StartProvider(false);
diff --git a/services/device/public/cpp/device_features.cc b/services/device/public/cpp/device_features.cc index 8c07198..34610be 100644 --- a/services/device/public/cpp/device_features.cc +++ b/services/device/public/cpp/device_features.cc
@@ -58,12 +58,19 @@ const base::FeatureParam<int> kWinSystemLocationPermissionPollingParam{ &kWinSystemLocationPermission, "polling_interval_in_ms", 500}; #endif // BUILDFLAG(IS_WIN) + // Enables usage of the location provider manager to select between // the operating system's location API or our network-based provider // as the source of location data for Geolocation API. +#if BUILDFLAG(IS_MAC) +BASE_FEATURE(kLocationProviderManager, + "LocationProviderManager", + base::FEATURE_ENABLED_BY_DEFAULT); +#else BASE_FEATURE(kLocationProviderManager, "LocationProviderManager", base::FEATURE_DISABLED_BY_DEFAULT); +#endif // BUILDFLAG(IS_MAC) #if BUILDFLAG(IS_CHROMEOS) // Enables crash key logging for USB device open operations on ChromeOS. See @@ -102,11 +109,19 @@ "HybridPlatform2"}, }; +#if BUILDFLAG(IS_MAC) +const base::FeatureParam<device::mojom::LocationProviderManagerMode> + kLocationProviderManagerParam{ + &kLocationProviderManager, "LocationProviderManagerMode", + device::mojom::LocationProviderManagerMode::kHybridPlatform, + &location_provider_manager_mode_options}; +#else const base::FeatureParam<device::mojom::LocationProviderManagerMode> kLocationProviderManagerParam{ &kLocationProviderManager, "LocationProviderManagerMode", device::mojom::LocationProviderManagerMode::kNetworkOnly, &location_provider_manager_mode_options}; +#endif // BUILDFLAG(IS_MAC) bool IsOsLevelGeolocationPermissionSupportEnabled() { #if BUILDFLAG(IS_WIN)
diff --git a/services/network/cookie_settings.cc b/services/network/cookie_settings.cc index 4aaeac9..0bb709aa 100644 --- a/services/network/cookie_settings.cc +++ b/services/network/cookie_settings.cc
@@ -473,8 +473,8 @@ net::CookieInclusionStatus::ExclusionReason::EXCLUDE_USER_PREFERENCES); } -// TODO(crbug.com/366284840): Deprecate this function when moving storage access -// status out of //net. +// TODO(crbug.com/388550981): Deprecate this function; Storage Access Headers +// is enabled by default. bool CookieSettings::IsStorageAccessHeadersEnabled( const GURL& url, base::optional_ref<const url::Origin> top_frame_origin) const {
diff --git a/services/network/public/cpp/BUILD.gn b/services/network/public/cpp/BUILD.gn index a89b81a..95f52d2 100644 --- a/services/network/public/cpp/BUILD.gn +++ b/services/network/public/cpp/BUILD.gn
@@ -532,6 +532,8 @@ "isolation_info_mojom_traits.h", "load_timing_info_mojom_traits.cc", "load_timing_info_mojom_traits.h", + "load_timing_internal_info_mojom_traits.cc", + "load_timing_internal_info_mojom_traits.h", "network_anonymization_key_mojom_traits.cc", "network_anonymization_key_mojom_traits.h", "network_interface_mojom_traits.cc", @@ -696,6 +698,7 @@ "is_potentially_trustworthy_unittest.cc", "isolation_info_mojom_traits_unittest.cc", "link_header_parser_unittest.cc", + "load_timing_internal_info_mojom_traits_unittest.cc", "mutable_network_traffic_annotation_tag_mojom_traits_unittest.cc", "mutable_partial_network_traffic_annotation_tag_mojom_traits_unittest.cc", "net_log_mojom_traits_unittest.cc",
diff --git a/services/network/public/cpp/load_timing_internal_info_mojom_traits.cc b/services/network/public/cpp/load_timing_internal_info_mojom_traits.cc new file mode 100644 index 0000000..7f0202dc --- /dev/null +++ b/services/network/public/cpp/load_timing_internal_info_mojom_traits.cc
@@ -0,0 +1,30 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/network/public/cpp/load_timing_internal_info_mojom_traits.h" + +#include "mojo/public/cpp/base/time_mojom_traits.h" + +namespace mojo { + +// static +const base::TimeDelta& +StructTraits<network::mojom::LoadTimingInternalInfoDataView, + net::LoadTimingInternalInfo>:: + initialize_stream_delay(const net::LoadTimingInternalInfo& info) { + return info.initialize_stream_delay; +} + +// static +bool StructTraits<network::mojom::LoadTimingInternalInfoDataView, + net::LoadTimingInternalInfo>:: + Read(network::mojom::LoadTimingInternalInfoDataView data, + net::LoadTimingInternalInfo* info) { + if (!data.ReadInitializeStreamDelay(&info->initialize_stream_delay)) { + return false; + } + return true; +} + +} // namespace mojo
diff --git a/services/network/public/cpp/load_timing_internal_info_mojom_traits.h b/services/network/public/cpp/load_timing_internal_info_mojom_traits.h new file mode 100644 index 0000000..a41c3c93 --- /dev/null +++ b/services/network/public/cpp/load_timing_internal_info_mojom_traits.h
@@ -0,0 +1,27 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_NETWORK_PUBLIC_CPP_LOAD_TIMING_INTERNAL_INFO_MOJOM_TRAITS_H_ +#define SERVICES_NETWORK_PUBLIC_CPP_LOAD_TIMING_INTERNAL_INFO_MOJOM_TRAITS_H_ + +#include "base/time/time.h" +#include "mojo/public/cpp/bindings/struct_traits.h" +#include "net/base/load_timing_internal_info.h" +#include "services/network/public/mojom/load_timing_internal_info.mojom-shared.h" + +namespace mojo { + +template <> +struct COMPONENT_EXPORT(NETWORK_CPP_BASE) + StructTraits<network::mojom::LoadTimingInternalInfoDataView, + net::LoadTimingInternalInfo> { + static const base::TimeDelta& initialize_stream_delay( + const net::LoadTimingInternalInfo& info); + static bool Read(network::mojom::LoadTimingInternalInfoDataView data, + net::LoadTimingInternalInfo* info); +}; + +} // namespace mojo + +#endif // SERVICES_NETWORK_PUBLIC_CPP_LOAD_TIMING_INTERNAL_INFO_MOJOM_TRAITS_H_
diff --git a/services/network/public/cpp/load_timing_internal_info_mojom_traits_unittest.cc b/services/network/public/cpp/load_timing_internal_info_mojom_traits_unittest.cc new file mode 100644 index 0000000..5c515ad --- /dev/null +++ b/services/network/public/cpp/load_timing_internal_info_mojom_traits_unittest.cc
@@ -0,0 +1,30 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/network/public/cpp/load_timing_internal_info_mojom_traits.h" + +#include "base/time/time.h" +#include "mojo/public/cpp/base/time_mojom_traits.h" +#include "mojo/public/cpp/test_support/test_utils.h" +#include "net/base/load_timing_internal_info.h" +#include "services/network/public/mojom/load_timing_internal_info.mojom.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace network { +namespace { + +TEST(LoadTimingInternalInfoMojomTraitsTest, SerializeAndDeserialize) { + net::LoadTimingInternalInfo original; + original.initialize_stream_delay = base::Seconds(1); + + net::LoadTimingInternalInfo deserialized; + ASSERT_NE(deserialized, original); + EXPECT_TRUE( + mojo::test::SerializeAndDeserialize<mojom::LoadTimingInternalInfo>( + original, deserialized)); + EXPECT_EQ(deserialized, original); +} + +} // namespace +} // namespace network
diff --git a/services/network/public/mojom/BUILD.gn b/services/network/public/mojom/BUILD.gn index 537e3ac3..57bb88f 100644 --- a/services/network/public/mojom/BUILD.gn +++ b/services/network/public/mojom/BUILD.gn
@@ -606,6 +606,7 @@ "isolation_info.mojom", "link_header.mojom", "load_timing_info.mojom", + "load_timing_internal_info.mojom", "network_change_manager.mojom", "network_interface.mojom", "network_interface_change_listener.mojom", @@ -832,6 +833,19 @@ { types = [ { + mojom = "network.mojom.LoadTimingInternalInfo" + cpp = "::net::LoadTimingInternalInfo" + }, + ] + traits_headers = [ "//services/network/public/cpp/load_timing_internal_info_mojom_traits.h" ] + traits_public_deps = [ + "//base", + "//net", + ] + }, + { + types = [ + { mojom = "network.mojom.NetworkInterface" cpp = "::net::NetworkInterface" },
diff --git a/services/network/public/mojom/load_timing_internal_info.mojom b/services/network/public/mojom/load_timing_internal_info.mojom new file mode 100644 index 0000000..10ced8f9 --- /dev/null +++ b/services/network/public/mojom/load_timing_internal_info.mojom
@@ -0,0 +1,12 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module network.mojom; + +import "mojo/public/mojom/base/time.mojom"; + +// Mirror of net::LoadTimingInternalInfo. +struct LoadTimingInternalInfo { + mojo_base.mojom.TimeDelta initialize_stream_delay; +};
diff --git a/services/network/public/mojom/network_service_test.mojom b/services/network/public/mojom/network_service_test.mojom index 2c475db9..204a233a 100644 --- a/services/network/public/mojom/network_service_test.mojom +++ b/services/network/public/mojom/network_service_test.mojom
@@ -259,4 +259,7 @@ // can be fully drained of tasks during network context shutdown. [EnableIf=is_win] DisableExclusiveCookieDatabaseLockingForTesting() => (); + + // Returns true if the HappyEyeballs V3 is enabled for testing. + IsHappyEyeballsV3Enabled() => (bool is_happy_eyeballs_v3_enabled); };
diff --git a/services/network/public/mojom/url_response_head.mojom b/services/network/public/mojom/url_response_head.mojom index 1e5b36d..72188dae 100644 --- a/services/network/public/mojom/url_response_head.mojom +++ b/services/network/public/mojom/url_response_head.mojom
@@ -16,6 +16,7 @@ import "services/network/public/mojom/ip_endpoint.mojom"; import "services/network/public/mojom/load_timing_info.mojom"; import "services/network/public/mojom/network_param.mojom"; +import "services/network/public/mojom/load_timing_internal_info.mojom"; import "services/network/public/mojom/source_type.mojom"; import "services/network/public/mojom/network_types.mojom"; import "services/network/public/mojom/parsed_headers.mojom"; @@ -75,6 +76,10 @@ // Tools. Includes socket ID and socket reuse information. LoadTimingInfo load_timing; + // Load timing internal information that is exposed only to trustworthy + // processes. Only provided if request has `trusted_params`. + LoadTimingInternalInfo? load_timing_internal_info; + // Set to true if the request had devtools_request_id set and OnRawRequest // and OnRawResponse are called on the corresponding DevToolsObserver. This // allows Chrome DevTools Protocol clients to know whether they should wait
diff --git a/services/network/sec_header_helpers.cc b/services/network/sec_header_helpers.cc index 290c9b8..878da237 100644 --- a/services/network/sec_header_helpers.cc +++ b/services/network/sec_header_helpers.cc
@@ -137,8 +137,7 @@ net::cookie_util::SecFetchStorageAccessOutcome ComputeSecFetchStorageAccessOutcome(const net::URLRequest& request, mojom::CredentialsMode credentials_mode) { - if (request.storage_access_status().IsSet() && - !request.storage_access_status().GetStatusForThirdPartyContext()) { + if (!request.storage_access_status().GetStatusForThirdPartyContext()) { return net::cookie_util::SecFetchStorageAccessOutcome:: kOmittedStatusMissing; } @@ -146,7 +145,6 @@ return net::cookie_util::SecFetchStorageAccessOutcome:: kOmittedRequestOmitsCredentials; } - CHECK(request.storage_access_status().IsSet()); switch ( request.storage_access_status().GetStatusForThirdPartyContext().value()) { case net::cookie_util::StorageAccessStatus::kInactive: @@ -207,8 +205,7 @@ ComputeSecFetchStorageAccessOutcome(request, credentials_mode)); if (credentials_mode != mojom::CredentialsMode::kInclude || - (request.storage_access_status().IsSet() && - !request.storage_access_status().GetStatusForThirdPartyContext())) { + !request.storage_access_status().GetStatusForThirdPartyContext()) { // A credentials mode of "same-origin" or "omit" prevents including cookies // on the request in the first place, so we don't bother to include the // `Sec-Fetch-Storage-Access` header in that case. @@ -219,7 +216,6 @@ request.RemoveRequestHeaderByName(kSecFetchStorageAccess); return; } - CHECK(request.storage_access_status().IsSet()); request.SetExtraRequestHeaderByName( kSecFetchStorageAccess, GetSecFetchStorageAccessHeaderValue(request.storage_access_status()
diff --git a/services/network/sec_header_helpers.h b/services/network/sec_header_helpers.h index 7b3997d..8245bd0 100644 --- a/services/network/sec_header_helpers.h +++ b/services/network/sec_header_helpers.h
@@ -27,9 +27,6 @@ // origins of |request.url_chain()| and |pending_redirect_url| against // |request.initiator()|. // -// `request->storage_access_status()` must be set if `credentials_mode` is not -// `mojom::CredentialsMode::kInclude`. -// // Note that |pending_redirect_url| is optional - it should be set only when // calling this method from net::URLRequest::Delegate::OnReceivedRedirect (in // this case |request.url_chain()| won't yet contain the URL being redirected
diff --git a/services/network/sec_header_helpers_unittest.cc b/services/network/sec_header_helpers_unittest.cc index ef5aee8b..4fd4352 100644 --- a/services/network/sec_header_helpers_unittest.cc +++ b/services/network/sec_header_helpers_unittest.cc
@@ -25,7 +25,6 @@ #include "services/network/public/mojom/fetch_api.mojom.h" #include "services/network/public/mojom/network_context.mojom.h" #include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest-death-test.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" #include "url/gurl.h" @@ -59,9 +58,9 @@ using testing::UnorderedElementsAreArray; -class SecHeaderHelpersTestBase : public PlatformTest { +class SecHeaderHelpersTest : public PlatformTest { public: - SecHeaderHelpersTestBase() + SecHeaderHelpersTest() : task_environment_(base::test::TaskEnvironment::MainThreadType::IO), context_(net::CreateTestURLRequestContextBuilder()->Build()), url_request_(context_->CreateRequest(GURL(kSecureSite), @@ -78,24 +77,13 @@ scoped_feature_list_.InitAndEnableFeature(features::kFrameAncestorHeaders); } - protected: + private: base::test::ScopedFeatureList scoped_feature_list_; base::test::TaskEnvironment task_environment_; std::unique_ptr<net::URLRequestContext> context_; std::unique_ptr<net::URLRequest> url_request_; }; -class SecHeaderHelpersTest : public SecHeaderHelpersTestBase { - public: - SecHeaderHelpersTest() = default; - - void SetUp() override { - SecHeaderHelpersTestBase::SetUp(); - url_request_->set_storage_access_status(net::StorageAccessStatusCache( - net::cookie_util::StorageAccessStatus::kNone)); - } -}; - // Validate that Sec- prefixed headers are all removed when a request is // downgraded from trustworthy to not such as when an https => http redirect // occurs. We should only remove sec-ch- and sec-fetch- prefixed headers. Others @@ -194,6 +182,8 @@ // unprivileged requests from chrome extension background page. TEST_F(SecHeaderHelpersTest, UnprivilegedRequestOnExtension) { net::URLRequest* current_url_request = url_request(); + url_request()->set_storage_access_status(net::StorageAccessStatusCache( + net::cookie_util::StorageAccessStatus::kNone)); GURL url = GURL(kSecureSite); // Set the request's net::IsolationInfo for Sec-Fetch-Frame-Top. @@ -231,6 +221,8 @@ // requests from chrome extension background page. TEST_F(SecHeaderHelpersTest, PrivilegedRequestOnExtension) { net::URLRequest* current_url_request = url_request(); + current_url_request->set_storage_access_status(net::StorageAccessStatusCache( + net::cookie_util::StorageAccessStatus::kNone)); GURL url = GURL(kSecureSite); // Set the request's net::IsolationInfo for Sec-Fetch-Frame-Top. @@ -303,8 +295,6 @@ void SetUp() override { scoped_feature_list_.InitAndEnableFeature(features::kFrameAncestorHeaders); - url_request_->set_storage_access_status(net::StorageAccessStatusCache( - net::cookie_util::StorageAccessStatus::kNone)); } private: @@ -371,13 +361,13 @@ }; class StorageAccessSecHeaderHelpersTest - : public SecHeaderHelpersTestBase, + : public SecHeaderHelpersTest, public testing::WithParamInterface<StorageAccessTestData> {}; TEST_P(StorageAccessSecHeaderHelpersTest, Serialization) { const StorageAccessTestData& test_data = GetParam(); net::URLRequest* current_url_request = url_request(); - current_url_request->set_storage_access_status(test_data.status); + url_request()->set_storage_access_status(test_data.status); GURL url = GURL(kSecureSite); base::HistogramTester histogram_tester; @@ -392,7 +382,8 @@ test_data.expected_value); histogram_tester.ExpectUniqueSample( "API.StorageAccessHeader.SecFetchStorageAccessOutcome", - /*sample=*/test_data.expected_sample, + /*sample=*/ + test_data.expected_sample, /*expected_bucket_count=*/1); } @@ -401,20 +392,6 @@ StorageAccessSecHeaderHelpersTest, testing::Values( StorageAccessTestData{ - net::StorageAccessStatusCache(), - mojom::CredentialsMode::kOmit, - std::nullopt, - net::cookie_util::SecFetchStorageAccessOutcome:: - kOmittedRequestOmitsCredentials, - }, - StorageAccessTestData{ - net::StorageAccessStatusCache(), - mojom::CredentialsMode::kSameOrigin, - std::nullopt, - net::cookie_util::SecFetchStorageAccessOutcome:: - kOmittedRequestOmitsCredentials, - }, - StorageAccessTestData{ net::StorageAccessStatusCache(std::nullopt), mojom::CredentialsMode::kOmit, std::nullopt, @@ -505,25 +482,6 @@ net::cookie_util::SecFetchStorageAccessOutcome::kValueActive, })); -#ifdef GTEST_HAS_DEATH_TEST -TEST_F( - SecHeaderHelpersTest, - StorageAccessSecHeaderHelpersCrashWithCredentialsModeIncludeWithoutStorageAccessStatus) { - net::URLRequest* current_url_request = url_request(); - current_url_request->set_storage_access_status( - net::StorageAccessStatusCache()); - GURL url = GURL(kSecureSite); - - EXPECT_DEATH_IF_SUPPORTED( - SetFetchMetadataHeaders( - current_url_request, network::mojom::RequestMode::kCors, - /*has_user_activation=*/false, - network::mojom::RequestDestination::kIframe, &url, {}, - /*origin_access_list=*/{}, mojom::CredentialsMode::kInclude), - "Check failed"); -} -#endif // GTEST_HAS_DEATH_TEST - // Parameterized test Suite for the Sec-Fetch-Frame-Top header. The // params of this test are GURLs, which are used to set the destination of // the test's url_request_ when it is constructed. @@ -539,8 +497,6 @@ TRAFFIC_ANNOTATION_FOR_TESTS)) { url_request_->set_initiator( url::Origin::Create(GURL(kPrivilegedInitiator))); - url_request_->set_storage_access_status(net::StorageAccessStatusCache( - net::cookie_util::StorageAccessStatus::kNone)); } net::URLRequest* url_request() const { return url_request_.get(); }
diff --git a/services/network/throttling/throttling_network_transaction.cc b/services/network/throttling/throttling_network_transaction.cc index 46a4050b..b059713 100644 --- a/services/network/throttling/throttling_network_transaction.cc +++ b/services/network/throttling/throttling_network_transaction.cc
@@ -258,6 +258,12 @@ return network_transaction_->GetLoadTimingInfo(load_timing_info); } +void ThrottlingNetworkTransaction::PopulateLoadTimingInternalInfo( + net::LoadTimingInternalInfo* load_timing_internal_info) const { + network_transaction_->PopulateLoadTimingInternalInfo( + load_timing_internal_info); +} + bool ThrottlingNetworkTransaction::GetRemoteEndpoint( net::IPEndPoint* endpoint) const { return network_transaction_->GetRemoteEndpoint(endpoint);
diff --git a/services/network/throttling/throttling_network_transaction.h b/services/network/throttling/throttling_network_transaction.h index f45d510..9c7e8dea 100644 --- a/services/network/throttling/throttling_network_transaction.h +++ b/services/network/throttling/throttling_network_transaction.h
@@ -26,6 +26,7 @@ class HttpResponseInfo; class IOBuffer; struct LoadTimingInfo; +struct LoadTimingInternalInfo; class NetLogWithSource; class X509Certificate; } // namespace net @@ -77,6 +78,8 @@ net::LoadState GetLoadState() const override; void SetQuicServerInfo(net::QuicServerInfo* quic_server_info) override; bool GetLoadTimingInfo(net::LoadTimingInfo* load_timing_info) const override; + void PopulateLoadTimingInternalInfo( + net::LoadTimingInternalInfo* load_timing_internal_info) const override; bool GetRemoteEndpoint(net::IPEndPoint* endpoint) const override; void PopulateNetErrorDetails(net::NetErrorDetails* details) const override; void SetPriority(net::RequestPriority priority) override;
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index 52404db..b759ba48 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc
@@ -46,6 +46,7 @@ #include "net/base/isolation_info.h" #include "net/base/load_flags.h" #include "net/base/load_timing_info.h" +#include "net/base/load_timing_internal_info.h" #include "net/base/mime_sniffer.h" #include "net/base/net_errors.h" #include "net/base/proxy_chain.h" @@ -734,6 +735,8 @@ include_request_cookies_with_response_( request.trusted_params && request.trusted_params->include_request_cookies_with_response), + include_load_timing_internal_info_with_response_( + request.trusted_params.has_value()), provide_data_use_updates_(context.DataUseUpdatesEnabled()), partial_decoder_decoding_buffer_size_(net::kMaxBytesToSniff) { DCHECK(delete_callback_); @@ -1690,6 +1693,13 @@ if (is_load_timing_enabled_) url_request_->GetLoadTimingInfo(&response->load_timing); + if (include_load_timing_internal_info_with_response_) { + response->load_timing_internal_info = + url_request_->GetLoadTimingInternalInfo(); + } + CHECK(include_load_timing_internal_info_with_response_ || + !response->load_timing_internal_info); + if (url_request_->ssl_info().cert.get()) { response->cert_status = url_request_->ssl_info().cert_status; if ((options_ & mojom::kURLLoadOptionSendSSLInfoWithResponse) || @@ -3568,10 +3578,6 @@ return net::cookie_util::ActivateStorageAccessLoadOutcome:: kFailureHeaderDisabled; } - if (!url_request_->storage_access_status().IsSet()) { - url_request_->set_storage_access_status( - url_request_->CalculateStorageAccessStatus()); - } if (!url_request_->storage_access_status() .GetStatusForThirdPartyContext()) { return net::cookie_util::ActivateStorageAccessLoadOutcome::
diff --git a/services/network/url_loader.h b/services/network/url_loader.h index 083bceb..1c9800e 100644 --- a/services/network/url_loader.h +++ b/services/network/url_loader.h
@@ -917,6 +917,9 @@ const bool include_request_cookies_with_response_ = false; net::cookie_util::ParsedRequestCookies request_cookies_; + // Specifies that the response head should include load timing internal info. + const bool include_load_timing_internal_info_with_response_; + std::vector<network::mojom::CookieAccessDetailsPtr> cookie_access_details_; const bool provide_data_use_updates_;
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc index 231aabc..6fcd9a7f 100644 --- a/services/network/url_loader_unittest.cc +++ b/services/network/url_loader_unittest.cc
@@ -8125,6 +8125,49 @@ delete_run_loop.Run(); } +// These tests verify that LoadTimingInternalInfo is only set for trustworthy +// loaders. + +TEST_P(ParameterizedURLLoaderTest, SetLoadTimingInternalInfoForTrustedLoaders) { + GURL url = test_server()->GetURL("/hello.html"); + + ResourceRequest request = CreateResourceRequest("GET", url); + ASSERT_TRUE(request.trusted_params); + + base::RunLoop delete_run_loop; + mojo::PendingRemote<mojom::URLLoader> loader; + std::unique_ptr<URLLoader> url_loader; + context().mutable_factory_params().process_id = mojom::kBrowserProcessId; + url_loader = URLLoaderOptions().MakeURLLoader( + context(), DeleteLoaderCallback(&delete_run_loop, &url_loader), + loader.InitWithNewPipeAndPassReceiver(), request, + client()->CreateRemote()); + + client()->RunUntilResponseBodyArrived(); + EXPECT_TRUE(client()->response_head()->load_timing_internal_info); +} + +TEST_P(ParameterizedURLLoaderTest, + DoNotSetLoadTimingInternalInfoForUntrustedLoaders) { + GURL url = test_server()->GetURL("/hello.html"); + + ResourceRequest request = CreateResourceRequest("GET", url); + // Clear trusted_params. + request.trusted_params = std::nullopt; + + base::RunLoop delete_run_loop; + mojo::PendingRemote<mojom::URLLoader> loader; + std::unique_ptr<URLLoader> url_loader; + context().mutable_factory_params().process_id = mojom::kBrowserProcessId; + url_loader = URLLoaderOptions().MakeURLLoader( + context(), DeleteLoaderCallback(&delete_run_loop, &url_loader), + loader.InitWithNewPipeAndPassReceiver(), request, + client()->CreateRemote()); + + client()->RunUntilResponseBodyArrived(); + EXPECT_FALSE(client()->response_head()->load_timing_internal_info); +} + class SharedStorageRequestHelperURLLoaderTest : public URLLoaderTest { public: void RegisterAdditionalHandlers() override {
diff --git a/services/on_device_model/ml/session_accessor.cc b/services/on_device_model/ml/session_accessor.cc index f95d9d7..d566b17f 100644 --- a/services/on_device_model/ml/session_accessor.cc +++ b/services/on_device_model/ml/session_accessor.cc
@@ -12,16 +12,6 @@ namespace { -// TODO(crbug.com/385173789): Pass enable_image_input via LoadAdaptationParams. -const base::FeatureParam<bool> kImageInput{ - &optimization_guide::features::kOptimizationGuideOnDeviceModel, - "on_device_model_image_input", false}; - -// TODO(crbug.com/385173368): Pass enable_audio_input via LoadAdaptationParams. -const base::FeatureParam<bool> kAudioInput{ - &optimization_guide::features::kOptimizationGuideOnDeviceModel, - "on_device_model_audio_input", false}; - float GetTemperature(std::optional<float> temperature) { return std::max(0.0f, temperature.value_or(0.0f)); } @@ -172,13 +162,6 @@ params->top_k = GetTopK(params->top_k); params->temperature = GetTemperature(params->temperature); } - if (kImageInput.Get()) { - params->capabilities.Put(on_device_model::CapabilityFlags::kImageInput); - } - if (kAudioInput.Get()) { - params->capabilities.Put(on_device_model::CapabilityFlags::kAudioInput); - } - ChromeMLAdaptationDescriptor descriptor = { .max_tokens = params->max_tokens, .top_k = params->top_k,
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 128d584..64a2109 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -14172,24 +14172,6 @@ ] } ], - "MacPlatformLocationProvider": [ - { - "platforms": [ - "mac" - ], - "experiments": [ - { - "name": "Enabled", - "params": { - "LocationProviderManagerMode": "HybridPlatform" - }, - "enable_features": [ - "LocationProviderManager" - ] - } - ] - } - ], "MagicStackGradientView": [ { "platforms": [ @@ -17308,6 +17290,21 @@ ] } ], + "PinweaverPasswords": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSLateBootPinweaverForPassword" + ] + } + ] + } + ], "PlainTextPainter": [ { "platforms": [
diff --git a/third_party/android_deps/autorolled/VERSION.txt b/third_party/android_deps/autorolled/VERSION.txt index 27b3f64..85f1704 100644 --- a/third_party/android_deps/autorolled/VERSION.txt +++ b/third_party/android_deps/autorolled/VERSION.txt
@@ -1 +1 @@ -2fb3b3a937db4bc \ No newline at end of file +21804f3aa633d70 \ No newline at end of file
diff --git a/third_party/android_deps/autorolled/bill_of_materials.json b/third_party/android_deps/autorolled/bill_of_materials.json index 1c78027..24e0b1d 100644 --- a/third_party/android_deps/autorolled/bill_of_materials.json +++ b/third_party/android_deps/autorolled/bill_of_materials.json
@@ -42,17 +42,17 @@ { "name": "appsearch", "group": "androidx.appsearch", - "version": "1.1.0-SNAPSHOT" + "version": "1.2.0-SNAPSHOT" }, { "name": "appsearch-builtin-types", "group": "androidx.appsearch", - "version": "1.1.0-SNAPSHOT" + "version": "1.2.0-SNAPSHOT" }, { "name": "appsearch-platform-storage", "group": "androidx.appsearch", - "version": "1.1.0-SNAPSHOT" + "version": "1.2.0-SNAPSHOT" }, { "name": "core-common",
diff --git a/third_party/android_deps/autorolled/build.gradle b/third_party/android_deps/autorolled/build.gradle index 959daf6..928aefc 100644 --- a/third_party/android_deps/autorolled/build.gradle +++ b/third_party/android_deps/autorolled/build.gradle
@@ -22,9 +22,9 @@ versionCache['androidx.annotation:annotation-jvm'] = '1.9.1' versionCache['androidx.appcompat:appcompat'] = '1.8.0-SNAPSHOT' versionCache['androidx.appcompat:appcompat-resources'] = '1.8.0-SNAPSHOT' -versionCache['androidx.appsearch:appsearch'] = '1.1.0-SNAPSHOT' -versionCache['androidx.appsearch:appsearch-builtin-types'] = '1.1.0-SNAPSHOT' -versionCache['androidx.appsearch:appsearch-platform-storage'] = '1.1.0-SNAPSHOT' +versionCache['androidx.appsearch:appsearch'] = '1.2.0-SNAPSHOT' +versionCache['androidx.appsearch:appsearch-builtin-types'] = '1.2.0-SNAPSHOT' +versionCache['androidx.appsearch:appsearch-platform-storage'] = '1.2.0-SNAPSHOT' versionCache['androidx.arch.core:core-common'] = '2.3.0-SNAPSHOT' versionCache['androidx.arch.core:core-runtime'] = '2.3.0-SNAPSHOT' versionCache['androidx.asynclayoutinflater:asynclayoutinflater'] = '1.1.0-SNAPSHOT'
diff --git a/third_party/angle b/third_party/angle index 316c99e1..d3c9719 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit 316c99e166dc22f08c8f8a91433d01a0a509a0a4 +Subproject commit d3c9719bf06e5664fc544246188ffec8497f0b56
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 9817083..44f228a 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -2684,6 +2684,15 @@ "latency_exact", true); +// This feature flag controls whether the WebAudio destination resampler is +// bypassed. When enabled, if the WebAudio context's sample rate differs from +// the hardware's sample rate, the resampling step that normally occurs within +// the WebAudio destination node is skipped. This allows the AudioService to +// handle any necessary resampling, potentially reducing latency and overhead. +BASE_FEATURE(kWebAudioRemoveAudioDestinationResampler, + "WebAudioRemoveAudioDestinationResampler", + base::FEATURE_DISABLED_BY_DEFAULT); + /// Enables cache-aware WebFonts loading. See https://crbug.com/570205. // The feature is disabled on Android for WebView API issue discussed at // https://crbug.com/942440.
diff --git a/third_party/blink/common/messaging/DEPS b/third_party/blink/common/messaging/DEPS new file mode 100644 index 0000000..0e55736f56 --- /dev/null +++ b/third_party/blink/common/messaging/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ +"+components/viz/common/resources/shared_image_format_utils.h", +]
diff --git a/third_party/blink/common/messaging/accelerated_static_bitmap_image_mojom_traits.cc b/third_party/blink/common/messaging/accelerated_static_bitmap_image_mojom_traits.cc index 71c291e2..a8b3e41 100644 --- a/third_party/blink/common/messaging/accelerated_static_bitmap_image_mojom_traits.cc +++ b/third_party/blink/common/messaging/accelerated_static_bitmap_image_mojom_traits.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/public/common/messaging/accelerated_static_bitmap_image_mojom_traits.h" +#include "components/viz/common/resources/shared_image_format_utils.h" #include "gpu/command_buffer/common/shared_image_usage.h" #include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" @@ -67,7 +68,8 @@ } out->size = gfx::Size(image_info.width(), image_info.height()); - out->sk_color_type = image_info.colorType(); + out->format = + viz::SkColorTypeToSinglePlaneSharedImageFormat(image_info.colorType()); out->alpha_type = image_info.alphaType(); out->sk_color_space = image_info.refColorSpace();
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index 70fad93..d5f36d0 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -1768,6 +1768,9 @@ bool, kWebAudioBypassOutputBufferingExact); +BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE( + kWebAudioRemoveAudioDestinationResampler); + BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kWebFontsCacheAwareTimeoutAdaption); // Combine WebRTC Network and Worker threads. More info at crbug.com/1373439.
diff --git a/third_party/blink/public/common/messaging/DEPS b/third_party/blink/public/common/messaging/DEPS new file mode 100644 index 0000000..0e55736f56 --- /dev/null +++ b/third_party/blink/public/common/messaging/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ +"+components/viz/common/resources/shared_image_format_utils.h", +]
diff --git a/third_party/blink/public/common/messaging/accelerated_image_info.h b/third_party/blink/public/common/messaging/accelerated_image_info.h index 268e5a1..9f9304e 100644 --- a/third_party/blink/public/common/messaging/accelerated_image_info.h +++ b/third_party/blink/public/common/messaging/accelerated_image_info.h
@@ -24,7 +24,7 @@ gpu::ExportedSharedImage shared_image; gpu::SyncToken sync_token; gfx::Size size; - SkColorType sk_color_type; + viz::SharedImageFormat format; SkAlphaType alpha_type; sk_sp<SkColorSpace> sk_color_space; base::OnceCallback<void(const gpu::SyncToken& sync_token)> release_callback;
diff --git a/third_party/blink/public/common/messaging/accelerated_static_bitmap_image_mojom_traits.h b/third_party/blink/public/common/messaging/accelerated_static_bitmap_image_mojom_traits.h index abbb051..51bd86a 100644 --- a/third_party/blink/public/common/messaging/accelerated_static_bitmap_image_mojom_traits.h +++ b/third_party/blink/public/common/messaging/accelerated_static_bitmap_image_mojom_traits.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_MESSAGING_ACCELERATED_STATIC_BITMAP_IMAGE_MOJOM_TRAITS_H_ #define THIRD_PARTY_BLINK_PUBLIC_COMMON_MESSAGING_ACCELERATED_STATIC_BITMAP_IMAGE_MOJOM_TRAITS_H_ +#include "components/viz/common/resources/shared_image_format_utils.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/blink/public/common/messaging/accelerated_image_info.h" #include "third_party/blink/public/mojom/messaging/static_bitmap_image.mojom.h" @@ -40,8 +41,8 @@ static SkImageInfo image_info(const blink::AcceleratedImageInfo& input) { return SkImageInfo::Make(gfx::SizeToSkISize(input.size), - input.sk_color_type, input.alpha_type, - input.sk_color_space); + viz::ToClosestSkColorType(input.format), + input.alpha_type, input.sk_color_space); } static mojo::PendingRemote<blink::mojom::ImageReleaseCallback>
diff --git a/third_party/blink/public/mojom/ai/ai_language_model.mojom b/third_party/blink/public/mojom/ai/ai_language_model.mojom index d08cc6b..db73362 100644 --- a/third_party/blink/public/mojom/ai/ai_language_model.mojom +++ b/third_party/blink/public/mojom/ai/ai_language_model.mojom
@@ -37,10 +37,10 @@ // The maximum number of tokens that the AILanguageModel can hold in the // context. When the new prompt or response is being stored in the context, // the AILanguageModel will ensure the context stores no more than - // `max_tokens`, by optionally evicting some oldest entries. - uint64 max_tokens; + // `input_quota`, by optionally evicting some oldest entries. + uint64 input_quota; // The number of tokens that are already in the context. - uint64 current_tokens; + uint64 input_usage; // The sampling params provided by the caller when creating the instance. AILanguageModelSamplingParams sampling_params; @@ -111,11 +111,11 @@ OnError(AIManagerCreateClientError error); }; -// The client interface that receives the number of tokens counted by the +// The client interface that receives the number of tokens measured by the // AIManager. -interface AILanguageModelCountPromptTokensClient { +interface AILanguageModelMeasureInputUsageClient { // Called with a created language model's mojo interface as a result for the - // CountPromptTokens() method of the AIManager. + // MeasureInputUsage() method of the AIManager. OnResult(uint32 number_of_tokens); }; @@ -141,8 +141,8 @@ Destroy(); // Counts the number of token in the given prompt text `input` which can // be an arbitrary string from the JavaScript API. - CountPromptTokens( + MeasureInputUsage( string input, - pending_remote<AILanguageModelCountPromptTokensClient> client + pending_remote<AILanguageModelMeasureInputUsageClient> client ); };
diff --git a/third_party/blink/public/mojom/ai/model_streaming_responder.mojom b/third_party/blink/public/mojom/ai/model_streaming_responder.mojom index 95514c9..a3dbced 100644 --- a/third_party/blink/public/mojom/ai/model_streaming_responder.mojom +++ b/third_party/blink/public/mojom/ai/model_streaming_responder.mojom
@@ -87,5 +87,5 @@ // order to make space for the newly added items. // This might be called multiple times after prompting, but it won't happen // after `OnCompletion()` or `OnError()`. - OnContextOverflow(); + OnQuotaOverflow(); };
diff --git a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom index 77a3c11..711549c 100644 --- a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom +++ b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
@@ -4526,7 +4526,7 @@ kV8AILanguageModel_Destroy_Method = 5142, kV8AILanguageModel_Prompt_Method = 5143, kV8AILanguageModel_PromptStreaming_Method = 5144, - kV8AILanguageModel_CountPromptTokens_Method = 5145, + kOBSOLETE_V8AILanguageModel_CountPromptTokens_Method = 5145, kV8AILanguageModelCapabilities_LanguageAvailable_Method = 5146, kV8AILanguageModelCapabilities_Available_AttributeGetter = 5147, kV8AILanguageModelCapabilities_DefaultTopK_AttributeGetter = 5148, @@ -4534,9 +4534,9 @@ kV8AILanguageModelCapabilities_DefaultTemperature_AttributeGetter = 5150, kV8AILanguageModelFactory_Capabilities_Method = 5151, kV8AILanguageModelFactory_Create_Method = 5152, - kV8AILanguageModel_MaxTokens_AttributeGetter = 5153, - kV8AILanguageModel_TokensSoFar_AttributeGetter = 5154, - kV8AILanguageModel_TokensLeft_AttributeGetter = 5155, + kOBSOLETE_V8AILanguageModel_MaxTokens_AttributeGetter = 5153, + kOBSOLETE_V8AILanguageModel_TokensSoFar_AttributeGetter = 5154, + kOBSOLETE_V8AILanguageModel_TokensLeft_AttributeGetter = 5155, kSvgContextFillOrStroke = 5156, kARIAActionsAttribute = 5157, kOBSOLETE_ResolveToConfigValueCoercedToTrue = 5158, @@ -4769,6 +4769,11 @@ kAriaNotify = 5383, kLanguageDetector_MeasureInputUsage = 5384, kLanguageDetector_InputQuota = 5385, + kV8AILanguageModel_InputUsage_AttributeGetter = 5386, + kV8AILanguageModel_InputQuota_AttributeGetter = 5387, + kV8AILanguageModel_MeasureInputUsage_Method = 5388, + kCredentialsGetImmediateMediationWithWebAuthnOnly = 5389, + kCredentialsGetImmediateMediationWithWebAuthnAndPasswords = 5390, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots. Also don't add extra
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h index 1e84e382..336f771 100644 --- a/third_party/blink/public/platform/platform.h +++ b/third_party/blink/public/platform/platform.h
@@ -213,6 +213,7 @@ const WebAudioSinkDescriptor& sink_descriptor, unsigned number_of_output_channels, const WebAudioLatencyHint& latency_hint, + std::optional<float> context_sample_rate, media::AudioRendererSink::RenderCallback*) { return nullptr; }
diff --git a/third_party/blink/renderer/controller/blink_initializer.cc b/third_party/blink/renderer/controller/blink_initializer.cc index 7bcd9ad..433173ef 100644 --- a/third_party/blink/renderer/controller/blink_initializer.cc +++ b/third_party/blink/renderer/controller/blink_initializer.cc
@@ -300,9 +300,8 @@ UserLevelMemoryPressureSignalGenerator::Initialize(platform, main_thread_task_runner); } - - MemorySaverController::Initialize(); #endif + MemorySaverController::Initialize(); #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \ BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_WIN)
diff --git a/third_party/blink/renderer/core/events/event_type_names.json5 b/third_party/blink/renderer/core/events/event_type_names.json5 index 6d36b44a..a2187f4 100644 --- a/third_party/blink/renderer/core/events/event_type_names.json5 +++ b/third_party/blink/renderer/core/events/event_type_names.json5
@@ -90,7 +90,6 @@ "contentvisibilityautostatechange", "contextlost", "contextmenu", - "contextoverflow", "contextrestored", "controllerchange", "cookiechange", @@ -257,6 +256,7 @@ "push", "pushsubscriptionchange", "quicstream", + "quotaoverflow", "ratechange", "readeradd", "readerremove",
diff --git a/third_party/blink/renderer/core/html/custom/element_internals.cc b/third_party/blink/renderer/core/html/custom/element_internals.cc index f1757ac..49be5fb 100644 --- a/third_party/blink/renderer/core/html/custom/element_internals.cc +++ b/third_party/blink/renderer/core/html/custom/element_internals.cc
@@ -140,14 +140,16 @@ NotifyFormStateChanged(); } -HTMLFormElement* ElementInternals::form(ExceptionState& exception_state) const { +HTMLElement* ElementInternals::formForBinding( + ExceptionState& exception_state) const { if (!IsTargetFormAssociated()) { exception_state.ThrowDOMException( DOMExceptionCode::kNotSupportedError, "The target element is not a form-associated custom element."); return nullptr; } - return ListedElement::Form(); + + return ListedElement::RetargetedForm(); } void ElementInternals::setValidity(ValidityStateFlags* flags,
diff --git a/third_party/blink/renderer/core/html/custom/element_internals.h b/third_party/blink/renderer/core/html/custom/element_internals.h index 7087a0b2..58510b5 100644 --- a/third_party/blink/renderer/core/html/custom/element_internals.h +++ b/third_party/blink/renderer/core/html/custom/element_internals.h
@@ -44,7 +44,7 @@ void setFormValue(const V8ControlValue* value, const V8ControlValue* state, ExceptionState& exception_state); - HTMLFormElement* form(ExceptionState& exception_state) const; + HTMLElement* formForBinding(ExceptionState& exception_state) const; void setValidity(ValidityStateFlags* flags, ExceptionState& exception_state); void setValidity(ValidityStateFlags* flags, const String& message,
diff --git a/third_party/blink/renderer/core/html/custom/element_internals.idl b/third_party/blink/renderer/core/html/custom/element_internals.idl index 01b8c862..176b762 100644 --- a/third_party/blink/renderer/core/html/custom/element_internals.idl +++ b/third_party/blink/renderer/core/html/custom/element_internals.idl
@@ -13,7 +13,9 @@ // Attributes and operations for form-associated custom elements. [RaisesException] void setFormValue(ControlValue? value, optional ControlValue? state); - [RaisesException] readonly attribute HTMLFormElement? form; + // Until ReferenceTarget is enabled, this will only ever return HTMLFormElement. + // https://github.com/whatwg/html/pull/10995 + [RaisesException, ImplementedAs=formForBinding] readonly attribute HTMLElement? form; [RaisesException] void setValidity(ValidityStateFlags flags, optional DOMString message, optional HTMLElement anchor); [RaisesException] readonly attribute boolean willValidate;
diff --git a/third_party/blink/renderer/core/html/forms/html_button_element.idl b/third_party/blink/renderer/core/html/forms/html_button_element.idl index ee38328..9f59796 100644 --- a/third_party/blink/renderer/core/html/forms/html_button_element.idl +++ b/third_party/blink/renderer/core/html/forms/html_button_element.idl
@@ -24,7 +24,9 @@ HTMLConstructor ] interface HTMLButtonElement : HTMLElement { [CEReactions, Reflect] attribute boolean disabled; - [ImplementedAs=formOwner] readonly attribute HTMLFormElement? form; + // Until ReferenceTarget is enabled, this will only ever return HTMLFormElement. + // https://github.com/whatwg/html/pull/10995 + [ImplementedAs=formForBinding] readonly attribute HTMLElement? form; [CEReactions] attribute USVString formAction; [CEReactions] attribute DOMString formEnctype; [CEReactions] attribute DOMString formMethod;
diff --git a/third_party/blink/renderer/core/html/forms/html_field_set_element.idl b/third_party/blink/renderer/core/html/forms/html_field_set_element.idl index f9b20c2c..2f5c94c6 100644 --- a/third_party/blink/renderer/core/html/forms/html_field_set_element.idl +++ b/third_party/blink/renderer/core/html/forms/html_field_set_element.idl
@@ -23,7 +23,9 @@ HTMLConstructor ] interface HTMLFieldSetElement : HTMLElement { [CEReactions, Reflect] attribute boolean disabled; - [ImplementedAs=formOwner] readonly attribute HTMLFormElement? form; + // Until ReferenceTarget is enabled, this will only ever return HTMLFormElement. + // https://github.com/whatwg/html/pull/10995 + [ImplementedAs=formForBinding] readonly attribute HTMLElement? form; [CEReactions, Reflect] attribute DOMString name; readonly attribute DOMString type;
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 71a5406..0683842 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
@@ -268,6 +268,13 @@ formOwner()->InvalidateDefaultButtonStyle(); } +// Note HTMLFormControlElement also inherits from HTMLElement, which has its own +// formForBinding for non-form control elements. This function is needed to +// ensure we are calling the correct version from ListedElement. +HTMLElement* HTMLFormControlElement::formForBinding() const { + return ListedElement::RetargetedForm(); +} + HTMLFormElement* HTMLFormControlElement::formOwner() const { return ListedElement::Form(); }
diff --git a/third_party/blink/renderer/core/html/forms/html_form_control_element.h b/third_party/blink/renderer/core/html/forms/html_form_control_element.h index 02c8194..c52ecc8 100644 --- a/third_party/blink/renderer/core/html/forms/html_form_control_element.h +++ b/third_party/blink/renderer/core/html/forms/html_form_control_element.h
@@ -62,6 +62,7 @@ void DetachLayoutTree(bool performing_reattach) override; HTMLFormElement* formOwner() const final; + HTMLElement* formForBinding() const final; bool IsDisabledFormControl() const override;
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.cc b/third_party/blink/renderer/core/html/forms/html_input_element.cc index cf74d4b..c84f87c 100644 --- a/third_party/blink/renderer/core/html/forms/html_input_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_input_element.cc
@@ -1839,6 +1839,16 @@ return nullptr; } + if (RuntimeEnabledFeatures::ShadowRootReferenceTargetEnabled( + GetExecutionContext())) { + if (IsA<HTMLDataListElement>(GetElementAttributeResolvingReferenceTarget( + html_names::kListAttr))) { + // Return the host to avoid exposing the shadow dom. + return DynamicTo<HTMLElement>(GetElementAttribute(html_names::kListAttr)); + } + return nullptr; + } + return DynamicTo<HTMLDataListElement>( GetElementAttribute(html_names::kListAttr)); }
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.idl b/third_party/blink/renderer/core/html/forms/html_input_element.idl index 2913f10..d8f1bd6 100644 --- a/third_party/blink/renderer/core/html/forms/html_input_element.idl +++ b/third_party/blink/renderer/core/html/forms/html_input_element.idl
@@ -35,7 +35,9 @@ [ImplementedAs=checkedForBinding] attribute boolean checked; [CEReactions, Reflect] attribute DOMString dirName; [CEReactions, Reflect] attribute boolean disabled; - [ImplementedAs=formOwner] readonly attribute HTMLFormElement? form; + // Until ReferenceTarget is enabled, this will only ever return HTMLFormElement. + // https://github.com/whatwg/html/pull/10995 + [ImplementedAs=formForBinding] readonly attribute HTMLElement? form; // The 'files' attribute is intentionally not readonly. // https://www.w3.org/Bugs/Public/show_bug.cgi?id=22682 attribute FileList? files;
diff --git a/third_party/blink/renderer/core/html/forms/html_label_element.cc b/third_party/blink/renderer/core/html/forms/html_label_element.cc index f827207..4b08f5c3 100644 --- a/third_party/blink/renderer/core/html/forms/html_label_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_label_element.cc
@@ -39,6 +39,7 @@ #include "third_party/blink/renderer/core/html/custom/element_internals.h" #include "third_party/blink/renderer/core/html/forms/html_button_element.h" #include "third_party/blink/renderer/core/html/forms/html_form_control_element.h" +#include "third_party/blink/renderer/core/html/forms/html_form_element.h" #include "third_party/blink/renderer/core/html/forms/html_select_element.h" #include "third_party/blink/renderer/core/html/forms/listed_element.h" #include "third_party/blink/renderer/core/html_names.h" @@ -106,12 +107,16 @@ return control; } -HTMLFormElement* HTMLLabelElement::form() const { - if (HTMLElement* control = Control()) { - if (auto* form_control_element = DynamicTo<HTMLFormControlElement>(control)) - return form_control_element->Form(); - if (control->IsFormAssociatedCustomElement()) - return control->EnsureElementInternals().Form(); +HTMLElement* HTMLLabelElement::formForBinding() const { + HTMLElement* control = Control(); + if (!control) { + return nullptr; + } + if (auto* form_control_element = DynamicTo<HTMLFormControlElement>(control)) { + return form_control_element->RetargetedForm(); + } + if (control->IsFormAssociatedCustomElement()) { + return control->EnsureElementInternals().RetargetedForm(); } return nullptr; }
diff --git a/third_party/blink/renderer/core/html/forms/html_label_element.h b/third_party/blink/renderer/core/html/forms/html_label_element.h index 1aef8413..d602da6 100644 --- a/third_party/blink/renderer/core/html/forms/html_label_element.h +++ b/third_party/blink/renderer/core/html/forms/html_label_element.h
@@ -38,7 +38,7 @@ HTMLElement* controlForBinding() const; HTMLElement* Control() const; - HTMLFormElement* form() const; + HTMLElement* formForBinding() const override; bool WillRespondToMouseClickEvents() override;
diff --git a/third_party/blink/renderer/core/html/forms/html_label_element.idl b/third_party/blink/renderer/core/html/forms/html_label_element.idl index e7ea73f..30eca45 100644 --- a/third_party/blink/renderer/core/html/forms/html_label_element.idl +++ b/third_party/blink/renderer/core/html/forms/html_label_element.idl
@@ -23,7 +23,9 @@ Exposed=Window, HTMLConstructor ] interface HTMLLabelElement : HTMLElement { - readonly attribute HTMLFormElement? form; + // Until ReferenceTarget is enabled, this will only ever return HTMLFormElement. + // https://github.com/whatwg/html/pull/10995 + [ImplementedAs=formForBinding] readonly attribute HTMLElement? form; [CEReactions, Reflect=for] attribute DOMString htmlFor; [ImplementedAs=controlForBinding] readonly attribute HTMLElement? control; };
diff --git a/third_party/blink/renderer/core/html/forms/html_legend_element.cc b/third_party/blink/renderer/core/html/forms/html_legend_element.cc index 2bee478b..5604ced 100644 --- a/third_party/blink/renderer/core/html/forms/html_legend_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_legend_element.cc
@@ -36,12 +36,12 @@ HTMLLegendElement::HTMLLegendElement(Document& document) : HTMLElement(html_names::kLegendTag, document) {} -HTMLFormElement* HTMLLegendElement::form() const { +HTMLElement* HTMLLegendElement::formForBinding() const { // According to the specification, If the legend has a fieldset element as // its parent, then the form attribute must return the same value as the // form attribute on that fieldset element. Otherwise, it must return null. if (auto* fieldset = DynamicTo<HTMLFieldSetElement>(parentNode())) - return fieldset->formOwner(); + return fieldset->formForBinding(); return nullptr; }
diff --git a/third_party/blink/renderer/core/html/forms/html_legend_element.h b/third_party/blink/renderer/core/html/forms/html_legend_element.h index 0fbd78e..2f922da 100644 --- a/third_party/blink/renderer/core/html/forms/html_legend_element.h +++ b/third_party/blink/renderer/core/html/forms/html_legend_element.h
@@ -34,7 +34,7 @@ public: explicit HTMLLegendElement(Document&); - HTMLFormElement* form() const; + HTMLElement* formForBinding() const override; private: void DetachLayoutTree(bool performing_reattach) override;
diff --git a/third_party/blink/renderer/core/html/forms/html_legend_element.idl b/third_party/blink/renderer/core/html/forms/html_legend_element.idl index 6b0a63b..a1071e6 100644 --- a/third_party/blink/renderer/core/html/forms/html_legend_element.idl +++ b/third_party/blink/renderer/core/html/forms/html_legend_element.idl
@@ -23,7 +23,9 @@ Exposed=Window, HTMLConstructor ] interface HTMLLegendElement : HTMLElement { - readonly attribute HTMLFormElement? form; + // Until ReferenceTarget is enabled, this will only ever return HTMLFormElement. + // https://github.com/whatwg/html/pull/10995 + [ImplementedAs=formForBinding] readonly attribute HTMLElement? form; // obsolete members // https://html.spec.whatwg.org/C/#HTMLLegendElement-partial
diff --git a/third_party/blink/renderer/core/html/forms/html_option_element.cc b/third_party/blink/renderer/core/html/forms/html_option_element.cc index ec70c986..905f8f2 100644 --- a/third_party/blink/renderer/core/html/forms/html_option_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_option_element.cc
@@ -453,9 +453,9 @@ return text.ToString(); } -HTMLFormElement* HTMLOptionElement::form() const { +HTMLElement* HTMLOptionElement::formForBinding() const { if (HTMLSelectElement* select_element = OwnerSelectElement()) - return select_element->formOwner(); + return select_element->formForBinding(); return nullptr; }
diff --git a/third_party/blink/renderer/core/html/forms/html_option_element.h b/third_party/blink/renderer/core/html/forms/html_option_element.h index 0826e384..81f4db4 100644 --- a/third_party/blink/renderer/core/html/forms/html_option_element.h +++ b/third_party/blink/renderer/core/html/forms/html_option_element.h
@@ -100,7 +100,7 @@ // Update 'dirtiness'. void SetDirty(bool); - HTMLFormElement* form() const; + HTMLElement* formForBinding() const override; bool SpatialNavigationFocused() const; bool IsDisplayNone(bool ensure_style);
diff --git a/third_party/blink/renderer/core/html/forms/html_option_element.idl b/third_party/blink/renderer/core/html/forms/html_option_element.idl index 30f91ec..512fa90 100644 --- a/third_party/blink/renderer/core/html/forms/html_option_element.idl +++ b/third_party/blink/renderer/core/html/forms/html_option_element.idl
@@ -32,7 +32,9 @@ [HTMLConstructor] constructor(); [CEReactions, Reflect] attribute boolean disabled; - readonly attribute HTMLFormElement? form; + // Until ReferenceTarget is enabled, this will only ever return HTMLFormElement. + // https://github.com/whatwg/html/pull/10995 + [ImplementedAs=formForBinding] readonly attribute HTMLElement? form; [CEReactions] attribute DOMString label; [CEReactions, Reflect=selected] attribute boolean defaultSelected; [ImplementedAs=selectedForBinding] attribute boolean selected;
diff --git a/third_party/blink/renderer/core/html/forms/html_output_element.idl b/third_party/blink/renderer/core/html/forms/html_output_element.idl index 369394a6c..9002e2a 100644 --- a/third_party/blink/renderer/core/html/forms/html_output_element.idl +++ b/third_party/blink/renderer/core/html/forms/html_output_element.idl
@@ -29,7 +29,9 @@ HTMLConstructor ] interface HTMLOutputElement : HTMLElement { [PutForwards=value] readonly attribute DOMTokenList htmlFor; - [ImplementedAs=formOwner] readonly attribute HTMLFormElement? form; + // Until ReferenceTarget is enabled, this will only ever return HTMLFormElement. + // https://github.com/whatwg/html/pull/10995 + [ImplementedAs=formForBinding] readonly attribute HTMLElement? form; [CEReactions, Reflect] attribute DOMString name; readonly attribute DOMString type;
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.idl b/third_party/blink/renderer/core/html/forms/html_select_element.idl index 71e2566..67f3309 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.idl +++ b/third_party/blink/renderer/core/html/forms/html_select_element.idl
@@ -26,7 +26,9 @@ ] interface HTMLSelectElement : HTMLElement { [CEReactions, ImplementedAs=IDLExposedAutofillValue] attribute DOMString autocomplete; [CEReactions, Reflect] attribute boolean disabled; - [ImplementedAs=formOwner] readonly attribute HTMLFormElement? form; + // Until ReferenceTarget is enabled, this will only ever return HTMLFormElement. + // https://github.com/whatwg/html/pull/10995 + [ImplementedAs=formForBinding] readonly attribute HTMLElement? form; [CEReactions, Reflect] attribute boolean multiple; [CEReactions, Reflect] attribute DOMString name; [CEReactions, Reflect] attribute boolean required;
diff --git a/third_party/blink/renderer/core/html/forms/html_text_area_element.idl b/third_party/blink/renderer/core/html/forms/html_text_area_element.idl index 7dc6238..79fca97 100644 --- a/third_party/blink/renderer/core/html/forms/html_text_area_element.idl +++ b/third_party/blink/renderer/core/html/forms/html_text_area_element.idl
@@ -28,7 +28,9 @@ [CEReactions] attribute unsigned long cols; [CEReactions, Reflect] attribute DOMString dirName; [CEReactions, Reflect] attribute boolean disabled; - [ImplementedAs=formOwner] readonly attribute HTMLFormElement? form; + // Until ReferenceTarget is enabled, this will only ever return HTMLFormElement. + // https://github.com/whatwg/html/pull/10995 + [ImplementedAs=formForBinding] readonly attribute HTMLElement? form; [CEReactions, RaisesException=Setter] attribute long maxLength; [CEReactions, RaisesException=Setter] attribute long minLength; [CEReactions, Reflect] attribute DOMString name;
diff --git a/third_party/blink/renderer/core/html/forms/listed_element.cc b/third_party/blink/renderer/core/html/forms/listed_element.cc index c6b6983..49200ed 100644 --- a/third_party/blink/renderer/core/html/forms/listed_element.cc +++ b/third_party/blink/renderer/core/html/forms/listed_element.cc
@@ -292,6 +292,20 @@ (field_set = Traversal<HTMLFieldSetElement>::FirstAncestor(*field_set))); } +HTMLElement* ListedElement::RetargetedForm() const { + auto* form = Form(); + if (!form) { + return nullptr; + } + const HTMLElement& element = ToHTMLElement(); + if (RuntimeEnabledFeatures::ShadowRootReferenceTargetEnabled( + element.GetDocument().GetExecutionContext())) { + // Retarget to avoid exposing reference target elements. + return DynamicTo<HTMLElement>(&element.GetTreeScope().Retarget(*form)); + } + return form; +} + // https://html.spec.whatwg.org/multipage/C#reset-the-form-owner void ListedElement::ResetFormOwner() { // 1. Unset element's parser inserted flag. @@ -321,6 +335,14 @@ Element* new_form_candidate = element.GetTreeScope().getElementById(form_id); new_form = DynamicTo<HTMLFormElement>(new_form_candidate); + + if (RuntimeEnabledFeatures::ShadowRootReferenceTargetEnabled( + element.GetDocument().GetExecutionContext()) && + new_form_candidate) { + new_form = DynamicTo<HTMLFormElement>( + new_form_candidate->GetShadowReferenceTargetOrSelf( + html_names::kFormAttr)); + } } else { // 5. Otherwise, if element has an ancestor form element, then associate // element with the nearest such ancestor form element.
diff --git a/third_party/blink/renderer/core/html/forms/listed_element.h b/third_party/blink/renderer/core/html/forms/listed_element.h index 2b448ec..ca21ac1 100644 --- a/third_party/blink/renderer/core/html/forms/listed_element.h +++ b/third_party/blink/renderer/core/html/forms/listed_element.h
@@ -59,6 +59,10 @@ const HTMLElement& ToHTMLElement() const; HTMLElement& ToHTMLElement(); + // Returns the associated form element or its host element if the form is + // associated through reference target. + HTMLElement* RetargetedForm() const; + // Returns the associated form element. HTMLFormElement* Form() const { return form_.Get(); } ValidityState* validity();
diff --git a/third_party/blink/renderer/core/html/html_element.cc b/third_party/blink/renderer/core/html/html_element.cc index b7d7fd4..090af373 100644 --- a/third_party/blink/renderer/core/html/html_element.cc +++ b/third_party/blink/renderer/core/html/html_element.cc
@@ -2489,9 +2489,17 @@ setAttribute(html_names::kDirAttr, value); } +HTMLElement* HTMLElement::formForBinding() const { + if (const auto* internals = GetElementInternals()) { + return internals->RetargetedForm(); + } + return nullptr; +} + HTMLFormElement* HTMLElement::formOwner() const { - if (const auto* internals = GetElementInternals()) + if (const auto* internals = GetElementInternals()) { return internals->Form(); + } return nullptr; }
diff --git a/third_party/blink/renderer/core/html/html_element.h b/third_party/blink/renderer/core/html/html_element.h index 30b96c53..de44b1b 100644 --- a/third_party/blink/renderer/core/html/html_element.h +++ b/third_party/blink/renderer/core/html/html_element.h
@@ -158,6 +158,7 @@ bool ShouldSerializeEndTag() const; virtual HTMLFormElement* formOwner() const; + virtual HTMLElement* formForBinding() const; HTMLFormElement* FindFormAncestor() const;
diff --git a/third_party/blink/renderer/core/html/html_object_element.cc b/third_party/blink/renderer/core/html/html_object_element.cc index 48671af..84319d0 100644 --- a/third_party/blink/renderer/core/html/html_object_element.cc +++ b/third_party/blink/renderer/core/html/html_object_element.cc
@@ -374,6 +374,10 @@ return ListedElement::Form(); } +HTMLElement* HTMLObjectElement::formForBinding() const { + return ListedElement::RetargetedForm(); +} + bool HTMLObjectElement::UseFallbackContent() const { return HTMLPlugInElement::UseFallbackContent() || use_fallback_content_; }
diff --git a/third_party/blink/renderer/core/html/html_object_element.h b/third_party/blink/renderer/core/html/html_object_element.h index 3108e3c..c388ffa 100644 --- a/third_party/blink/renderer/core/html/html_object_element.h +++ b/third_party/blink/renderer/core/html/html_object_element.h
@@ -54,6 +54,7 @@ const String& ClassId() const { return class_id_; } HTMLFormElement* formOwner() const override; + HTMLElement* formForBinding() const override; bool ContainsJavaApplet() const;
diff --git a/third_party/blink/renderer/core/html/html_object_element.idl b/third_party/blink/renderer/core/html/html_object_element.idl index 8ea4dcfc..9dd7c80 100644 --- a/third_party/blink/renderer/core/html/html_object_element.idl +++ b/third_party/blink/renderer/core/html/html_object_element.idl
@@ -31,7 +31,9 @@ [CEReactions, Reflect] attribute DOMString type; [CEReactions, Reflect] attribute DOMString name; [CEReactions, Reflect] attribute DOMString useMap; - [ImplementedAs=formOwner] readonly attribute HTMLFormElement? form; + // Until ReferenceTarget is enabled, this will only ever return HTMLFormElement. + // https://github.com/whatwg/html/pull/10995 + [ImplementedAs=formForBinding] readonly attribute HTMLElement? form; [CEReactions, Reflect] attribute DOMString width; [CEReactions, Reflect] attribute DOMString height; [CheckSecurity=ReturnValue] readonly attribute Document? contentDocument;
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message.cc b/third_party/blink/renderer/core/messaging/blink_transferable_message.cc index 26dd942..34ca8d1 100644 --- a/third_party/blink/renderer/core/messaging/blink_transferable_message.cc +++ b/third_party/blink/renderer/core/messaging/blink_transferable_message.cc
@@ -144,8 +144,7 @@ scoped_refptr<StaticBitmapImage> WrapAcceleratedBitmapImage( AcceleratedImageInfo image) { return AcceleratedStaticBitmapImage::CreateFromExternalSharedImage( - std::move(image.shared_image), image.sync_token, - gfx::Size(image.size.width(), image.size.height()), image.sk_color_type, + std::move(image.shared_image), image.sync_token, image.size, image.format, image.alpha_type, image.sk_color_space, std::move(image.release_callback)); }
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.cc b/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.cc index c605ef5..ec906ff9 100644 --- a/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.cc +++ b/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.cc
@@ -60,7 +60,7 @@ blink::mojom::blink::SerializedStaticBitmapImage::NewAcceleratedImage( blink::AcceleratedImageInfo{ shared_image->Export(), cloned_image->GetSyncToken(), - cloned_image->GetSize(), cloned_image->GetSkColorType(), + cloned_image->GetSize(), cloned_image->GetSharedImageFormat(), cloned_image->GetAlphaType(), cloned_image->GetSkColorSpace(), WTF::BindOnce(&blink::StaticBitmapImage::UpdateSyncToken, std::move(cloned_image))});
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h index 5d6be984..cd66273b 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -741,7 +741,7 @@ ax::mojom::blink::Action event_from_action; BlinkAXEventIntentsSet event_intents; - virtual ~TreeUpdateParams() = default; + ~TreeUpdateParams() = default; void Trace(Visitor* visitor) const { visitor->Trace(node); } std::string ToString(); };
diff --git a/third_party/blink/renderer/modules/ai/ai_language_model.cc b/third_party/blink/renderer/modules/ai/ai_language_model.cc index e223794..20a00cf 100644 --- a/third_party/blink/renderer/modules/ai/ai_language_model.cc +++ b/third_party/blink/renderer/modules/ai/ai_language_model.cc
@@ -115,30 +115,30 @@ receiver_; }; -class CountPromptTokensClient - : public GarbageCollected<CountPromptTokensClient>, - public mojom::blink::AILanguageModelCountPromptTokensClient, - public AIContextObserver<IDLUnsignedLongLong> { +class MeasureInputUsageClient + : public GarbageCollected<MeasureInputUsageClient>, + public mojom::blink::AILanguageModelMeasureInputUsageClient, + public AIContextObserver<IDLDouble> { public: - CountPromptTokensClient(ScriptState* script_state, + MeasureInputUsageClient(ScriptState* script_state, AILanguageModel* language_model, - ScriptPromiseResolver<IDLUnsignedLongLong>* resolver, + ScriptPromiseResolver<IDLDouble>* resolver, AbortSignal* signal, const WTF::String& input) : AIContextObserver(script_state, language_model, resolver, signal), language_model_(language_model), receiver_(this, language_model->GetExecutionContext()) { - mojo::PendingRemote<mojom::blink::AILanguageModelCountPromptTokensClient> + mojo::PendingRemote<mojom::blink::AILanguageModelMeasureInputUsageClient> client_remote; receiver_.Bind(client_remote.InitWithNewPipeAndPassReceiver(), language_model->GetTaskRunner()); - language_model_->GetAILanguageModelRemote()->CountPromptTokens( + language_model_->GetAILanguageModelRemote()->MeasureInputUsage( input, std::move(client_remote)); } - ~CountPromptTokensClient() override = default; + ~MeasureInputUsageClient() override = default; - CountPromptTokensClient(const CountPromptTokensClient&) = delete; - CountPromptTokensClient& operator=(const CountPromptTokensClient&) = delete; + MeasureInputUsageClient(const MeasureInputUsageClient&) = delete; + MeasureInputUsageClient& operator=(const MeasureInputUsageClient&) = delete; void Trace(Visitor* visitor) const override { AIContextObserver::Trace(visitor); @@ -146,7 +146,7 @@ visitor->Trace(receiver_); } - // mojom::blink::AILanguageModelCountPromptTokensClient implementation. + // mojom::blink::AILanguageModelMeasureInputUsageClient implementation. void OnResult(uint32_t number_of_tokens) override { if (!GetResolver()) { return; @@ -161,8 +161,8 @@ private: Member<AILanguageModel> language_model_; - HeapMojoReceiver<mojom::blink::AILanguageModelCountPromptTokensClient, - CountPromptTokensClient> + HeapMojoReceiver<mojom::blink::AILanguageModelMeasureInputUsageClient, + MeasureInputUsageClient> receiver_; }; @@ -374,8 +374,8 @@ language_model_remote_(execution_context) { language_model_remote_.Bind(std::move(pending_remote), task_runner); if (info) { - max_tokens_ = info->max_tokens; - current_tokens_ = info->current_tokens; + input_quota_ = info->input_quota; + input_usage_ = info->input_usage; top_k_ = info->sampling_params->top_k; temperature_ = info->sampling_params->temperature; } @@ -451,7 +451,7 @@ AIMetrics::AISessionType::kLanguageModel, WTF::BindOnce(&AILanguageModel::OnResponseComplete, WrapWeakPersistent(this)), - WTF::BindRepeating(&AILanguageModel::OnContextOverflow, + WTF::BindRepeating(&AILanguageModel::OnQuotaOverflow, WrapWeakPersistent(this))); language_model_remote_->Prompt(std::move(prompts).value(), std::move(pending_remote)); @@ -513,7 +513,7 @@ AIMetrics::AISessionType::kLanguageModel, WTF::BindOnce(&AILanguageModel::OnResponseComplete, WrapWeakPersistent(this)), - WTF::BindRepeating(&AILanguageModel::OnContextOverflow, + WTF::BindRepeating(&AILanguageModel::OnQuotaOverflow, WrapWeakPersistent(this))); language_model_remote_->Prompt(std::move(prompts).value(), @@ -556,23 +556,28 @@ return promise; } -ScriptPromise<IDLUnsignedLongLong> AILanguageModel::countPromptTokens( +ScriptPromise<IDLDouble> AILanguageModel::measureInputUsage( ScriptState* script_state, - const WTF::String& input, + const V8AILanguageModelPromptInput* input, const AILanguageModelPromptOptions* options, ExceptionState& exception_state) { if (!script_state->ContextIsValid()) { ThrowInvalidContextException(exception_state); - return ScriptPromise<IDLUnsignedLongLong>(); + return ScriptPromise<IDLDouble>(); + } + + // The API impl only accepts a string by default for now, more to come soon! + if (!input->IsString()) { + exception_state.ThrowTypeError("Input type not supported"); + return ScriptPromise<IDLDouble>(); } base::UmaHistogramEnumeration(AIMetrics::GetAIAPIUsageMetricName( AIMetrics::AISessionType::kLanguageModel), AIMetrics::AIAPI::kSessionCountPromptTokens); - ScriptPromiseResolver<IDLUnsignedLongLong>* resolver = - MakeGarbageCollected<ScriptPromiseResolver<IDLUnsignedLongLong>>( - script_state); + ScriptPromiseResolver<IDLDouble>* resolver = + MakeGarbageCollected<ScriptPromiseResolver<IDLDouble>>(script_state); auto promise = resolver->Promise(); if (!language_model_remote_) { @@ -586,8 +591,8 @@ return promise; } - MakeGarbageCollected<CountPromptTokensClient>(script_state, this, resolver, - signal, input); + MakeGarbageCollected<MeasureInputUsageClient>(script_state, this, resolver, + signal, input->GetAsString()); return promise; } @@ -613,7 +618,7 @@ void AILanguageModel::OnResponseComplete( mojom::blink::ModelExecutionContextInfoPtr context_info) { if (context_info) { - current_tokens_ = context_info->current_tokens; + input_usage_ = context_info->current_tokens; } } @@ -626,12 +631,8 @@ return task_runner_; } -uint64_t AILanguageModel::GetCurrentTokens() { - return current_tokens_; -} - -void AILanguageModel::OnContextOverflow() { - DispatchEvent(*Event::Create(event_type_names::kContextoverflow)); +void AILanguageModel::OnQuotaOverflow() { + DispatchEvent(*Event::Create(event_type_names::kQuotaoverflow)); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/ai/ai_language_model.h b/third_party/blink/renderer/modules/ai/ai_language_model.h index 7beedde..96e639a8 100644 --- a/third_party/blink/renderer/modules/ai/ai_language_model.h +++ b/third_party/blink/renderer/modules/ai/ai_language_model.h
@@ -7,6 +7,7 @@ #include "base/types/pass_key.h" #include "third_party/blink/public/mojom/ai/ai_language_model.mojom-blink-forward.h" +#include "third_party/blink/renderer/bindings/core/v8/idl_types.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_ai_language_model_clone_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_ai_language_model_prompt_options.h" @@ -45,7 +46,7 @@ const AtomicString& InterfaceName() const override; ExecutionContext* GetExecutionContext() const override; - DEFINE_ATTRIBUTE_EVENT_LISTENER(contextoverflow, kContextoverflow) + DEFINE_ATTRIBUTE_EVENT_LISTENER(quotaoverflow, kQuotaoverflow) // ai_language_model.idl implementation. ScriptPromise<IDLString> prompt(ScriptState* script_state, @@ -56,14 +57,13 @@ const V8AILanguageModelPromptInput* input, const AILanguageModelPromptOptions* options, ExceptionState& exception_state); - ScriptPromise<IDLUnsignedLongLong> countPromptTokens( + ScriptPromise<IDLDouble> measureInputUsage( ScriptState* script_state, - const WTF::String& input, + const V8AILanguageModelPromptInput* input, const AILanguageModelPromptOptions* options, ExceptionState& exception_state); - uint64_t maxTokens() const { return max_tokens_; } - uint64_t tokensSoFar() const { return current_tokens_; } - uint64_t tokensLeft() const { return max_tokens_ - current_tokens_; } + double inputQuota() const { return input_quota_; } + double inputUsage() const { return input_usage_; } uint32_t topK() const { return top_k_; } float temperature() const { return temperature_; } @@ -76,15 +76,14 @@ HeapMojoRemote<mojom::blink::AILanguageModel>& GetAILanguageModelRemote(); scoped_refptr<base::SequencedTaskRunner> GetTaskRunner(); - uint64_t GetCurrentTokens(); private: void OnResponseComplete( mojom::blink::ModelExecutionContextInfoPtr context_info); - void OnContextOverflow(); + void OnQuotaOverflow(); - uint64_t current_tokens_; - uint64_t max_tokens_ = 0; + uint64_t input_usage_; + uint64_t input_quota_ = 0; uint32_t top_k_ = 0; float temperature_ = 0.0;
diff --git a/third_party/blink/renderer/modules/ai/ai_language_model.idl b/third_party/blink/renderer/modules/ai/ai_language_model.idl index 2110dfc..955dbe2 100644 --- a/third_party/blink/renderer/modules/ai/ai_language_model.idl +++ b/third_party/blink/renderer/modules/ai/ai_language_model.idl
@@ -42,24 +42,22 @@ CallWith=ScriptState, RaisesException ] - Promise<unsigned long long> countPromptTokens( - DOMString input, + Promise<double> measureInputUsage( + AILanguageModelPromptInput input, optional AILanguageModelPromptOptions options = {} ); [Measure] - readonly attribute unsigned long long maxTokens; + readonly attribute double inputUsage; [Measure] - readonly attribute unsigned long long tokensSoFar; - [Measure] - readonly attribute unsigned long long tokensLeft; + readonly attribute unrestricted double inputQuota; [Measure] readonly attribute unsigned long topK; [Measure] readonly attribute float temperature; - attribute EventHandler oncontextoverflow; + attribute EventHandler onquotaoverflow; [ Measure,
diff --git a/third_party/blink/renderer/modules/ai/model_execution_responder.cc b/third_party/blink/renderer/modules/ai/model_execution_responder.cc index 854ab540..56c90f08 100644 --- a/third_party/blink/renderer/modules/ai/model_execution_responder.cc +++ b/third_party/blink/renderer/modules/ai/model_execution_responder.cc
@@ -120,7 +120,7 @@ Cleanup(); } - void OnContextOverflow() override { + void OnQuotaOverflow() override { if (overflow_callback_) { overflow_callback_.Run(); } @@ -282,7 +282,7 @@ Cleanup(); } - void OnContextOverflow() override { + void OnQuotaOverflow() override { if (overflow_callback_) { overflow_callback_.Run(); }
diff --git a/third_party/blink/renderer/modules/ai/model_execution_responder_test.cc b/third_party/blink/renderer/modules/ai/model_execution_responder_test.cc index f58af01..a14c2aca 100644 --- a/third_party/blink/renderer/modules/ai/model_execution_responder_test.cc +++ b/third_party/blink/renderer/modules/ai/model_execution_responder_test.cc
@@ -86,7 +86,7 @@ mojom::blink::ModelStreamingResponderAction::kReplace); responder->OnStreaming("ab", mojom::blink::ModelStreamingResponderAction::kReplace); - responder->OnContextOverflow(); + responder->OnQuotaOverflow(); responder->OnCompletion( mojom::blink::ModelExecutionContextInfo::New(kTestTokenNumber)); // Check that the promise will be resolved with the "result" string. @@ -137,7 +137,7 @@ mojom::blink::ModelStreamingResponderAction::kAppend); responder->OnStreaming("ab", mojom::blink::ModelStreamingResponderAction::kAppend); - responder->OnContextOverflow(); + responder->OnQuotaOverflow(); responder->OnCompletion( mojom::blink::ModelExecutionContextInfo::New(kTestTokenNumber)); // Check that the promise will be resolved with the "result" string.
diff --git a/third_party/blink/renderer/modules/animationworklet/animator_definition.h b/third_party/blink/renderer/modules/animationworklet/animator_definition.h index a8b5074..2956b5f 100644 --- a/third_party/blink/renderer/modules/animationworklet/animator_definition.h +++ b/third_party/blink/renderer/modules/animationworklet/animator_definition.h
@@ -29,7 +29,7 @@ V8AnimateCallback* animate, V8StateCallback* state); ~AnimatorDefinition() override = default; - virtual void Trace(Visitor* visitor) const; + void Trace(Visitor* visitor) const; const char* NameInHeapSnapshot() const override { return "AnimatorDefinition"; }
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h b/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h index 5f4ba535..4d745f6 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h
@@ -42,7 +42,7 @@ BackgroundFetchBridge(const BackgroundFetchBridge&) = delete; BackgroundFetchBridge& operator=(const BackgroundFetchBridge&) = delete; - virtual ~BackgroundFetchBridge(); + ~BackgroundFetchBridge(); void Trace(Visitor* visitor) const override; // Creates a new Background Fetch registration identified by |developer_id|
diff --git a/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.h b/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.h index ff151f5b..cceccc1 100644 --- a/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.h +++ b/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.h
@@ -27,7 +27,7 @@ ServiceWorkerRegistrationBackgroundFetch& operator=( const ServiceWorkerRegistrationBackgroundFetch&) = delete; - virtual ~ServiceWorkerRegistrationBackgroundFetch(); + ~ServiceWorkerRegistrationBackgroundFetch(); static ServiceWorkerRegistrationBackgroundFetch& From( ServiceWorkerRegistration& registration);
diff --git a/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.h b/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.h index 8af255e1..74a6f7e16 100644 --- a/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.h +++ b/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.h
@@ -35,7 +35,7 @@ ServiceWorkerRegistrationSync& operator=( const ServiceWorkerRegistrationSync&) = delete; - virtual ~ServiceWorkerRegistrationSync(); + ~ServiceWorkerRegistrationSync(); PeriodicSyncManager* periodicSync(); SyncManager* sync();
diff --git a/third_party/blink/renderer/modules/beacon/navigator_beacon.h b/third_party/blink/renderer/modules/beacon/navigator_beacon.h index 7f4a85af..60033ba3 100644 --- a/third_party/blink/renderer/modules/beacon/navigator_beacon.h +++ b/third_party/blink/renderer/modules/beacon/navigator_beacon.h
@@ -24,7 +24,7 @@ static NavigatorBeacon& From(Navigator&); explicit NavigatorBeacon(Navigator&); - virtual ~NavigatorBeacon(); + ~NavigatorBeacon(); static bool sendBeacon( ScriptState* script_state,
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.h b/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.h index 1a08f81..dc6d0d6 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.h +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth_attribute_instance_map.h
@@ -67,7 +67,7 @@ // TODO(crbug.com/654950): Remove descriptors when implemented. void Clear(); - virtual void Trace(Visitor*) const; + void Trace(Visitor*) const; private: // BluetoothDevice that owns this map.
diff --git a/third_party/blink/renderer/modules/cache_storage/cache.cc b/third_party/blink/renderer/modules/cache_storage/cache.cc index e230a0a9..8f43cd0 100644 --- a/third_party/blink/renderer/modules/cache_storage/cache.cc +++ b/third_party/blink/renderer/modules/cache_storage/cache.cc
@@ -461,7 +461,7 @@ method_name_ + " was aborted"); } - virtual void Trace(Visitor* visitor) const { + void Trace(Visitor* visitor) const { visitor->Trace(cache_); visitor->Trace(resolver_); }
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 dea2701..5cab03ba6 100644 --- a/third_party/blink/renderer/modules/credentialmanagement/authentication_credentials_container.cc +++ b/third_party/blink/renderer/modules/credentialmanagement/authentication_credentials_container.cc
@@ -88,10 +88,6 @@ #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/wtf_size_t.h" -#if BUILDFLAG(IS_ANDROID) -#include "third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_rp_entity.h" -#endif - namespace blink { namespace { @@ -1036,6 +1032,21 @@ return nullptr; } +void EmitImmediateMediationUseCounters( + ExecutionContext* context, + const CredentialRequestOptions* options) { + CHECK(options->hasMediation() && options->mediation() == "immediate"); + if (options->hasPublicKey() && options->password()) { + UseCounter::Count( + context, + WebFeature::kCredentialsGetImmediateMediationWithWebAuthnAndPasswords); + } else if (options->hasPublicKey()) { + UseCounter::Count( + context, WebFeature::kCredentialsGetImmediateMediationWithWebAuthnOnly); + } + // TODO(crbug.com/392549444): Add other combinations. +} + } // namespace const char AuthenticationCredentialsContainer::kSupplementName[] = @@ -1520,6 +1531,7 @@ } else if (options->mediation() == "immediate") { if (RuntimeEnabledFeatures::WebAuthenticationImmediateGetEnabled()) { mediation = Mediation::IMMEDIATE; + EmitImmediateMediationUseCounters(context, options); } else { resolver->Reject(MakeGarbageCollected<DOMException>( DOMExceptionCode::kNotSupportedError, "Not implemented"));
diff --git a/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc b/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc index bf3d8583..1eeb41a 100644 --- a/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc +++ b/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.cc
@@ -29,7 +29,7 @@ MapEntry(WebData key_id, const V8MediaKeyStatus& status) : key_id_(DOMArrayBuffer::Create(scoped_refptr<SharedBuffer>(key_id))), status_(status) {} - virtual ~MapEntry() = default; + ~MapEntry() = default; DOMArrayBuffer* KeyId() const { return key_id_.Get(); } @@ -62,7 +62,7 @@ return a->KeyId()->ByteLength() < b->KeyId()->ByteLength(); } - virtual void Trace(Visitor* visitor) const { visitor->Trace(key_id_); } + void Trace(Visitor* visitor) const { visitor->Trace(key_id_); } private: const Member<DOMArrayBuffer> key_id_;
diff --git a/third_party/blink/renderer/modules/installedapp/installed_app_controller.h b/third_party/blink/renderer/modules/installedapp/installed_app_controller.h index 19e84017..afbc9a9c 100644 --- a/third_party/blink/renderer/modules/installedapp/installed_app_controller.h +++ b/third_party/blink/renderer/modules/installedapp/installed_app_controller.h
@@ -29,7 +29,7 @@ InstalledAppController(const InstalledAppController&) = delete; InstalledAppController& operator=(const InstalledAppController&) = delete; - virtual ~InstalledAppController(); + ~InstalledAppController(); // Gets a list of related apps from the current page's manifest that belong // to the current underlying platform, and are installed.
diff --git a/third_party/blink/renderer/modules/keyboard/keyboard_layout.h b/third_party/blink/renderer/modules/keyboard/keyboard_layout.h index fef43c5..0a1bf182 100644 --- a/third_party/blink/renderer/modules/keyboard/keyboard_layout.h +++ b/third_party/blink/renderer/modules/keyboard/keyboard_layout.h
@@ -25,7 +25,7 @@ KeyboardLayout(const KeyboardLayout&) = delete; KeyboardLayout& operator=(const KeyboardLayout&) = delete; - virtual ~KeyboardLayout() = default; + ~KeyboardLayout() = default; ScriptPromise<KeyboardLayoutMap> GetKeyboardLayoutMap(ScriptState*, ExceptionState&);
diff --git a/third_party/blink/renderer/modules/mediastream/apply_constraints_request.h b/third_party/blink/renderer/modules/mediastream/apply_constraints_request.h index e7a79a97..57e0896 100644 --- a/third_party/blink/renderer/modules/mediastream/apply_constraints_request.h +++ b/third_party/blink/renderer/modules/mediastream/apply_constraints_request.h
@@ -27,7 +27,7 @@ void RequestSucceeded(); void RequestFailed(const String& constraint, const String& message); - virtual void Trace(Visitor*) const; + void Trace(Visitor*) const; private: Member<MediaStreamTrack> track_;
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_set.h b/third_party/blink/renderer/modules/mediastream/media_stream_set.h index 4c802128..70eec02 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_set.h +++ b/third_party/blink/renderer/modules/mediastream/media_stream_set.h
@@ -31,7 +31,7 @@ const MediaStreamDescriptorVector& stream_descriptors, UserMediaRequestType request_type, MediaStreamSetInitializedCallback callback); - virtual ~MediaStreamSet() = default; + ~MediaStreamSet() = default; void Trace(Visitor*) const override;
diff --git a/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h b/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h index 607d4fb6..a5dfd2e3 100644 --- a/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h +++ b/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.h
@@ -69,7 +69,7 @@ NavigatorContentUtils(Navigator& navigator, NavigatorContentUtilsClient* client) : Supplement<Navigator>(navigator), client_(client) {} - virtual ~NavigatorContentUtils(); + ~NavigatorContentUtils(); static void registerProtocolHandler(Navigator&, const String& scheme,
diff --git a/third_party/blink/renderer/modules/notifications/notification_resources_loader.h b/third_party/blink/renderer/modules/notifications/notification_resources_loader.h index 5decaf5b..b7d8fa9 100644 --- a/third_party/blink/renderer/modules/notifications/notification_resources_loader.h +++ b/third_party/blink/renderer/modules/notifications/notification_resources_loader.h
@@ -51,7 +51,7 @@ // pre-finalizer. void Stop(); - virtual void Trace(Visitor* visitor) const; + void Trace(Visitor* visitor) const; private: void LoadIcon(ExecutionContext* context,
diff --git a/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.h b/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.h index 9505c63..ae3c6520 100644 --- a/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.h +++ b/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.h
@@ -28,7 +28,7 @@ PaymentAppServiceWorkerRegistration& operator=( const PaymentAppServiceWorkerRegistration&) = delete; - virtual ~PaymentAppServiceWorkerRegistration(); + ~PaymentAppServiceWorkerRegistration(); static PaymentAppServiceWorkerRegistration& From(ServiceWorkerRegistration&);
diff --git a/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h b/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h index 84eced1d..9b9e54b 100644 --- a/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h +++ b/third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h
@@ -38,7 +38,7 @@ PushMessagingBridge(const PushMessagingBridge&) = delete; PushMessagingBridge& operator=(const PushMessagingBridge&) = delete; - virtual ~PushMessagingBridge(); + ~PushMessagingBridge(); // Asynchronously determines the permission state for the current origin. ScriptPromise<V8PermissionState> GetPermissionState(
diff --git a/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.h b/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.h index db7f48d5..cb62ccf6 100644 --- a/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.h +++ b/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.h
@@ -27,7 +27,7 @@ ServiceWorkerRegistrationPush& operator=( const ServiceWorkerRegistrationPush&) = delete; - virtual ~ServiceWorkerRegistrationPush(); + ~ServiceWorkerRegistrationPush(); static ServiceWorkerRegistrationPush& From( ServiceWorkerRegistration& registration);
diff --git a/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.h b/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.h index 65d84f22b..ac55725 100644 --- a/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.h +++ b/third_party/blink/renderer/modules/remoteplayback/availability_callback_wrapper.h
@@ -32,7 +32,7 @@ void Run(RemotePlayback*, bool new_availability); - virtual void Trace(Visitor*) const; + void Trace(Visitor*) const; const char* NameInHeapSnapshot() const override { return "AvailabilityCallbackWrapper"; }
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h b/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h index 993badb..69052e5 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h +++ b/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h
@@ -29,7 +29,7 @@ ServiceWorkerInstalledScriptsManager( std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams>, scoped_refptr<base::SingleThreadTaskRunner> io_task_runner); - virtual ~ServiceWorkerInstalledScriptsManager() = default; + ~ServiceWorkerInstalledScriptsManager() = default; // InstalledScriptsManager implementation. bool IsScriptInstalled(const KURL& script_url) const override;
diff --git a/third_party/blink/renderer/modules/shared_storage/shared_storage_operation_definition.h b/third_party/blink/renderer/modules/shared_storage/shared_storage_operation_definition.h index 697ef3b..dd17c00f 100644 --- a/third_party/blink/renderer/modules/shared_storage/shared_storage_operation_definition.h +++ b/third_party/blink/renderer/modules/shared_storage/shared_storage_operation_definition.h
@@ -32,7 +32,7 @@ ~SharedStorageOperationDefinition() override; - virtual void Trace(Visitor* visitor) const; + void Trace(Visitor* visitor) const; const char* NameInHeapSnapshot() const override { return "SharedStorageOperationDefinition";
diff --git a/third_party/blink/renderer/modules/speech/speech_recognition_controller.h b/third_party/blink/renderer/modules/speech/speech_recognition_controller.h index 87f5345..e8968b2 100644 --- a/third_party/blink/renderer/modules/speech/speech_recognition_controller.h +++ b/third_party/blink/renderer/modules/speech/speech_recognition_controller.h
@@ -52,7 +52,7 @@ static const char kSupplementName[]; explicit SpeechRecognitionController(LocalDOMWindow&); - virtual ~SpeechRecognitionController(); + ~SpeechRecognitionController(); // Builds the speech recognition request params. If `audio_forwarder` and // `audio_parameters` are not defined, speech recognition will use audio from
diff --git a/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h b/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h index 8c8b731..78973b4 100644 --- a/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h +++ b/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback_collection.h
@@ -88,7 +88,7 @@ bool IsEmpty() const { return !frame_callbacks_.size(); } - virtual void Trace(Visitor*) const; + void Trace(Visitor*) const; const char* NameInHeapSnapshot() const override { return "VideoFrameRequestCallbackCollection"; }
diff --git a/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc b/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc index 897cc33..92880aaf 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_context_autoplay_test.cc
@@ -67,6 +67,7 @@ const WebAudioSinkDescriptor& sink_descriptor, unsigned number_of_output_channels, const WebAudioLatencyHint& latency_hint, + std::optional<float> context_sample_rate, media::AudioRendererSink::RenderCallback*) override { return std::make_unique<MockWebAudioDeviceForAutoplayTest>( AudioHardwareSampleRate(), AudioHardwareBufferSize());
diff --git a/third_party/blink/renderer/modules/webaudio/audio_context_test.cc b/third_party/blink/renderer/modules/webaudio/audio_context_test.cc index 3e479e5..65db1bce 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_context_test.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_context_test.cc
@@ -179,6 +179,7 @@ const WebAudioSinkDescriptor& sink_descriptor, unsigned number_of_output_channels, const WebAudioLatencyHint& latency_hint, + std::optional<float> context_sample_rate, media::AudioRendererSink::RenderCallback*) override { double buffer_size = 0; const double interactive_size = AudioHardwareBufferSize(); @@ -205,7 +206,7 @@ } return std::make_unique<MockWebAudioDeviceForAudioContext>( - AudioHardwareSampleRate(), buffer_size); + context_sample_rate.value_or(AudioHardwareSampleRate()), buffer_size); } double AudioHardwareSampleRate() override { return 44100; }
diff --git a/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_handler_test.cc b/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_handler_test.cc index 2bb2198a..4779064 100644 --- a/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_handler_test.cc +++ b/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_handler_test.cc
@@ -69,6 +69,7 @@ const WebAudioSinkDescriptor& sink_descriptor, unsigned number_of_output_channels, const WebAudioLatencyHint& latency_hint, + std::optional<float> context_sample_rate, media::AudioRendererSink::RenderCallback*) override { return std::make_unique<MockWebAudioDevice>( AudioHardwareSampleRate(), AudioHardwareBufferSize());
diff --git a/third_party/blink/renderer/modules/xr/xr_frame_provider.h b/third_party/blink/renderer/modules/xr/xr_frame_provider.h index 0fa6d06..fc91dae6 100644 --- a/third_party/blink/renderer/modules/xr/xr_frame_provider.h +++ b/third_party/blink/renderer/modules/xr/xr_frame_provider.h
@@ -83,7 +83,7 @@ bool DrawingIntoSharedBuffer() const; - virtual void Trace(Visitor*) const; + void Trace(Visitor*) const; private: enum class ScheduledFrameType {
diff --git a/third_party/blink/renderer/modules/xr/xr_system.h b/third_party/blink/renderer/modules/xr/xr_system.h index 915eb3d6..9761345 100644 --- a/third_party/blink/renderer/modules/xr/xr_system.h +++ b/third_party/blink/renderer/modules/xr/xr_system.h
@@ -188,7 +188,7 @@ PendingRequestSessionQuery& operator=(const PendingRequestSessionQuery&) = delete; - virtual ~PendingRequestSessionQuery() = default; + ~PendingRequestSessionQuery() = default; // Resolves underlying promise with passed in XR session. // If metrics are to be recorded for this session, an @@ -268,7 +268,7 @@ uint64_t TraceId() const { return trace_id_; } - virtual void Trace(Visitor*) const; + void Trace(Visitor*) const; private: void ParseSensorRequirement(); @@ -317,7 +317,7 @@ PendingSupportsSessionQuery& operator=(const PendingSupportsSessionQuery&) = delete; - virtual ~PendingSupportsSessionQuery() = default; + ~PendingSupportsSessionQuery() = default; // Resolves underlying promise. void Resolve(bool supported, ExceptionState* exception_state = nullptr); @@ -352,7 +352,7 @@ uint64_t TraceId() const { return trace_id_; } - virtual void Trace(Visitor*) const; + void Trace(Visitor*) const; private: Member<ScriptPromiseResolverBase> resolver_;
diff --git a/third_party/blink/renderer/platform/audio/audio_destination.cc b/third_party/blink/renderer/platform/audio/audio_destination.cc index 853a0be9..6843b9d 100644 --- a/third_party/blink/renderer/platform/audio/audio_destination.cc +++ b/third_party/blink/renderer/platform/audio/audio_destination.cc
@@ -417,6 +417,7 @@ Platform::Current()->CreateAudioDevice(sink_descriptor, number_of_output_channels, latency_hint, + context_sample_rate, this)), callback_buffer_size_( web_audio_device_ ? web_audio_device_->FramesPerBuffer() : 0), @@ -479,7 +480,9 @@ double scale_factor = 1.0; - if (context_sample_rate_ != web_audio_device_->SampleRate()) { + if (!base::FeatureList::IsEnabled( + features::kWebAudioRemoveAudioDestinationResampler) && + context_sample_rate_ != web_audio_device_->SampleRate()) { scale_factor = context_sample_rate_ / web_audio_device_->SampleRate(); SendLogMessage(__func__, String::Format("=> (resampling from %0.f Hz to %0.f Hz)",
diff --git a/third_party/blink/renderer/platform/audio/audio_destination.h b/third_party/blink/renderer/platform/audio/audio_destination.h index f3c9f0d..ab8131a 100644 --- a/third_party/blink/renderer/platform/audio/audio_destination.h +++ b/third_party/blink/renderer/platform/audio/audio_destination.h
@@ -152,6 +152,10 @@ return fifo_->GetStateForTest(); } + MediaMultiChannelResampler* GetResamplerForTesting() { + return resampler_.get(); + } + private: explicit AudioDestination(AudioIOCallback&, const WebAudioSinkDescriptor& sink_descriptor,
diff --git a/third_party/blink/renderer/platform/audio/audio_destination_test.cc b/third_party/blink/renderer/platform/audio/audio_destination_test.cc index 9c106cd..0e3fda4 100644 --- a/third_party/blink/renderer/platform/audio/audio_destination_test.cc +++ b/third_party/blink/renderer/platform/audio/audio_destination_test.cc
@@ -7,6 +7,7 @@ #include <array> #include <memory> +#include "base/test/scoped_feature_list.h" #include "media/base/audio_glitch_info.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -25,10 +26,20 @@ namespace { using ::testing::_; -using ::testing::InSequence; const LocalFrameToken kFrameToken; +constexpr float kDefaultHardwareSampleRate = 44100; +constexpr int kDefaultHardwareBufferSize = 512; +constexpr int kDefaultHardwareOutputChannelNumber = 2; +constexpr int kWebAudioRenderQuantum = 128; + +int RoundUpToRenderQuantum(int requested_frames) { + return std::ceil(requested_frames / + static_cast<double>(kWebAudioRenderQuantum)) * + kWebAudioRenderQuantum; +} + class MockWebAudioDevice : public WebAudioDevice { public: explicit MockWebAudioDevice(double sample_rate, int frames_per_buffer) @@ -54,15 +65,19 @@ class TestPlatform : public TestingPlatformSupport { public: - TestPlatform() { - webaudio_device_ = std::make_unique<MockWebAudioDevice>( - AudioHardwareSampleRate(), AudioHardwareBufferSize()); + TestPlatform() = default; + ~TestPlatform() override = default; + + void CreateMockWebAudioDevice(float context_sample_rate, int buffer_size) { + webaudio_device_ = + std::make_unique<MockWebAudioDevice>(context_sample_rate, buffer_size); } std::unique_ptr<WebAudioDevice> CreateAudioDevice( const WebAudioSinkDescriptor& sink_descriptor, unsigned number_of_output_channels, const WebAudioLatencyHint& latency_hint, + std::optional<float> context_sample_rate, media::AudioRendererSink::RenderCallback*) override { CHECK(webaudio_device_ != nullptr) << "Calling CreateAudioDevice (via AudioDestination::Create) multiple " @@ -70,9 +85,15 @@ return std::move(webaudio_device_); } - double AudioHardwareSampleRate() override { return 44100; } - size_t AudioHardwareBufferSize() override { return 512; } - unsigned AudioHardwareOutputChannels() override { return 2; } + double AudioHardwareSampleRate() override { + return kDefaultHardwareSampleRate; + } + size_t AudioHardwareBufferSize() override { + return kDefaultHardwareBufferSize; + } + unsigned AudioHardwareOutputChannels() override { + return kDefaultHardwareOutputChannelNumber; + } const MockWebAudioDevice& web_audio_device() { CHECK(webaudio_device_ != nullptr) @@ -109,69 +130,82 @@ class AudioDestinationTest : public ::testing::TestWithParam<std::optional<float>> { public: - void CountWASamplesProcessedForRate(std::optional<float> sample_rate) { - WebAudioLatencyHint latency_hint(WebAudioLatencyHint::kCategoryInteractive); - - const int channel_count = - Platform::Current()->AudioHardwareOutputChannels(); - const size_t request_frames = - Platform::Current()->AudioHardwareBufferSize(); - + scoped_refptr<AudioDestination> CreateAudioDestination( + std::optional<float> context_sample_rate, + WebAudioLatencyHint latency_hint) { // Assume the default audio device. (i.e. the empty string) WebAudioSinkDescriptor sink_descriptor(WebString::FromUTF8(""), kFrameToken); + const int channel_count = + Platform::Current()->AudioHardwareOutputChannels(); - // TODO(https://crbug.com/988121) Replace 128 with the appropriate - // AudioContextRenderSizeHintCategory. - constexpr int render_quantum_frames = 128; - scoped_refptr<AudioDestination> destination = AudioDestination::Create( - callback_, sink_descriptor, channel_count, latency_hint, sample_rate, - render_quantum_frames); - destination->Start(); - - destination->Render( - base::TimeDelta::Min(), base::TimeTicks::Now(), {}, - media::AudioBus::Create(channel_count, request_frames).get()); - - // Calculate the expected number of frames to be consumed to produce - // |request_frames| frames. - int exact_frames_required = request_frames; - if (destination->SampleRate() != - Platform::Current()->AudioHardwareSampleRate()) { - exact_frames_required = - std::ceil(request_frames * destination->SampleRate() / - Platform::Current()->AudioHardwareSampleRate()); - // The internal resampler requires media::SincResampler::KernelSize() / 2 - // more frames to flush the output. See sinc_resampler.cc for details. - exact_frames_required += - media::SincResampler::KernelSizeFromRequestFrames(request_frames) / 2; - } - const int expected_frames_processed = - std::ceil(exact_frames_required / - static_cast<double>(render_quantum_frames)) * - render_quantum_frames; - - EXPECT_EQ(expected_frames_processed, callback_.frames_processed_); + return AudioDestination::Create(callback_, sink_descriptor, channel_count, + latency_hint, context_sample_rate, + kWebAudioRenderQuantum); } protected: + base::test::ScopedFeatureList feature_list_; AudioCallback callback_; }; +// This test verifies that resampling occurs correctly when the AudioContext's +// sample rate differs from the hardware's sample rate. We explicitly disable +// kWebAudioRemoveAudioDestinationResampler to ensure the resampler can be +// created. TEST_P(AudioDestinationTest, ResamplingTest) { #if defined(MEMORY_SANITIZER) // TODO(crbug.com/342415791): Fix and re-enable tests with MSan. GTEST_SKIP(); #else + feature_list_.InitAndDisableFeature( + blink::features::kWebAudioRemoveAudioDestinationResampler); ScopedTestingPlatformSupport<TestPlatform> platform; - { - InSequence s; + platform->CreateMockWebAudioDevice(kDefaultHardwareSampleRate, + kDefaultHardwareBufferSize); + EXPECT_CALL(platform->web_audio_device(), Start).Times(1); + EXPECT_CALL(platform->web_audio_device(), Stop).Times(1); - EXPECT_CALL(platform->web_audio_device(), Start).Times(1); - EXPECT_CALL(platform->web_audio_device(), Stop).Times(1); + scoped_refptr<AudioDestination> audio_destination = CreateAudioDestination( + GetParam(), + WebAudioLatencyHint(WebAudioLatencyHint::kCategoryInteractive)); + + const int requested_frames = audio_destination->FramesPerBuffer(); + + audio_destination->Start(); + audio_destination->Render( + base::TimeDelta::Min(), base::TimeTicks::Now(), {}, + media::AudioBus::Create(kDefaultHardwareOutputChannelNumber, + requested_frames) + .get()); + + int scaled_requested_frames = requested_frames; + + // Check if resampling was performed and calculate the expected frame count. + if (audio_destination->SampleRate() != + Platform::Current()->AudioHardwareSampleRate()) { + // Resampler should be created when sample rates differ. + EXPECT_NE(audio_destination->GetResamplerForTesting(), nullptr); + + // Calculate the scaled frame count based on the sample rate difference. + scaled_requested_frames = + std::ceil(requested_frames * audio_destination->SampleRate() / + Platform::Current()->AudioHardwareSampleRate()); + + // The internal resampler requires media::SincResampler::KernelSize() / 2 + // more frames to flush the output. See sinc_resampler.cc for details. + scaled_requested_frames += + media::SincResampler::KernelSizeFromRequestFrames(requested_frames) / 2; + } else { + // No resampler should be created when sample rates are the same. + EXPECT_EQ(audio_destination->GetResamplerForTesting(), nullptr); } - CountWASamplesProcessedForRate(GetParam()); + // Verify that the number of frames processed matches the expected count, + // rounded up to the render quantum. + const int expected_processed_frames = + RoundUpToRenderQuantum(scaled_requested_frames); + EXPECT_EQ(expected_processed_frames, callback_.frames_processed_); #endif } @@ -180,26 +214,19 @@ // TODO(crbug.com/342415791): Fix and re-enable tests with MSan. GTEST_SKIP(); #else + feature_list_.InitAndDisableFeature( + blink::features::kWebAudioRemoveAudioDestinationResampler); ScopedTestingPlatformSupport<TestPlatform> platform; - { - InSequence s; - EXPECT_CALL(platform->web_audio_device(), Start).Times(1); - EXPECT_CALL(platform->web_audio_device(), Stop).Times(1); - } + platform->CreateMockWebAudioDevice(kDefaultHardwareSampleRate, + kDefaultHardwareBufferSize); - std::optional<float> sample_rate = GetParam(); - WebAudioLatencyHint latency_hint(WebAudioLatencyHint::kCategoryInteractive); + EXPECT_CALL(platform->web_audio_device(), Start).Times(1); + EXPECT_CALL(platform->web_audio_device(), Stop).Times(1); - const int channel_count = Platform::Current()->AudioHardwareOutputChannels(); - const size_t request_frames = Platform::Current()->AudioHardwareBufferSize(); - - // Assume the default audio device. (i.e. the empty string) - WebAudioSinkDescriptor sink_descriptor(WebString::FromUTF8(""), kFrameToken); - - int render_quantum_frames = 128; - scoped_refptr<AudioDestination> destination = AudioDestination::Create( - callback_, sink_descriptor, channel_count, latency_hint, sample_rate, - render_quantum_frames); + scoped_refptr<AudioDestination> audio_destination = CreateAudioDestination( + GetParam(), + WebAudioLatencyHint(WebAudioLatencyHint::kCategoryInteractive)); + const int requested_frames = audio_destination->FramesPerBuffer(); const int kRenderCount = 3; @@ -218,23 +245,22 @@ // When creating the AudioDestination, some silence is added to the fifo to // prevent an underrun on the first callback. This contributes a constant // delay. - int priming_frames = - ceil(request_frames / static_cast<float>(render_quantum_frames)) * - render_quantum_frames; + const int priming_frames = RoundUpToRenderQuantum(requested_frames); base::TimeDelta priming_delay = audio_utilities::FramesToTime( priming_frames, Platform::Current()->AudioHardwareSampleRate()); - auto audio_bus = media::AudioBus::Create(channel_count, request_frames); + auto audio_bus = media::AudioBus::Create(kDefaultHardwareOutputChannelNumber, + requested_frames); - destination->Start(); + audio_destination->Start(); for (int i = 0; i < kRenderCount; ++i) { - destination->Render(delays[i], base::TimeTicks::Now(), glitches[i], - audio_bus.get()); + audio_destination->Render(delays[i], base::TimeTicks::Now(), glitches[i], + audio_bus.get()); EXPECT_EQ(callback_.glitch_accumulator_.GetAndReset(), glitches[i]); - if (destination->SampleRate() != + if (audio_destination->SampleRate() != Platform::Current()->AudioHardwareSampleRate()) { // Resampler kernel adds a bit of a delay. EXPECT_GE(callback_.last_latency_, delays[i] + priming_delay); @@ -245,10 +271,64 @@ } } - destination->Stop(); + audio_destination->Stop(); #endif } +// This test verifies that the AudioDestination resampler is correctly removed +// when the kWebAudioRemoveAudioDestinationResampler feature is enabled +// and WebAudioBypassOutputBuffering is also enabled. +TEST_P(AudioDestinationTest, ResamplerIsRemoved) { + feature_list_.InitAndEnableFeature( + blink::features::kWebAudioRemoveAudioDestinationResampler); + + // Ideally we should have two separate test for WebAudioBypassOutputBuffering + // enabled and disabled. The difference here is the + // `expected_processed_frames` will be different. In FIFO non-bypass case the + // buffer is primed so expected processed frames will need to account for + // that. But considering that `WebAudioBypassOutputBuffering` is soon to be + // default, we only add the bypass buffer enabled test here. + blink::WebRuntimeFeatures::EnableFeatureFromString( + "WebAudioBypassOutputBuffering", true); + + float context_sample_rate = GetParam().value_or(kDefaultHardwareSampleRate); + + // Use a non-default buffer size (kFakeScaledSinkBufferSize) to confirm it's + // correctly applied in AudioDestination. The specific value of + // kFakeScaledSinkBufferSize is unimportant, as the scaling calculations are + // verified in RendererWebAudioDeviceImplBufferSizeTest. This test + // focuses on ensuring the resampler is not created, allowing us to use the + // original request frames (kFakeScaledSinkBufferSize) when calculating + // expected_processed_frames. + constexpr int kFakeScaledSinkBufferSize = 399; + + ScopedTestingPlatformSupport<TestPlatform> platform; + platform->CreateMockWebAudioDevice(context_sample_rate, + kFakeScaledSinkBufferSize); + EXPECT_CALL(platform->web_audio_device(), Start).Times(1); + EXPECT_CALL(platform->web_audio_device(), Stop).Times(1); + + scoped_refptr<AudioDestination> audio_destination = CreateAudioDestination( + GetParam(), + WebAudioLatencyHint(WebAudioLatencyHint::kCategoryInteractive)); + + EXPECT_EQ(nullptr, audio_destination->GetResamplerForTesting()); + + audio_destination->Start(); + audio_destination->Render( + base::TimeDelta::Min(), base::TimeTicks::Now(), {}, + media::AudioBus::Create( + Platform::Current()->AudioHardwareOutputChannels(), + kFakeScaledSinkBufferSize) + .get()); + + // Calculate the expected number of processed frames, rounded up to the render + // quantum. + int expected_processed_frames = + RoundUpToRenderQuantum(audio_destination->FramesPerBuffer()); + EXPECT_EQ(callback_.frames_processed_, expected_processed_frames); +} + INSTANTIATE_TEST_SUITE_P(/* no label */, AudioDestinationTest, ::testing::Values(std::optional<float>(), @@ -264,32 +344,28 @@ blink::WebRuntimeFeatures::EnableFeatureFromString( "WebAudioBypassOutputBuffering", true); ScopedTestingPlatformSupport<TestPlatform> platform; + platform->CreateMockWebAudioDevice(kDefaultHardwareSampleRate, + kDefaultHardwareBufferSize); - const std::optional<float> sample_rate = 44100; - const WebAudioLatencyHint latency_hint( - WebAudioLatencyHint::kCategoryInteractive); - const int channel_count = Platform::Current()->AudioHardwareOutputChannels(); - const size_t request_frames = Platform::Current()->AudioHardwareBufferSize(); - const WebAudioSinkDescriptor sink_descriptor(WebString::FromUTF8(""), - kFrameToken); - const int render_quantum_frames = 128; + const std::optional<float> context_sample_rate = 44100; + scoped_refptr<AudioDestination> audio_destination = CreateAudioDestination( + context_sample_rate, + WebAudioLatencyHint(WebAudioLatencyHint::kCategoryInteractive)); - scoped_refptr<AudioDestination> destination = AudioDestination::Create( - callback_, sink_descriptor, channel_count, latency_hint, sample_rate, - render_quantum_frames); + auto audio_bus = media::AudioBus::Create( + Platform::Current()->AudioHardwareOutputChannels(), + audio_destination->FramesPerBuffer()); - auto audio_bus = media::AudioBus::Create(channel_count, request_frames); + audio_destination->Start(); + audio_destination->Render(base::Milliseconds(90), base::TimeTicks::Now(), + media::AudioGlitchInfo(), audio_bus.get()); + audio_destination->Stop(); + audio_destination->Render(base::Milliseconds(90), base::TimeTicks::Now(), + media::AudioGlitchInfo(), audio_bus.get()); - destination->Start(); - destination->Render(base::Milliseconds(90), base::TimeTicks::Now(), - media::AudioGlitchInfo(), audio_bus.get()); - destination->Stop(); - destination->Render(base::Milliseconds(90), base::TimeTicks::Now(), - media::AudioGlitchInfo(), audio_bus.get()); - - EXPECT_EQ((destination->GetPushPullFIFOStateForTest()).overflow_count, + EXPECT_EQ((audio_destination->GetPushPullFIFOStateForTest()).overflow_count, unsigned{0}); - EXPECT_EQ((destination->GetPushPullFIFOStateForTest()).underflow_count, + EXPECT_EQ((audio_destination->GetPushPullFIFOStateForTest()).underflow_count, unsigned{0}); }
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc b/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc index f5d425f..6f4c5542 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc
@@ -2018,25 +2018,27 @@ void ShapeResult::ComputePositionData() const { unsigned next_character_index = 0; InlineLayoutUnit total_advance; - InlineLayoutUnit last_x_position; + LayoutUnit last_x_position; // Iterate runs/glyphs in the visual order; i.e., from the left edge // regardless of the directionality, so that |x_position| is always in // ascending order. // TODO(kojii): It does not work when large negative letter-/word- // spacing is applied. - for (const auto& run : runs_) { - if (!run) + for (const auto& run_ptr : runs_) { + if (!run_ptr) [[unlikely]] { continue; + } + const RunInfo& run = *run_ptr; // Assumes all runs have the same directionality as the ShapeResult so that // |x_position| is in ascending order. - DCHECK_EQ(IsRtl(), run->IsRtl()); + DCHECK_EQ(IsRtl(), run.IsRtl()); - for (const auto& glyph_data : run->glyph_data_) { - DCHECK_GE(run->start_index_, start_index_); + for (const auto& glyph_data : run.glyph_data_) { + DCHECK_GE(run.start_index_, start_index_); const unsigned logical_index = - run->start_index_ + glyph_data.character_index - start_index_; + run.start_index_ + glyph_data.character_index - start_index_; // Make |character_index| to the visual offset. DCHECK_LT(logical_index, num_characters_); @@ -2058,17 +2060,16 @@ // the logical order; i.e., the last position for LTR or this position // for RTL. const LayoutUnit x_position = - (!rtl ? last_x_position : total_advance).ToCeil<LayoutUnit>(); + (!rtl ? last_x_position : total_advance.ToCeil<LayoutUnit>()); for (unsigned i = next_character_index; i < character_index; i++) { DCHECK_LT(i, num_characters_); character_position_[i].SetCachedData(x_position, false, false); } } - const LayoutUnit x_position = total_advance.ToCeil<LayoutUnit>(); + last_x_position = total_advance.ToCeil<LayoutUnit>(); character_position_[character_index].SetCachedData( - x_position, true, glyph_data.safe_to_break_before); - last_x_position = total_advance; + last_x_position, true, glyph_data.safe_to_break_before); } total_advance += glyph_data.advance; @@ -2080,7 +2081,7 @@ // corresponding glyphs. if (next_character_index < num_characters_) { const LayoutUnit x_position = - (!rtl ? last_x_position : total_advance).ToCeil<LayoutUnit>(); + (!rtl ? last_x_position : total_advance.ToCeil<LayoutUnit>()); for (unsigned i = next_character_index; i < num_characters_; i++) { character_position_[i].SetCachedData(x_position, false, false); }
diff --git a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc index b88a5bc..ddfc1f2 100644 --- a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc +++ b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
@@ -86,7 +86,7 @@ gpu::ExportedSharedImage exported_shared_image, const gpu::SyncToken& sync_token, const gfx::Size& size, - SkColorType sk_color_type, + viz::SharedImageFormat format, SkAlphaType alpha_type, sk_sp<SkColorSpace> sk_color_space, base::OnceCallback<void(const gpu::SyncToken&)> external_callback) { @@ -118,8 +118,7 @@ shared_gpu_context, shared_image); return base::AdoptRef(new AcceleratedStaticBitmapImage( - std::move(shared_image), sync_token, 0u, size, - viz::SkColorTypeToSinglePlaneSharedImageFormat(sk_color_type), alpha_type, + std::move(shared_image), sync_token, 0u, size, format, alpha_type, std::move(sk_color_space), ImageOrientationEnum::kDefault, shared_gpu_context, base::PlatformThreadRef(), ThreadScheduler::Current()->CleanupTaskRunner(),
diff --git a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h index 5418816..adad39f 100644 --- a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h +++ b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h
@@ -72,7 +72,7 @@ gpu::ExportedSharedImage exported_shared_image, const gpu::SyncToken& sync_token, const gfx::Size& size, - SkColorType sk_color_type, + viz::SharedImageFormat format, SkAlphaType alpha_type, sk_sp<SkColorSpace> sk_color_space, base::OnceCallback<void(const gpu::SyncToken&)> release_callback);
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_resource_provider_cache.cc b/third_party/blink/renderer/platform/graphics/gpu/webgpu_resource_provider_cache.cc index f26f3a2..ba38247 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_resource_provider_cache.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_resource_provider_cache.cc
@@ -102,19 +102,21 @@ std::unique_ptr<CanvasResourceProvider> WebGPURecyclableResourceCache::AcquireCachedProvider( const SkImageInfo& image_info) { + gfx::Size size = gfx::Size(image_info.width(), image_info.height()); + viz::SharedImageFormat format = + viz::SkColorTypeToSinglePlaneSharedImageFormat(image_info.colorType()); + SkAlphaType alpha_type = image_info.alphaType(); + gfx::ColorSpace color_space = + SkColorSpaceToGfxColorSpace(image_info.refColorSpace()); + // Loop from MRU to LRU DequeResourceProvider::iterator it; for (it = unused_providers_.begin(); it != unused_providers_.end(); ++it) { CanvasResourceProvider* resource_provider = it->resource_provider_.get(); - if (image_info == resource_provider->GetSkImageInfo()) { - break; - } - // Detect and allow for the case wherein the passed-info implicitly - // specifies sRGB via a null SkColorSpace whereas the resource provider is - // explicitly storing sRGB. - if (!image_info.colorSpace() && - (image_info.makeColorSpace(SkColorSpace::MakeSRGB()) == - resource_provider->GetSkImageInfo())) { + if (resource_provider->Size() == size && + resource_provider->GetSharedImageFormat() == format && + resource_provider->GetAlphaType() == alpha_type && + resource_provider->GetColorSpace() == color_space) { break; } }
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py index 03ca646..11451fc5 100755 --- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py +++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -1035,6 +1035,9 @@ 'gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE', 'gpu::SharedImageUsageSet', 'gpu::SyncToken', + 'viz::SharedImageFormat', + 'viz::SkColorTypeToSinglePlaneSharedImageFormat', + 'viz::ToClosestSkColorType', ], }, {
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index b0c8c41..1933ed0 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1769,7 +1769,6 @@ # By about a quarter or less of a pixel. crbug.com/997202 [ Mac ] virtual/text-antialias/international/bdo-bidi-width.html [ Failure ] -crbug.com/599670 [ Win ] http/tests/devtools/resource-parameters-ipv6.js [ Crash Failure Pass ] crbug.com/472330 fast/borders/border-image-outset-split-inline-vertical-lr.html [ Failure ] crbug.com/472330 fast/writing-mode/box-shadow-vertical-lr.html [ Failure ] crbug.com/472330 fast/writing-mode/box-shadow-vertical-rl.html [ Failure ] @@ -9105,3 +9104,9 @@ # Gardener 2025-03-21 crbug.com/405231143 [ Win11-arm64 ] external/wpt/clear-site-data/clear-cache-partitioning.https.html [ Failure ] + +# TODO(crbug.com/375515693): Re-enable after landing CL. +crbug.com/375515693 http/tests/devtools/resource-har-conversion.js [ Failure Pass ] +crbug.com/375515693 http/tests/devtools/resource-har-headers.js [ Failure Pass ] +crbug.com/375515693 http/tests/devtools/resource-parameters-ipv6.js [ Crash Failure Pass ] +crbug.com/375515693 http/tests/devtools/resource-parameters.js [ Failure Pass ]
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/reference-target/tentative/form.html b/third_party/blink/web_tests/external/wpt/shadow-dom/reference-target/tentative/form.html new file mode 100644 index 0000000..a4a5f37 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/shadow-dom/reference-target/tentative/form.html
@@ -0,0 +1,60 @@ +<!DOCTYPE HTML> +<html> +<head> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/testdriver.js"></script> + <script src="/resources/testdriver-vendor.js"></script> + <script src="/resources/testdriver-actions.js"></script> +</head> + +<body> + <button id="reset-button-1" type="reset" form="fancy-form-1"></button> + <fancy-form-1 id="fancy-form-1"> + <template shadowrootmode="open" shadowrootreferencetarget="real-form"> + <form id="real-form"> + <input type="text" value="default value"> + </form> + </template> + </fancy-form-1> + + <button id="reset-button-2" type="reset" form="fancy-form-2"></button> + <fancy-form-2 id="fancy-form-2"></fancy-form-2> + <script> + const fancyForm2 = document.querySelector('fancy-form-2'); + fancyForm2.attachShadow({ mode: 'open', referenceTarget: 'real-form' }); + fancyForm2.shadowRoot.innerHTML = '<form id="real-form"><input type="text" value="default value"></form>'; + </script> + + <button id="reset-button-3" type="reset"></button> + <fancy-form-3 id="fancy-form-3"> + <template shadowrootmode="open" shadowrootreferencetarget="real-form"> + <form id="real-form"> + <input type="text" value="default value"> + </form> + </template> + </fancy-form-3> + + <script> + function testFormWithReferenceTarget(formId, resetButtonId, name) { + test(function () { + const fancyForm = document.getElementById(formId); + const realForm = fancyForm.shadowRoot.getElementById("real-form"); + const input = realForm.firstElementChild; + + input.value = "new value"; + const resetButton = document.getElementById(resetButtonId); + assert_equals(input.value, "new value", "The input value should be updated to the new value."); + resetButton.click(); + assert_equals(input.value, "default value", "The input value should be reset to the default value."); + }, name); + } + + testFormWithReferenceTarget('fancy-form-1', 'reset-button-1', "Reference target works with form attribute."); + testFormWithReferenceTarget('fancy-form-2', 'reset-button-2', "Reference target works with form attribute via options."); + + document.getElementById('reset-button-3').setAttribute('form', "fancy-form-3"); + testFormWithReferenceTarget('fancy-form-3', 'reset-button-3', "Reference target works with setAttribute('form')"); + </script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/reference-target/tentative/property-reflection.html b/third_party/blink/web_tests/external/wpt/shadow-dom/reference-target/tentative/property-reflection.html index a44baea..6e8b77f 100644 --- a/third_party/blink/web_tests/external/wpt/shadow-dom/reference-target/tentative/property-reflection.html +++ b/third_party/blink/web_tests/external/wpt/shadow-dom/reference-target/tentative/property-reflection.html
@@ -104,14 +104,18 @@ const expected_htmlFor_property_behavior = (referencing_element_type == "output") ? Behavior.ReflectsHostIDInDOMTokenList : Behavior.ReflectsHostID; test_property_reflection(element_creation_method, referencing_element_type, referenced_element_type, "for", "htmlFor", expected_htmlFor_property_behavior); - // It's unclear whether `form` and `list` should return null or should return the - // shadow host. See https://github.com/WICG/webcomponents/issues/1072. - test_property_reflection(element_creation_method, referencing_element_type, referenced_element_type, "form", "form", Behavior.IsNull); - test_property_reflection(element_creation_method, referencing_element_type, referenced_element_type, "list", "list", Behavior.IsNull); + // The form property of <label>, <legend>, and <option> reflects the form property of the associated labelable element, + // the associated <fieldset>, and the associated <select>, respectively. Here since we don't have those associated elements, + // the form property would return null. + const expected_form_property_behavior = (referenced_element_type == 'form' && + referencing_element_type != "label" && + referencing_element_type != "legend" && + referencing_element_type != "option") ? Behavior.ReflectsHost : Behavior.IsNull; + test_property_reflection(element_creation_method, referencing_element_type, referenced_element_type, "form", "form", expected_form_property_behavior); - // It's unclear whether this should always reflect the host even if the underlying - // referenced element isn't labelable. See - // https://github.com/WICG/webcomponents/issues/1072#issuecomment-2305875929 + const expected_list_property_behavior = (referenced_element_type == 'datalist') ? Behavior.ReflectsHost : Behavior.IsNull; + test_property_reflection(element_creation_method, referencing_element_type, referenced_element_type, "list", "list", expected_list_property_behavior); + const expected_control_property_behavior = HTML5_LABELABLE_ELEMENTS.includes(referenced_element_type) ? Behavior.ReflectsHost : Behavior.IsNull; test_property_reflection(element_creation_method, referencing_element_type, referenced_element_type, "for", "control", expected_control_property_behavior); }
diff --git a/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/batch_normalization.https.any.js b/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/batch_normalization.https.any.js index b8fa3f0..1da8577 100644 --- a/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/batch_normalization.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/batch_normalization.https.any.js
@@ -81,7 +81,7 @@ } }, { - 'name': 'batchNormalization float32 2D constant tensor default options', + 'name': 'batchNormalization float32 2D constant tensors default options', 'graph': { 'inputs': { 'bnInput': { @@ -697,6 +697,590 @@ } } } + }, + + // float16 tests + { + 'name': + 'batchNormalization float16 2D tensor (mean and variance are non-constant) default options', + 'graph': { + 'inputs': { + 'bnInput': { + 'data': [ + -41.3125, 64.0625, -63.375, -46.78125, 83, + -80.0625, -62.15625, -0.10009765625, -40.90625, 56.96875, + 37.375, 57.03125, 82.0625, -86.125, 76.875, + 97.0625, -21.34375, -96.9375, -9.359375, 80.1875, + -85.375, 62.34375, -68.5, -12.109375 + ], + 'descriptor': {shape: [4, 6], dataType: 'float16'} + }, + 'bnMean': { + 'data': [-7.8125, -95.625, 38.15625, -55.9375, -87.875, -41.625], + 'descriptor': {shape: [6], dataType: 'float16'} + }, + 'bnVariance': { + 'data': [60.3125, 26.4375, 53.28125, 40.15625, 59.40625, 36], + 'descriptor': {shape: [6], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'batchNormalization', + 'arguments': [ + {'input': 'bnInput'}, {'mean': 'bnMean'}, {'variance': 'bnVariance'} + ], + 'outputs': 'bnOutput' + }], + 'expectedOutputs': { + 'bnOutput': { + 'data': [ + -4.3125, 31.0625, -13.90625, 1.4453125, 22.171875, + -6.40625, -6.99609375, 18.578125, -10.828125, 17.8125, + 16.25, 16.4375, 11.5703125, 1.84765625, 5.3046875, + 24.140625, 8.6328125, -9.21875, -0.19921875, 34.1875, + -16.921875, 18.671875, 2.513671875, 4.91796875 + ], + 'descriptor': {shape: [4, 6], dataType: 'float16'} + } + } + } + }, + { + 'name': 'batchNormalization float16 2D constant tensors default options', + 'graph': { + 'inputs': { + 'bnInput': { + 'data': [ + -41.3125, 64.0625, -63.375, -46.78125, 83, + -80.0625, -62.15625, -0.10009765625, -40.90625, 56.96875, + 37.375, 57.03125, 82.0625, -86.125, 76.875, + 97.0625, -21.34375, -96.9375, -9.359375, 80.1875, + -85.375, 62.34375, -68.5, -12.109375 + ], + 'descriptor': {shape: [4, 6], dataType: 'float16'}, + 'constant': true + }, + 'bnMean': { + 'data': [-7.8125, -95.625, 38.15625, -55.9375, -87.875, -41.625], + 'descriptor': {shape: [6], dataType: 'float16'}, + 'constant': true + }, + 'bnVariance': { + 'data': [60.3125, 26.4375, 53.28125, 40.15625, 59.40625, 36], + 'descriptor': {shape: [6], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'batchNormalization', + 'arguments': [ + {'input': 'bnInput'}, {'mean': 'bnMean'}, {'variance': 'bnVariance'} + ], + 'outputs': 'bnOutput' + }], + 'expectedOutputs': { + 'bnOutput': { + 'data': [ + -4.3125, 31.0625, -13.90625, 1.4453125, 22.171875, + -6.40625, -6.99609375, 18.578125, -10.828125, 17.8125, + 16.25, 16.4375, 11.5703125, 1.84765625, 5.3046875, + 24.140625, 8.6328125, -9.21875, -0.19921875, 34.1875, + -16.921875, 18.671875, 2.513671875, 4.91796875 + ], + 'descriptor': {shape: [4, 6], dataType: 'float16'} + } + } + } + }, + { + 'name': 'batchNormalization float16 2D tensor default options', + 'graph': { + 'inputs': { + 'bnInput': { + 'data': [ + -41.3125, 64.0625, -63.375, -46.78125, 83, + -80.0625, -62.15625, -0.10009765625, -40.90625, 56.96875, + 37.375, 57.03125, 82.0625, -86.125, 76.875, + 97.0625, -21.34375, -96.9375, -9.359375, 80.1875, + -85.375, 62.34375, -68.5, -12.109375 + ], + 'descriptor': {shape: [4, 6], dataType: 'float16'} + }, + 'bnMean': { + 'data': [-7.8125, -95.625, 38.15625, -55.9375, -87.875, -41.625], + 'descriptor': {shape: [6], dataType: 'float16'}, + 'constant': true + }, + 'bnVariance': { + 'data': [60.3125, 26.4375, 53.28125, 40.15625, 59.40625, 36], + 'descriptor': {shape: [6], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'batchNormalization', + 'arguments': [ + {'input': 'bnInput'}, {'mean': 'bnMean'}, {'variance': 'bnVariance'} + ], + 'outputs': 'bnOutput' + }], + 'expectedOutputs': { + 'bnOutput': { + 'data': [ + -4.3125, 31.0625, -13.90625, 1.4453125, 22.171875, + -6.40625, -6.99609375, 18.578125, -10.828125, 17.8125, + 16.25, 16.4375, 11.5703125, 1.84765625, 5.3046875, + 24.140625, 8.6328125, -9.21875, -0.19921875, 34.1875, + -16.921875, 18.671875, 2.513671875, 4.91796875 + ], + 'descriptor': {shape: [4, 6], dataType: 'float16'} + } + } + } + }, + { + 'name': 'batchNormalization float16 3D tensor default options', + 'graph': { + 'inputs': { + 'bnInput': { + 'data': [ + -41.3125, 64.0625, -63.375, -46.78125, 83, + -80.0625, -62.15625, -0.10009765625, -40.90625, 56.96875, + 37.375, 57.03125, 82.0625, -86.125, 76.875, + 97.0625, -21.34375, -96.9375, -9.359375, 80.1875, + -85.375, 62.34375, -68.5, -12.109375 + ], + 'descriptor': {shape: [2, 3, 4], dataType: 'float16'} + }, + 'bnMean': { + 'data': [12.8125, 63.125, -61.625], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + }, + 'bnVariance': { + 'data': [18.359375, 41.84375, 16.125], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'batchNormalization', + 'arguments': [ + {'input': 'bnInput'}, {'mean': 'bnMean'}, {'variance': 'bnVariance'} + ], + 'outputs': 'bnOutput' + }], + 'expectedOutputs': { + 'bnOutput': { + 'data': [ + -12.6328125, 11.9609375, -17.78125, -13.90625, 3.072265625, + -22.140625, -19.375, -9.7734375, 5.16015625, 29.53125, + 24.65625, 29.546875, 16.15625, -23.09375, 14.953125, + 19.65625, -13.0546875, -24.75, -11.203125, 2.638671875, + -5.9140625, 30.875, -1.7119140625, 12.328125 + ], + 'descriptor': {shape: [2, 3, 4], dataType: 'float16'} + } + } + } + }, + { + 'name': 'batchNormalization float16 4D tensor default options', + 'graph': { + 'inputs': { + 'bnInput': { + 'data': [ + -41.3125, 64.0625, -63.375, -46.78125, 83, + -80.0625, -62.15625, -0.10009765625, -40.90625, 56.96875, + 37.375, 57.03125, 82.0625, -86.125, 76.875, + 97.0625, -21.34375, -96.9375, -9.359375, 80.1875, + -85.375, 62.34375, -68.5, -12.109375 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + }, + 'bnMean': { + 'data': [51.625, 99.375, -96.125], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + }, + 'bnVariance': { + 'data': [30.453125, 86.375, 73.875], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'batchNormalization', + 'arguments': [ + {'input': 'bnInput'}, {'mean': 'bnMean'}, {'variance': 'bnVariance'} + ], + 'outputs': 'bnOutput' + }], + 'expectedOutputs': { + 'bnOutput': { + 'data': [ + -16.84375, 2.25390625, -20.84375, -17.828125, -1.76171875, + -19.3125, -17.375, -10.703125, 6.42578125, 17.8125, + 15.53125, 17.8125, 5.515625, -24.96875, 4.57421875, + 8.234375, -12.9921875, -21.125, -11.703125, -2.064453125, + 1.2509765625, 18.4375, 3.21484375, 9.7734375 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + } + } + } + }, + { + 'name': 'batchNormalization float16 5D tensor default options', + 'graph': { + 'inputs': { + 'bnInput': { + 'data': [ + -41.3125, 64.0625, -63.375, -46.78125, 83, + -80.0625, -62.15625, -0.10009765625, -40.90625, 56.96875, + 37.375, 57.03125, 82.0625, -86.125, 76.875, + 97.0625, -21.34375, -96.9375, -9.359375, 80.1875, + -85.375, 62.34375, -68.5, -12.109375 + ], + 'descriptor': {shape: [6, 1, 1, 2, 2], dataType: 'float16'} + }, + 'bnMean': { + 'data': [35.40625], + 'descriptor': {shape: [1], dataType: 'float16'}, + 'constant': true + }, + 'bnVariance': { + 'data': [40.9375], + 'descriptor': {shape: [1], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'batchNormalization', + 'arguments': [ + {'input': 'bnInput'}, {'mean': 'bnMean'}, {'variance': 'bnVariance'} + ], + 'outputs': 'bnOutput' + }], + 'expectedOutputs': { + 'bnOutput': { + 'data': [ + -11.9921875, 4.48046875, -15.4375, -12.84375, 7.4375, + -18.046875, -15.25, -5.55078125, -11.9296875, 3.369140625, + 0.3076171875, 3.37890625, 7.29296875, -19, 6.48046875, + 9.6328125, -8.8671875, -20.6875, -6.99609375, 7, + -18.875, 4.2109375, -16.234375, -7.42578125 + ], + 'descriptor': {shape: [6, 1, 1, 2, 2], dataType: 'float16'} + } + } + } + }, + { + 'name': 'batchNormalization float16 4D NCHW tensor options.axis=1', + 'graph': { + 'inputs': { + 'bnInput': { + 'data': [ + -41.3125, 64.0625, -63.375, -46.78125, 83, + -80.0625, -62.15625, -0.10009765625, -40.90625, 56.96875, + 37.375, 57.03125, 82.0625, -86.125, 76.875, + 97.0625, -21.34375, -96.9375, -9.359375, 80.1875, + -85.375, 62.34375, -68.5, -12.109375 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + }, + 'bnMean': { + 'data': [51.625, 99.375, -96.125], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + }, + 'bnVariance': { + 'data': [30.453125, 86.375, 73.875], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'batchNormalization', + 'arguments': [ + {'input': 'bnInput'}, {'mean': 'bnMean'}, {'variance': 'bnVariance'}, + {'options': {'axis': 1}} + ], + 'outputs': 'bnOutput' + }], + 'expectedOutputs': { + 'bnOutput': { + 'data': [ + -16.84375, 2.25390625, -20.84375, -17.828125, -1.76171875, + -19.3125, -17.375, -10.703125, 6.42578125, 17.8125, + 15.53125, 17.8125, 5.515625, -24.96875, 4.57421875, + 8.234375, -12.9921875, -21.125, -11.703125, -2.064453125, + 1.2509765625, 18.4375, 3.21484375, 9.7734375 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + } + } + } + }, + { + 'name': 'batchNormalization float16 4D NHWC tensor options.axis=3', + 'graph': { + 'inputs': { + 'bnInput': { + 'data': [ + -41.3125, 83, -40.90625, 64.0625, -80.0625, + 56.96875, -63.375, -62.15625, 37.375, -46.78125, + -0.10009765625, 57.03125, 82.0625, -21.34375, -85.375, + -86.125, -96.9375, 62.34375, 76.875, -9.359375, + -68.5, 97.0625, 80.1875, -12.109375 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + }, + 'bnMean': { + 'data': [51.625, 99.375, -96.125], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + }, + 'bnVariance': { + 'data': [30.453125, 86.375, 73.875], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'batchNormalization', + 'arguments': [ + {'input': 'bnInput'}, {'mean': 'bnMean'}, {'variance': 'bnVariance'}, + {'options': {'axis': 3}} + ], + 'outputs': 'bnOutput' + }], + 'expectedOutputs': { + 'bnOutput': { + 'data': [ + -16.84375, -1.76171875, 6.42578125, 2.25390625, -19.3125, + 17.8125, -20.84375, -17.375, 15.53125, -17.828125, + -10.703125, 17.8125, 5.515625, -12.9921875, 1.2509765625, + -24.96875, -21.125, 18.4375, 4.57421875, -11.703125, + 3.21484375, 8.234375, -2.064453125, 9.7734375 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + } + } + } + }, + { + 'name': 'batchNormalization float16 4D NCHW tensor options.scale', + 'graph': { + 'inputs': { + 'bnInput': { + 'data': [ + -41.3125, 64.0625, -63.375, -46.78125, 83, + -80.0625, -62.15625, -0.10009765625, -40.90625, 56.96875, + 37.375, 57.03125, 82.0625, -86.125, 76.875, + 97.0625, -21.34375, -96.9375, -9.359375, 80.1875, + -85.375, 62.34375, -68.5, -12.109375 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + }, + 'bnMean': { + 'data': [51.625, 99.375, -96.125], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + }, + 'bnVariance': { + 'data': [30.453125, 86.375, 73.875], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + }, + 'bnScale': { + 'data': [65.5, -71, -5.5703125], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'batchNormalization', + 'arguments': [ + {'input': 'bnInput'}, {'mean': 'bnMean'}, {'variance': 'bnVariance'}, + {'options': {'scale': 'bnScale'}} + ], + 'outputs': 'bnOutput' + }], + 'expectedOutputs': { + 'bnOutput': { + 'data': [ + -1103, 147.625, -1365, -1168, 125.125, 1371, + 1234, 760, -35.78125, -99.1875, -86.5, -99.25, + 361.25, -1635, 299.75, 539.5, 922, 1500, + 830.5, 146.625, -6.96875, -102.6875, -17.90625, -54.4375 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + } + } + } + }, + { + 'name': 'batchNormalization float16 4D NCHW tensor options.bias', + 'graph': { + 'inputs': { + 'bnInput': { + 'data': [ + -41.3125, 64.0625, -63.375, -46.78125, 83, + -80.0625, -62.15625, -0.10009765625, -40.90625, 56.96875, + 37.375, 57.03125, 82.0625, -86.125, 76.875, + 97.0625, -21.34375, -96.9375, -9.359375, 80.1875, + -85.375, 62.34375, -68.5, -12.109375 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + }, + 'bnMean': { + 'data': [51.625, 99.375, -96.125], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + }, + 'bnVariance': { + 'data': [30.453125, 86.375, 73.875], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + }, + 'bnBias': { + 'data': [64.1875, 75.3125, -84.5625], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'batchNormalization', + 'arguments': [ + {'input': 'bnInput'}, {'mean': 'bnMean'}, {'variance': 'bnVariance'}, + {'options': {'bias': 'bnBias'}} + ], + 'outputs': 'bnOutput' + }], + 'expectedOutputs': { + 'bnOutput': { + 'data': [ + 47.34375, 66.4375, 43.34375, 46.34375, 73.5625, 56, + 57.9375, 64.625, -78.125, -66.75, -69, -66.75, + 69.6875, 39.21875, 68.75, 72.4375, 62.3125, 54.1875, + 63.625, 73.25, -83.3125, -66.125, -81.375, -74.8125 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + } + } + } + }, + { + 'name': 'batchNormalization float16 4D NCHW tensor options.epsilon', + 'graph': { + 'inputs': { + 'bnInput': { + 'data': [ + -41.3125, 64.0625, -63.375, -46.78125, 83, + -80.0625, -62.15625, -0.10009765625, -40.90625, 56.96875, + 37.375, 57.03125, 82.0625, -86.125, 76.875, + 97.0625, -21.34375, -96.9375, -9.359375, 80.1875, + -85.375, 62.34375, -68.5, -12.109375 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + }, + 'bnMean': { + 'data': [51.625, 99.375, -96.125], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + }, + 'bnVariance': { + 'data': [30.453125, 86.375, 73.875], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'batchNormalization', + 'arguments': [ + {'input': 'bnInput'}, {'mean': 'bnMean'}, {'variance': 'bnVariance'}, + {'options': {'epsilon': 0.000001}} + ], + 'outputs': 'bnOutput' + }], + 'expectedOutputs': { + 'bnOutput': { + 'data': [ + -16.84375, 2.25390625, -20.84375, -17.828125, -1.76171875, + -19.3125, -17.375, -10.703125, 6.42578125, 17.8125, + 15.53125, 17.8125, 5.515625, -24.96875, 4.57421875, + 8.234375, -12.9921875, -21.125, -11.703125, -2.064453125, + 1.2509765625, 18.4375, 3.21484375, 9.7734375 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + } + } + } + }, + { + 'name': 'batchNormalization float16 4D NHWC tensor all options', + 'graph': { + 'inputs': { + 'bnInput': { + 'data': [ + -41.3125, 83, -40.90625, 64.0625, -80.0625, + 56.96875, -63.375, -62.15625, 37.375, -46.78125, + -0.10009765625, 57.03125, 82.0625, -21.34375, -85.375, + -86.125, -96.9375, 62.34375, 76.875, -9.359375, + -68.5, 97.0625, 80.1875, -12.109375 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + }, + 'bnMean': { + 'data': [51.625, 99.375, -96.125], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + }, + 'bnVariance': { + 'data': [30.453125, 86.375, 73.875], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + }, + 'bnScale': { + 'data': [65.5, -71, -5.5703125], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + }, + 'bnBias': { + 'data': [64.1875, 75.3125, -84.5625], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'batchNormalization', + 'arguments': [ + {'input': 'bnInput'}, {'mean': 'bnMean'}, {'variance': 'bnVariance'}, + { + 'options': { + 'scale': 'bnScale', + 'bias': 'bnBias', + 'axis': 3, + 'epsilon': 0.000001 + } + } + ], + 'outputs': 'bnOutput' + }], + 'expectedOutputs': { + 'bnOutput': { + 'data': [ + -1039, 200.375, -120.375, 211.75, 1446, -183.75, + -1301, 1309, -171.125, -1104, 835.5, -183.875, + 425.5, 997.5, -91.5, -1571, 1575, -187.25, + 364, 906, -102.4375, 603.5, 221.875, -139 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + } + } + } } ];
diff --git a/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/instance_normalization.https.any.js b/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/instance_normalization.https.any.js index 08d7d6c..2766f914 100644 --- a/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/instance_normalization.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/instance_normalization.https.any.js
@@ -202,7 +202,7 @@ }, { 'name': - 'instanceNormalization float32 4D tensor explict options.layout=\'nchw\'', + 'instanceNormalization float32 4D tensor explicit options.layout=\'nchw\'', 'graph': { 'inputs': { 'instanceNormInput': { @@ -341,6 +341,290 @@ } } } + }, + + // float16 tests + { + 'name': 'instanceNormalization float16 4D tensor default options', + 'graph': { + 'inputs': { + 'instanceNormInput': { + 'data': [ + -97.9375, 29.4375, -73.9375, -38.125, 41.34375, -59.78125, + -74.6875, -68.1875, 35.8125, -6.94921875, 54.4375, 47.53125, + 66.9375, 76.75, 5.67578125, 25.6875, 37.375, 56.25, + -16.578125, 42.9375, 73.875, -99, -33.125, -17.375 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'instanceNormalization', + 'arguments': [{'input': 'instanceNormInput'}], + 'outputs': 'instanceNormOutput' + }], + 'expectedOutputs': { + 'instanceNormOutput': { + 'data': [ + -1.099609375, 1.552734375, -0.599609375, + 0.1461181640625, 1.7216796875, -0.409912109375, + -0.72412109375, -0.5869140625, 0.1302490234375, + -1.6630859375, 0.9111328125, 0.62158203125, + 0.79443359375, 1.130859375, -1.3056640625, + -0.61962890625, 0.265869140625, 0.9462890625, + -1.6787109375, 0.46630859375, 1.50390625, + -1.2978515625, -0.23046875, 0.024810791015625 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + } + } + } + }, + { + 'name': 'instanceNormalization float16 4D tensor options.scale', + 'graph': { + 'inputs': { + 'instanceNormInput': { + 'data': [ + -97.9375, 29.4375, -73.9375, -38.125, 41.34375, -59.78125, + -74.6875, -68.1875, 35.8125, -6.94921875, 54.4375, 47.53125, + 66.9375, 76.75, 5.67578125, 25.6875, 37.375, 56.25, + -16.578125, 42.9375, 73.875, -99, -33.125, -17.375 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + }, + 'instanceNormScale': { + 'data': [-94.4375, 66.6875, -98.5625], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'instanceNormalization', + 'arguments': [ + {'input': 'instanceNormInput'}, + {'options': {'scale': 'instanceNormScale'}} + ], + 'outputs': 'instanceNormOutput' + }], + 'expectedOutputs': { + 'instanceNormOutput': { + 'data': [ + 103.8125, -146.625, 56.625, -13.796875, 114.8125, + -27.34375, -48.28125, -39.15625, -12.8359375, 163.875, + -89.8125, -61.28125, -75.0625, -106.8125, 123.3125, + 58.53125, 17.734375, 63.09375, -111.9375, 31.09375, + -148.25, 127.9375, 22.71875, -2.4453125 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + } + } + } + }, + { + 'name': 'instanceNormalization float16 4D tensor options.bias', + 'graph': { + 'inputs': { + 'instanceNormInput': { + 'data': [ + -97.9375, 29.4375, -73.9375, -38.125, 41.34375, -59.78125, + -74.6875, -68.1875, 35.8125, -6.94921875, 54.4375, 47.53125, + 66.9375, 76.75, 5.67578125, 25.6875, 37.375, 56.25, + -16.578125, 42.9375, 73.875, -99, -33.125, -17.375 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + }, + 'instanceNormBias': { + 'data': [-33.0625, 4.51171875, -37.9375], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'instanceNormalization', + 'arguments': [ + {'input': 'instanceNormInput'}, + {'options': {'bias': 'instanceNormBias'}} + ], + 'outputs': 'instanceNormOutput' + }], + 'expectedOutputs': { + 'instanceNormOutput': { + 'data': [ + -34.15625, -31.515625, -33.65625, -32.90625, 6.234375, + 4.1015625, 3.787109375, 3.923828125, -37.8125, -39.59375, + -37.03125, -37.3125, -32.28125, -31.9375, -34.375, + -33.6875, 4.77734375, 5.45703125, 2.833984375, 4.9765625, + -36.4375, -39.25, -38.15625, -37.90625 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + } + } + } + }, + { + 'name': 'instanceNormalization float16 4D tensor options.epsilon', + 'graph': { + 'inputs': { + 'instanceNormInput': { + 'data': [ + -97.9375, 29.4375, -73.9375, -38.125, 41.34375, -59.78125, + -74.6875, -68.1875, 35.8125, -6.94921875, 54.4375, 47.53125, + 66.9375, 76.75, 5.67578125, 25.6875, 37.375, 56.25, + -16.578125, 42.9375, 73.875, -99, -33.125, -17.375 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'instanceNormalization', + 'arguments': [ + {'input': 'instanceNormInput'}, {'options': {'epsilon': 0.000001}} + ], + 'outputs': 'instanceNormOutput' + }], + 'expectedOutputs': { + 'instanceNormOutput': { + 'data': [ + -1.099609375, 1.552734375, -0.599609375, + 0.1461181640625, 1.7216796875, -0.409912109375, + -0.72412109375, -0.5869140625, 0.1302490234375, + -1.6630859375, 0.9111328125, 0.62158203125, + 0.79443359375, 1.130859375, -1.3056640625, + -0.61962890625, 0.265869140625, 0.9462890625, + -1.6787109375, 0.46630859375, 1.50390625, + -1.2978515625, -0.23046875, 0.024810791015625 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + } + } + } + }, + { + 'name': + 'instanceNormalization float16 4D tensor explicit options.layout=\'nchw\'', + 'graph': { + 'inputs': { + 'instanceNormInput': { + 'data': [ + -97.9375, 29.4375, -73.9375, -38.125, 41.34375, -59.78125, + -74.6875, -68.1875, 35.8125, -6.94921875, 54.4375, 47.53125, + 66.9375, 76.75, 5.67578125, 25.6875, 37.375, 56.25, + -16.578125, 42.9375, 73.875, -99, -33.125, -17.375 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'instanceNormalization', + 'arguments': + [{'input': 'instanceNormInput'}, {'options': {'layout': 'nchw'}}], + 'outputs': 'instanceNormOutput' + }], + 'expectedOutputs': { + 'instanceNormOutput': { + 'data': [ + -1.099609375, 1.552734375, -0.599609375, + 0.1461181640625, 1.7216796875, -0.409912109375, + -0.72412109375, -0.5869140625, 0.1302490234375, + -1.6630859375, 0.9111328125, 0.62158203125, + 0.79443359375, 1.130859375, -1.3056640625, + -0.61962890625, 0.265869140625, 0.9462890625, + -1.6787109375, 0.46630859375, 1.50390625, + -1.2978515625, -0.23046875, 0.024810791015625 + ], + 'descriptor': {shape: [2, 3, 2, 2], dataType: 'float16'} + } + } + } + }, + { + 'name': 'instanceNormalization float16 4D tensor options.layout=\'nhwc\'', + 'graph': { + 'inputs': { + 'instanceNormInput': { + 'data': [ + -97.9375, 41.34375, 35.8125, 29.4375, -59.78125, -6.94921875, + -73.9375, -74.6875, 54.4375, -38.125, -68.1875, 47.53125, + 66.9375, 37.375, 73.875, 76.75, 56.25, -99, + 5.67578125, -16.578125, -33.125, 25.6875, 42.9375, -17.375 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'instanceNormalization', + 'arguments': + [{'input': 'instanceNormInput'}, {'options': {'layout': 'nhwc'}}], + 'outputs': 'instanceNormOutput' + }], + 'expectedOutputs': { + 'instanceNormOutput': { + 'data': [ + -1.099609375, 1.7216796875, 0.1302490234375, + 1.552734375, -0.409912109375, -1.6630859375, + -0.599609375, -0.72412109375, 0.9111328125, + 0.1461181640625, -0.5869140625, 0.62158203125, + 0.79443359375, 0.265869140625, 1.50390625, + 1.130859375, 0.9462890625, -1.2978515625, + -1.3056640625, -1.6787109375, -0.23046875, + -0.61962890625, 0.46630859375, 0.024810791015625 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + } + } + } + }, + { + 'name': 'instanceNormalization float16 4D tensor all options', + 'graph': { + 'inputs': { + 'instanceNormInput': { + 'data': [ + -97.9375, 41.34375, 35.8125, 29.4375, -59.78125, -6.94921875, + -73.9375, -74.6875, 54.4375, -38.125, -68.1875, 47.53125, + 66.9375, 37.375, 73.875, 76.75, 56.25, -99, + 5.67578125, -16.578125, -33.125, 25.6875, 42.9375, -17.375 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + }, + 'instanceNormScale': { + 'data': [-94.4375, 66.6875, -98.5625], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + }, + 'instanceNormBias': { + 'data': [-33.0625, 4.51171875, -37.9375], + 'descriptor': {shape: [3], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'instanceNormalization', + 'arguments': [ + {'input': 'instanceNormInput'}, { + 'options': { + 'scale': 'instanceNormScale', + 'bias': 'instanceNormBias', + 'epsilon': 0.000001, + 'layout': 'nhwc' + } + } + ], + 'outputs': 'instanceNormOutput' + }], + 'expectedOutputs': { + 'instanceNormOutput': { + 'data': [ + 70.75, 119.3125, -50.78125, -179.75, -22.828125, 126, + 23.5625, -43.78125, -127.75, -46.84375, -34.65625, -99.1875, + -108.125, 22.25, -186.125, -139.875, 67.625, 90, + 90.25, -107.4375, -15.2265625, 25.46875, 35.625, -40.375 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'} + } + } + } } ];
diff --git a/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/layer_normalization.https.any.js b/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/layer_normalization.https.any.js index 2d5e98e..f22d044 100644 --- a/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/layer_normalization.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/layer_normalization.https.any.js
@@ -22,11 +22,8 @@ // MLOperand input, optional MLLayerNormalizationOptions options = {}); -const getLayerNormPrecisionTolerance = (graphResources) => { - const toleranceValueDict = {float32: 1 / 1024, float16: 1 / 512}; - const expectedDataType = - getExpectedDataTypeOfSingleOutput(graphResources.expectedOutputs); - return {metricType: 'ATOL', value: toleranceValueDict[expectedDataType]}; +const getLayerNormPrecisionTolerance = () => { + return {metricType: 'ULP', value: 14}; }; const layerNormTests = [ @@ -56,14 +53,14 @@ 'inputs': { 'layerNormInput': { 'data': [ - -35.51446533203125, 54.735408782958984, 19.659019470214844, - -15.882678031921387, 65.48657989501953, 25.818492889404297, - 97.55302429199219, -8.057161331176758, 62.9412956237793, - -48.91555404663086, 91.90644073486328, 46.67098617553711, - -74.85331726074219, 30.126361846923828, 26.13089370727539, - 59.30270767211914, -60.361995697021484, 18.55615234375, - -88.03730773925781, -26.5667724609375, 70.81292724609375, - 9.105611801147461, 56.66746139526367, 21.78444480895996 + -5.712825298309326, 1.4681644439697266, 6.143280029296875, + 9.427258491516113, 2.0522539615631104, -8.829475402832031, + 9.143593788146973, -7.643154144287109, -2.0325264930725098, + 6.063992500305176, 4.094968318939209, 0.8910917043685913, + 8.712732315063477, -0.0006124831270426512, 5.505736827850342, + -9.155109405517578, -9.89109992980957, 1.0480059385299683, + -5.925083637237549, 7.741676330566406, 0.700584352016449, + -5.662013530731201, 1.3204102516174316, 2.7849292755126953 ], 'descriptor': {shape: [4, 6], dataType: 'float32'} } @@ -76,14 +73,14 @@ 'expectedOutputs': { 'layerNormOutput': { 'data': [ - -1.5257738828659058, 0.997844934463501, 0.017018765211105347, - -0.9768186211585999, 1.2984753847122192, 0.18925349414348602, - 1.0812907218933105, -0.915019690990448, 0.4270379841327667, - -1.6873507499694824, 0.9745554327964783, 0.11948632448911667, - -1.5086692571640015, 0.6123882532119751, 0.5316619873046875, - 1.2018805742263794, -1.215880036354065, 0.378618448972702, - -1.795186161994934, -0.6376377940177917, 1.1961140632629395, - 0.034106940031051636, 0.9297415614128113, 0.2728613615036011 + -1.0228718519210815, 0.11223962903022766, 0.8512431979179382, + 1.3703473806381226, 0.20456767082214355, -1.5155260562896729, + 1.3417094945907593, -1.705802321434021, -0.6872337460517883, + 0.7826303243637085, 0.42516833543777466, -0.1564721316099167, + 1.3518258333206177, 0.09107562154531479, 0.8877996206283569, + -1.2335057258605957, -1.3399975299835205, 0.2428021878004074, + -1.273769736289978, 1.58700692653656, 0.1131395623087883, + -1.2187029123306274, 0.2428838163614273, 0.5494423508644104 ], 'descriptor': {shape: [4, 6], dataType: 'float32'} } @@ -647,6 +644,459 @@ } } } + }, + + // float16 tests + { + 'name': 'layerNormalization float16 2D tensor default options', + 'graph': { + 'inputs': { + 'layerNormInput': { + 'data': [ + -5.7109375, 1.4677734375, + 6.14453125, 9.4296875, + 2.052734375, -8.828125, + 9.140625, -7.64453125, + -2.033203125, 6.0625, + 4.09375, 0.89111328125, + 8.7109375, -0.0006122589111328125, + 5.50390625, -9.15625, + -9.890625, 1.0478515625, + -5.92578125, 7.7421875, + 0.70068359375, -5.66015625, + 1.3203125, 2.78515625 + ], + 'descriptor': {shape: [4, 6], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'layerNormalization', + 'arguments': [{'input': 'layerNormInput'}], + 'outputs': 'layerNormOutput' + }], + 'expectedOutputs': { + 'layerNormOutput': { + 'data': [ + -1.0224609375, 0.11199951171875, 0.85107421875, 1.3701171875, + 0.2044677734375, -1.515625, 1.341796875, -1.7060546875, + -0.68701171875, 0.78271484375, 0.42529296875, -0.15625, + 1.3515625, 0.0911865234375, 0.8876953125, -1.2333984375, + -1.33984375, 0.242919921875, -1.2744140625, 1.5869140625, + 0.11309814453125, -1.21875, 0.2427978515625, 0.54931640625 + ], + 'descriptor': {shape: [4, 6], dataType: 'float16'} + } + } + } + }, + { + 'name': 'layerNormalization float16 3D tensor default options', + 'graph': { + 'inputs': { + 'layerNormInput': { + 'data': [ + -35.5, 54.75, 19.65625, -15.8828125, 65.5, 25.8125, + 97.5625, -8.0546875, 62.9375, -48.90625, 91.9375, 46.65625, + -74.875, 30.125, 26.125, 59.3125, -60.375, 18.5625, + -88.0625, -26.5625, 70.8125, 9.109375, 56.65625, 21.78125 + ], + 'descriptor': {shape: [2, 3, 4], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'layerNormalization', + 'arguments': [{'input': 'layerNormInput'}], + 'outputs': 'layerNormOutput' + }], + 'expectedOutputs': { + 'layerNormOutput': { + 'data': [ + -1.4052734375, 0.5400390625, -0.216552734375, -0.982421875, + 0.771484375, -0.08392333984375, 1.462890625, -0.81396484375, + 0.71630859375, -1.6943359375, 1.341796875, 0.365234375, + -1.5234375, 0.51611328125, 0.4384765625, 1.0830078125, + -1.2421875, 0.291748046875, -1.7802734375, -0.5849609375, + 1.306640625, 0.10797119140625, 1.03125, 0.354248046875 + ], + 'descriptor': {shape: [2, 3, 4], dataType: 'float16'} + } + } + } + }, + { + 'name': 'layerNormalization float16 4D tensor default options', + 'graph': { + 'inputs': { + 'layerNormInput': { + 'data': [ + -35.5, 54.75, 19.65625, -15.8828125, 65.5, 25.8125, + 97.5625, -8.0546875, 62.9375, -48.90625, 91.9375, 46.65625, + -74.875, 30.125, 26.125, 59.3125, -60.375, 18.5625, + -88.0625, -26.5625, 70.8125, 9.109375, 56.65625, 21.78125 + ], + 'descriptor': {shape: [2, 1, 4, 3], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'layerNormalization', + 'arguments': [{'input': 'layerNormInput'}], + 'outputs': 'layerNormOutput' + }], + 'expectedOutputs': { + 'layerNormOutput': { + 'data': [ + -1.4052734375, 0.5400390625, -0.216552734375, -0.982421875, + 0.771484375, -0.08392333984375, 1.462890625, -0.81396484375, + 0.71630859375, -1.6943359375, 1.341796875, 0.365234375, + -1.5234375, 0.51611328125, 0.4384765625, 1.0830078125, + -1.2421875, 0.291748046875, -1.7802734375, -0.5849609375, + 1.306640625, 0.10797119140625, 1.03125, 0.354248046875 + ], + 'descriptor': {shape: [2, 1, 4, 3], dataType: 'float16'} + } + } + } + }, + { + 'name': 'layerNormalization float16 5D tensor default options', + 'graph': { + 'inputs': { + 'layerNormInput': { + 'data': [ + -35.5, 54.75, 19.65625, -15.8828125, 65.5, 25.8125, + 97.5625, -8.0546875, 62.9375, -48.90625, 91.9375, 46.65625, + -74.875, 30.125, 26.125, 59.3125, -60.375, 18.5625, + -88.0625, -26.5625, 70.8125, 9.109375, 56.65625, 21.78125 + ], + 'descriptor': {shape: [2, 1, 2, 2, 3], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'layerNormalization', + 'arguments': [{'input': 'layerNormInput'}], + 'outputs': 'layerNormOutput' + }], + 'expectedOutputs': { + 'layerNormOutput': { + 'data': [ + -1.4052734375, 0.5400390625, -0.216552734375, -0.982421875, + 0.771484375, -0.08392333984375, 1.462890625, -0.81396484375, + 0.71630859375, -1.6943359375, 1.341796875, 0.365234375, + -1.5234375, 0.51611328125, 0.4384765625, 1.0830078125, + -1.2421875, 0.291748046875, -1.7802734375, -0.5849609375, + 1.306640625, 0.10797119140625, 1.03125, 0.354248046875 + ], + 'descriptor': {shape: [2, 1, 2, 2, 3], dataType: 'float16'} + } + } + } + }, + { + 'name': 'layerNormalization float16 4D tensor options.scale', + 'graph': { + 'inputs': { + 'layerNormInput': { + 'data': [ + -35.5, 54.75, 19.65625, -15.8828125, 65.5, 25.8125, + 97.5625, -8.0546875, 62.9375, -48.90625, 91.9375, 46.65625, + -74.875, 30.125, 26.125, 59.3125, -60.375, 18.5625, + -88.0625, -26.5625, 70.8125, 9.109375, 56.65625, 21.78125 + ], + 'descriptor': {shape: [2, 1, 4, 3], dataType: 'float16'} + }, + 'layerNormScale': { + 'data': [ + -3.822265625, -5.453125, 0.677734375, -4.02734375, -3.77734375, + -9.328125, 7.18359375, 1.505859375, 3.12109375, 0.521484375, + 2.671875, -3.572265625 + ], + 'descriptor': {shape: [1, 4, 3], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'layerNormalization', + 'arguments': [ + {'input': 'layerNormInput'}, {'options': {'scale': 'layerNormScale'}} + ], + 'outputs': 'layerNormOutput' + }], + 'expectedOutputs': { + 'layerNormOutput': { + 'data': [ + 5.37109375, -2.943359375, -0.1468505859375, 3.95703125, + -2.9140625, 0.78271484375, 10.5078125, -1.2255859375, + 2.236328125, -0.8837890625, 3.583984375, -1.3046875, + 5.82421875, -2.814453125, 0.297119140625, -4.36328125, + 4.69140625, -2.720703125, -12.7890625, -0.880859375, + 4.078125, 0.056304931640625, 2.755859375, -1.265625 + ], + 'descriptor': {shape: [2, 1, 4, 3], dataType: 'float16'} + } + } + } + }, + { + 'name': 'layerNormalization float16 4D tensor options.bias', + 'graph': { + 'inputs': { + 'layerNormInput': { + 'data': [ + -35.5, 54.75, 19.65625, -15.8828125, 65.5, 25.8125, + 97.5625, -8.0546875, 62.9375, -48.90625, 91.9375, 46.65625, + -74.875, 30.125, 26.125, 59.3125, -60.375, 18.5625, + -88.0625, -26.5625, 70.8125, 9.109375, 56.65625, 21.78125 + ], + 'descriptor': {shape: [2, 1, 4, 3], dataType: 'float16'} + }, + 'layerNormBias': { + 'data': [ + 7.86328125, -3.66015625, -6.95703125, -6.3984375, 3.26953125, -2.75, + -4.08203125, -7.13671875, 8.46875, 2.76171875, 0.8232421875, + -3.828125 + ], + 'descriptor': {shape: [1, 4, 3], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'layerNormalization', + 'arguments': [ + {'input': 'layerNormInput'}, {'options': {'bias': 'layerNormBias'}} + ], + 'outputs': 'layerNormOutput' + }], + 'expectedOutputs': { + 'layerNormOutput': { + 'data': [ + 6.45703125, -3.12109375, -7.171875, -7.3828125, 4.04296875, + -2.833984375, -2.619140625, -7.94921875, 9.1875, 1.0673828125, + 2.1640625, -3.462890625, 6.33984375, -3.14453125, -6.51953125, + -5.31640625, 2.02734375, -2.458984375, -5.86328125, -7.72265625, + 9.7734375, 2.869140625, 1.8544921875, -3.474609375 + ], + 'descriptor': {shape: [2, 1, 4, 3], dataType: 'float16'} + } + } + } + }, + { + 'name': 'layerNormalization float16 4D tensor options.axes=[2]', + 'graph': { + 'inputs': { + 'layerNormInput': { + 'data': [ + -35.5, 54.75, 19.65625, -15.8828125, 65.5, 25.8125, + 97.5625, -8.0546875, 62.9375, -48.90625, 91.9375, 46.65625, + -74.875, 30.125, 26.125, 59.3125, -60.375, 18.5625, + -88.0625, -26.5625, 70.8125, 9.109375, 56.65625, 21.78125 + ], + 'descriptor': {shape: [2, 1, 4, 3], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'layerNormalization', + 'arguments': [{'input': 'layerNormInput'}, {'options': {'axes': [2]}}], + 'outputs': 'layerNormOutput' + }], + 'expectedOutputs': { + 'layerNormOutput': { + 'data': [ + -0.60107421875, 0.10125732421875, -1.11328125, -0.262451171875, + 0.394287109375, -0.75439453125, 1.6962890625, -1.6103515625, + 1.4072265625, -0.83251953125, 1.1142578125, 0.45947265625, + -0.8447265625, 0.65576171875, -0.3857421875, 1.3671875, + -1.3115234375, -0.74169921875, -1.0615234375, -0.57666015625, + 1.7177734375, 0.53955078125, 1.232421875, -0.59033203125 + ], + 'descriptor': {shape: [2, 1, 4, 3], dataType: 'float16'} + } + } + } + }, + { + 'name': 'layerNormalization float16 4D tensor options.epsilon', + 'graph': { + 'inputs': { + 'layerNormInput': { + 'data': [ + -35.5, 54.75, 19.65625, -15.8828125, 65.5, 25.8125, + 97.5625, -8.0546875, 62.9375, -48.90625, 91.9375, 46.65625, + -74.875, 30.125, 26.125, 59.3125, -60.375, 18.5625, + -88.0625, -26.5625, 70.8125, 9.109375, 56.65625, 21.78125 + ], + 'descriptor': {shape: [2, 1, 4, 3], dataType: 'float16'} + } + }, + 'operators': [{ + 'name': 'layerNormalization', + 'arguments': + [{'input': 'layerNormInput'}, {'options': {'epsilon': 0.0001}}], + 'outputs': 'layerNormOutput' + }], + 'expectedOutputs': { + 'layerNormOutput': { + 'data': [ + -1.4052734375, 0.5400390625, -0.216552734375, -0.982421875, + 0.771484375, -0.08392333984375, 1.462890625, -0.81396484375, + 0.71630859375, -1.6943359375, 1.341796875, 0.365234375, + -1.5234375, 0.51611328125, 0.4384765625, 1.0830078125, + -1.2421875, 0.291748046875, -1.7802734375, -0.5849609375, + 1.306640625, 0.10797119140625, 1.03125, 0.354248046875 + ], + 'descriptor': {shape: [2, 1, 4, 3], dataType: 'float16'} + } + } + } + }, + { + 'name': + 'layerNormalization float16 4D tensor options.scale and options.axes=[0, 2]', + 'graph': { + 'inputs': { + 'layerNormInput': { + 'data': [ + -35.5, 54.75, 19.65625, -15.8828125, 65.5, 25.8125, + 97.5625, -8.0546875, 62.9375, -48.90625, 91.9375, 46.65625, + -74.875, 30.125, 26.125, 59.3125, -60.375, 18.5625, + -88.0625, -26.5625, 70.8125, 9.109375, 56.65625, 21.78125 + ], + 'descriptor': {shape: [2, 1, 4, 3], dataType: 'float16'} + }, + 'layerNormScale': { + 'data': [ + 8.7265625, -5.38671875, -6.8125, 4.70703125, -4.70703125, + -5.14453125, -1.111328125, 5.25 + ], + 'descriptor': {shape: [2, 4], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'layerNormalization', + 'arguments': [ + {'input': 'layerNormInput'}, + {'options': {'scale': 'layerNormScale', 'axes': [0, 2]}} + ], + 'outputs': 'layerNormOutput' + }], + 'expectedOutputs': { + 'layerNormOutput': { + 'data': [ + -3.37109375, 5.2265625, -7.58203125, 0.332275390625, + -4.4140625, 2.97265625, -12.375, 4.6796875, + -9.25, -2.86328125, 6.40625, 2.44921875, + 4.88671875, -0.446044921875, 2.5234375, -6.0859375, + 9.046875, 4.7578125, 1.396484375, 1.1845703125, + -1.958984375, 1.84765625, 3.349609375, -3.986328125 + ], + 'descriptor': {shape: [2, 1, 4, 3], dataType: 'float16'} + } + } + } + }, + { + 'name': + 'layerNormalization float16 4D tensor options.bias and options.axes=[3, 1, 2]', + 'graph': { + 'inputs': { + 'layerNormInput': { + 'data': [ + -35.5, 54.75, 19.65625, -15.8828125, 65.5, 25.8125, + 97.5625, -8.0546875, 62.9375, -48.90625, 91.9375, 46.65625, + -74.875, 30.125, 26.125, 59.3125, -60.375, 18.5625, + -88.0625, -26.5625, 70.8125, 9.109375, 56.65625, 21.78125 + ], + 'descriptor': {shape: [2, 1, 4, 3], dataType: 'float16'} + }, + 'layerNormBias': { + 'data': [ + -0.1396484375, -6.15625, 4.36328125, 8.859375, 9.7734375, + -3.462890625, 9.7421875, -0.39599609375, -8.5, 6.171875, + -2.892578125, 1.7216796875 + ], + 'descriptor': {shape: [3, 1, 4], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'layerNormalization', + 'arguments': [ + {'input': 'layerNormInput'}, + {'options': {'bias': 'layerNormBias', 'axes': [3, 1, 2]}} + ], + 'outputs': 'layerNormOutput' + }], + 'expectedOutputs': { + 'layerNormOutput': { + 'data': [ + -1.544921875, 10.3125, -8.71875, -7.140625, -2.69140625, + 6.08984375, 5.82421875, 8.9296875, -2.17578125, 7.1640625, + 0.9453125, 2.087890625, -1.6630859375, 10.2890625, -8.0625, + -5.07421875, -4.703125, 6.46484375, 2.583984375, 9.15625, + -1.5859375, 8.96875, 0.6357421875, 2.076171875 + ], + 'descriptor': {shape: [2, 1, 4, 3], dataType: 'float16'} + } + } + } + }, + { + 'name': 'layerNormalization float16 4D tensor all options', + 'graph': { + 'inputs': { + 'layerNormInput': { + 'data': [ + -35.5, 54.75, 19.65625, -15.8828125, 65.5, 25.8125, + 97.5625, -8.0546875, 62.9375, -48.90625, 91.9375, 46.65625, + -74.875, 30.125, 26.125, 59.3125, -60.375, 18.5625, + -88.0625, -26.5625, 70.8125, 9.109375, 56.65625, 21.78125 + ], + 'descriptor': {shape: [2, 1, 4, 3], dataType: 'float16'} + }, + 'layerNormScale': { + 'data': [ + 7.71484375, 1.7373046875, 9.140625, 5.7578125, -2.8203125, + -0.6865234375 + ], + 'descriptor': {shape: [2, 3, 1], dataType: 'float16'}, + 'constant': true + }, + 'layerNormBias': { + 'data': [ + -8.7109375, -7.64453125, 4.9375, -2.1875, -4.06640625, -6.8359375 + ], + 'descriptor': {shape: [2, 3, 1], dataType: 'float16'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'layerNormalization', + 'arguments': [ + {'input': 'layerNormInput'}, { + 'options': { + 'scale': 'layerNormScale', + 'bias': 'layerNormBias', + 'axes': [0, 3, 1], + 'epsilon': 0.0001 + } + } + ], + 'outputs': 'layerNormOutput' + }], + 'expectedOutputs': { + 'layerNormOutput': { + 'data': [ + -15.484375, -5.62890625, 8.296875, -14.296875, -5.640625, + 7.11328125, 0.775390625, -8.3515625, 11.28125, -22.5, + -5.17578125, 8.5, -12.359375, -5.76953125, -7.1875, + 3.6328125, 0.86865234375, -6.8828125, -11.6484375, -2.1171875, + -7.39453125, -4.8671875, -5.80859375, -6.71484375 + ], + 'descriptor': {shape: [2, 1, 4, 3], dataType: 'float16'} + } + } + } } ];
diff --git a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index 7f1cacc..dfee4371 100644 --- a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -27,19 +27,18 @@ method create interface AILanguageModel : EventTarget attribute @@toStringTag - getter maxTokens - getter oncontextoverflow + getter inputQuota + getter inputUsage + getter onquotaoverflow getter temperature - getter tokensLeft - getter tokensSoFar getter topK method clone method constructor - method countPromptTokens method destroy + method measureInputUsage method prompt method promptStreaming - setter oncontextoverflow + setter onquotaoverflow interface AILanguageModelFactory attribute @@toStringTag method availability
diff --git a/third_party/blink/web_tests/platform/mac-mac14/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_cpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac14/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_cpu-expected.txt index b28cfd4..1bb39f8 100644 --- a/third_party/blink/web_tests/platform/mac-mac14/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac14/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_cpu-expected.txt
@@ -5,5 +5,11 @@ promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." [FAIL] layerNormalization float32 4D tensor all options promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." +[FAIL] layerNormalization float16 4D tensor options.scale and options.axes=[0, 2] + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be consecutive for layerNormalization on cpu." +[FAIL] layerNormalization float16 4D tensor options.bias and options.axes=[3, 1, 2] + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." +[FAIL] layerNormalization float16 4D tensor all options + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac14/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_npu-expected.txt b/third_party/blink/web_tests/platform/mac-mac14/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_npu-expected.txt index 5ed44c46..791d8b8 100644 --- a/third_party/blink/web_tests/platform/mac-mac14/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac14/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_npu-expected.txt
@@ -3,5 +3,9 @@ promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." [FAIL] layerNormalization float32 4D tensor all options promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." +[FAIL] layerNormalization float16 4D tensor options.bias and options.axes=[3, 1, 2] + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." +[FAIL] layerNormalization float16 4D tensor all options + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac14/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac14/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt index 5ed44c46..791d8b8 100644 --- a/third_party/blink/web_tests/platform/mac-mac14/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac14/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt
@@ -3,5 +3,9 @@ promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." [FAIL] layerNormalization float32 4D tensor all options promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." +[FAIL] layerNormalization float16 4D tensor options.bias and options.axes=[3, 1, 2] + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." +[FAIL] layerNormalization float16 4D tensor all options + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_cpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_cpu-expected.txt index b28cfd4..1bb39f8 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_cpu-expected.txt
@@ -5,5 +5,11 @@ promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." [FAIL] layerNormalization float32 4D tensor all options promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." +[FAIL] layerNormalization float16 4D tensor options.scale and options.axes=[0, 2] + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be consecutive for layerNormalization on cpu." +[FAIL] layerNormalization float16 4D tensor options.bias and options.axes=[3, 1, 2] + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." +[FAIL] layerNormalization float16 4D tensor all options + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_npu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_npu-expected.txt index 5ed44c46..791d8b8 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_npu-expected.txt
@@ -3,5 +3,9 @@ promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." [FAIL] layerNormalization float32 4D tensor all options promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." +[FAIL] layerNormalization float16 4D tensor options.bias and options.axes=[3, 1, 2] + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." +[FAIL] layerNormalization float16 4D tensor all options + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt index 5ed44c46..791d8b8 100644 --- a/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac-mac15-arm64/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt
@@ -3,5 +3,9 @@ promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." [FAIL] layerNormalization float32 4D tensor all options promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." +[FAIL] layerNormalization float16 4D tensor options.bias and options.axes=[3, 1, 2] + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." +[FAIL] layerNormalization float16 4D tensor all options + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/batch_normalization.https.any_cpu-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/batch_normalization.https.any_cpu-expected.txt index 5f1749f..5195ea6 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/batch_normalization.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/batch_normalization.https.any_cpu-expected.txt
@@ -1,7 +1,7 @@ This is a testharness.js-based test. [FAIL] batchNormalization float32 2D tensor (mean and variance are non-constant) default options promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'batchNormalization' on 'MLGraphBuilder': Unsupported rank 2 for argument input (must be at least 3)." -[FAIL] batchNormalization float32 2D constant tensor default options +[FAIL] batchNormalization float32 2D constant tensors default options promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'batchNormalization' on 'MLGraphBuilder': Unsupported rank 2 for argument input (must be at least 3)." [FAIL] batchNormalization float32 2D tensor default options promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'batchNormalization' on 'MLGraphBuilder': Unsupported rank 2 for argument input (must be at least 3)." @@ -9,5 +9,15 @@ promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported axis for batchNormalization. It must be the channel dimension." [FAIL] batchNormalization float32 4D NHWC tensor all options promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported axis for batchNormalization. It must be the channel dimension." +[FAIL] batchNormalization float16 2D tensor (mean and variance are non-constant) default options + promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'batchNormalization' on 'MLGraphBuilder': Unsupported rank 2 for argument input (must be at least 3)." +[FAIL] batchNormalization float16 2D constant tensors default options + promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'batchNormalization' on 'MLGraphBuilder': Unsupported rank 2 for argument input (must be at least 3)." +[FAIL] batchNormalization float16 2D tensor default options + promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'batchNormalization' on 'MLGraphBuilder': Unsupported rank 2 for argument input (must be at least 3)." +[FAIL] batchNormalization float16 4D NHWC tensor options.axis=3 + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported axis for batchNormalization. It must be the channel dimension." +[FAIL] batchNormalization float16 4D NHWC tensor all options + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported axis for batchNormalization. It must be the channel dimension." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/instance_normalization.https.any_cpu-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/instance_normalization.https.any_cpu-expected.txt index be01c34..8be6f5d1 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/instance_normalization.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/instance_normalization.https.any_cpu-expected.txt
@@ -3,5 +3,9 @@ promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported input layout." [FAIL] instanceNormalization float32 4D tensor all options promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported input layout." +[FAIL] instanceNormalization float16 4D tensor options.layout='nhwc' + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported input layout." +[FAIL] instanceNormalization float16 4D tensor all options + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported input layout." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_cpu-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_cpu-expected.txt index 19e58a2..79dbfc2 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_cpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-on-cpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_cpu-expected.txt
@@ -5,5 +5,11 @@ promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." [FAIL] layerNormalization float32 4D tensor all options promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." +[FAIL] layerNormalization float16 4D tensor options.scale and options.axes=[0, 2] + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be consecutive for layerNormalization." +[FAIL] layerNormalization float16 4D tensor options.bias and options.axes=[3, 1, 2] + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." +[FAIL] layerNormalization float16 4D tensor all options + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/batch_normalization.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/batch_normalization.https.any_gpu-expected.txt index 5f1749f..5195ea6 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/batch_normalization.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/batch_normalization.https.any_gpu-expected.txt
@@ -1,7 +1,7 @@ This is a testharness.js-based test. [FAIL] batchNormalization float32 2D tensor (mean and variance are non-constant) default options promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'batchNormalization' on 'MLGraphBuilder': Unsupported rank 2 for argument input (must be at least 3)." -[FAIL] batchNormalization float32 2D constant tensor default options +[FAIL] batchNormalization float32 2D constant tensors default options promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'batchNormalization' on 'MLGraphBuilder': Unsupported rank 2 for argument input (must be at least 3)." [FAIL] batchNormalization float32 2D tensor default options promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'batchNormalization' on 'MLGraphBuilder': Unsupported rank 2 for argument input (must be at least 3)." @@ -9,5 +9,15 @@ promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported axis for batchNormalization. It must be the channel dimension." [FAIL] batchNormalization float32 4D NHWC tensor all options promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported axis for batchNormalization. It must be the channel dimension." +[FAIL] batchNormalization float16 2D tensor (mean and variance are non-constant) default options + promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'batchNormalization' on 'MLGraphBuilder': Unsupported rank 2 for argument input (must be at least 3)." +[FAIL] batchNormalization float16 2D constant tensors default options + promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'batchNormalization' on 'MLGraphBuilder': Unsupported rank 2 for argument input (must be at least 3)." +[FAIL] batchNormalization float16 2D tensor default options + promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'batchNormalization' on 'MLGraphBuilder': Unsupported rank 2 for argument input (must be at least 3)." +[FAIL] batchNormalization float16 4D NHWC tensor options.axis=3 + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported axis for batchNormalization. It must be the channel dimension." +[FAIL] batchNormalization float16 4D NHWC tensor all options + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported axis for batchNormalization. It must be the channel dimension." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/instance_normalization.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/instance_normalization.https.any_gpu-expected.txt index be01c34..8be6f5d1 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/instance_normalization.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/instance_normalization.https.any_gpu-expected.txt
@@ -3,5 +3,9 @@ promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported input layout." [FAIL] instanceNormalization float32 4D tensor all options promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported input layout." +[FAIL] instanceNormalization float16 4D tensor options.layout='nhwc' + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported input layout." +[FAIL] instanceNormalization float16 4D tensor all options + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported input layout." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt index 19e58a2..79dbfc2 100644 --- a/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/mac/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt
@@ -5,5 +5,11 @@ promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." [FAIL] layerNormalization float32 4D tensor all options promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." +[FAIL] layerNormalization float16 4D tensor options.scale and options.axes=[0, 2] + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be consecutive for layerNormalization." +[FAIL] layerNormalization float16 4D tensor options.bias and options.axes=[3, 1, 2] + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." +[FAIL] layerNormalization float16 4D tensor all options + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/batch_normalization.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/batch_normalization.https.any_gpu-expected.txt new file mode 100644 index 0000000..5269be09 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/batch_normalization.https.any_gpu-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +[FAIL] batchNormalization float16 4D NHWC tensor all options + assert_true: assert_array_approx_equals_ulp: test batchNormalization float16 actual 199.5 should be close enough to expected 200.375 by the acceptable 6 ULP distance, but they have 7 ULP distance expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt index 701c51b..759937bc 100644 --- a/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt +++ b/third_party/blink/web_tests/platform/win/virtual/webnn-service-with-gpu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_gpu-expected.txt
@@ -1,9 +1,9 @@ This is a testharness.js-based test. [FAIL] layerNormalization float32 0D tensor default options - assert_array_approx_equals: test layerNormalization float32 property 0, expected 0 +/- 0.0009765625, expected 0 but got NaN + assert_true: assert_array_approx_equals_ulp: test layerNormalization float32 actual NaN should be close enough to expected 0 by the acceptable 14 ULP distance, but they have 2143289344 ULP distance expected true got false [FAIL] layerNormalization float32 2D tensor axes=[] and options.bias - assert_array_approx_equals: test layerNormalization float32 property 0, expected 7.862982749938965 +/- 0.0009765625, expected 7.862982749938965 but got NaN + assert_true: assert_array_approx_equals_ulp: test layerNormalization float32 actual NaN should be close enough to expected 7.862982749938965 by the acceptable 14 ULP distance, but they have 1053057650 ULP distance expected true got false [FAIL] layerNormalization float32 2D tensor axes=[] - assert_array_approx_equals: test layerNormalization float32 property 0, expected 0 +/- 0.0009765625, expected 0 but got NaN + assert_true: assert_array_approx_equals_ulp: test layerNormalization float32 actual NaN should be close enough to expected 0 by the acceptable 14 ULP distance, but they have 2143289344 ULP distance expected true got false Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/batch_normalization.https.any_npu-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/batch_normalization.https.any_npu-expected.txt index 5f1749f..5195ea6 100644 --- a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/batch_normalization.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/batch_normalization.https.any_npu-expected.txt
@@ -1,7 +1,7 @@ This is a testharness.js-based test. [FAIL] batchNormalization float32 2D tensor (mean and variance are non-constant) default options promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'batchNormalization' on 'MLGraphBuilder': Unsupported rank 2 for argument input (must be at least 3)." -[FAIL] batchNormalization float32 2D constant tensor default options +[FAIL] batchNormalization float32 2D constant tensors default options promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'batchNormalization' on 'MLGraphBuilder': Unsupported rank 2 for argument input (must be at least 3)." [FAIL] batchNormalization float32 2D tensor default options promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'batchNormalization' on 'MLGraphBuilder': Unsupported rank 2 for argument input (must be at least 3)." @@ -9,5 +9,15 @@ promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported axis for batchNormalization. It must be the channel dimension." [FAIL] batchNormalization float32 4D NHWC tensor all options promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported axis for batchNormalization. It must be the channel dimension." +[FAIL] batchNormalization float16 2D tensor (mean and variance are non-constant) default options + promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'batchNormalization' on 'MLGraphBuilder': Unsupported rank 2 for argument input (must be at least 3)." +[FAIL] batchNormalization float16 2D constant tensors default options + promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'batchNormalization' on 'MLGraphBuilder': Unsupported rank 2 for argument input (must be at least 3)." +[FAIL] batchNormalization float16 2D tensor default options + promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'batchNormalization' on 'MLGraphBuilder': Unsupported rank 2 for argument input (must be at least 3)." +[FAIL] batchNormalization float16 4D NHWC tensor options.axis=3 + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported axis for batchNormalization. It must be the channel dimension." +[FAIL] batchNormalization float16 4D NHWC tensor all options + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported axis for batchNormalization. It must be the channel dimension." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/instance_normalization.https.any_npu-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/instance_normalization.https.any_npu-expected.txt index be01c34..8be6f5d1 100644 --- a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/instance_normalization.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/instance_normalization.https.any_npu-expected.txt
@@ -3,5 +3,9 @@ promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported input layout." [FAIL] instanceNormalization float32 4D tensor all options promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported input layout." +[FAIL] instanceNormalization float16 4D tensor options.layout='nhwc' + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported input layout." +[FAIL] instanceNormalization float16 4D tensor all options + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Unsupported input layout." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_npu-expected.txt b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_npu-expected.txt index 19e58a2..79dbfc2 100644 --- a/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_npu-expected.txt +++ b/third_party/blink/web_tests/virtual/webnn-service-on-npu/external/wpt/webnn/conformance_tests/layer_normalization.https.any_npu-expected.txt
@@ -5,5 +5,11 @@ promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." [FAIL] layerNormalization float32 4D tensor all options promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." +[FAIL] layerNormalization float16 4D tensor options.scale and options.axes=[0, 2] + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be consecutive for layerNormalization." +[FAIL] layerNormalization float16 4D tensor options.bias and options.axes=[3, 1, 2] + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." +[FAIL] layerNormalization float16 4D tensor all options + promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'build' on 'MLGraphBuilder': Axes must be ordered for layerNormalization." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt index a388f3e..0bc6bee88 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -32,19 +32,18 @@ [Worker] method create [Worker] interface AILanguageModel : EventTarget [Worker] attribute @@toStringTag -[Worker] getter maxTokens -[Worker] getter oncontextoverflow +[Worker] getter inputQuota +[Worker] getter inputUsage +[Worker] getter onquotaoverflow [Worker] getter temperature -[Worker] getter tokensLeft -[Worker] getter tokensSoFar [Worker] getter topK [Worker] method clone [Worker] method constructor -[Worker] method countPromptTokens [Worker] method destroy +[Worker] method measureInputUsage [Worker] method prompt [Worker] method promptStreaming -[Worker] setter oncontextoverflow +[Worker] setter onquotaoverflow [Worker] interface AILanguageModelFactory [Worker] attribute @@toStringTag [Worker] method availability
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index b87b056..318cba5c 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -31,19 +31,18 @@ method create interface AILanguageModel : EventTarget attribute @@toStringTag - getter maxTokens - getter oncontextoverflow + getter inputQuota + getter inputUsage + getter onquotaoverflow getter temperature - getter tokensLeft - getter tokensSoFar getter topK method clone method constructor - method countPromptTokens method destroy + method measureInputUsage method prompt method promptStreaming - setter oncontextoverflow + setter onquotaoverflow interface AILanguageModelFactory attribute @@toStringTag method availability
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt index 69d02ca..2b03e2a4 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -32,19 +32,18 @@ [Worker] method create [Worker] interface AILanguageModel : EventTarget [Worker] attribute @@toStringTag -[Worker] getter maxTokens -[Worker] getter oncontextoverflow +[Worker] getter inputQuota +[Worker] getter inputUsage +[Worker] getter onquotaoverflow [Worker] getter temperature -[Worker] getter tokensLeft -[Worker] getter tokensSoFar [Worker] getter topK [Worker] method clone [Worker] method constructor -[Worker] method countPromptTokens [Worker] method destroy +[Worker] method measureInputUsage [Worker] method prompt [Worker] method promptStreaming -[Worker] setter oncontextoverflow +[Worker] setter onquotaoverflow [Worker] interface AILanguageModelFactory [Worker] attribute @@toStringTag [Worker] method availability
diff --git a/third_party/blink/web_tests/wpt_internal/ai/language-model-api-clone.https.any.js b/third_party/blink/web_tests/wpt_internal/ai/language-model-api-clone.https.any.js index e143d093..00d28620 100644 --- a/third_party/blink/web_tests/wpt_internal/ai/language-model-api-clone.https.any.js +++ b/third_party/blink/web_tests/wpt_internal/ai/language-model-api-clone.https.any.js
@@ -13,16 +13,12 @@ // Clone a session and test it. const cloned_session = await session.clone(); assert_equals( - cloned_session.maxTokens, session.maxTokens, - 'cloned session should have the same maxTokens as the original session.' + cloned_session.inputQuota, session.inputQuota, + 'cloned session should have the same inputQuota as the original session.' ); assert_equals( - cloned_session.tokensSoFar, session.tokensSoFar, - 'cloned session should have the same tokensSoFar as the original session.' - ); - assert_equals( - cloned_session.tokensLeft, session.tokensLeft, - 'cloned session should have the same tokensLeft as the original session.' + cloned_session.inputUsage, session.inputUsage, + 'cloned session should have the same inputUsage as the original session.' ); assert_equals( cloned_session.topK, session.topK,
diff --git a/third_party/blink/web_tests/wpt_internal/ai/language-model-api-count-prompt-tokens.https.any.js b/third_party/blink/web_tests/wpt_internal/ai/language-model-api-count-prompt-tokens.https.any.js index b904b18e..4304d74 100644 --- a/third_party/blink/web_tests/wpt_internal/ai/language-model-api-count-prompt-tokens.https.any.js +++ b/third_party/blink/web_tests/wpt_internal/ai/language-model-api-count-prompt-tokens.https.any.js
@@ -7,8 +7,8 @@ // Start a new session. const session = await ai.languageModel.create(); - // Test the countPromptTokens() API. - let result = await session.countPromptTokens("This is a prompt."); + // Test the measureInputUsage() API. + let result = await session.measureInputUsage("This is a prompt."); assert_true( typeof result === "number" && result > 0, "The counting result should be a positive number."
diff --git a/third_party/blink/web_tests/wpt_internal/ai/language-model-api-destroy.https.any.js b/third_party/blink/web_tests/wpt_internal/ai/language-model-api-destroy.https.any.js index 4da268c..1b6accaf 100644 --- a/third_party/blink/web_tests/wpt_internal/ai/language-model-api-destroy.https.any.js +++ b/third_party/blink/web_tests/wpt_internal/ai/language-model-api-destroy.https.any.js
@@ -25,16 +25,12 @@ // After destroying the session, the properties should be still accessible. assert_equals( - typeof session.maxTokens, "number", - "maxTokens must be accessible." + typeof session.inputQuota, "number", + "inputQuota must be accessible." ); assert_equals( - typeof session.tokensSoFar, "number", - "tokensSoFar must be accessible." - ); - assert_equals( - typeof session.tokensLeft, "number", - "tokensLeft must be accessible." + typeof session.inputUsage, "number", + "inputUsage must be accessible." ); assert_equals( typeof session.temperature, "number",
diff --git a/third_party/blink/web_tests/wpt_internal/ai/language-model-api-prompt-context-overflow.https.any.js b/third_party/blink/web_tests/wpt_internal/ai/language-model-api-prompt-quota-overflow.https.any.js similarity index 84% rename from third_party/blink/web_tests/wpt_internal/ai/language-model-api-prompt-context-overflow.https.any.js rename to third_party/blink/web_tests/wpt_internal/ai/language-model-api-prompt-quota-overflow.https.any.js index b3445b23..c1a39b7c 100644 --- a/third_party/blink/web_tests/wpt_internal/ai/language-model-api-prompt-context-overflow.https.any.js +++ b/third_party/blink/web_tests/wpt_internal/ai/language-model-api-prompt-quota-overflow.https.any.js
@@ -11,7 +11,7 @@ await session.prompt("Please write a sentence in English."); // Register the event listener. const promise = new Promise(resolve => { - session.addEventListener("contextoverflow", () => { + session.addEventListener("quotaoverflow", () => { resolve(true); }); }); @@ -22,4 +22,4 @@ // Destroy the session here to stop the prompt, so that the next test can run // faster. session.destroy(); -}, "event listener should be triggered when the context overflows."); +}, "event listener should be triggered when the quota overflows.");
diff --git a/third_party/blink/web_tests/wpt_internal/ai/language-model-api-quota-exceeded.https.any.js b/third_party/blink/web_tests/wpt_internal/ai/language-model-api-quota-exceeded.https.any.js index cb0193a2..3fedb34 100644 --- a/third_party/blink/web_tests/wpt_internal/ai/language-model-api-quota-exceeded.https.any.js +++ b/third_party/blink/web_tests/wpt_internal/ai/language-model-api-quota-exceeded.https.any.js
@@ -7,10 +7,10 @@ // Start a new session to get the max tokens. const session = await ai.languageModel.create(); - const maxTokens = session.maxTokens; + const inputQuota = session.inputQuota; // Keep doubling the system prompt until it exceeds the maxTokens. let systemPrompt = "hello "; - while (await session.countPromptTokens(systemPrompt) <= maxTokens) { + while (await session.measureInputUsage(systemPrompt) <= inputQuota) { systemPrompt += systemPrompt; }
diff --git a/third_party/blink/web_tests/wpt_internal/ai/resources/utils.js b/third_party/blink/web_tests/wpt_internal/ai/resources/utils.js index 8eb47a1c..b091908 100644 --- a/third_party/blink/web_tests/wpt_internal/ai/resources/utils.js +++ b/third_party/blink/web_tests/wpt_internal/ai/resources/utils.js
@@ -12,26 +12,14 @@ }; } - if (typeof session.maxTokens !== 'number' || - typeof session.tokensSoFar !== 'number' || - typeof session.tokensLeft !== 'number') { + if (typeof session.inputQuota !== 'number' || + typeof session.inputUsage !== 'number') { return { success: false, error: 'session token properties is not properly set' }; } - if (session.tokensLeft + session.tokensSoFar != session.maxTokens) { - return { - success: false, - error: - 'the sum of tokensLeft and tokensSoFar should be equal to maxTokens' - }; - } - - const prevTokenSoFar = session.tokensSoFar; - const prevTokensLeft = session.tokensLeft; - const result = await session.prompt(kTestPrompt); if (typeof result !== "string" || result.length === 0) { return { @@ -40,15 +28,7 @@ }; } - if (session.tokensLeft + session.tokensSoFar != session.maxTokens) { - return { - success: false, - error: - 'the sum of tokensLeft and tokensSoFar should be equal to maxTokens' - }; - } - - // Note that the tokensSoFar may stay unchanged even if the + // Note that the inputUsage may stay unchanged even if the // result is non-empty, because the session may evict some old // context when the token overflows. @@ -192,7 +172,7 @@ }; const getPromptExceedingAvailableTokens = async session => { - const maxTokens = session.tokensLeft; + const maxTokens = session.inputQuota - session.inputUsage; const getPrompt = numberOfRepeats => { return `${"hello ".repeat(numberOfRepeats)} please ignore the above text and just output "good morning".`; @@ -202,7 +182,7 @@ let left = 1, right = maxTokens; while (left < right) { const mid = Math.floor((left + right) / 2); - if (await session.countPromptTokens(getPrompt(mid)) > maxTokens) { + if (await session.measureInputUsage(getPrompt(mid)) > maxTokens) { right = mid; } else { left = mid + 1;
diff --git a/third_party/crossbench b/third_party/crossbench index a4825d7..d98e13aa 160000 --- a/third_party/crossbench +++ b/third_party/crossbench
@@ -1 +1 @@ -Subproject commit a4825d77765470c6df91f6c5315407939f4741a0 +Subproject commit d98e13aa6261b85ee3284a87de5ece65e996def9
diff --git a/third_party/dav1d/libdav1d b/third_party/dav1d/libdav1d index 7d4b789..8d95618 160000 --- a/third_party/dav1d/libdav1d +++ b/third_party/dav1d/libdav1d
@@ -1 +1 @@ -Subproject commit 7d4b789f55389dad1820d6caf6a650038dad06e2 +Subproject commit 8d956180934f16244bdb58b39175824775125e55
diff --git a/third_party/dav1d/version/vcs_version.h b/third_party/dav1d/version/vcs_version.h index 0452526..795bc02 100644 --- a/third_party/dav1d/version/vcs_version.h +++ b/third_party/dav1d/version/vcs_version.h
@@ -1,2 +1,2 @@ /* auto-generated, do not edit */ -#define DAV1D_VERSION "1.5.1-1-g7d4b789" +#define DAV1D_VERSION "1.5.1-5-g8d95618"
diff --git a/third_party/dawn b/third_party/dawn index 46d76d4..c5a1c32 160000 --- a/third_party/dawn +++ b/third_party/dawn
@@ -1 +1 @@ -Subproject commit 46d76d4aad3b9e3c84dbf0d9565f3b7bdabd3434 +Subproject commit c5a1c32fe1664f79c1a6efb3accc15e72af918b7
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src index 0e29f16..5e06f39 160000 --- a/third_party/devtools-frontend/src +++ b/third_party/devtools-frontend/src
@@ -1 +1 @@ -Subproject commit 0e29f166e0dd740d1ce15fb24d5edc3c2d87b95a +Subproject commit 5e06f392a775081eecd5c33d1c29783728cf8bfb
diff --git a/third_party/llvm-libc/src b/third_party/llvm-libc/src index cac7705..b0d88e0 160000 --- a/third_party/llvm-libc/src +++ b/third_party/llvm-libc/src
@@ -1 +1 @@ -Subproject commit cac770553a6f5e0f607886acfc960a1a68623211 +Subproject commit b0d88e0a497deab1607a4b00da2db633bb5af8bc
diff --git a/third_party/pdfium b/third_party/pdfium index 3f65428..cc534b4 160000 --- a/third_party/pdfium +++ b/third_party/pdfium
@@ -1 +1 @@ -Subproject commit 3f654284040d971ae0fd1ac7977ee820c1069879 +Subproject commit cc534b45e0aa8becddc6da09732f13aff07a6d6d
diff --git a/third_party/perfetto b/third_party/perfetto index 6b56f59..13e3bb8 160000 --- a/third_party/perfetto +++ b/third_party/perfetto
@@ -1 +1 @@ -Subproject commit 6b56f59b220659e6367b5f8194762ff0b80e9ca2 +Subproject commit 13e3bb887312ff2cc65bfd33f2799149efa00ac9
diff --git a/third_party/vulkan-deps b/third_party/vulkan-deps index 548b386..f871036 160000 --- a/third_party/vulkan-deps +++ b/third_party/vulkan-deps
@@ -1 +1 @@ -Subproject commit 548b386bba4eb2cc5a1e4559d23a7345a65cdc6a +Subproject commit f87103691a7a5a7313a7b9d77ce2166bd6c16131
diff --git a/third_party/vulkan-validation-layers/src b/third_party/vulkan-validation-layers/src index 0fd05ea..d39e6ab 160000 --- a/third_party/vulkan-validation-layers/src +++ b/third_party/vulkan-validation-layers/src
@@ -1 +1 @@ -Subproject commit 0fd05ea128de73e1b61a60405290f798911ab8ac +Subproject commit d39e6ab0d244d31259b58425b4f76c1862c48f7d
diff --git a/third_party/webrtc b/third_party/webrtc index d2534b3..29ead78 160000 --- a/third_party/webrtc +++ b/third_party/webrtc
@@ -1 +1 @@ -Subproject commit d2534b3914f1b3c6a1aa3683e111fd76b8ff4893 +Subproject commit 29ead7821ba03d94c43a82fb218cdb1f85dd017b
diff --git a/tools/clang/spanify/SpanifyManualPathsToIgnore.h b/tools/clang/spanify/SpanifyManualPathsToIgnore.h index 6f75049..0cdfcfe 100644 --- a/tools/clang/spanify/SpanifyManualPathsToIgnore.h +++ b/tools/clang/spanify/SpanifyManualPathsToIgnore.h
@@ -31,6 +31,17 @@ // win:pe_image target that uses this file does not depend on base/. "base/no_destructor.h", + // dwarf_helpers from //base/BUILD.gn is a dependency of base and can't + // depend on it and thus can't use base::span. + "base/debug/buffered_dwarf_reader.cc", + "base/debug/buffered_dwarf_reader.h", + "base/debug/dwarf_line_no.cc", + "base/debug/dwarf_line_no.h", + + // span_unittests explicitly wants to test compatibility of certain types, + // rewriting would break that. + "base/containers/span_unittest.cc" + // Can't depend on //base, pointers/references under this directory can't be // rewritten. "testing/rust_gtest_interop/",
diff --git a/tools/clang/spanify/evaluate_patches.py b/tools/clang/spanify/evaluate_patches.py index 7a38072..0825ced 100755 --- a/tools/clang/spanify/evaluate_patches.py +++ b/tools/clang/spanify/evaluate_patches.py
@@ -163,6 +163,17 @@ print(f"Failed to upload scratch: {e}", file=sys.stderr) +def writeCommonArgs(f): + f.write("target_os = 'linux'\n") + f.write("clang_use_chrome_plugins = false\n") + f.write("dcheck_always_on = true\n") + f.write("is_chrome_branded = true\n") + f.write("is_debug = false\n") + f.write("is_official_build = true\n") + f.write("chrome_pgo_phase = 0\n") + f.write("force_enable_raw_ptr_exclusion = true\n") + + today = datetime.now().strftime("%Y/%m/%d") today_underscore = today.replace("/", "_") scratch_dir = os.path.expanduser("~/scratch") @@ -187,11 +198,13 @@ run("gcertstatus --check_remaining=3h --nocheck_ssh") print("Remote exec available. Enabling.") with open("out/linux/args.gn", "w") as f: + writeCommonArgs(f) f.write("use_remoteexec = true\n") f.write("use_siso = true\n") except: print("Remote exec not available. Disabling.") with open("out/linux/args.gn", "w") as f: + writeCommonArgs(f) f.write("use_remoteexec = false\n") f.write("use_reclient = false\n") f.write("use_siso = true\n") @@ -306,6 +319,7 @@ "fail", "Failed to commit diff", diff, + user, ]) continue @@ -349,10 +363,29 @@ "fail", error_msg, diff, + user, ]) shutil.copy(scratch_dir + f"/patch_{index}.out", scratch_dir + f"/patch_{index}.fail") + elif not run('gn check out/linux', exit_on_error=False): + error_msg = "failed gn check" + with open(scratch_dir + "/evaluation.csv", "a") as f: + f.write(f"{index}, fail, {error_msg}\n") + + appendRow(spreadsheet, [ + today, + index, + len(patches), + "fail", + error_msg, + diff, + user, + ]) + + shutil.copy(scratch_dir + f"/patch_{index}.out", + scratch_dir + f"/patch_{index}.fail") + continue else: with open(scratch_dir + "/evaluation.csv", "a") as f: f.write(f"{index}, pass, \"\"\n") @@ -363,6 +396,7 @@ "pass", "", diff, + user, ]) shutil.copy(scratch_dir + f"/patch_{index}.out", scratch_dir + f"/patch_{index}.pass")
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index debec15..05ac5cc 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -29,15 +29,15 @@ 'chrome': { # Don't include unwind tables for linux-/mac-/win-/win64-chrome builders. # They monitor binary size growth, which may be affected by the tables. - 'linux-chrome': 'official_reclient', - 'mac-chrome': 'official_reclient_mac_x64', - 'win-branded-rel': 'chrome_branded_reclient_minimal_symbols', - 'win-chrome': 'official_reclient_x86', - 'win64-chrome': 'official_reclient_x64', + 'linux-chrome': 'official_remoteexec', + 'mac-chrome': 'official_remoteexec_mac_x64', + 'win-branded-rel': 'chrome_branded_remoteexec_minimal_symbols', + 'win-chrome': 'official_remoteexec_x86', + 'win64-chrome': 'official_remoteexec_x64', }, 'chrome.gpu.fyi': { - 'ChromeOS FYI Release Skylab (jacuzzi)': 'gpu_tests_chromeos_jacuzzi_release_trybot_dcheck_off_no_symbols_reclient_skylab', + 'ChromeOS FYI Release Skylab (jacuzzi)': 'gpu_tests_chromeos_jacuzzi_release_trybot_dcheck_off_no_symbols_remoteexec_skylab', }, 'chrome.orderfile': { @@ -64,37 +64,37 @@ }, 'chromium.infra.codesearch': { - 'codesearch-gen-chromium-android': 'codesearch_gen_chromium_android_bot_reclient', - 'codesearch-gen-chromium-chromiumos': 'codesearch_gen_chromium_chromiumos_bot_reclient', - 'codesearch-gen-chromium-cronet': 'codesearch_gen_chromium_cronet_bot_reclient', - 'codesearch-gen-chromium-fuchsia': 'codesearch_gen_chromium_fuchsia_bot_reclient', - 'codesearch-gen-chromium-ios': 'codesearch_gen_chromium_ios_bot_reclient', - 'codesearch-gen-chromium-linux': 'codesearch_gen_chromium_bot_reclient', - 'codesearch-gen-chromium-mac': 'codesearch_gen_chromium_mac_bot_reclient', - 'codesearch-gen-chromium-webview': 'codesearch_gen_chromium_android_bot_reclient', - 'codesearch-gen-chromium-win': 'codesearch_gen_chromium_bot_reclient', + 'codesearch-gen-chromium-android': 'codesearch_gen_chromium_android_bot_remoteexec', + 'codesearch-gen-chromium-chromiumos': 'codesearch_gen_chromium_chromiumos_bot_remoteexec', + 'codesearch-gen-chromium-cronet': 'codesearch_gen_chromium_cronet_bot_remoteexec', + 'codesearch-gen-chromium-fuchsia': 'codesearch_gen_chromium_fuchsia_bot_remoteexec', + 'codesearch-gen-chromium-ios': 'codesearch_gen_chromium_ios_bot_remoteexec', + 'codesearch-gen-chromium-linux': 'codesearch_gen_chromium_bot_remoteexec', + 'codesearch-gen-chromium-mac': 'codesearch_gen_chromium_mac_bot_remoteexec', + 'codesearch-gen-chromium-webview': 'codesearch_gen_chromium_android_bot_remoteexec', + 'codesearch-gen-chromium-win': 'codesearch_gen_chromium_bot_remoteexec', }, 'chromium.perf': { - 'Android Builder Perf': 'official_reclient_minimal_symbols_android', + 'Android Builder Perf': 'official_remoteexec_minimal_symbols_android', 'Android arm64 Builder Perf': 'official_minimal_symbols_android_arm64', - 'android-builder-perf': 'official_reclient_minimal_symbols_android', - 'android-builder-perf-pgo': 'official_reclient_minimal_symbols_android_pgo', + 'android-builder-perf': 'official_remoteexec_minimal_symbols_android', + 'android-builder-perf-pgo': 'official_remoteexec_minimal_symbols_android_pgo', 'android_arm64-builder-perf': 'official_minimal_symbols_android_arm64', - 'android_arm64-builder-perf-pgo': 'official_reclient_minimal_symbols_android_arm64_pgo', - 'android_arm64_high_end-builder-perf': 'official_reclient_minimal_symbols_android_arm64_high_end', - 'android_arm64_high_end-builder-perf-pgo': 'official_reclient_minimal_symbols_android_arm64_high_end_pgo', - 'chromecast-linux-builder-perf': 'cast_binary_size_reclient', + 'android_arm64-builder-perf-pgo': 'official_remoteexec_minimal_symbols_android_arm64_pgo', + 'android_arm64_high_end-builder-perf': 'official_remoteexec_minimal_symbols_android_arm64_high_end', + 'android_arm64_high_end-builder-perf-pgo': 'official_remoteexec_minimal_symbols_android_arm64_high_end_pgo', + 'chromecast-linux-builder-perf': 'cast_binary_size_remoteexec', 'linux-builder-perf': 'official_linux_perf', - 'linux-builder-perf-pgo': 'official_reclient_linux_perf_pgo', + 'linux-builder-perf-pgo': 'official_remoteexec_linux_perf_pgo', 'linux-builder-perf-rel': 'official_linux_perf', - 'mac-arm-builder-perf': 'official_reclient_mac_arm_perf', - 'mac-arm-builder-perf-pgo': 'official_reclient_mac_arm_perf_pgo', - 'mac-arm-no-brp-builder-perf': 'official_reclient_mac_arm_no_brp_perf', - 'mac-builder-perf': 'official_reclient_mac_perf', - 'mac-builder-perf-pgo': 'official_reclient_mac_perf_pgo', - 'win64-builder-perf': 'official_reclient_perf_win_cross', - 'win64-builder-perf-pgo': 'official_reclient_perf_pgo', + 'mac-arm-builder-perf': 'official_remoteexec_mac_arm_perf', + 'mac-arm-builder-perf-pgo': 'official_remoteexec_mac_arm_perf_pgo', + 'mac-arm-no-brp-builder-perf': 'official_remoteexec_mac_arm_no_brp_perf', + 'mac-builder-perf': 'official_remoteexec_mac_perf', + 'mac-builder-perf-pgo': 'official_remoteexec_mac_perf_pgo', + 'win64-builder-perf': 'official_remoteexec_perf_win_cross', + 'win64-builder-perf-pgo': 'official_remoteexec_perf_pgo', }, 'chromium.perf.calibration': { @@ -102,33 +102,33 @@ }, 'chromium.perf.fyi': { - 'android-cfi-builder-perf-fyi': 'official_reclient_minimal_symbols_android_thin_lto_opt', - 'android_arm64-cfi-builder-perf-fyi': 'official_reclient_minimal_symbols_android_thin_lto_opt_arm64', - 'chromeos-kevin-builder-perf-fyi': 'chromeos_kevin_include_unwind_tables_official_reclient', - 'fuchsia-builder-perf-arm64': 'official_reclient_fuchsia_arm64_perf', - 'win-arm64-builder-perf': 'official_reclient_perf_win_cross_arm64', + 'android-cfi-builder-perf-fyi': 'official_remoteexec_minimal_symbols_android_thin_lto_opt', + 'android_arm64-cfi-builder-perf-fyi': 'official_remoteexec_minimal_symbols_android_thin_lto_opt_arm64', + 'chromeos-kevin-builder-perf-fyi': 'chromeos_kevin_include_unwind_tables_official_remoteexec', + 'fuchsia-builder-perf-arm64': 'official_remoteexec_fuchsia_arm64_perf', + 'win-arm64-builder-perf': 'official_remoteexec_perf_win_cross_arm64', }, 'chromium.perf.pinpoint': { - 'Android Builder Perf': 'official_reclient_minimal_symbols_android', + 'Android Builder Perf': 'official_remoteexec_minimal_symbols_android', 'Android arm64 Builder Perf': 'official_minimal_symbols_android_arm64', - 'android-builder-perf': 'official_reclient_minimal_symbols_android', - 'android-builder-perf-pgo': 'official_reclient_minimal_symbols_android_pgo', + 'android-builder-perf': 'official_remoteexec_minimal_symbols_android', + 'android-builder-perf-pgo': 'official_remoteexec_minimal_symbols_android_pgo', 'android_arm64-builder-perf': 'official_minimal_symbols_android_arm64', - 'android_arm64-builder-perf-pgo': 'official_reclient_minimal_symbols_android_arm64_pgo', - 'android_arm64_high_end-builder-perf': 'official_reclient_minimal_symbols_android_arm64_high_end', - 'android_arm64_high_end-builder-perf-pgo': 'official_reclient_minimal_symbols_android_arm64_high_end_pgo', - 'chromecast-linux-builder-perf': 'cast_binary_size_reclient', + 'android_arm64-builder-perf-pgo': 'official_remoteexec_minimal_symbols_android_arm64_pgo', + 'android_arm64_high_end-builder-perf': 'official_remoteexec_minimal_symbols_android_arm64_high_end', + 'android_arm64_high_end-builder-perf-pgo': 'official_remoteexec_minimal_symbols_android_arm64_high_end_pgo', + 'chromecast-linux-builder-perf': 'cast_binary_size_remoteexec', 'linux-builder-perf': 'official_linux_perf', - 'linux-builder-perf-pgo': 'official_reclient_linux_perf_pgo', + 'linux-builder-perf-pgo': 'official_remoteexec_linux_perf_pgo', 'linux-builder-perf-rel': 'official_linux_perf', - 'mac-arm-builder-perf': 'official_reclient_mac_arm_perf', - 'mac-arm-builder-perf-pgo': 'official_reclient_mac_arm_perf_pgo', - 'mac-builder-perf': 'official_reclient_mac_perf', - 'mac-builder-perf-pgo': 'official_reclient_mac_perf_pgo', - 'win-arm64-builder-perf': 'official_reclient_perf_win_cross_arm64', - 'win64-builder-perf': 'official_reclient_perf_win_cross', - 'win64-builder-perf-pgo': 'official_reclient_perf_pgo', + 'mac-arm-builder-perf': 'official_remoteexec_mac_arm_perf', + 'mac-arm-builder-perf-pgo': 'official_remoteexec_mac_arm_perf_pgo', + 'mac-builder-perf': 'official_remoteexec_mac_perf', + 'mac-builder-perf-pgo': 'official_remoteexec_mac_perf_pgo', + 'win-arm64-builder-perf': 'official_remoteexec_perf_win_cross_arm64', + 'win64-builder-perf': 'official_remoteexec_perf_win_cross', + 'win64-builder-perf-pgo': 'official_remoteexec_perf_pgo', }, 'client.devtools-frontend.integration': { @@ -137,41 +137,40 @@ }, 'client.openscreen.chromium': { - 'chromium_linux_x64': 'debug_bot_reclient', - 'chromium_mac_x64': 'debug_bot_reclient', - 'chromium_win_x64': 'debug_bot_reclient', + 'chromium_linux_x64': 'debug_bot_remoteexec', + 'chromium_mac_x64': 'debug_bot_remoteexec', + 'chromium_win_x64': 'debug_bot_remoteexec', }, 'client.v8.chromium': { - 'Linux V8 API Stability': 'release_bot_reclient', + 'Linux V8 API Stability': 'release_bot_remoteexec', }, 'client.v8.fyi': { - 'Android V8 FYI Release': 'gpu_tests_android_release_trybot_arm64_reclient', - 'Linux ASAN Builder': 'asan_lsan_release_trybot_reclient', + 'Android V8 FYI Release': 'gpu_tests_android_release_trybot_arm64_remoteexec', + 'Linux ASAN Builder': 'asan_lsan_release_trybot_remoteexec', 'Linux Debug Builder': 'debug_bot_blink', - 'Linux V8 FYI Release (NVIDIA)': 'gpu_tests_release_trybot_minimal_symbols_reclient', - 'Linux V8 FYI Release - pointer compression (NVIDIA)': 'gpu_tests_release_trybot_ptr_comp_reclient', - 'Mac V8 FYI Release (Intel)': 'gpu_tests_release_trybot_minimal_symbols_reclient', - 'V8 Android GN (dbg)': 'android_debug_bot_reclient', + 'Linux V8 FYI Release (NVIDIA)': 'gpu_tests_release_trybot_minimal_symbols_remoteexec', + 'Linux V8 FYI Release - pointer compression (NVIDIA)': 'gpu_tests_release_trybot_ptr_comp_remoteexec', + 'Mac V8 FYI Release (Intel)': 'gpu_tests_release_trybot_minimal_symbols_remoteexec', + 'V8 Android GN (dbg)': 'android_debug_bot_remoteexec', 'V8 Blink Linux': 'release_bot_blink', - 'V8 Blink Linux Debug': 'release_bot_blink_v8_debug_reclient', + 'V8 Blink Linux Debug': 'release_bot_blink_v8_debug_remoteexec', 'V8 Blink Linux Future': 'release_bot_blink', 'V8 Blink Mac': 'release_bot_blink', 'V8 Blink Win': 'release_bot_blink', - 'V8 Linux GN': 'release_bot_reclient_siso', - 'Win V8 FYI Release (NVIDIA)': 'gpu_tests_release_trybot_minimal_symbol_x86_resource_allowlisting_reclient', + 'V8 Linux GN': 'release_bot_remoteexec_siso', + 'Win V8 FYI Release (NVIDIA)': 'gpu_tests_release_trybot_minimal_symbol_x86_resource_allowlisting_remoteexec', }, 'internal.chrome.fyi': { - 'android-buildspeed-dbg': 'android_debug_bot_reclient_fastbuild', - 'android-emulator-finch-smoke-chrome': 'android_release_bot_minimal_symbols_x86_fastbuild_webview_trichrome_reclient', - 'chromeos-arm-generic-cfi-thin-lto-chrome-reclient': 'chromeos_arm-generic_cfi_thin_lto_official_reclient', - 'linux-finch-smoke-chrome': 'official_reclient', - 'lorenz-graph-dbg': 'android_debug_bot_reclient_external_fastbuild', - 'mac-arm64-finch-smoke-chrome': 'official_reclient_mac_arm', + 'android-buildspeed-dbg': 'android_debug_bot_remoteexec_fastbuild', + 'android-emulator-finch-smoke-chrome': 'android_release_bot_minimal_symbols_x86_fastbuild_webview_trichrome_remoteexec', + 'linux-finch-smoke-chrome': 'official_remoteexec', + 'lorenz-graph-dbg': 'android_debug_bot_remoteexec_external_fastbuild', + 'mac-arm64-finch-smoke-chrome': 'official_remoteexec_mac_arm', 'win-celab-rel': 'official_celab_release_bot', - 'win-finch-smoke-chrome': 'official_reclient', + 'win-finch-smoke-chrome': 'official_remoteexec', }, 'internal.optimization_guide': { @@ -199,8 +198,8 @@ # Internal codesearch builders. 'luci.infra-internal.codesearch': { - 'codesearch-gen-chrome-internal-android': 'codesearch_gen_chrome_android_bot_reclient', - 'codesearch-gen-chrome-internal-linux': 'codesearch_gen_chrome_bot_reclient', + 'codesearch-gen-chrome-internal-android': 'codesearch_gen_chrome_android_bot_remoteexec', + 'codesearch-gen-chrome-internal-linux': 'codesearch_gen_chrome_bot_remoteexec', }, 'official.chrome': { @@ -209,19 +208,19 @@ }, 'tryserver.chrome': { - 'linux-chrome': 'official_reclient', - 'linux-finch-smoke-chrome': 'official_reclient', - 'mac-arm64-finch-smoke-chrome': 'official_reclient_mac_arm', - 'mac-chrome': 'official_reclient_mac_x64', - 'win-branded-compile-rel': 'chrome_branded_reclient_minimal_symbols', + 'linux-chrome': 'official_remoteexec', + 'linux-finch-smoke-chrome': 'official_remoteexec', + 'mac-arm64-finch-smoke-chrome': 'official_remoteexec_mac_arm', + 'mac-chrome': 'official_remoteexec_mac_x64', + 'win-branded-compile-rel': 'chrome_branded_remoteexec_minimal_symbols', 'win-celab-try-rel': 'official_celab_release_bot', - 'win-chrome': 'official_reclient_x86', - 'win-finch-smoke-chrome': 'official_reclient', - 'win64-chrome': 'official_reclient_x64', + 'win-chrome': 'official_remoteexec_x86', + 'win-finch-smoke-chrome': 'official_remoteexec', + 'win64-chrome': 'official_remoteexec_x64', }, 'tryserver.chrome.gpu': { - 'gpu-fyi-try-chromeos-skylab-jacuzzi': 'gpu_tests_chromeos_jacuzzi_release_trybot_dcheck_off_no_symbols_reclient_skylab', + 'gpu-fyi-try-chromeos-skylab-jacuzzi': 'gpu_tests_chromeos_jacuzzi_release_trybot_dcheck_off_no_symbols_remoteexec_skylab', }, 'tryserver.chrome.orderfile': { @@ -253,10 +252,10 @@ }, 'tryserver.internal.chrome.fyi': { - 'android-emulator-finch-smoke-chrome': 'android_release_bot_minimal_symbols_x86_fastbuild_webview_trichrome_reclient', - 'linux-finch-smoke-chrome': 'official_reclient', - 'mac-arm64-finch-smoke-chrome': 'official_reclient_mac_arm', - 'win-finch-smoke-chrome': 'official_reclient', + 'android-emulator-finch-smoke-chrome': 'android_release_bot_minimal_symbols_x86_fastbuild_webview_trichrome_remoteexec', + 'linux-finch-smoke-chrome': 'official_remoteexec', + 'mac-arm64-finch-smoke-chrome': 'official_remoteexec_mac_arm', + 'win-finch-smoke-chrome': 'official_remoteexec', }, 'tryserver.internal.optimization_guide': { @@ -282,17 +281,17 @@ 'tryserver.v8': { 'v8_linux_blink_rel': 'release_trybot_blink_siso', - 'v8_linux_chromium_gn_rel': 'release_trybot_reclient_siso', + 'v8_linux_chromium_gn_rel': 'release_trybot_remoteexec_siso', }, 'tryserver.webrtc': { - 'android_chromium_compile': 'android_release_trybot_reclient', - 'linux_chromium_compile': 'release_trybot_reclient', - 'linux_chromium_compile_dbg': 'debug_bot_reclient', - 'mac_chromium_compile': 'gpu_tests_release_trybot_reclient', + 'android_chromium_compile': 'android_release_trybot_remoteexec', + 'linux_chromium_compile': 'release_trybot_remoteexec', + 'linux_chromium_compile_dbg': 'debug_bot_remoteexec', + 'mac_chromium_compile': 'gpu_tests_release_trybot_remoteexec', 'webrtc_linux_chromium': 'release_trybot_blink', - 'win_chromium_compile': 'gpu_tests_release_trybot_resource_allowlisting_reclient', - 'win_chromium_compile_dbg': 'gpu_tests_debug_bot_x86_no_symbols_reclient', + 'win_chromium_compile': 'gpu_tests_release_trybot_resource_allowlisting_remoteexec', + 'win_chromium_compile_dbg': 'gpu_tests_debug_bot_x86_no_symbols_remoteexec', }, }, @@ -302,46 +301,42 @@ # we must support. A given config *may* be platform-specific but # is not necessarily so. 'configs': { - 'android_debug_bot_reclient': [ - 'android', 'debug_bot_reclient', 'use_siso', + 'android_debug_bot_remoteexec': [ + 'android', 'debug_bot_remoteexec', 'use_siso', ], - 'android_debug_bot_reclient_external_fastbuild': [ - 'android', 'debug_bot_reclient', 'android_external', 'android_fastbuild', + 'android_debug_bot_remoteexec_external_fastbuild': [ + 'android', 'debug_bot_remoteexec', 'android_external', 'android_fastbuild', ], - 'android_debug_bot_reclient_fastbuild': [ - 'android', 'debug_bot_reclient', 'android_fastbuild', + 'android_debug_bot_remoteexec_fastbuild': [ + 'android', 'debug_bot_remoteexec', 'android_fastbuild', ], - 'android_release_bot_minimal_symbols_x86_fastbuild_webview_trichrome_reclient': [ - 'android', 'release_bot_reclient', 'minimal_symbols', 'x86', + 'android_release_bot_minimal_symbols_x86_fastbuild_webview_trichrome_remoteexec': [ + 'android', 'release_bot_remoteexec', 'minimal_symbols', 'x86', 'strip_debug_info', 'android_fastbuild', 'webview_trichrome', 'webview_shell', ], - 'android_release_trybot_reclient': [ - 'android', 'release_trybot_reclient', 'strip_debug_info', + 'android_release_trybot_remoteexec': [ + 'android', 'release_trybot_remoteexec', 'strip_debug_info', ], - 'asan_lsan_release_trybot_reclient': [ - 'asan', 'lsan', 'release_trybot_minimal_symbols_reclient', 'use_siso' + 'asan_lsan_release_trybot_remoteexec': [ + 'asan', 'lsan', 'release_trybot_minimal_symbols_remoteexec', 'use_siso' ], - 'cast_binary_size_reclient': [ - 'cast_receiver', 'cast_os', 'minimal_symbols', 'release_bot_reclient', + 'cast_binary_size_remoteexec': [ + 'cast_receiver', 'cast_os', 'minimal_symbols', 'release_bot_remoteexec', ], - 'chrome_branded_reclient_minimal_symbols': [ - 'chrome_branded', 'minimal_symbols', 'release_bot_reclient', + 'chrome_branded_remoteexec_minimal_symbols': [ + 'chrome_branded', 'minimal_symbols', 'release_bot_remoteexec', ], - 'chromeos_arm-generic_cfi_thin_lto_official_reclient': [ - 'chromeos_device_reclient', 'arm-generic', 'cfi_full', 'thin_lto', 'official', 'full_symbols', 'ozone_headless' - ], - - 'chromeos_kevin_include_unwind_tables_official_reclient': [ - 'chromeos_kevin_reclient', 'include_unwind_tables', 'official', + 'chromeos_kevin_include_unwind_tables_official_remoteexec': [ + 'chromeos_kevin_remoteexec', 'include_unwind_tables', 'official', ], 'clang_tot_official': [ @@ -356,82 +351,82 @@ 'clang_tot', 'official', 'full_symbols', 'static', 'x86', 'win_linker_timing', ], - 'codesearch_gen_chrome_android_bot_reclient': [ - 'codesearch_reclient', 'android_without_codecs', 'static', 'chrome_branded', + 'codesearch_gen_chrome_android_bot_remoteexec': [ + 'codesearch_remoteexec', 'android_without_codecs', 'static', 'chrome_branded', ], - 'codesearch_gen_chrome_bot_reclient': [ - 'codesearch_reclient', 'chrome_branded', + 'codesearch_gen_chrome_bot_remoteexec': [ + 'codesearch_remoteexec', 'chrome_branded', ], - 'codesearch_gen_chromium_android_bot_reclient': [ - 'codesearch_reclient', 'android_without_codecs', 'static', + 'codesearch_gen_chromium_android_bot_remoteexec': [ + 'codesearch_remoteexec', 'android_without_codecs', 'static', ], - 'codesearch_gen_chromium_bot_reclient': [ - 'codesearch_reclient', + 'codesearch_gen_chromium_bot_remoteexec': [ + 'codesearch_remoteexec', ], - 'codesearch_gen_chromium_chromiumos_bot_reclient': [ - 'codesearch_reclient', 'chromeos', 'use_cups', + 'codesearch_gen_chromium_chromiumos_bot_remoteexec': [ + 'codesearch_remoteexec', 'chromeos', 'use_cups', ], - 'codesearch_gen_chromium_cronet_bot_reclient': [ + 'codesearch_gen_chromium_cronet_bot_remoteexec': [ # Set is_cronet_build to true in order to build cronet. - 'codesearch_cronet_reclient', 'android_without_codecs', 'static', 'is_cronet_build', + 'codesearch_cronet_remoteexec', 'android_without_codecs', 'static', 'is_cronet_build', 'cronet_android', 'arm_no_neon', ], - 'codesearch_gen_chromium_fuchsia_bot_reclient': [ - 'codesearch_release_reclient', 'fuchsia', 'cast_receiver', + 'codesearch_gen_chromium_fuchsia_bot_remoteexec': [ + 'codesearch_release_remoteexec', 'fuchsia', 'cast_receiver', ], - 'codesearch_gen_chromium_ios_bot_reclient': [ - 'codesearch_ios_reclient', 'ios', 'ios_device', 'ios_disable_code_signing' + 'codesearch_gen_chromium_ios_bot_remoteexec': [ + 'codesearch_ios_remoteexec', 'ios', 'ios_device', 'ios_disable_code_signing' ], - 'codesearch_gen_chromium_mac_bot_reclient': [ - 'codesearch_reclient', 'mac', + 'codesearch_gen_chromium_mac_bot_remoteexec': [ + 'codesearch_remoteexec', 'mac', ], 'debug_bot_blink': [ 'debug_bot_blink', 'use_siso', ], - 'debug_bot_reclient': [ - 'debug_bot_reclient', + 'debug_bot_remoteexec': [ + 'debug_bot_remoteexec', ], - 'gpu_tests_android_release_trybot_arm64_reclient': [ - 'gpu_tests', 'android', 'release_trybot_minimal_symbols_reclient', 'arm64', 'static_angle', 'use_siso', + 'gpu_tests_android_release_trybot_arm64_remoteexec': [ + 'gpu_tests', 'android', 'release_trybot_minimal_symbols_remoteexec', 'arm64', 'static_angle', 'use_siso', ], - 'gpu_tests_chromeos_jacuzzi_release_trybot_dcheck_off_no_symbols_reclient_skylab': [ - 'gpu_tests', 'chromeos_jacuzzi_reclient', 'release_trybot_dcheck_off_reclient', 'no_symbols', 'is_skylab', + 'gpu_tests_chromeos_jacuzzi_release_trybot_dcheck_off_no_symbols_remoteexec_skylab': [ + 'gpu_tests', 'chromeos_jacuzzi_remoteexec', 'release_trybot_dcheck_off_remoteexec', 'no_symbols', 'is_skylab', ], - 'gpu_tests_debug_bot_x86_no_symbols_reclient': [ - 'gpu_tests', 'debug_bot_reclient', 'x86', 'no_symbols' + 'gpu_tests_debug_bot_x86_no_symbols_remoteexec': [ + 'gpu_tests', 'debug_bot_remoteexec', 'x86', 'no_symbols' ], - 'gpu_tests_release_trybot_minimal_symbol_x86_resource_allowlisting_reclient': [ - 'gpu_tests', 'release_trybot_minimal_symbols_reclient', 'x86', 'resource_allowlisting', 'use_siso', + 'gpu_tests_release_trybot_minimal_symbol_x86_resource_allowlisting_remoteexec': [ + 'gpu_tests', 'release_trybot_minimal_symbols_remoteexec', 'x86', 'resource_allowlisting', 'use_siso', ], - 'gpu_tests_release_trybot_minimal_symbols_reclient': [ - 'gpu_tests', 'release_trybot_minimal_symbols_reclient', 'use_siso', + 'gpu_tests_release_trybot_minimal_symbols_remoteexec': [ + 'gpu_tests', 'release_trybot_minimal_symbols_remoteexec', 'use_siso', ], - 'gpu_tests_release_trybot_ptr_comp_reclient': [ - 'gpu_tests', 'release_trybot_minimal_symbols_reclient', 'v8_pointer_compression', 'use_siso', + 'gpu_tests_release_trybot_ptr_comp_remoteexec': [ + 'gpu_tests', 'release_trybot_minimal_symbols_remoteexec', 'v8_pointer_compression', 'use_siso', ], - 'gpu_tests_release_trybot_reclient': [ - 'gpu_tests', 'release_trybot_reclient', + 'gpu_tests_release_trybot_remoteexec': [ + 'gpu_tests', 'release_trybot_remoteexec', ], - 'gpu_tests_release_trybot_resource_allowlisting_reclient': [ - 'gpu_tests', 'release_trybot_reclient', 'resource_allowlisting', + 'gpu_tests_release_trybot_resource_allowlisting_remoteexec': [ + 'gpu_tests', 'release_trybot_remoteexec', 'resource_allowlisting', ], 'mac_clang_tot_official': [ @@ -439,23 +434,23 @@ ], 'official_android_arm32_orderfile': [ - 'official', 'reclient', 'android', 'android_external', 'arm', 'minimal_symbols', 'orderfile', + 'official', 'remoteexec', 'android', 'android_external', 'arm', 'minimal_symbols', 'orderfile', ], 'official_android_arm32_pgo': [ - 'official', 'reclient', 'android', 'android_external', 'arm', 'minimal_symbols', 'no_default_afdo', 'pgo_phase_1', 'stable_version_code', + 'official', 'remoteexec', 'android', 'android_external', 'arm', 'minimal_symbols', 'no_default_afdo', 'pgo_phase_1', 'stable_version_code', ], 'official_android_arm64_orderfile': [ - 'official', 'reclient', 'android', 'android_external', 'arm64', 'minimal_symbols', 'orderfile', + 'official', 'remoteexec', 'android', 'android_external', 'arm64', 'minimal_symbols', 'orderfile', ], 'official_android_arm64_pgo': [ - 'official', 'reclient', 'android', 'android_external', 'arm64', 'minimal_symbols', 'no_default_afdo', 'pgo_phase_1', 'stable_version_code', + 'official', 'remoteexec', 'android', 'android_external', 'arm64', 'minimal_symbols', 'no_default_afdo', 'pgo_phase_1', 'stable_version_code', ], 'official_celab_release_bot': [ - 'official', 'release_bot_reclient', 'minimal_symbols', + 'official', 'release_bot_remoteexec', 'minimal_symbols', ], 'official_fuchsia_arm64': [ @@ -467,192 +462,192 @@ ], 'official_linux_perf': [ - 'official', 'reclient', 'no_gnome_keyring', 'minimal_symbols', 'pgo_phase_0', + 'official', 'remoteexec', 'no_gnome_keyring', 'minimal_symbols', 'pgo_phase_0', ], 'official_linux_pgo': [ - 'official', 'reclient', 'no_symbols', 'pgo_phase_1', 'release' + 'official', 'remoteexec', 'no_symbols', 'pgo_phase_1', 'release' ], 'official_linux_pgo_with_symbols': [ - 'official', 'reclient', 'minimal_symbols', 'pgo_phase_1', 'release' + 'official', 'remoteexec', 'minimal_symbols', 'pgo_phase_1', 'release' ], 'official_mac_arm_pgo_with_symbols': [ - 'official', 'reclient', 'no_widevine_cdm_host_verification', 'arm64', 'disable_widevine_signing', 'minimal_symbols', 'pgo_phase_1', 'release', 'disable_stripping' + 'official', 'remoteexec', 'no_widevine_cdm_host_verification', 'arm64', 'disable_widevine_signing', 'minimal_symbols', 'pgo_phase_1', 'release', 'disable_stripping' ], 'official_mac_pgo_with_symbols': [ - 'official', 'reclient', 'no_widevine_cdm_host_verification', 'x64', 'disable_widevine_signing', 'minimal_symbols', 'pgo_phase_1', 'release', 'disable_stripping' + 'official', 'remoteexec', 'no_widevine_cdm_host_verification', 'x64', 'disable_widevine_signing', 'minimal_symbols', 'pgo_phase_1', 'release', 'disable_stripping' ], 'official_minimal_symbols_android_arm64': [ - 'official', 'reclient', 'minimal_symbols', 'android', 'arm64', 'pgo_phase_0', 'no_default_afdo', 'android_low_end', + 'official', 'remoteexec', 'minimal_symbols', 'android', 'arm64', 'pgo_phase_0', 'no_default_afdo', 'android_low_end', ], - 'official_reclient': [ - 'official', 'reclient', + 'official_remoteexec': [ + 'official', 'remoteexec', ], - 'official_reclient_fuchsia_arm64_perf': [ - 'cast_receiver_size_optimized_internal', 'official', 'reclient', 'minimal_symbols', 'fuchsia', 'fuchsia_include_sd_images', 'arm64', 'ffmpeg_branding_chrome', 'proprietary_codecs', 'release', 'test_isolate_no_emulator', + 'official_remoteexec_fuchsia_arm64_perf': [ + 'cast_receiver_size_optimized_internal', 'official', 'remoteexec', 'minimal_symbols', 'fuchsia', 'fuchsia_include_sd_images', 'arm64', 'ffmpeg_branding_chrome', 'proprietary_codecs', 'release', 'test_isolate_no_emulator', ], - 'official_reclient_linux_perf_pgo': [ - 'official', 'reclient', 'no_gnome_keyring', 'minimal_symbols', + 'official_remoteexec_linux_perf_pgo': [ + 'official', 'remoteexec', 'no_gnome_keyring', 'minimal_symbols', ], - 'official_reclient_mac_arm': [ - 'official', 'reclient', 'no_widevine_cdm_host_verification', 'arm64', + 'official_remoteexec_mac_arm': [ + 'official', 'remoteexec', 'no_widevine_cdm_host_verification', 'arm64', ], - 'official_reclient_mac_arm_no_brp_perf': [ - 'official', 'reclient', 'no_keystone_registration_framework', 'no_widevine_cdm_host_verification', 'minimal_symbols', 'arm64', 'pgo_phase_0', 'no_brp', + 'official_remoteexec_mac_arm_no_brp_perf': [ + 'official', 'remoteexec', 'no_keystone_registration_framework', 'no_widevine_cdm_host_verification', 'minimal_symbols', 'arm64', 'pgo_phase_0', 'no_brp', ], - 'official_reclient_mac_arm_perf': [ - 'official', 'reclient', 'no_keystone_registration_framework', 'no_widevine_cdm_host_verification', 'minimal_symbols', 'arm64', 'pgo_phase_0', + 'official_remoteexec_mac_arm_perf': [ + 'official', 'remoteexec', 'no_keystone_registration_framework', 'no_widevine_cdm_host_verification', 'minimal_symbols', 'arm64', 'pgo_phase_0', ], - 'official_reclient_mac_arm_perf_pgo': [ - 'official', 'reclient', 'no_keystone_registration_framework', 'no_widevine_cdm_host_verification', 'minimal_symbols', 'arm64', + 'official_remoteexec_mac_arm_perf_pgo': [ + 'official', 'remoteexec', 'no_keystone_registration_framework', 'no_widevine_cdm_host_verification', 'minimal_symbols', 'arm64', ], - 'official_reclient_mac_perf': [ - 'official', 'reclient', 'no_keystone_registration_framework', 'no_widevine_cdm_host_verification', 'minimal_symbols', 'pgo_phase_0', + 'official_remoteexec_mac_perf': [ + 'official', 'remoteexec', 'no_keystone_registration_framework', 'no_widevine_cdm_host_verification', 'minimal_symbols', 'pgo_phase_0', ], - 'official_reclient_mac_perf_pgo': [ - 'official', 'reclient', 'no_keystone_registration_framework', 'no_widevine_cdm_host_verification', 'minimal_symbols', + 'official_remoteexec_mac_perf_pgo': [ + 'official', 'remoteexec', 'no_keystone_registration_framework', 'no_widevine_cdm_host_verification', 'minimal_symbols', ], - 'official_reclient_mac_x64': [ - 'official', 'reclient', 'x64', 'no_widevine_cdm_host_verification', + 'official_remoteexec_mac_x64': [ + 'official', 'remoteexec', 'x64', 'no_widevine_cdm_host_verification', ], - 'official_reclient_minimal_symbols_android': [ - 'official', 'reclient', 'minimal_symbols', 'android', 'pgo_phase_0', 'no_default_afdo' + 'official_remoteexec_minimal_symbols_android': [ + 'official', 'remoteexec', 'minimal_symbols', 'android', 'pgo_phase_0', 'no_default_afdo' ], - 'official_reclient_minimal_symbols_android_arm64_high_end': [ - 'official', 'reclient', 'minimal_symbols', 'android', 'arm64', 'pgo_phase_0', 'no_default_afdo', + 'official_remoteexec_minimal_symbols_android_arm64_high_end': [ + 'official', 'remoteexec', 'minimal_symbols', 'android', 'arm64', 'pgo_phase_0', 'no_default_afdo', ], - 'official_reclient_minimal_symbols_android_arm64_high_end_pgo': [ - 'official', 'reclient', 'minimal_symbols', 'android', 'arm64', 'no_default_afdo', + 'official_remoteexec_minimal_symbols_android_arm64_high_end_pgo': [ + 'official', 'remoteexec', 'minimal_symbols', 'android', 'arm64', 'no_default_afdo', ], - 'official_reclient_minimal_symbols_android_arm64_pgo': [ - 'official', 'reclient', 'minimal_symbols', 'android', 'arm64', 'android_low_end', + 'official_remoteexec_minimal_symbols_android_arm64_pgo': [ + 'official', 'remoteexec', 'minimal_symbols', 'android', 'arm64', 'android_low_end', ], - 'official_reclient_minimal_symbols_android_pgo': [ - 'official', 'reclient', 'minimal_symbols', 'android' + 'official_remoteexec_minimal_symbols_android_pgo': [ + 'official', 'remoteexec', 'minimal_symbols', 'android' ], - 'official_reclient_minimal_symbols_android_thin_lto_opt': [ - 'official', 'reclient', 'minimal_symbols', 'android', 'thin_lto_opt', 'no_default_afdo' + 'official_remoteexec_minimal_symbols_android_thin_lto_opt': [ + 'official', 'remoteexec', 'minimal_symbols', 'android', 'thin_lto_opt', 'no_default_afdo' ], - 'official_reclient_minimal_symbols_android_thin_lto_opt_arm64': [ - 'official', 'reclient', 'minimal_symbols', 'android', 'thin_lto_opt', 'arm64', 'no_default_afdo' + 'official_remoteexec_minimal_symbols_android_thin_lto_opt_arm64': [ + 'official', 'remoteexec', 'minimal_symbols', 'android', 'thin_lto_opt', 'arm64', 'no_default_afdo' ], - 'official_reclient_perf_pgo': [ - 'official', 'reclient', 'minimal_symbols', + 'official_remoteexec_perf_pgo': [ + 'official', 'remoteexec', 'minimal_symbols', ], - 'official_reclient_perf_win_cross': [ - 'official', 'reclient_win_cross', 'minimal_symbols', 'pgo_phase_0', + 'official_remoteexec_perf_win_cross': [ + 'official', 'remoteexec_win_cross', 'minimal_symbols', 'pgo_phase_0', ], - 'official_reclient_perf_win_cross_arm64': [ - 'official', 'reclient_win_cross', 'arm64', 'minimal_symbols', 'pgo_phase_0', + 'official_remoteexec_perf_win_cross_arm64': [ + 'official', 'remoteexec_win_cross', 'arm64', 'minimal_symbols', 'pgo_phase_0', ], - 'official_reclient_x64': [ - 'official', 'reclient', 'x64', 'minimal_symbols', + 'official_remoteexec_x64': [ + 'official', 'remoteexec', 'x64', 'minimal_symbols', ], - 'official_reclient_x86': [ - 'official', 'reclient', 'x86', 'minimal_symbols', + 'official_remoteexec_x86': [ + 'official', 'remoteexec', 'x86', 'minimal_symbols', ], 'official_win_arm64_pgo': [ - 'official', 'reclient', 'arm64', 'no_symbols', 'pgo_phase_1', 'release' + 'official', 'remoteexec', 'arm64', 'no_symbols', 'pgo_phase_1', 'release' ], 'official_win_arm64_pgo_with_symbols': [ - 'official', 'reclient', 'arm64', 'minimal_symbols', 'pgo_phase_1', 'release' + 'official', 'remoteexec', 'arm64', 'minimal_symbols', 'pgo_phase_1', 'release' ], 'official_x64_pgo': [ - 'official', 'reclient', 'x64', 'no_symbols', 'pgo_phase_1', 'release' + 'official', 'remoteexec', 'x64', 'no_symbols', 'pgo_phase_1', 'release' ], 'official_x64_pgo_with_symbols': [ - 'official', 'reclient', 'x64', 'minimal_symbols', 'pgo_phase_1', 'release' + 'official', 'remoteexec', 'x64', 'minimal_symbols', 'pgo_phase_1', 'release' ], 'official_x86_pgo': [ - 'official', 'reclient', 'x86', 'no_symbols', 'pgo_phase_1', 'release' + 'official', 'remoteexec', 'x86', 'no_symbols', 'pgo_phase_1', 'release' ], 'official_x86_pgo_with_symbols': [ - 'official', 'reclient', 'x86', 'minimal_symbols', 'pgo_phase_1', 'release' + 'official', 'remoteexec', 'x86', 'minimal_symbols', 'pgo_phase_1', 'release' ], 'optimization_guide_android_arm64_rel': [ - 'minimal_symbols', 'reclient', 'release', 'android', 'arm64', + 'minimal_symbols', 'remoteexec', 'release', 'android', 'arm64', ], 'optimization_guide_cros_rel': [ - 'minimal_symbols', 'optimization_guide', 'reclient', 'release', 'chromeos', + 'minimal_symbols', 'optimization_guide', 'remoteexec', 'release', 'chromeos', ], 'optimization_guide_ios_device_rel': [ - 'arm64', 'codesigning_identity', 'ios', 'ios_default_args', 'ios_device', 'minimal_symbols', 'ml_internal', 'optimization_guide', 'reclient', 'release', 'xctest', + 'arm64', 'codesigning_identity', 'ios', 'ios_default_args', 'ios_device', 'minimal_symbols', 'ml_internal', 'optimization_guide', 'remoteexec', 'release', 'xctest', ], 'optimization_guide_ios_sim_rel': [ - 'arm64', 'codesigning_identity', 'ios', 'ios_default_args', 'ios_simulator', 'minimal_symbols', 'ml_internal', 'optimization_guide', 'reclient', 'release', 'xctest', + 'arm64', 'codesigning_identity', 'ios', 'ios_default_args', 'ios_simulator', 'minimal_symbols', 'ml_internal', 'optimization_guide', 'remoteexec', 'release', 'xctest', ], 'optimization_guide_mac_arm64_rel': [ - 'chrome_branded', 'minimal_symbols', 'ml_internal', 'optimization_guide', 'reclient', 'release', 'arm64', + 'chrome_branded', 'minimal_symbols', 'ml_internal', 'optimization_guide', 'remoteexec', 'release', 'arm64', ], 'optimization_guide_official_rel': [ - 'minimal_symbols', 'ml_internal', 'no_widevine_cdm_host_verification', 'official', 'optimization_guide', 'pgo_phase_0', 'reclient', 'release', + 'minimal_symbols', 'ml_internal', 'no_widevine_cdm_host_verification', 'official', 'optimization_guide', 'pgo_phase_0', 'remoteexec', 'release', ], 'optimization_guide_rel': [ - 'chrome_branded', 'minimal_symbols', 'ml_internal', 'optimization_guide', 'reclient', 'release', + 'chrome_branded', 'minimal_symbols', 'ml_internal', 'optimization_guide', 'remoteexec', 'release', ], 'optimization_guide_win_arm64_rel': [ - 'chrome_branded', 'minimal_symbols', 'ml_internal', 'optimization_guide', 'reclient', 'release', 'x86', 'arm64' + 'chrome_branded', 'minimal_symbols', 'ml_internal', 'optimization_guide', 'remoteexec', 'release', 'x86', 'arm64' ], 'optimization_guide_x86_rel': [ - 'chrome_branded', 'minimal_symbols', 'ml_internal', 'optimization_guide', 'reclient', 'release', 'x86', + 'chrome_branded', 'minimal_symbols', 'ml_internal', 'optimization_guide', 'remoteexec', 'release', 'x86', ], 'release_bot_blink': [ 'release_bot_blink', 'use_siso', ], - 'release_bot_blink_v8_debug_reclient': [ + 'release_bot_blink_v8_debug_remoteexec': [ 'release_bot_blink', 'v8_enable_debugging_features', 'use_siso', ], - 'release_bot_reclient': [ - 'release_bot_reclient', + 'release_bot_remoteexec': [ + 'release_bot_remoteexec', ], - 'release_bot_reclient_siso': [ - 'release_bot_reclient', 'use_siso', + 'release_bot_remoteexec_siso': [ + 'release_bot_remoteexec', 'use_siso', ], 'release_trybot_blink': [ @@ -667,12 +662,12 @@ 'release_trybot_blink', 'use_siso', ], - 'release_trybot_reclient': [ - 'release_trybot_reclient', + 'release_trybot_remoteexec': [ + 'release_trybot_remoteexec', ], - 'release_trybot_reclient_siso': [ - 'release_trybot_reclient', 'use_siso', + 'release_trybot_remoteexec_siso': [ + 'release_trybot_remoteexec', 'use_siso', ], }, @@ -713,10 +708,6 @@ 'gn_args': 'target_cpu="arm"', }, - 'arm-generic': { - 'args_file': '//build/args/chromeos/arm-generic.gni', - }, - 'arm64': { 'gn_args': 'target_cpu="arm64"', }, @@ -750,15 +741,6 @@ 'args_file': '//build/config/fuchsia/size_optimized_cast_receiver_args_internal.gn', }, - 'cfi': { - 'gn_args': 'is_cfi=true', - }, - - 'cfi_full': { - 'mixins': ['cfi'], - 'gn_args': 'use_cfi_cast=true', - }, - 'chrome_branded': { 'gn_args': 'is_chrome_branded=true' }, @@ -771,17 +753,17 @@ 'gn_args': 'target_os="chromeos"', }, - 'chromeos_device_reclient': { + 'chromeos_device_remoteexec': { 'gn_args': 'is_chromeos_device=true', - 'mixins': ['dcheck_off', 'reclient'], + 'mixins': ['dcheck_off', 'remoteexec'], }, - 'chromeos_jacuzzi_reclient': { - 'mixins': ['chromeos_device_reclient', 'jacuzzi', 'ozone_headless'] + 'chromeos_jacuzzi_remoteexec': { + 'mixins': ['chromeos_device_remoteexec', 'jacuzzi', 'ozone_headless'] }, - 'chromeos_kevin_reclient': { - 'mixins': ['chromeos_device_reclient', 'kevin', 'ozone_headless'] + 'chromeos_kevin_remoteexec': { + 'mixins': ['chromeos_device_remoteexec', 'kevin', 'ozone_headless'] }, 'clang': { @@ -794,28 +776,28 @@ }, # Same as regulary codesearch without blink_enable_generated_code_formatting - 'codesearch_cronet_reclient': { + 'codesearch_cronet_remoteexec': { 'gn_args': 'clang_use_chrome_plugins=false enable_kythe_annotations=true', - 'mixins': ['reclient', 'clang', 'shared', 'debug', 'minimal_symbols'], + 'mixins': ['remoteexec', 'clang', 'shared', 'debug', 'minimal_symbols'], }, # Same as regular codesearch except ios does not allow component builds - 'codesearch_ios_reclient': { + 'codesearch_ios_remoteexec': { 'gn_args': 'clang_use_chrome_plugins=false enable_kythe_annotations=true', - 'mixins': ['reclient', 'clang', 'debug', 'minimal_symbols', + 'mixins': ['remoteexec', 'clang', 'debug', 'minimal_symbols', + 'blink_enable_generated_code_formatting'], + }, + + 'codesearch_release_remoteexec': { + 'gn_args': 'clang_use_chrome_plugins=false enable_kythe_annotations=true', + 'mixins': ['release', 'static', 'remoteexec', 'blink_enable_generated_code_formatting'], }, # Settings used by the codesearch builders to generate cross-references. - 'codesearch_reclient': { + 'codesearch_remoteexec': { 'gn_args': 'clang_use_chrome_plugins=false enable_kythe_annotations=true', - 'mixins': ['reclient', 'clang', 'shared', 'debug', 'minimal_symbols', - 'blink_enable_generated_code_formatting'], - }, - - 'codesearch_release_reclient': { - 'gn_args': 'clang_use_chrome_plugins=false enable_kythe_annotations=true', - 'mixins': ['release', 'static', 'reclient', + 'mixins': ['remoteexec', 'clang', 'shared', 'debug', 'minimal_symbols', 'blink_enable_generated_code_formatting'], }, @@ -863,11 +845,11 @@ }, 'debug_bot_blink': { - 'mixins': ['debug', 'shared', 'reclient', 'minimal_symbols', 'chrome_with_codecs'], + 'mixins': ['debug', 'shared', 'remoteexec', 'minimal_symbols', 'chrome_with_codecs'], }, - 'debug_bot_reclient': { - 'mixins': ['debug', 'shared', 'reclient', 'minimal_symbols'], + 'debug_bot_remoteexec': { + 'mixins': ['debug', 'shared', 'remoteexec', 'minimal_symbols'], }, # Representative GN args for developer builds. @@ -1033,15 +1015,6 @@ 'gn_args': 'proprietary_codecs=true', }, - 'reclient': { - 'gn_args': 'use_remoteexec=true', - }, - - # windows cross. crbug.com/1213717 crbug.com/1407983 - 'reclient_win_cross': { - 'gn_args': 'use_remoteexec=true reclient_cfg_dir="//buildtools/reclient_cfgs/win-cross"', - }, - # Historically, a 'release' bot had DCHECKs turned off. DCHECKs are now # enabled by default, but explicitly turning them off here preserves # backwards compatibility. TODO: We should probably come up with better @@ -1053,11 +1026,11 @@ # All bots that run the WPT test suite must have H.264 compiled in, # in order to give consistent results for WebRTC codec-dependent tests. 'release_bot_blink': { - 'mixins': ['release', 'static', 'reclient', 'chrome_with_codecs'], + 'mixins': ['release', 'static', 'remoteexec', 'chrome_with_codecs'], }, - 'release_bot_reclient': { - 'mixins': ['release', 'static', 'reclient'], + 'release_bot_remoteexec': { + 'mixins': ['release', 'static', 'remoteexec'], }, 'release_trybot_blink': { @@ -1068,16 +1041,26 @@ 'mixins': ['release_bot_blink', 'minimal_symbols', 'dcheck_always_on'], }, - 'release_trybot_dcheck_off_reclient': { - 'mixins': ['release_trybot_reclient', 'dcheck_off'], + 'release_trybot_dcheck_off_remoteexec': { + 'mixins': ['release_trybot_remoteexec', 'dcheck_off'], }, - 'release_trybot_minimal_symbols_reclient': { - 'mixins': ['release_bot_reclient', 'minimal_symbols', 'dcheck_always_on'], + 'release_trybot_minimal_symbols_remoteexec': { + 'mixins': ['release_bot_remoteexec', 'minimal_symbols', 'dcheck_always_on'], }, - 'release_trybot_reclient': { - 'mixins': ['release_bot_reclient', 'no_symbols', 'dcheck_always_on'], + 'release_trybot_remoteexec': { + 'mixins': ['release_bot_remoteexec', 'no_symbols', 'dcheck_always_on'], + }, + + 'remoteexec': { + 'gn_args': 'use_remoteexec=true use_reclient=false', + }, + + # windows cross. crbug.com/1213717 crbug.com/1407983 + 'remoteexec_win_cross': { + 'mixins': ['remoteexec'], + 'gn_args': 'reclient_cfg_dir="//buildtools/reclient_cfgs/win-cross"', }, 'resource_allowlisting': { @@ -1114,10 +1097,6 @@ 'gn_args': 'test_isolate_uses_emulator=false', }, - 'thin_lto': { - 'gn_args': 'use_thin_lto=true', - }, - 'thin_lto_opt': { 'gn_args': 'use_thin_lto=true thin_lto_enable_optimizations=true', },
diff --git a/tools/mb/mb_config_expectations/chrome.gpu.fyi.json b/tools/mb/mb_config_expectations/chrome.gpu.fyi.json index e534ebfad..00c0302 100644 --- a/tools/mb/mb_config_expectations/chrome.gpu.fyi.json +++ b/tools/mb/mb_config_expectations/chrome.gpu.fyi.json
@@ -11,6 +11,7 @@ "ozone_platform_headless": true, "proprietary_codecs": true, "symbol_level": 0, + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/mb/mb_config_expectations/chrome.json b/tools/mb/mb_config_expectations/chrome.json index 4702895..6a05db56 100644 --- a/tools/mb/mb_config_expectations/chrome.json +++ b/tools/mb/mb_config_expectations/chrome.json
@@ -3,6 +3,7 @@ "gn_args": { "is_chrome_branded": true, "is_official_build": true, + "use_reclient": false, "use_remoteexec": true } }, @@ -12,6 +13,7 @@ "is_chrome_branded": true, "is_official_build": true, "target_cpu": "x64", + "use_reclient": false, "use_remoteexec": true } }, @@ -22,6 +24,7 @@ "is_component_build": false, "is_debug": false, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -31,6 +34,7 @@ "is_official_build": true, "symbol_level": 1, "target_cpu": "x86", + "use_reclient": false, "use_remoteexec": true } }, @@ -40,6 +44,7 @@ "is_official_build": true, "symbol_level": 1, "target_cpu": "x64", + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/mb/mb_config_expectations/chrome.orderfile.json b/tools/mb/mb_config_expectations/chrome.orderfile.json index cecf27e..7a467fcd 100644 --- a/tools/mb/mb_config_expectations/chrome.orderfile.json +++ b/tools/mb/mb_config_expectations/chrome.orderfile.json
@@ -13,6 +13,7 @@ "target_cpu": "arm", "target_os": "android", "use_order_profiling": true, + "use_reclient": false, "use_remoteexec": true } }, @@ -30,6 +31,7 @@ "target_cpu": "arm64", "target_os": "android", "use_order_profiling": true, + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/mb/mb_config_expectations/chrome.pgo.json b/tools/mb/mb_config_expectations/chrome.pgo.json index be4f7ae..015284c 100644 --- a/tools/mb/mb_config_expectations/chrome.pgo.json +++ b/tools/mb/mb_config_expectations/chrome.pgo.json
@@ -13,6 +13,7 @@ "symbol_level": 1, "target_cpu": "arm", "target_os": "android", + "use_reclient": false, "use_remoteexec": true, "v8_is_on_release_branch": true } @@ -31,6 +32,7 @@ "symbol_level": 1, "target_cpu": "arm64", "target_os": "android", + "use_reclient": false, "use_remoteexec": true, "v8_is_on_release_branch": true } @@ -43,6 +45,7 @@ "is_debug": false, "is_official_build": true, "symbol_level": 0, + "use_reclient": false, "use_remoteexec": true, "v8_is_on_release_branch": true } @@ -59,6 +62,7 @@ "is_official_build": true, "symbol_level": 1, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true, "v8_is_on_release_branch": true } @@ -75,6 +79,7 @@ "is_official_build": true, "symbol_level": 1, "target_cpu": "x64", + "use_reclient": false, "use_remoteexec": true, "v8_is_on_release_branch": true } @@ -88,6 +93,7 @@ "is_official_build": true, "symbol_level": 0, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true, "v8_is_on_release_branch": true } @@ -101,6 +107,7 @@ "is_official_build": true, "symbol_level": 0, "target_cpu": "x86", + "use_reclient": false, "use_remoteexec": true, "v8_is_on_release_branch": true } @@ -114,6 +121,7 @@ "is_official_build": true, "symbol_level": 0, "target_cpu": "x64", + "use_reclient": false, "use_remoteexec": true, "v8_is_on_release_branch": true }
diff --git a/tools/mb/mb_config_expectations/chromium.infra.codesearch.json b/tools/mb/mb_config_expectations/chromium.infra.codesearch.json index 2b6c842..5a51baba 100644 --- a/tools/mb/mb_config_expectations/chromium.infra.codesearch.json +++ b/tools/mb/mb_config_expectations/chromium.infra.codesearch.json
@@ -10,6 +10,7 @@ "is_debug": true, "symbol_level": 1, "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -24,6 +25,7 @@ "symbol_level": 1, "target_os": "chromeos", "use_cups": true, + "use_reclient": false, "use_remoteexec": true } }, @@ -48,6 +50,7 @@ "use_hashed_jni_names": true, "use_partition_alloc": false, "use_platform_icu_alternatives": true, + "use_reclient": false, "use_remoteexec": true, "use_thin_lto": false } @@ -62,6 +65,7 @@ "is_component_build": false, "is_debug": false, "target_os": "fuchsia", + "use_reclient": false, "use_remoteexec": true } }, @@ -76,6 +80,7 @@ "symbol_level": 1, "target_environment": "device", "target_os": "ios", + "use_reclient": false, "use_remoteexec": true } }, @@ -88,6 +93,7 @@ "is_component_build": true, "is_debug": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -101,6 +107,7 @@ "is_debug": true, "symbol_level": 1, "target_os": "mac", + "use_reclient": false, "use_remoteexec": true } }, @@ -115,6 +122,7 @@ "is_debug": true, "symbol_level": 1, "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -127,6 +135,7 @@ "is_component_build": true, "is_debug": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/mb/mb_config_expectations/chromium.perf.calibration.json b/tools/mb/mb_config_expectations/chromium.perf.calibration.json index 14f51295..d1f20a6 100644 --- a/tools/mb/mb_config_expectations/chromium.perf.calibration.json +++ b/tools/mb/mb_config_expectations/chromium.perf.calibration.json
@@ -7,6 +7,7 @@ "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, "use_gnome_keyring": false, + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/mb/mb_config_expectations/chromium.perf.fyi.json b/tools/mb/mb_config_expectations/chromium.perf.fyi.json index 3ad9544..97a6c6a 100644 --- a/tools/mb/mb_config_expectations/chromium.perf.fyi.json +++ b/tools/mb/mb_config_expectations/chromium.perf.fyi.json
@@ -10,6 +10,7 @@ "symbol_level": 1, "target_os": "android", "thin_lto_enable_optimizations": true, + "use_reclient": false, "use_remoteexec": true, "use_thin_lto": true } @@ -26,6 +27,7 @@ "target_cpu": "arm64", "target_os": "android", "thin_lto_enable_optimizations": true, + "use_reclient": false, "use_remoteexec": true, "use_thin_lto": true } @@ -39,6 +41,7 @@ "is_chromeos_device": true, "is_official_build": true, "ozone_platform_headless": true, + "use_reclient": false, "use_remoteexec": true } }, @@ -60,6 +63,7 @@ "target_cpu": "arm64", "target_os": "fuchsia", "test_isolate_uses_emulator": false, + "use_reclient": false, "use_remoteexec": true } }, @@ -72,6 +76,7 @@ "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/mb/mb_config_expectations/chromium.perf.json b/tools/mb/mb_config_expectations/chromium.perf.json index 5a39f5d..2472aad 100644 --- a/tools/mb/mb_config_expectations/chromium.perf.json +++ b/tools/mb/mb_config_expectations/chromium.perf.json
@@ -11,6 +11,7 @@ "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -28,6 +29,7 @@ "symbol_level": 1, "target_cpu": "arm64", "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -43,6 +45,7 @@ "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -55,6 +58,7 @@ "proprietary_codecs": true, "symbol_level": 1, "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -72,6 +76,7 @@ "symbol_level": 1, "target_cpu": "arm64", "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -86,6 +91,7 @@ "symbol_level": 1, "target_cpu": "arm64", "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -102,6 +108,7 @@ "symbol_level": 1, "target_cpu": "arm64", "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -116,6 +123,7 @@ "symbol_level": 1, "target_cpu": "arm64", "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -127,6 +135,7 @@ "is_component_build": false, "is_debug": false, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -138,6 +147,7 @@ "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, "use_gnome_keyring": false, + "use_reclient": false, "use_remoteexec": true } }, @@ -147,6 +157,7 @@ "is_official_build": true, "symbol_level": 1, "use_gnome_keyring": false, + "use_reclient": false, "use_remoteexec": true } }, @@ -158,6 +169,7 @@ "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, "use_gnome_keyring": false, + "use_reclient": false, "use_remoteexec": true } }, @@ -171,6 +183,7 @@ "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true } }, @@ -182,6 +195,7 @@ "is_official_build": true, "symbol_level": 1, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true } }, @@ -197,6 +211,7 @@ "symbol_level": 1, "target_cpu": "arm64", "use_raw_ptr_backup_ref_impl": false, + "use_reclient": false, "use_remoteexec": true } }, @@ -209,6 +224,7 @@ "is_official_build": true, "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -219,6 +235,7 @@ "is_chrome_branded": true, "is_official_build": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -230,6 +247,7 @@ "reclient_cfg_dir": "//buildtools/reclient_cfgs/win-cross", "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -238,6 +256,7 @@ "is_chrome_branded": true, "is_official_build": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/mb/mb_config_expectations/chromium.perf.pinpoint.json b/tools/mb/mb_config_expectations/chromium.perf.pinpoint.json index 5de61533..116688de 100644 --- a/tools/mb/mb_config_expectations/chromium.perf.pinpoint.json +++ b/tools/mb/mb_config_expectations/chromium.perf.pinpoint.json
@@ -11,6 +11,7 @@ "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -28,6 +29,7 @@ "symbol_level": 1, "target_cpu": "arm64", "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -43,6 +45,7 @@ "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -55,6 +58,7 @@ "proprietary_codecs": true, "symbol_level": 1, "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -72,6 +76,7 @@ "symbol_level": 1, "target_cpu": "arm64", "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -86,6 +91,7 @@ "symbol_level": 1, "target_cpu": "arm64", "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -102,6 +108,7 @@ "symbol_level": 1, "target_cpu": "arm64", "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -116,6 +123,7 @@ "symbol_level": 1, "target_cpu": "arm64", "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -127,6 +135,7 @@ "is_component_build": false, "is_debug": false, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -138,6 +147,7 @@ "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, "use_gnome_keyring": false, + "use_reclient": false, "use_remoteexec": true } }, @@ -147,6 +157,7 @@ "is_official_build": true, "symbol_level": 1, "use_gnome_keyring": false, + "use_reclient": false, "use_remoteexec": true } }, @@ -158,6 +169,7 @@ "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, "use_gnome_keyring": false, + "use_reclient": false, "use_remoteexec": true } }, @@ -171,6 +183,7 @@ "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true } }, @@ -182,6 +195,7 @@ "is_official_build": true, "symbol_level": 1, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true } }, @@ -194,6 +208,7 @@ "is_official_build": true, "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -204,6 +219,7 @@ "is_chrome_branded": true, "is_official_build": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -216,6 +232,7 @@ "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true } }, @@ -227,6 +244,7 @@ "reclient_cfg_dir": "//buildtools/reclient_cfgs/win-cross", "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -235,6 +253,7 @@ "is_chrome_branded": true, "is_official_build": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/mb/mb_config_expectations/client.devtools-frontend.integration.json b/tools/mb/mb_config_expectations/client.devtools-frontend.integration.json index 78099c7..a0ae48e 100644 --- a/tools/mb/mb_config_expectations/client.devtools-frontend.integration.json +++ b/tools/mb/mb_config_expectations/client.devtools-frontend.integration.json
@@ -8,6 +8,7 @@ "is_debug": false, "proprietary_codecs": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true, "use_siso": true } @@ -20,6 +21,7 @@ "is_debug": false, "proprietary_codecs": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true, "use_siso": true }
diff --git a/tools/mb/mb_config_expectations/client.openscreen.chromium.json b/tools/mb/mb_config_expectations/client.openscreen.chromium.json index e3b85d24..5e65f7b 100644 --- a/tools/mb/mb_config_expectations/client.openscreen.chromium.json +++ b/tools/mb/mb_config_expectations/client.openscreen.chromium.json
@@ -4,6 +4,7 @@ "is_component_build": true, "is_debug": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -12,6 +13,7 @@ "is_component_build": true, "is_debug": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -20,6 +22,7 @@ "is_component_build": true, "is_debug": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/mb/mb_config_expectations/client.v8.chromium.json b/tools/mb/mb_config_expectations/client.v8.chromium.json index 1b9d35c..a41d4a3 100644 --- a/tools/mb/mb_config_expectations/client.v8.chromium.json +++ b/tools/mb/mb_config_expectations/client.v8.chromium.json
@@ -4,6 +4,7 @@ "dcheck_always_on": false, "is_component_build": false, "is_debug": false, + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/mb/mb_config_expectations/client.v8.fyi.json b/tools/mb/mb_config_expectations/client.v8.fyi.json index f04c1627..be94658 100644 --- a/tools/mb/mb_config_expectations/client.v8.fyi.json +++ b/tools/mb/mb_config_expectations/client.v8.fyi.json
@@ -10,6 +10,7 @@ "symbol_level": 1, "target_cpu": "arm64", "target_os": "android", + "use_reclient": false, "use_remoteexec": true, "use_siso": true, "use_static_angle": true @@ -23,6 +24,7 @@ "is_debug": false, "is_lsan": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true, "use_siso": true } @@ -34,6 +36,7 @@ "is_debug": true, "proprietary_codecs": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true, "use_siso": true } @@ -46,6 +49,7 @@ "is_debug": false, "proprietary_codecs": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true, "use_siso": true } @@ -58,6 +62,7 @@ "is_debug": false, "proprietary_codecs": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true, "use_siso": true, "v8_enable_pointer_compression": false @@ -71,6 +76,7 @@ "is_debug": false, "proprietary_codecs": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true, "use_siso": true } @@ -84,6 +90,7 @@ "proprietary_codecs": true, "symbol_level": 1, "target_os": "android", + "use_reclient": false, "use_remoteexec": true, "use_siso": true } @@ -95,6 +102,7 @@ "is_component_build": false, "is_debug": false, "proprietary_codecs": true, + "use_reclient": false, "use_remoteexec": true, "use_siso": true } @@ -106,6 +114,7 @@ "is_component_build": false, "is_debug": false, "proprietary_codecs": true, + "use_reclient": false, "use_remoteexec": true, "use_siso": true, "v8_enable_debugging_features": true @@ -118,6 +127,7 @@ "is_component_build": false, "is_debug": false, "proprietary_codecs": true, + "use_reclient": false, "use_remoteexec": true, "use_siso": true } @@ -129,6 +139,7 @@ "is_component_build": false, "is_debug": false, "proprietary_codecs": true, + "use_reclient": false, "use_remoteexec": true, "use_siso": true } @@ -140,6 +151,7 @@ "is_component_build": false, "is_debug": false, "proprietary_codecs": true, + "use_reclient": false, "use_remoteexec": true, "use_siso": true } @@ -149,6 +161,7 @@ "dcheck_always_on": false, "is_component_build": false, "is_debug": false, + "use_reclient": false, "use_remoteexec": true, "use_siso": true } @@ -163,6 +176,7 @@ "proprietary_codecs": true, "symbol_level": 1, "target_cpu": "x86", + "use_reclient": false, "use_remoteexec": true, "use_siso": true }
diff --git a/tools/mb/mb_config_expectations/internal.chrome.fyi.json b/tools/mb/mb_config_expectations/internal.chrome.fyi.json index d198bcec..1fdae019 100644 --- a/tools/mb/mb_config_expectations/internal.chrome.fyi.json +++ b/tools/mb/mb_config_expectations/internal.chrome.fyi.json
@@ -9,6 +9,7 @@ "proprietary_codecs": true, "symbol_level": 1, "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -27,28 +28,15 @@ "system_webview_shell_package_name": "org.chromium.my_webview_shell", "target_cpu": "x86", "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, - "chromeos-arm-generic-cfi-thin-lto-chrome-reclient": { - "args_file": "//build/args/chromeos/arm-generic.gni", - "gn_args": { - "dcheck_always_on": false, - "is_cfi": true, - "is_chrome_branded": true, - "is_chromeos_device": true, - "is_official_build": true, - "ozone_platform_headless": true, - "symbol_level": 2, - "use_cfi_cast": true, - "use_remoteexec": true, - "use_thin_lto": true - } - }, "linux-finch-smoke-chrome": { "gn_args": { "is_chrome_branded": true, "is_official_build": true, + "use_reclient": false, "use_remoteexec": true } }, @@ -63,6 +51,7 @@ "proprietary_codecs": true, "symbol_level": 1, "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -72,6 +61,7 @@ "is_chrome_branded": true, "is_official_build": true, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true } }, @@ -83,6 +73,7 @@ "is_debug": false, "is_official_build": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -90,6 +81,7 @@ "gn_args": { "is_chrome_branded": true, "is_official_build": true, + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/mb/mb_config_expectations/internal.optimization_guide.json b/tools/mb/mb_config_expectations/internal.optimization_guide.json index 134e82e9..1ebdee4 100644 --- a/tools/mb/mb_config_expectations/internal.optimization_guide.json +++ b/tools/mb/mb_config_expectations/internal.optimization_guide.json
@@ -7,6 +7,7 @@ "is_chrome_branded": true, "is_debug": false, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -19,6 +20,7 @@ "is_debug": false, "symbol_level": 1, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true } }, @@ -30,6 +32,7 @@ "is_chrome_branded": true, "is_debug": false, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -42,6 +45,7 @@ "is_debug": false, "symbol_level": 1, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true } }, @@ -54,6 +58,7 @@ "is_debug": false, "symbol_level": 1, "target_cpu": "x86", + "use_reclient": false, "use_remoteexec": true } }, @@ -65,6 +70,7 @@ "is_chrome_branded": true, "is_debug": false, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -78,6 +84,7 @@ "symbol_level": 1, "target_cpu": "arm64", "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -88,6 +95,7 @@ "is_debug": false, "symbol_level": 1, "target_os": "chromeos", + "use_reclient": false, "use_remoteexec": true } }, @@ -104,6 +112,7 @@ "target_cpu": "arm64", "target_environment": "device", "target_os": "ios", + "use_reclient": false, "use_remoteexec": true } }, @@ -120,6 +129,7 @@ "target_cpu": "arm64", "target_environment": "simulator", "target_os": "ios", + "use_reclient": false, "use_remoteexec": true } }, @@ -131,6 +141,7 @@ "is_chrome_branded": true, "is_debug": false, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -143,6 +154,7 @@ "is_debug": false, "symbol_level": 1, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true } }, @@ -154,6 +166,7 @@ "is_chrome_branded": true, "is_debug": false, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -166,6 +179,7 @@ "is_debug": false, "symbol_level": 1, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true } }, @@ -178,6 +192,7 @@ "is_debug": false, "symbol_level": 1, "target_cpu": "x86", + "use_reclient": false, "use_remoteexec": true } }, @@ -189,6 +204,7 @@ "is_chrome_branded": true, "is_debug": false, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -204,6 +220,7 @@ "is_official_build": true, "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -219,6 +236,7 @@ "is_official_build": true, "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/mb/mb_config_expectations/luci.infra-internal.codesearch.json b/tools/mb/mb_config_expectations/luci.infra-internal.codesearch.json index ed202372..ce0d8616e 100644 --- a/tools/mb/mb_config_expectations/luci.infra-internal.codesearch.json +++ b/tools/mb/mb_config_expectations/luci.infra-internal.codesearch.json
@@ -11,6 +11,7 @@ "is_debug": true, "symbol_level": 1, "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -24,6 +25,7 @@ "is_component_build": true, "is_debug": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/mb/mb_config_expectations/tryserver.chrome.gpu.json b/tools/mb/mb_config_expectations/tryserver.chrome.gpu.json index 7d789b0c..3b6fe0f 100644 --- a/tools/mb/mb_config_expectations/tryserver.chrome.gpu.json +++ b/tools/mb/mb_config_expectations/tryserver.chrome.gpu.json
@@ -11,6 +11,7 @@ "ozone_platform_headless": true, "proprietary_codecs": true, "symbol_level": 0, + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/mb/mb_config_expectations/tryserver.chrome.json b/tools/mb/mb_config_expectations/tryserver.chrome.json index d3d826f6..7c4dd78 100644 --- a/tools/mb/mb_config_expectations/tryserver.chrome.json +++ b/tools/mb/mb_config_expectations/tryserver.chrome.json
@@ -3,6 +3,7 @@ "gn_args": { "is_chrome_branded": true, "is_official_build": true, + "use_reclient": false, "use_remoteexec": true } }, @@ -10,6 +11,7 @@ "gn_args": { "is_chrome_branded": true, "is_official_build": true, + "use_reclient": false, "use_remoteexec": true } }, @@ -19,6 +21,7 @@ "is_chrome_branded": true, "is_official_build": true, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true } }, @@ -28,6 +31,7 @@ "is_chrome_branded": true, "is_official_build": true, "target_cpu": "x64", + "use_reclient": false, "use_remoteexec": true } }, @@ -38,6 +42,7 @@ "is_component_build": false, "is_debug": false, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -49,6 +54,7 @@ "is_debug": false, "is_official_build": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -58,6 +64,7 @@ "is_official_build": true, "symbol_level": 1, "target_cpu": "x86", + "use_reclient": false, "use_remoteexec": true } }, @@ -65,6 +72,7 @@ "gn_args": { "is_chrome_branded": true, "is_official_build": true, + "use_reclient": false, "use_remoteexec": true } }, @@ -74,6 +82,7 @@ "is_official_build": true, "symbol_level": 1, "target_cpu": "x64", + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/mb/mb_config_expectations/tryserver.chrome.orderfile.json b/tools/mb/mb_config_expectations/tryserver.chrome.orderfile.json index cecf27e..7a467fcd 100644 --- a/tools/mb/mb_config_expectations/tryserver.chrome.orderfile.json +++ b/tools/mb/mb_config_expectations/tryserver.chrome.orderfile.json
@@ -13,6 +13,7 @@ "target_cpu": "arm", "target_os": "android", "use_order_profiling": true, + "use_reclient": false, "use_remoteexec": true } }, @@ -30,6 +31,7 @@ "target_cpu": "arm64", "target_os": "android", "use_order_profiling": true, + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/mb/mb_config_expectations/tryserver.chrome.pgo.json b/tools/mb/mb_config_expectations/tryserver.chrome.pgo.json index 1f83617..73609592 100644 --- a/tools/mb/mb_config_expectations/tryserver.chrome.pgo.json +++ b/tools/mb/mb_config_expectations/tryserver.chrome.pgo.json
@@ -13,6 +13,7 @@ "symbol_level": 1, "target_cpu": "arm", "target_os": "android", + "use_reclient": false, "use_remoteexec": true, "v8_is_on_release_branch": true } @@ -31,6 +32,7 @@ "symbol_level": 1, "target_cpu": "arm64", "target_os": "android", + "use_reclient": false, "use_remoteexec": true, "v8_is_on_release_branch": true } @@ -43,6 +45,7 @@ "is_debug": false, "is_official_build": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true, "v8_is_on_release_branch": true } @@ -59,6 +62,7 @@ "is_official_build": true, "symbol_level": 1, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true, "v8_is_on_release_branch": true } @@ -75,6 +79,7 @@ "is_official_build": true, "symbol_level": 1, "target_cpu": "x64", + "use_reclient": false, "use_remoteexec": true, "v8_is_on_release_branch": true } @@ -88,6 +93,7 @@ "is_official_build": true, "symbol_level": 1, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true, "v8_is_on_release_branch": true } @@ -101,6 +107,7 @@ "is_official_build": true, "symbol_level": 1, "target_cpu": "x86", + "use_reclient": false, "use_remoteexec": true, "v8_is_on_release_branch": true } @@ -114,6 +121,7 @@ "is_official_build": true, "symbol_level": 1, "target_cpu": "x64", + "use_reclient": false, "use_remoteexec": true, "v8_is_on_release_branch": true }
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.perf.json b/tools/mb/mb_config_expectations/tryserver.chromium.perf.json index 40e660b93..b7bfdfc 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.perf.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.perf.json
@@ -13,6 +13,7 @@ "symbol_level": 1, "target_cpu": "arm64", "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -24,6 +25,7 @@ "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, "use_gnome_keyring": false, + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/mb/mb_config_expectations/tryserver.devtools-frontend.json b/tools/mb/mb_config_expectations/tryserver.devtools-frontend.json index f4b8f36..291a468 100644 --- a/tools/mb/mb_config_expectations/tryserver.devtools-frontend.json +++ b/tools/mb/mb_config_expectations/tryserver.devtools-frontend.json
@@ -8,6 +8,7 @@ "is_debug": false, "proprietary_codecs": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true, "use_siso": true } @@ -20,6 +21,7 @@ "is_debug": false, "proprietary_codecs": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true, "use_siso": true } @@ -33,6 +35,7 @@ "is_debug": false, "proprietary_codecs": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true, "use_siso": true }
diff --git a/tools/mb/mb_config_expectations/tryserver.internal.chrome.fyi.json b/tools/mb/mb_config_expectations/tryserver.internal.chrome.fyi.json index f5218fe..2ab05f8 100644 --- a/tools/mb/mb_config_expectations/tryserver.internal.chrome.fyi.json +++ b/tools/mb/mb_config_expectations/tryserver.internal.chrome.fyi.json
@@ -14,6 +14,7 @@ "system_webview_shell_package_name": "org.chromium.my_webview_shell", "target_cpu": "x86", "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -21,6 +22,7 @@ "gn_args": { "is_chrome_branded": true, "is_official_build": true, + "use_reclient": false, "use_remoteexec": true } }, @@ -30,6 +32,7 @@ "is_chrome_branded": true, "is_official_build": true, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true } }, @@ -37,6 +40,7 @@ "gn_args": { "is_chrome_branded": true, "is_official_build": true, + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/mb/mb_config_expectations/tryserver.internal.optimization_guide.json b/tools/mb/mb_config_expectations/tryserver.internal.optimization_guide.json index 134e82e9..1ebdee4 100644 --- a/tools/mb/mb_config_expectations/tryserver.internal.optimization_guide.json +++ b/tools/mb/mb_config_expectations/tryserver.internal.optimization_guide.json
@@ -7,6 +7,7 @@ "is_chrome_branded": true, "is_debug": false, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -19,6 +20,7 @@ "is_debug": false, "symbol_level": 1, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true } }, @@ -30,6 +32,7 @@ "is_chrome_branded": true, "is_debug": false, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -42,6 +45,7 @@ "is_debug": false, "symbol_level": 1, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true } }, @@ -54,6 +58,7 @@ "is_debug": false, "symbol_level": 1, "target_cpu": "x86", + "use_reclient": false, "use_remoteexec": true } }, @@ -65,6 +70,7 @@ "is_chrome_branded": true, "is_debug": false, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -78,6 +84,7 @@ "symbol_level": 1, "target_cpu": "arm64", "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -88,6 +95,7 @@ "is_debug": false, "symbol_level": 1, "target_os": "chromeos", + "use_reclient": false, "use_remoteexec": true } }, @@ -104,6 +112,7 @@ "target_cpu": "arm64", "target_environment": "device", "target_os": "ios", + "use_reclient": false, "use_remoteexec": true } }, @@ -120,6 +129,7 @@ "target_cpu": "arm64", "target_environment": "simulator", "target_os": "ios", + "use_reclient": false, "use_remoteexec": true } }, @@ -131,6 +141,7 @@ "is_chrome_branded": true, "is_debug": false, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -143,6 +154,7 @@ "is_debug": false, "symbol_level": 1, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true } }, @@ -154,6 +166,7 @@ "is_chrome_branded": true, "is_debug": false, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -166,6 +179,7 @@ "is_debug": false, "symbol_level": 1, "target_cpu": "arm64", + "use_reclient": false, "use_remoteexec": true } }, @@ -178,6 +192,7 @@ "is_debug": false, "symbol_level": 1, "target_cpu": "x86", + "use_reclient": false, "use_remoteexec": true } }, @@ -189,6 +204,7 @@ "is_chrome_branded": true, "is_debug": false, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -204,6 +220,7 @@ "is_official_build": true, "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -219,6 +236,7 @@ "is_official_build": true, "strip_absolute_paths_from_debug_symbols": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/mb/mb_config_expectations/tryserver.v8.json b/tools/mb/mb_config_expectations/tryserver.v8.json index 859c1f1..a7c80ad9 100644 --- a/tools/mb/mb_config_expectations/tryserver.v8.json +++ b/tools/mb/mb_config_expectations/tryserver.v8.json
@@ -7,6 +7,7 @@ "is_debug": false, "proprietary_codecs": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true, "use_siso": true } @@ -17,6 +18,7 @@ "is_component_build": false, "is_debug": false, "symbol_level": 0, + "use_reclient": false, "use_remoteexec": true, "use_siso": true }
diff --git a/tools/mb/mb_config_expectations/tryserver.webrtc.json b/tools/mb/mb_config_expectations/tryserver.webrtc.json index 30bb4a0a..a4c064d 100644 --- a/tools/mb/mb_config_expectations/tryserver.webrtc.json +++ b/tools/mb/mb_config_expectations/tryserver.webrtc.json
@@ -10,6 +10,7 @@ "strip_debug_info": true, "symbol_level": 0, "target_os": "android", + "use_reclient": false, "use_remoteexec": true } }, @@ -19,6 +20,7 @@ "is_component_build": false, "is_debug": false, "symbol_level": 0, + "use_reclient": false, "use_remoteexec": true } }, @@ -27,6 +29,7 @@ "is_component_build": true, "is_debug": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -38,6 +41,7 @@ "is_debug": false, "proprietary_codecs": true, "symbol_level": 0, + "use_reclient": false, "use_remoteexec": true } }, @@ -49,6 +53,7 @@ "is_debug": false, "proprietary_codecs": true, "symbol_level": 1, + "use_reclient": false, "use_remoteexec": true } }, @@ -61,6 +66,7 @@ "is_debug": false, "proprietary_codecs": true, "symbol_level": 0, + "use_reclient": false, "use_remoteexec": true } }, @@ -72,6 +78,7 @@ "proprietary_codecs": true, "symbol_level": 0, "target_cpu": "x86", + "use_reclient": false, "use_remoteexec": true } }
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index d53b944..d4c6849 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -2742,6 +2742,7 @@ <int value="38" label="Learn more about the shared highlighting feature"/> <int value="39" label="Open in new tab in group"/> <int value="40" label="Open in new window"/> + <int value="41" label="Save page"/> </enum> <!-- LINT.IfChange(ConversionCreateAggregatableReportStatus) --> @@ -12132,6 +12133,7 @@ <int value="-792079435" label="EnableAppsGridGapFeature:disabled"/> <int value="-791916053" label="FriendlierErrorDialog:disabled"/> <int value="-791778534" label="LauncherQueryHighlighting:enabled"/> + <int value="-791730714" label="NotebookLmAppPreinstall:disabled"/> <int value="-791590673" label="bookmarks-tree-view:enabled"/> <int value="-790900615" label="NtpShoppingTasksModule:disabled"/> <int value="-790544721" @@ -14369,6 +14371,7 @@ <int value="86582659" label="enable-extension-ai-data-collection"/> <int value="86900696" label="SanitizerAPIv0:enabled"/> <int value="87306743" label="VariationsFakeCrashAfterStartup:disabled"/> + <int value="88127181" label="NotebookLmAppPreinstall:enabled"/> <int value="88437020" label="FeaturePolicy:enabled"/> <int value="88863813" label="DesktopPWAsDetailedInstallDialog:enabled"/> <int value="89036875" label="DeferRendererTasksAfterInput:disabled"/> @@ -21032,6 +21035,8 @@ </int> </enum> +<!-- LINT.IfChange(OmniboxSearchEngineType) --> + <enum name="OmniboxSearchEngineType"> <int value="0" label="Other"/> <int value="1" label="AOL"/> @@ -21113,6 +21118,8 @@ <int value="77" label="McAfee"/> </enum> +<!-- LINT.ThenChange(//components/search_engines/search_engine_type.h:SearchEngineType) --> + <!-- LINT.IfChange(OnboardingUserActionMetric) --> <enum name="OnboardingUserActionMetric">
diff --git a/tools/metrics/histograms/metadata/accessibility/histograms.xml b/tools/metrics/histograms/metadata/accessibility/histograms.xml index 972a5f7..d8b93ea5 100644 --- a/tools/metrics/histograms/metadata/accessibility/histograms.xml +++ b/tools/metrics/histograms/metadata/accessibility/histograms.xml
@@ -2007,7 +2007,7 @@ </histogram> <histogram name="Accessibility.MainNodeAnnotations.AnnotationResult" - enum="MainNodeAnnotationResult" expires_after="2025-07-13"> + enum="MainNodeAnnotationResult" expires_after="2025-09-21"> <owner>abigailbklein@google.com</owner> <owner>chrome-a11y-core@google.com</owner> <summary> @@ -3359,7 +3359,7 @@ </histogram> <histogram name="Accessibility.VTTContainsStyleBlock" enum="BooleanEnabled" - expires_after="2025-06-27"> + expires_after="2025-09-21"> <owner>evliu@google.com</owner> <owner>chrome-media-ux@google.com</owner> <summary> @@ -3429,7 +3429,7 @@ </histogram> <histogram name="Accessibility.WinAPIs.UIAutomation" enum="BooleanEnabled" - expires_after="2025-07-06"> + expires_after="2025-09-21"> <owner>aleventhal@chromium.org</owner> <owner>almaher@microsoft.com</owner> <owner>benjamin.beaudry@microsoft.com</owner>
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml index 865e87d8..8b6acf3 100644 --- a/tools/metrics/histograms/metadata/android/histograms.xml +++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -2414,7 +2414,7 @@ </histogram> <histogram name="Android.InputOnViz.Viz.StateProcessingResult" - enum="InputOnVizStateProcessingResult" expires_after="2025-06-30"> + enum="InputOnVizStateProcessingResult" expires_after="2025-09-21"> <owner>kartarsingh@google.com</owner> <owner>woa-performance-team@google.com</owner> <summary> @@ -2710,7 +2710,7 @@ </histogram> <histogram name="Android.Messages.Enqueued.Hidden" enum="MessageIdentifier" - expires_after="2025-06-22"> + expires_after="2025-09-21"> <owner>lazzzis@chromium.org</owner> <owner>src/components/messages/OWNERS</owner> <summary> @@ -2897,7 +2897,7 @@ </histogram> <histogram name="Android.MultiInstance.IsSingleInstancePerTaskConfigured" - enum="Boolean" expires_after="2025-07-07"> + enum="Boolean" expires_after="2025-09-21"> <owner>nafisabedin@google.com</owner> <owner>twellington@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index 781470f..d997f3e 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -634,7 +634,7 @@ </histogram> <histogram name="Ash.AmbientMode.PhotoSource" enum="AmbientModePhotoSource" - expires_after="2025-06-30"> + expires_after="2025-09-21"> <owner>cowmoo@google.com</owner> <owner>cros-p13n-eng@google.com</owner> <summary> @@ -689,7 +689,7 @@ </histogram> <histogram name="Ash.AmbientMode.TopicSource" enum="AmbientModeTopicSource" - expires_after="2025-06-30"> + expires_after="2025-09-21"> <owner>cowmoo@google.com</owner> <owner>cros-p13n-eng@google.com</owner> <summary> @@ -738,7 +738,7 @@ </histogram> <histogram name="Ash.AmbientMode.VideoSmoothness.{Settings}" units="%" - expires_after="2025-06-30"> + expires_after="2025-09-21"> <owner>cowmoo@google.com</owner> <owner>cros-p13n-eng@chromium.org</owner> <summary> @@ -1065,7 +1065,7 @@ </histogram> <histogram name="Ash.Birch.Coral.Action" enum="CoralActionType" - expires_after="2025-07-13"> + expires_after="2025-09-21"> <owner>zxdan@chromium.org</owner> <owner>cros-coral@google.com</owner> <summary> @@ -4044,14 +4044,14 @@ </histogram> <histogram name="Ash.FullRestore.ShowFullRestoreNotification" enum="BooleanHit" - expires_after="2025-07-19"> + expires_after="2025-09-21"> <owner>sammiequon@chromium.org</owner> <owner>xdai@chromium.org</owner> <summary>Emitted every time the full restore notification shows up.</summary> </histogram> <histogram name="Ash.FullRestore.ShowInformedRestoreDialog" enum="BooleanHit" - expires_after="2025-07-19"> + expires_after="2025-09-21"> <owner>sammiequon@chromium.org</owner> <owner>xdai@chromium.org</owner> <summary>Emmited every time the informed restore dialog shows up.</summary>
diff --git a/tools/metrics/histograms/metadata/autofill/enums.xml b/tools/metrics/histograms/metadata/autofill/enums.xml index 5f6c03a..3f44cf7 100644 --- a/tools/metrics/histograms/metadata/autofill/enums.xml +++ b/tools/metrics/histograms/metadata/autofill/enums.xml
@@ -2257,55 +2257,6 @@ <int value="1" label="Suggestion Selected"/> </enum> -<enum name="AutofillLocalCardMigrationBubbleOffer"> - <int value="0" label="Show requested"/> - <int value="1" label="Shown"/> -</enum> - -<enum name="AutofillLocalCardMigrationBubbleResult"> - <int value="0" label="User explicitly accepted the bubble"/> - <int value="1" label="User explicitly closed the the bubble"/> - <int value="2" label="User did not interact with the bubble"/> - <int value="3" label="Bubble lost focus and was deactivated"/> - <int value="4" label="Bubble result unknown"/> -</enum> - -<enum name="AutofillLocalCardMigrationBubbleUserInteraction"> - <int value="0" label="User explicitly accepted bubble"/> - <int value="1" label="User explicitly denied bubble"/> - <int value="2" label="User navigated away from page while bubble showing"/> - <int value="3" label="User navigated away from page while bubble hidden"/> -</enum> - -<enum name="AutofillLocalCardMigrationDecisionMetric"> - <int value="0" label="Migration offered"/> - <int value="1" label="User used new card"/> - <int value="2" label="Failed migration prerequisites"/> - <int value="3" label="Reached max strikes"/> - <int value="4" label="No migratable cards"/> - <int value="5" label="Get upload details RPC failed"/> - <int value="6" label="All cards are unsupported"/> - <int value="7" label="Single local card"/> - <int value="8" label="User used unsupported local card"/> - <int value="9" label="Invalid legal message detected"/> -</enum> - -<enum name="AutofillLocalCardMigrationDialogOffer"> - <int value="0" label="Shown"/> - <int value="1" label="Not shown due to legal message being invalid"/> - <int value="2" label="Feedback dialog shown"/> - <int value="3" label="Feedback server error dialog shown"/> -</enum> - -<enum name="AutofillLocalCardMigrationDialogUserInteraction"> - <int value="0" label="User explicitly accepted dialog"/> - <int value="1" label="User explicitly denied dialog"/> - <int value="2" label="User clicked legal message link"/> - <int value="3" label="User clicked view card button"/> - <int value="4" label="User clicked done button"/> - <int value="5" label="User clicked delete card icon"/> -</enum> - <enum name="AutofillManageCardsPrompt"> <int value="0" label="Shown"/> <int value="1" label="Done button pressed"/> @@ -3676,13 +3627,6 @@ <!-- LINT.ThenChange(//components/autofill/ios/browser/autofill_util.h:InvalidSubmittedFormReasonIOS) --> -<enum name="LocalCardMigrationPrompt"> - <int value="0" label="Intermediate bubble shown"/> - <int value="1" label="Intermediate bubble accepted"/> - <int value="2" label="Main dialog shown"/> - <int value="3" label="Main dialog accepted"/> -</enum> - <enum name="MandatoryReauthAuthEvent"> <int value="0" label="Unknown"/> <int value="1" label="Flow started"/>
diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml index f4b51dd..ed481c5 100644 --- a/tools/metrics/histograms/metadata/autofill/histograms.xml +++ b/tools/metrics/histograms/metadata/autofill/histograms.xml
@@ -698,7 +698,6 @@ <variant name="FidoAuthentication" summary="Fido authentication (Better Auth Project)"/> <variant name="IBANSave" summary="IBAN save"/> - <variant name="LocalCardMigration" summary="Local card migration"/> <variant name="VirtualCardEnrollment" summary="virtual card enrollment"/> </variants> @@ -2541,7 +2540,7 @@ </histogram> <histogram name="Autofill.ExpirationDateFixFlowPrompt.Events" - enum="AutofillExpirationDateFixFlowPromptEvent" expires_after="2025-07-01"> + enum="AutofillExpirationDateFixFlowPromptEvent" expires_after="2025-09-21"> <owner>jsaul@google.com</owner> <owner>siashah@google.com</owner> <owner>payments-autofill-team@google.com</owner> @@ -3781,116 +3780,6 @@ </summary> </histogram> -<histogram name="Autofill.LocalCardMigrationBubbleOffer.{ShowType}" - enum="AutofillLocalCardMigrationBubbleOffer" expires_after="2025-08-31"> - <owner>siyua@chromium.org</owner> - <owner>jsaul@google.com</owner> - <summary> - Record events related to bubble showing. Logged when bubble is requested or - is actually shown to users. - </summary> - <token key="ShowType" variants="FirstShowOrReshow"/> -</histogram> - -<histogram name="Autofill.LocalCardMigrationBubbleResult.{ShowType}" - enum="AutofillLocalCardMigrationBubbleResult" expires_after="2025-08-31"> - <owner>siyua@chromium.org</owner> - <owner>jsaul@google.com</owner> - <summary> - Records whether and how the local card migration bubble was accepted or - closed. - </summary> - <token key="ShowType" variants="FirstShowOrReshow"/> -</histogram> - -<histogram name="Autofill.LocalCardMigrationBubbleUserInteraction" - enum="AutofillLocalCardMigrationBubbleUserInteraction" - expires_after="2025-07-01"> - <owner>siyua@chromium.org</owner> - <owner>jsaul@google.com</owner> - <summary>Record how bubble is closed by different user interactions.</summary> -</histogram> - -<histogram name="Autofill.LocalCardMigrationDecision" - enum="AutofillLocalCardMigrationDecisionMetric" expires_after="2025-08-31"> - <owner>sujiezhu@google.com</owner> - <owner>siyua@chromium.org</owner> - <owner>jsaul@google.com</owner> - <summary> - Record the decisions made when determining if local card migration should be - offered. - </summary> -</histogram> - -<histogram - name="Autofill.LocalCardMigrationDialogActiveDuration{AutofillLocalCardMigrationDialogDurationWithCloseEvent}" - units="ms" expires_after="2025-08-31"> - <owner>siyua@chromium.org</owner> - <owner>jsaul@google.com</owner> - <summary> - Record duration of the local card migration dialog being visible to users. - {AutofillLocalCardMigrationDialogDurationWithCloseEvent} - </summary> - <token key="AutofillLocalCardMigrationDialogDurationWithCloseEvent"> - <variant name=""/> - <variant name=".Accepted" - summary="The dialog was closed due to the user clicking the save - button."/> - <variant name=".Closed" - summary="The dialog was closed due to the user clicking the view - cards or done button."/> - <variant name=".Denied" - summary="The dialog was closed due to the user clicking the cancel - button."/> - </token> -</histogram> - -<histogram name="Autofill.LocalCardMigrationDialogOffer" - enum="AutofillLocalCardMigrationDialogOffer" expires_after="2025-08-31"> - <owner>siyua@chromium.org</owner> - <owner>jsaul@google.com</owner> - <summary> - Record events related to showing the local card migration dialog. - </summary> -</histogram> - -<histogram name="Autofill.LocalCardMigrationDialogUserInteraction" - enum="AutofillLocalCardMigrationDialogUserInteraction" - expires_after="2025-08-31"> - <owner>siyua@chromium.org</owner> - <owner>jsaul@google.com</owner> - <summary> - Record user interactions related to local card migration dialog. - </summary> -</histogram> - -<histogram name="Autofill.LocalCardMigrationDialogUserSelectionPercentage" - units="%" expires_after="2025-08-31"> - <owner>siyua@chromium.org</owner> - <owner>jsaul@google.com</owner> - <summary> - Record the percentage of cards selected by the user in the migration dialog. - </summary> -</histogram> - -<histogram - name="Autofill.LocalCardMigrationOrigin.{AutofillLocalCardMigrationOrigin}" - enum="LocalCardMigrationPrompt" expires_after="2025-08-31"> - <owner>siyua@chromium.org</owner> - <owner>jsaul@google.com</owner> - <summary> - Records when local card migration prompts are shown and/or accepted, after - being triggered from {AutofillLocalCardMigrationOrigin}. - </summary> - <token key="AutofillLocalCardMigrationOrigin"> - <variant name="SettingsPage" summary="the settings page"/> - <variant name="UseOfLocalCard" - summary="submitting a form with a local card"/> - <variant name="UseOfServerCard" - summary="submitting a form with a server card"/> - </token> -</histogram> - <histogram name="Autofill.LocalHeuristics.MatchedAttribute" enum="AutofillMatchAttribute" expires_after="2025-08-03"> <owner>fleimgruber@google.com</owner> @@ -5994,7 +5883,7 @@ <histogram name="Autofill.StrikeDatabase.CreditCardSaveNotOfferedDueToMaxStrikes" - enum="AutofillSaveType" expires_after="2025-07-01"> + enum="AutofillSaveType" expires_after="2025-09-21"> <owner>jsaul@google.com</owner> <owner>payments-autofill-team@google.com</owner> <summary> @@ -6017,17 +5906,6 @@ </histogram> <histogram - name="Autofill.StrikeDatabase.LocalCardMigrationNotOfferedDueToMaxStrikes" - enum="AutofillSaveType" expires_after="2025-08-31"> - <owner>jsaul@google.com</owner> - <owner>payments-autofill-team@google.com</owner> - <summary> - Records when local card migration is not offered due to the candidate's - LocalCardMigration strike count reaching maximum strikes. - </summary> -</histogram> - -<histogram name="Autofill.StrikeDatabase.NthStrikeAdded.{AutofillStrikeDatabaseProjectType}" units="strikes" expires_after="2025-08-31"> <owner>jsaul@google.com</owner> @@ -6065,17 +5943,6 @@ <token key="IbanTypeToBeSaved" variants="IbanTypeToBeSaved"/> </histogram> -<histogram - name="Autofill.StrikeDatabase.StrikesPresentWhenLocalCardMigrationAccepted" - units="strikes" expires_after="2025-08-31"> - <owner>jsaul@google.com</owner> - <owner>payments-autofill-team@google.com</owner> - <summary> - Records the number of "strikes" a user has when local card - migration is accepted. - </summary> -</histogram> - <histogram name="Autofill.StrikeDatabase.StrikesPresentWhenLocalCardSaved" units="strikes" expires_after="2025-08-31"> <owner>jsaul@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/blink/enums.xml b/tools/metrics/histograms/metadata/blink/enums.xml index ee2ea7d..339a29c 100644 --- a/tools/metrics/histograms/metadata/blink/enums.xml +++ b/tools/metrics/histograms/metadata/blink/enums.xml
@@ -5729,7 +5729,8 @@ <int value="5142" label="V8AILanguageModel_Destroy_Method"/> <int value="5143" label="V8AILanguageModel_Prompt_Method"/> <int value="5144" label="V8AILanguageModel_PromptStreaming_Method"/> - <int value="5145" label="V8AILanguageModel_CountPromptTokens_Method"/> + <int value="5145" + label="OBSOLETE_V8AILanguageModel_CountPromptTokens_Method"/> <int value="5146" label="V8AILanguageModelCapabilities_LanguageAvailable_Method"/> <int value="5147" @@ -5742,9 +5743,12 @@ label="V8AILanguageModelCapabilities_DefaultTemperature_AttributeGetter"/> <int value="5151" label="V8AILanguageModelFactory_Capabilities_Method"/> <int value="5152" label="V8AILanguageModelFactory_Create_Method"/> - <int value="5153" label="V8AILanguageModel_MaxTokens_AttributeGetter"/> - <int value="5154" label="V8AILanguageModel_TokensSoFar_AttributeGetter"/> - <int value="5155" label="V8AILanguageModel_TokensLeft_AttributeGetter"/> + <int value="5153" + label="OBSOLETE_V8AILanguageModel_MaxTokens_AttributeGetter"/> + <int value="5154" + label="OBSOLETE_V8AILanguageModel_TokensSoFar_AttributeGetter"/> + <int value="5155" + label="OBSOLETE_V8AILanguageModel_TokensLeft_AttributeGetter"/> <int value="5156" label="SvgContextFillOrStroke"/> <int value="5157" label="ARIAActionsAttribute"/> <int value="5158" label="OBSOLETE_ResolveToConfigValueCoercedToTrue"/> @@ -5989,6 +5993,12 @@ <int value="5383" label="AriaNotify"/> <int value="5384" label="LanguageDetector_MeasureInputUsage"/> <int value="5385" label="LanguageDetector_InputQuota"/> + <int value="5386" label="V8AILanguageModel_InputUsage_AttributeGetter"/> + <int value="5387" label="V8AILanguageModel_InputQuota_AttributeGetter"/> + <int value="5388" label="V8AILanguageModel_MeasureInputUsage_Method"/> + <int value="5389" label="CredentialsGetImmediateMediationWithWebAuthnOnly"/> + <int value="5390" + label="CredentialsGetImmediateMediationWithWebAuthnAndPasswords"/> </enum> <!-- LINT.ThenChange(//third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom:WebFeature) -->
diff --git a/tools/metrics/histograms/metadata/bluetooth/histograms.xml b/tools/metrics/histograms/metadata/bluetooth/histograms.xml index e038346..1fefce4e 100644 --- a/tools/metrics/histograms/metadata/bluetooth/histograms.xml +++ b/tools/metrics/histograms/metadata/bluetooth/histograms.xml
@@ -673,7 +673,7 @@ </histogram> <histogram name="Bluetooth.ChromeOS.FastPair.FootprintsFetcher.Delete.Result" - enum="BooleanSuccess" expires_after="2025-06-28"> + enum="BooleanSuccess" expires_after="2025-09-21"> <owner>jackshira@google.com</owner> <owner>dclasson@google.com</owner> <owner>brandosocarras@google.com</owner> @@ -1973,7 +1973,7 @@ </histogram> <histogram name="Bluetooth.Web.Characteristic.WriteValue.Outcome" - enum="WebBluetoothGATTOperationOutcome" expires_after="2025-07-21"> + enum="WebBluetoothGATTOperationOutcome" expires_after="2025-09-21"> <owner>alvinji@chromium.org</owner> <owner>deviceapi-team@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/browser/histograms.xml b/tools/metrics/histograms/metadata/browser/histograms.xml index 0cdb53dc..c5dc9fe 100644 --- a/tools/metrics/histograms/metadata/browser/histograms.xml +++ b/tools/metrics/histograms/metadata/browser/histograms.xml
@@ -467,7 +467,7 @@ <histogram name="Browser.ERP.UnuploadedCrashShouldNotReportReason" enum="EnterpriseReportingUnuploadedCrashShouldNotReportReason" - expires_after="2025-05-01"> + expires_after="2025-11-01"> <owner>lbaraz@chromium.org</owner> <owner>cros-reporting-team@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/browsing_topics/histograms.xml b/tools/metrics/histograms/metadata/browsing_topics/histograms.xml index fbc428b..a948adf 100644 --- a/tools/metrics/histograms/metadata/browsing_topics/histograms.xml +++ b/tools/metrics/histograms/metadata/browsing_topics/histograms.xml
@@ -303,7 +303,7 @@ </histogram> <histogram name="BrowsingTopics.SiteDataStorage.FileSize.KB" units="KB" - expires_after="2025-06-22"> + expires_after="2025-09-21"> <owner>yaoxia@chromium.org</owner> <owner>jkarlin@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/chrome/histograms.xml b/tools/metrics/histograms/metadata/chrome/histograms.xml index 6fbad03..a1cbec7 100644 --- a/tools/metrics/histograms/metadata/chrome/histograms.xml +++ b/tools/metrics/histograms/metadata/chrome/histograms.xml
@@ -23,7 +23,7 @@ <histograms> <histogram name="Chrome.AppMenu.MenuHostInitToNextFramePresented" units="ms" - expires_after="2025-07-13"> + expires_after="2025-09-21"> <owner>temao@chromium.org</owner> <owner>robliao@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/chromeos/histograms.xml b/tools/metrics/histograms/metadata/chromeos/histograms.xml index adc12289..dc401dd 100644 --- a/tools/metrics/histograms/metadata/chromeos/histograms.xml +++ b/tools/metrics/histograms/metadata/chromeos/histograms.xml
@@ -2451,7 +2451,7 @@ </histogram> <histogram name="ChromeOS.Intents.LinkCapturingEvent2" - enum="LinkCapturingEvent" expires_after="2025-06-01"> + enum="LinkCapturingEvent" expires_after="2025-09-21"> <owner>vpao@google.com</owner> <owner>chromeos-apps-foundation-team@google.com</owner> <summary> @@ -3270,7 +3270,7 @@ </histogram> <histogram name="ChromeOS.SAML.Provider" enum="ChromeOSSamlProvider" - expires_after="2025-07-21"> + expires_after="2025-09-21"> <owner>mslus@chromium.org</owner> <owner>cros-3pidp@google.com</owner> <summary>Records SAML provider when SAML login flow is used.</summary>
diff --git a/tools/metrics/histograms/metadata/commerce/histograms.xml b/tools/metrics/histograms/metadata/commerce/histograms.xml index 3190018..28230e2 100644 --- a/tools/metrics/histograms/metadata/commerce/histograms.xml +++ b/tools/metrics/histograms/metadata/commerce/histograms.xml
@@ -724,7 +724,7 @@ </histogram> <histogram name="Commerce.PriceTracking.PriceInsightsSidePanel.{Action}" - enum="PriceInsightsPriceBucket" expires_after="2025-07-06"> + enum="PriceInsightsPriceBucket" expires_after="2025-09-21"> <owner>yuezhanggg@chromium.org</owner> <owner>mdjones@chromium.org</owner> <summary> @@ -823,7 +823,7 @@ </histogram> <histogram name="Commerce.ShoppingService.ProductInfo.ImageAvailability" - enum="ProductImageAvailability" expires_after="2025-06-08"> + enum="ProductImageAvailability" expires_after="2025-09-21"> <owner>ayman@chromium.org</owner> <owner>mdjones@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/compositing/histograms.xml b/tools/metrics/histograms/metadata/compositing/histograms.xml index 215f227e..cf81c5b 100644 --- a/tools/metrics/histograms/metadata/compositing/histograms.xml +++ b/tools/metrics/histograms/metadata/compositing/histograms.xml
@@ -1372,7 +1372,7 @@ </histogram> <histogram name="Graphics.Smoothness.MaxPercentDroppedFrames_1sWindow" - units="%" expires_after="2025-05-11"> + units="%" expires_after="2025-09-21"> <owner>jonross@chromium.org</owner> <owner>chrome-gpu-metric-alerts@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/cookie/histograms.xml b/tools/metrics/histograms/metadata/cookie/histograms.xml index 9229670..67307a31 100644 --- a/tools/metrics/histograms/metadata/cookie/histograms.xml +++ b/tools/metrics/histograms/metadata/cookie/histograms.xml
@@ -528,7 +528,7 @@ </histogram> <histogram name="Cookie.GetCookieListWithOptions.Duration.Subsampled" - units="microseconds" expires_after="2025-07-13"> + units="microseconds" expires_after="2025-09-21"> <owner>anthonyvd@chromium.org</owner> <owner>chrome-catan@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/cras/histograms.xml b/tools/metrics/histograms/metadata/cras/histograms.xml index 14ab543..5f88f25 100644 --- a/tools/metrics/histograms/metadata/cras/histograms.xml +++ b/tools/metrics/histograms/metadata/cras/histograms.xml
@@ -469,7 +469,7 @@ </histogram> <histogram name="Cras.DlcManagerStatus.ElapsedTimeHistogramOnSuccess.{DlcType}" - units="seconds" expires_after="2025-06-22"> + units="seconds" expires_after="2025-09-21"> <owner>hunghsienchen@google.com</owner> <owner>chromeos-audio@google.com</owner> <summary> @@ -832,7 +832,7 @@ </histogram> <histogram name="Cras.RtcDevicePair" enum="CrasDevicePair" - expires_after="2025-07-13"> + expires_after="2025-09-21"> <owner>yuhsuan@chromium.org</owner> <owner>chromeos-audio@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/enterprise/enums.xml b/tools/metrics/histograms/metadata/enterprise/enums.xml index 13b339b..a7f13da 100644 --- a/tools/metrics/histograms/metadata/enterprise/enums.xml +++ b/tools/metrics/histograms/metadata/enterprise/enums.xml
@@ -2214,6 +2214,7 @@ <int value="1346" label="GenAIInlineImageSettings"/> <int value="1347" label="UserSecuritySignalsReporting"/> <int value="1348" label="UserSecurityAuthenticatedReporting"/> + <int value="1349" label="HappyEyeballsV3Enabled"/> </enum> <enum name="EnterprisePoliciesSources">
diff --git a/tools/metrics/histograms/metadata/enterprise/histograms.xml b/tools/metrics/histograms/metadata/enterprise/histograms.xml index 62fb99c..5805bfe7 100644 --- a/tools/metrics/histograms/metadata/enterprise/histograms.xml +++ b/tools/metrics/histograms/metadata/enterprise/histograms.xml
@@ -1553,7 +1553,7 @@ </histogram> <histogram name="Enterprise.Dlp.FilesWarnedCount" units="entries" - expires_after="2025-07-13"> + expires_after="2025-09-21"> <owner>ayaelattar@google.com</owner> <owner>chromeos-dlp@google.com</owner> <summary> @@ -2057,7 +2057,7 @@ </histogram> <histogram name="Enterprise.EnrollmentForcedManualFallback" - enum="EnterpriseEnrollmentType" expires_after="2025-06-01"> + enum="EnterpriseEnrollmentType" expires_after="2025-09-21"> <owner>asumaneev@google.com</owner> <owner>sergiyb@chromium.org</owner> <owner>chromeos-commercial-remote-management@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/event/histograms.xml b/tools/metrics/histograms/metadata/event/histograms.xml index 2f26474..61a877b 100644 --- a/tools/metrics/histograms/metadata/event/histograms.xml +++ b/tools/metrics/histograms/metadata/event/histograms.xml
@@ -212,7 +212,7 @@ <histogram name="Event.Jank.ScrollUpdate.{ScrollSpeed}.{VsyncStatus}.FrameAboveJankyThreshold2" - units="ratio * 100" expires_after="2025-06-22"> + units="ratio * 100" expires_after="2025-09-21"> <owner>jonross@chromium.org</owner> <owner>woa-performance@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/extensions/histograms.xml b/tools/metrics/histograms/metadata/extensions/histograms.xml index 663102e..1d83b403 100644 --- a/tools/metrics/histograms/metadata/extensions/histograms.xml +++ b/tools/metrics/histograms/metadata/extensions/histograms.xml
@@ -2364,7 +2364,7 @@ <histogram name="Extensions.ForceInstalledPreInstalledDeprecatedAppOpenUrl" enum="ExtensionForceInstalledPreInstalledDeprecatedSite" - expires_after="2025-07-06"> + expires_after="2025-09-21"> <owner>erikchen@chromium.org</owner> <owner>extensions-core@chromium.org</owner> <summary> @@ -3232,7 +3232,7 @@ </histogram> <histogram name="Extensions.InstallSource" enum="ExtensionLocation" - expires_after="2023-07-07"> + expires_after="2025-09-21"> <owner>rdevlin.cronin@chromium.org</owner> <owner>extensions-core@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/gpu/histograms.xml b/tools/metrics/histograms/metadata/gpu/histograms.xml index 322a878a..7966a70 100644 --- a/tools/metrics/histograms/metadata/gpu/histograms.xml +++ b/tools/metrics/histograms/metadata/gpu/histograms.xml
@@ -1342,7 +1342,7 @@ </histogram> <histogram name="GPU.TransferCache.ReusedTimes" units="Reuses" - expires_after="2025-06-15"> + expires_after="2025-09-21"> <owner>boliu@chromium.org</owner> <owner>chrome-gpu-metric-alerts@chromium.org</owner> <summary> @@ -1775,7 +1775,7 @@ </histogram> <histogram name="Viz.DisplayCompositor.RootDamageRect.Overlay" - enum="BooleanOverlayDamageRect" expires_after="2025-07-21"> + enum="BooleanOverlayDamageRect" expires_after="2025-09-21"> <owner>magchen@chromium.org</owner> <owner>zmo@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/history/histograms.xml b/tools/metrics/histograms/metadata/history/histograms.xml index 30aeb906..322b0378 100644 --- a/tools/metrics/histograms/metadata/history/histograms.xml +++ b/tools/metrics/histograms/metadata/history/histograms.xml
@@ -2847,7 +2847,7 @@ </histogram> <histogram name="History.VisitedLinks.TryToAddFingerprint" - enum="AddFingerprint" expires_after="2025-07-20"> + enum="AddFingerprint" expires_after="2025-09-21"> <owner>kyraseevers@chromium.org</owner> <owner>janiceliu@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/installer/histograms.xml b/tools/metrics/histograms/metadata/installer/histograms.xml index 4b5eb389..f8d3b52 100644 --- a/tools/metrics/histograms/metadata/installer/histograms.xml +++ b/tools/metrics/histograms/metadata/installer/histograms.xml
@@ -74,7 +74,7 @@ </histogram> <histogram name="Installer.Postinstall.EfiManagementEvent" - enum="ChromeOSEfiManagementEvent" expires_after="2025-07-06"> + enum="ChromeOSEfiManagementEvent" expires_after="2025-09-21"> <owner>tbrandston@google.com</owner> <owner>chromeos-flex-eng@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/ios/histograms.xml b/tools/metrics/histograms/metadata/ios/histograms.xml index f1cc5dc8..5ba731d 100644 --- a/tools/metrics/histograms/metadata/ios/histograms.xml +++ b/tools/metrics/histograms/metadata/ios/histograms.xml
@@ -2861,7 +2861,7 @@ </histogram> <histogram name="IOS.Notifications.OptInPrompt.Action" - enum="IOSNotificationsOptInActionOnPrompt" expires_after="2025-07-13"> + enum="IOSNotificationsOptInActionOnPrompt" expires_after="2025-09-21"> <owner>hiramahmood@google.com</owner> <owner>scottyoder@google.com</owner> <summary>Logs a user's action on the Notifications Opt-In Prompt.</summary> @@ -4184,7 +4184,7 @@ </histogram> <histogram name="IOS.SadTab.FileIsPDF" enum="Boolean" - expires_after="2025-07-21"> + expires_after="2025-09-21"> <owner>gambard@chromium.org</owner> <owner>bling-fundamentals@google.com</owner> <summary> @@ -4756,7 +4756,7 @@ </histogram> <histogram name="IOS.SetUpList.AllItemsCompleted" enum="Boolean" - expires_after="2025-07-06"> + expires_after="2025-09-21"> <owner>scottyoder@google.com</owner> <owner>bling-get-set-up@google.com</owner> <summary> @@ -5302,7 +5302,7 @@ </histogram> <histogram name="IOS.TabSwitcher.PinnedTabs.DragOrigin" - enum="IOSTabSwitcherDragOrigin" expires_after="2025-07-09"> + enum="IOSTabSwitcherDragOrigin" expires_after="2025-09-21"> <owner>ewannpv@chromium.org</owner> <owner>bling-team@google.com</owner> <summary>Records the origin of dropped items in the pinned tab view.</summary> @@ -5745,7 +5745,7 @@ </histogram> <histogram name="ManualFallback.PresentedOptions.AllPasswords" - units="Credentials" expires_after="2025-06-22"> + units="Credentials" expires_after="2025-09-21"> <owner>tmartino@chromium.org</owner> <owner>bling-transactions@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml index 6abc63c..89fc49c 100644 --- a/tools/metrics/histograms/metadata/media/histograms.xml +++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -531,7 +531,7 @@ </histogram> <histogram name="Media.Audio.Capture.DetectedMissingCallbacks" - enum="BooleanMissingCallbacks" expires_after="2025-07-21"> + enum="BooleanMissingCallbacks" expires_after="2025-09-21"> <owner>guidou@chromium.org</owner> <owner>olka@chromium.org</owner> <owner>webrtc-audio-uma@google.com</owner> @@ -689,7 +689,7 @@ </histogram> <histogram name="Media.Audio.Capture.SCK.ContentEnumerationTimedOut" - enum="Boolean" expires_after="2025-07-11"> + enum="Boolean" expires_after="2025-09-21"> <owner>mfoltz@chromium.org</owner> <owner>olka@chromium.org</owner> <owner>webrtc-audio-uma@google.com</owner> @@ -701,7 +701,7 @@ </histogram> <histogram name="Media.Audio.Capture.SCK.ContentEnumerationTimeMs" units="ms" - expires_after="2025-07-11"> + expires_after="2025-09-21"> <owner>mfoltz@chromium.org</owner> <owner>olka@chromium.org</owner> <owner>webrtc-audio-uma@google.com</owner> @@ -6171,7 +6171,7 @@ </histogram> <histogram name="Media.VideoCapture.Mac.Device.ReactionEffectsGesturesState" - enum="ReactionEffectsGesturesState" expires_after="2025-07-22"> + enum="ReactionEffectsGesturesState" expires_after="2025-09-21"> <owner>guidou@chromium.org</owner> <owner>video-cmi-apis@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/memory/histograms.xml b/tools/metrics/histograms/metadata/memory/histograms.xml index 26ce35f..d760a6c 100644 --- a/tools/metrics/histograms/metadata/memory/histograms.xml +++ b/tools/metrics/histograms/metadata/memory/histograms.xml
@@ -607,7 +607,7 @@ </histogram> <histogram base="true" name="Memory.Experimental.Browser2.Small" units="KB" - expires_after="2025-07-20"> + expires_after="2025-09-21"> <!-- Name completed by histogram_suffixes name="ProcessMemoryAllocatorSmall2" --> <owner>erikchen@chromium.org</owner> @@ -623,7 +623,7 @@ </histogram> <histogram base="true" name="Memory.Experimental.Browser2.Tiny" units="bytes" - expires_after="2025-07-20"> + expires_after="2025-09-21"> <!-- Name completed by histogram_suffixes name="ProcessMemoryAllocatorTiny2" --> <owner>sashamcintosh@chromium.org</owner> @@ -725,7 +725,7 @@ </histogram> <histogram base="true" name="Memory.Experimental.Gpu2.Custom" units="bytes" - expires_after="2025-07-20"> + expires_after="2025-09-21"> <!-- Name completed by histogram_suffixes name="ProcessMemoryAllocatorCustom2" --> <owner>sashamcintosh@chromium.org</owner> @@ -989,7 +989,7 @@ </histogram> <histogram base="true" name="Memory.Experimental.Renderer2.Small" units="KB" - expires_after="2025-07-20"> + expires_after="2025-09-21"> <!-- Name completed by histogram_suffixes name="ProcessMemoryAllocatorSmall2" --> <owner>erikchen@chromium.org</owner> @@ -1005,7 +1005,7 @@ </histogram> <histogram base="true" name="Memory.Experimental.Renderer2.Tiny" units="bytes" - expires_after="2025-07-20"> + expires_after="2025-09-21"> <!-- Name completed by histogram_suffixes name="ProcessMemoryAllocatorTiny2" --> <owner>sashamcintosh@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/network/histograms.xml b/tools/metrics/histograms/metadata/network/histograms.xml index 2ff3e5fb..298fb142b5 100644 --- a/tools/metrics/histograms/metadata/network/histograms.xml +++ b/tools/metrics/histograms/metadata/network/histograms.xml
@@ -1079,7 +1079,7 @@ </histogram> <histogram name="Network.Cellular.CarrierLock.FcmCommunicationResult" - enum="CellularCarrierLockFcmResult" expires_after="2025-05-15"> + enum="CellularCarrierLockFcmResult" expires_after="2025-09-21"> <owner>michamazur@google.com</owner> <owner>cros-cellular-core@google.com</owner> <summary> @@ -1088,7 +1088,7 @@ </histogram> <histogram name="Network.Cellular.CarrierLock.FcmNotificationType" - enum="CellularCarrierLockFcmNotification" expires_after="2025-05-15"> + enum="CellularCarrierLockFcmNotification" expires_after="2025-09-21"> <owner>michamazur@google.com</owner> <owner>cros-cellular-core@google.com</owner> <summary>Emitted on every notification received from FCM service.</summary> @@ -1123,7 +1123,7 @@ </histogram> <histogram name="Network.Cellular.CarrierLock.ModemConfigurationResult" - enum="CellularCarrierLockConfigurationResult" expires_after="2025-05-15"> + enum="CellularCarrierLockConfigurationResult" expires_after="2025-09-21"> <owner>michamazur@google.com</owner> <owner>cros-cellular-core@google.com</owner> <summary>Emitted each time the modem was successfully configured.</summary> @@ -1143,7 +1143,7 @@ </histogram> <histogram name="Network.Cellular.CarrierLock.ProvisioningServerResponse" - enum="CellularCarrierLockProvisioningResult" expires_after="2025-05-15"> + enum="CellularCarrierLockProvisioningResult" expires_after="2025-09-21"> <owner>michamazur@google.com</owner> <owner>cros-cellular-core@google.com</owner> <summary> @@ -1162,7 +1162,7 @@ </histogram> <histogram name="Network.Cellular.CarrierLock.{ConsecutiveFailuresType}" - units="count" expires_after="2025-05-15"> + units="count" expires_after="2025-09-21"> <owner>michamazur@google.com</owner> <owner>cros-cellular-core@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml index 7ba6e20..6a741776 100644 --- a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml +++ b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
@@ -337,7 +337,7 @@ </histogram> <histogram name="NewTabPage.Drive.FileClick" units="index" - expires_after="2025-07-21"> + expires_after="2025-09-21"> <owner>rtatum@google.com</owner> <owner>tiborg@chromium.org</owner> <owner>chrome-desktop-ntp@google.com</owner> @@ -374,7 +374,7 @@ </histogram> <histogram name="NewTabPage.FailToShowHomeSurfaceUI" - enum="FailToShowHomeSurfaceReason" expires_after="2025-07-20"> + enum="FailToShowHomeSurfaceReason" expires_after="2025-09-21"> <owner>hanxi@chromium.org</owner> <owner>xinyiji@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/oobe/histograms.xml b/tools/metrics/histograms/metadata/oobe/histograms.xml index 2693990..4a166b8d 100644 --- a/tools/metrics/histograms/metadata/oobe/histograms.xml +++ b/tools/metrics/histograms/metadata/oobe/histograms.xml
@@ -1384,7 +1384,7 @@ </histogram> <histogram name="OOBE.SyncConsentScreen.IsMinorUser" enum="Boolean" - expires_after="2025-07-06"> + expires_after="2025-09-21"> <owner>osamafathy@google.com</owner> <owner>cros-oobe@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index ecce0da..4929cba 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -572,7 +572,7 @@ <histogram name="Ads.InterestGroup.Auction.BidderWorkletIsolateTotalHeapSizeKilobytes" - units="KB" expires_after="2025-07-20"> + units="KB" expires_after="2025-09-21"> <owner>abigailkatcoff@google.com</owner> <owner>privacy-sandbox-dev@chromium.org</owner> <summary> @@ -1576,7 +1576,7 @@ <histogram name="Ads.InterestGroup.Auction.{WorkletType}.RequestWorkletServiceOutcome" - enum="RequestWorkletServiceOutcome" expires_after="2025-07-20"> + enum="RequestWorkletServiceOutcome" expires_after="2025-09-21"> <owner>abigailkatcoff@chromium.org</owner> <owner>privacy-sandbox-dev@chromium.org</owner> <summary> @@ -6194,7 +6194,7 @@ </histogram> <histogram name="Mojo.Channel.WriteToReadLatencyUs" units="microseconds" - expires_after="2025-07-20"> + expires_after="2025-09-21"> <owner>lizeb@chromium.org</owner> <owner>rockot@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/page/histograms.xml b/tools/metrics/histograms/metadata/page/histograms.xml index 5ada03f..e12d25d6 100644 --- a/tools/metrics/histograms/metadata/page/histograms.xml +++ b/tools/metrics/histograms/metadata/page/histograms.xml
@@ -1316,6 +1316,20 @@ </histogram> <histogram + name="PageLoad.Clients.GoogleSearch.NavigationTiming.InitializeStreamDelay" + units="ms" expires_after="2025-09-01"> + <owner>hayato@chromium.org</owner> + <owner>chrome-loading@google.com</owner> + <summary> + The time taken for HTTP stream initialization to finish if the + initialization was blocked, otherwise zero, for Google Search page loads. + Recorded every time HttpStream::InitializeStream() is called, for Google + Search page loads. Emitted when the navigation is completed or the app is + backgrounded on Android. + </summary> +</histogram> + +<histogram name="PageLoad.Clients.GoogleSearch.NavigationTiming.NavigationStartToFinalLoaderCallback" units="ms" expires_after="2025-08-17"> <owner>nidhijaju@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml index bd919436..76ca0794 100644 --- a/tools/metrics/histograms/metadata/password/histograms.xml +++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -659,7 +659,7 @@ </histogram> <histogram name="PasswordManager.AddCredentialFromSettings.UserAction2" - enum="AddCredentialFromSettingsUserInteractions" expires_after="2025-07-13"> + enum="AddCredentialFromSettingsUserInteractions" expires_after="2025-09-21"> <owner>vidhanj@google.com</owner> <summary> Records the user actions performed when a new credential is added from @@ -1701,7 +1701,7 @@ </histogram> <histogram name="PasswordManager.FirstWaitForUsernameReason" - enum="PasswordManagerFirstWaitForUsernameReason" expires_after="2025-06-22"> + enum="PasswordManagerFirstWaitForUsernameReason" expires_after="2025-09-21"> <owner>kazinova@google.com</owner> <owner>battre@chromium.org</owner> <summary> @@ -3680,7 +3680,7 @@ <histogram name="PasswordManager.ProcessIncomingPasswordSharingInvitationResult" enum="PasswordManager.ProcessIncomingPasswordSharingInvitationResult" - expires_after="2025-07-13"> + expires_after="2025-09-21"> <owner>mamir@chromium.org</owner> <owner>rushans@google.com</owner> <component>1457410</component> @@ -4524,6 +4524,18 @@ </summary> </histogram> +<histogram name="PasswordManager.UPM.NoGmsNoPasswordsDialogShown" + enum="BooleanShown" expires_after="2025-07-01"> + <owner>ioanap@chromium.org</owner> + <owner>atsvirchkova@google.com</owner> + <summary> + Records true whenever the dialog explaining why the password manager is no + longer available is shown to users on devices without Google Play Services. + This dialog is only shown if the users have already downloaded or don't have + passwords left over in Chrome. Android only. + </summary> +</histogram> + <histogram name="PasswordManager.UPMUpdateSignInCredentialsSucces" enum="Boolean" expires_after="2025-08-24"> <owner>izuzic@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/performance_manager/histograms.xml b/tools/metrics/histograms/metadata/performance_manager/histograms.xml index 0cfa9e7..385f8ef 100644 --- a/tools/metrics/histograms/metadata/performance_manager/histograms.xml +++ b/tools/metrics/histograms/metadata/performance_manager/histograms.xml
@@ -127,7 +127,7 @@ </histogram> <histogram name="CPU.Experimental.EstimatedFrequencyAsPercentOfMax.{CoreType}" - units="%" expires_after="2025-05-11"> + units="%" expires_after="2025-09-21"> <owner>anthonyvd@chromium.org</owner> <owner>catan-team@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/platform/histograms.xml b/tools/metrics/histograms/metadata/platform/histograms.xml index 4acce14..f122fb1 100644 --- a/tools/metrics/histograms/metadata/platform/histograms.xml +++ b/tools/metrics/histograms/metadata/platform/histograms.xml
@@ -691,7 +691,7 @@ </histogram> <histogram name="Platform.DeviceManagement.InstallAttributesStatus" - enum="InstallAttributesStatus" expires_after="2025-07-20"> + enum="InstallAttributesStatus" expires_after="2025-09-21"> <owner>sadmansakib@google.com</owner> <owner>cros-hwsec-userland-eng+uma@google.com</owner> <summary> @@ -3010,7 +3010,7 @@ </histogram> <histogram name="Platform.{GSC}.FlashLog" enum="Cr50FlashLogs" - expires_after="2025-05-11"> + expires_after="2025-09-21"> <owner>apronin@chromium.org</owner> <owner>vbendeb@chromium.org</owner> <owner>cros-hwsec+uma@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/power/histograms.xml b/tools/metrics/histograms/metadata/power/histograms.xml index 3dae0e4..bc7cd98 100644 --- a/tools/metrics/histograms/metadata/power/histograms.xml +++ b/tools/metrics/histograms/metadata/power/histograms.xml
@@ -1445,7 +1445,7 @@ </histogram> <histogram name="Power.KernelSuspendTimeOnBattery" units="ms" - expires_after="2025-06-22"> + expires_after="2025-09-21"> <owner>puthik@chromium.org</owner> <owner>mhiramat@google.com</owner> <owner>chromeos-platform-power@google.com</owner> @@ -1667,7 +1667,7 @@ </histogram> <histogram name="Power.SmartCharging.Messages" enum="SmartChargingMessages" - expires_after="2025-06-30"> + expires_after="2025-09-21"> <owner>alanlxl@chromium.org</owner> <owner>amoylan@chromium.org</owner> <summary>Type of messages that are reported by smart charging.</summary> @@ -1733,7 +1733,7 @@ </histogram> <histogram name="Power.SuspendResult" enum="SuspendResult" - expires_after="2025-06-22"> + expires_after="2025-09-21"> <owner>puthik@chromium.org</owner> <owner>chromeos-platform-power@google.com</owner> <summary> @@ -1772,7 +1772,7 @@ </histogram> <histogram name="Power.UserBrightnessAdjustmentsPerSessionOnBattery" - units="units" expires_after="2025-06-30"> + units="units" expires_after="2025-09-21"> <owner>alanlxl@chromium.org</owner> <owner>amoylan@chromium.org</owner> <owner>napper@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/printing/histograms.xml b/tools/metrics/histograms/metadata/printing/histograms.xml index 2dcae77..6e1b9cc 100644 --- a/tools/metrics/histograms/metadata/printing/histograms.xml +++ b/tools/metrics/histograms/metadata/printing/histograms.xml
@@ -231,7 +231,7 @@ </histogram> <histogram name="Printing.CUPS.NearbyNetworkDiscoveredPrintersCount" - units="printers" expires_after="2025-06-30"> + units="printers" expires_after="2025-09-21"> <owner>bmgordon@chromium.org</owner> <owner>project-bolton@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/profile/histograms.xml b/tools/metrics/histograms/metadata/profile/histograms.xml index 27774e57..869ec5f 100644 --- a/tools/metrics/histograms/metadata/profile/histograms.xml +++ b/tools/metrics/histograms/metadata/profile/histograms.xml
@@ -702,7 +702,7 @@ </histogram> <histogram name="ProfilePicker.FirstRun.OrganizationAvailableTiming" units="ms" - expires_after="2025-06-08"> + expires_after="2025-09-21"> <owner>dgn@chromium.org</owner> <owner>chrome-signin-team@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml index 21e1e0f..0f1a3488 100644 --- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml +++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -2260,7 +2260,7 @@ </histogram> <histogram name="SafeBrowsing.Pref.Daily.Extended" enum="BooleanEnabled" - expires_after="2025-07-13"> + expires_after="2025-09-21"> <owner>xinghuilu@chromium.org</owner> <owner>chrome-counter-abuse-alerts@google.com</owner> <summary> @@ -3196,7 +3196,7 @@ </histogram> <histogram name="SafeBrowsing.Triggers.SuspiciousSite.Event" - enum="SuspiciousSiteTriggerEvent" expires_after="2025-05-11"> + enum="SuspiciousSiteTriggerEvent" expires_after="2025-09-21"> <owner>vakh@chromium.org</owner> <owner>chrome-counter-abuse-alerts@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/security/histograms.xml b/tools/metrics/histograms/metadata/security/histograms.xml index 5b8f169..bc45a47 100644 --- a/tools/metrics/histograms/metadata/security/histograms.xml +++ b/tools/metrics/histograms/metadata/security/histograms.xml
@@ -331,7 +331,7 @@ </histogram> <histogram name="Security.JSONParser.ParsingTime" units="microseconds" - expires_after="2025-07-20"> + expires_after="2025-09-21"> <owner>djmitche@chromium.org</owner> <owner>chrome-platform-security@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/settings/enums.xml b/tools/metrics/histograms/metadata/settings/enums.xml index 10d6c296..c9ef909 100644 --- a/tools/metrics/histograms/metadata/settings/enums.xml +++ b/tools/metrics/histograms/metadata/settings/enums.xml
@@ -110,6 +110,7 @@ <int value="6" label="Site not disruptive"/> <int value="7" label="Revoke notification"/> <int value="8" label="Notification not revoked because of default block"/> + <int value="9" label="Previously marked as false positive"/> </enum> <!-- LINT.ThenChange(//chrome/browser/ui/safety_hub/disruptive_notification_permissions_manager.h:RevocationResult) -->
diff --git a/tools/metrics/histograms/metadata/settings/histograms.xml b/tools/metrics/histograms/metadata/settings/histograms.xml index de62af0..22ac4431 100644 --- a/tools/metrics/histograms/metadata/settings/histograms.xml +++ b/tools/metrics/histograms/metadata/settings/histograms.xml
@@ -233,7 +233,7 @@ </histogram> <histogram name="Settings.ClearBrowsingData.OpenMyActivity" - enum="ClearBrowsingDataMyActivityNavigation" expires_after="2025-07-20"> + enum="ClearBrowsingDataMyActivityNavigation" expires_after="2025-09-21"> <owner>andzaytsev@google.com</owner> <owner>chrome-privacy-controls@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/signin/histograms.xml b/tools/metrics/histograms/metadata/signin/histograms.xml index f2a2bec..619ece1 100644 --- a/tools/metrics/histograms/metadata/signin/histograms.xml +++ b/tools/metrics/histograms/metadata/signin/histograms.xml
@@ -795,7 +795,7 @@ <histogram name="Signin.BoundSessionCredentials.CookieRotationOutageAttempts{Interval}" - units="requests" expires_after="2025-05-11"> + units="requests" expires_after="2025-09-21"> <owner>alexilin@chromium.org</owner> <owner>msalama@chromium.org</owner> <owner>chrome-signin-team@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/sync/histograms.xml b/tools/metrics/histograms/metadata/sync/histograms.xml index 85f709ae..de36e1a9 100644 --- a/tools/metrics/histograms/metadata/sync/histograms.xml +++ b/tools/metrics/histograms/metadata/sync/histograms.xml
@@ -441,7 +441,7 @@ </histogram> <histogram name="Sync.ConfigureDataTypeManager.IsGaiaAccountId" enum="Boolean" - expires_after="2025-07-22"> + expires_after="2025-09-21"> <owner>rushans@google.com</owner> <owner>mastiz@chromium.org</owner> <summary> @@ -802,7 +802,7 @@ </histogram> <histogram name="Sync.DataTypeMetadataConsistency{SyncDataType}" - enum="SyncMetadataConsistency" expires_after="2025-07-22"> + enum="SyncMetadataConsistency" expires_after="2025-09-21"> <owner>rushans@google.com</owner> <owner>mastiz@chromium.org</owner> <summary> @@ -1842,7 +1842,7 @@ </histogram> <histogram name="Sync.SyncableServiceStartTime{SyncDataType}" units="ms" - expires_after="2025-07-23"> + expires_after="2025-09-21"> <owner>ankushkush@google.com</owner> <owner>treib@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/tab/histograms.xml b/tools/metrics/histograms/metadata/tab/histograms.xml index 53f6f503..3a54dbca 100644 --- a/tools/metrics/histograms/metadata/tab/histograms.xml +++ b/tools/metrics/histograms/metadata/tab/histograms.xml
@@ -2669,7 +2669,7 @@ </histogram> <histogram name="Tabs.TabAutoDeleted.AfterNDays" units="days" - expires_after="2025-07-06"> + expires_after="2025-09-21"> <owner>wylieb@google.com</owner> <owner>clank-tab-dev@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/ui/histograms.xml b/tools/metrics/histograms/metadata/ui/histograms.xml index f0ad092..c7e47532 100644 --- a/tools/metrics/histograms/metadata/ui/histograms.xml +++ b/tools/metrics/histograms/metadata/ui/histograms.xml
@@ -602,7 +602,7 @@ </histogram> <histogram name="WebUI.TopChrome.Preload.Result" enum="WebUIPreloadResult" - expires_after="2025-07-06"> + expires_after="2025-09-21"> <owner>kerenzhu@chromium.org</owner> <owner>dayeung@chromium.org</owner> <owner>elainechien@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/user_education/histograms.xml b/tools/metrics/histograms/metadata/user_education/histograms.xml index 515afd7..449eae9 100644 --- a/tools/metrics/histograms/metadata/user_education/histograms.xml +++ b/tools/metrics/histograms/metadata/user_education/histograms.xml
@@ -206,7 +206,7 @@ </histogram> <histogram name="UserEducation.MessageNotShown.TimeInQueue" units="ms" - expires_after="2025-06-29"> + expires_after="2025-09-21"> <owner>dfried@chromium.org</owner> <owner>frizzle-team@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/web_core/histograms.xml b/tools/metrics/histograms/metadata/web_core/histograms.xml index 909d72a..d6452c80 100644 --- a/tools/metrics/histograms/metadata/web_core/histograms.xml +++ b/tools/metrics/histograms/metadata/web_core/histograms.xml
@@ -63,7 +63,7 @@ </variants> <histogram name="WebCore.DistillabilityUs" units="microseconds" - expires_after="2025-07-20"> + expires_after="2025-09-21"> <owner>wychen@chromium.org</owner> <owner>gilmanmh@google.com</owner> <summary> @@ -506,7 +506,7 @@ </histogram> <histogram name="WebCore.IndexedDB.RequestDuration2.{RequestType}.Foreground" - units="ms" expires_after="2025-07-20"> + units="ms" expires_after="2025-09-21"> <owner>estade@chromium.org</owner> <owner>chrome-owp-storage@google.com</owner> <summary> @@ -550,7 +550,7 @@ <histogram name="WebCore.IndexedDB.Transaction.{TransactionType}.TimeActive2.Foreground" - units="ms" expires_after="2025-07-20"> + units="ms" expires_after="2025-09-21"> <owner>estade@chromium.org</owner> <owner>chrome-owp-storage@google.com</owner> <summary> @@ -580,7 +580,7 @@ <histogram name="WebCore.IndexedDB.Transaction.{TransactionType}.TimeQueued.Foreground" - units="ms" expires_after="2025-07-20"> + units="ms" expires_after="2025-09-21"> <owner>estade@chromium.org</owner> <owner>chrome-owp-storage@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/webapps/histograms.xml b/tools/metrics/histograms/metadata/webapps/histograms.xml index 08f9de7..612deab 100644 --- a/tools/metrics/histograms/metadata/webapps/histograms.xml +++ b/tools/metrics/histograms/metadata/webapps/histograms.xml
@@ -1376,7 +1376,7 @@ </histogram> <histogram name="WebApp.Isolated.UpdateError" enum="IsolatedWebAppUpdateError" - expires_after="2025-05-31"> + expires_after="2025-09-21"> <owner>giovax@chromium.org</owner> <owner>pwa-commercial@google.com</owner> <owner>src/chrome/browser/web_applications/isolated_web_apps/OWNERS</owner> @@ -1391,7 +1391,7 @@ </histogram> <histogram name="WebApp.Isolated.UpdateSuccess" enum="BooleanSuccess" - expires_after="2025-05-31"> + expires_after="2025-09-21"> <owner>giovax@chromium.org</owner> <owner>pwa-commercial@google.com</owner> <owner>src/chrome/browser/web_applications/isolated_web_apps/OWNERS</owner>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index f5f1bf8..3aab4def 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,8 +5,8 @@ "full_remote_path": "perfetto-luci-artifacts/v49.0/linux-arm64/trace_processor_shell" }, "win": { - "hash": "cb65fbf856cb42191c522ed9bdf17f23e4784424", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/c5f3bbf49aeafaed9cf434934e9a7a3a8f94d945/trace_processor_shell.exe" + "hash": "6b1d75b3ae56cffe9a805acefa8bea96f0eabf96", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/13e3bb887312ff2cc65bfd33f2799149efa00ac9/trace_processor_shell.exe" }, "linux_arm": { "hash": "a15d8362d80cfd7cd8d785cf6afc22586de688cd", @@ -21,8 +21,8 @@ "full_remote_path": "perfetto-luci-artifacts/v49.0/mac-arm64/trace_processor_shell" }, "linux": { - "hash": "ed5ab746111d9c151a33e5911f2a7c83bf189b88", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/c5f3bbf49aeafaed9cf434934e9a7a3a8f94d945/trace_processor_shell" + "hash": "332aa7f4b85f1a0fd7c26c846381815612fea908", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/13e3bb887312ff2cc65bfd33f2799149efa00ac9/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/pgo/generate_profile.py b/tools/pgo/generate_profile.py index 582d34c..d844f35 100755 --- a/tools/pgo/generate_profile.py +++ b/tools/pgo/generate_profile.py
@@ -85,6 +85,7 @@ # The following are bot-specific args. isolated_script_test_output: Optional[str] isolated_script_test_perf_output: Optional[str] + android_hostname: str def parse_args(): @@ -153,6 +154,8 @@ help='Output.json file that the script can write to.') parser.add_argument('--isolated-script-test-perf-output', help='Deprecated and ignored, but bots pass it.') + parser.add_argument("--android-hostname", + help="Run benchmarks with adb hostname.") # ▲▲▲▲▲ Please update OptionsNamespace when adding or modifying args. ▲▲▲▲▲ args = parser.parse_args(namespace=OptionsNamespace()) @@ -303,6 +306,10 @@ cmd += ['--assume-browser-already-installed'] else: _android_browser_installed = True + + if args.android_hostname: + cmd += [f"--android={args.android_hostname}"] + _LOGGER.debug( f"Running benchmark on Android with command: {' '.join(cmd)}") else:
diff --git a/tools/typescript/definitions/autofill_private.d.ts b/tools/typescript/definitions/autofill_private.d.ts index 5e98e0e4..8489a6f5 100644 --- a/tools/typescript/definitions/autofill_private.d.ts +++ b/tools/typescript/definitions/autofill_private.d.ts
@@ -256,7 +256,6 @@ export function getCreditCardList(): Promise<CreditCardEntry[]>; export function getIbanList(): Promise<IbanEntry[]>; export function isValidIban(ibanValue: string): Promise<boolean>; - export function migrateCreditCards(): void; export function logServerCardLinkClicked(): void; export function logServerIbanLinkClicked(): void; export function addVirtualCard(cardId: string): void;
diff --git a/ui/accessibility/platform/ax_platform_node_cocoa.h b/ui/accessibility/platform/ax_platform_node_cocoa.h index df89eab..8a5a3aeb 100644 --- a/ui/accessibility/platform/ax_platform_node_cocoa.h +++ b/ui/accessibility/platform/ax_platform_node_cocoa.h
@@ -73,7 +73,7 @@ + (NSString*)nativeNotificationFromAXEvent:(ax::mojom::Event)event; - (instancetype)initWithNode:(ui::AXPlatformNodeBase*)node; -- (void)detach; +- (void)detachAndNotifyDestroyed:(BOOL)shouldNotify; // Returns this node's internal role, i.e. the one that is stored in // the internal accessibility tree as opposed to the platform tree.
diff --git a/ui/accessibility/platform/ax_platform_node_cocoa.mm b/ui/accessibility/platform/ax_platform_node_cocoa.mm index 9fef3338..89e0792 100644 --- a/ui/accessibility/platform/ax_platform_node_cocoa.mm +++ b/ui/accessibility/platform/ax_platform_node_cocoa.mm
@@ -1019,12 +1019,14 @@ return self; } -- (void)detach { +- (void)detachAndNotifyDestroyed:(BOOL)shouldNotify { if (!_node) return; _node = nil; - NSAccessibilityPostNotification( - self, NSAccessibilityUIElementDestroyedNotification); + if (shouldNotify) { + NSAccessibilityPostNotification( + self, NSAccessibilityUIElementDestroyedNotification); + } } - (NSRect)boundsInScreen {
diff --git a/ui/accessibility/platform/ax_platform_node_mac.mm b/ui/accessibility/platform/ax_platform_node_mac.mm index 888fb49..c45959a 100644 --- a/ui/accessibility/platform/ax_platform_node_mac.mm +++ b/ui/accessibility/platform/ax_platform_node_mac.mm
@@ -70,7 +70,7 @@ void AXPlatformNodeMac::Destroy() { if (objc_storage_->native_node) { - [objc_storage_->native_node detach]; + [objc_storage_->native_node detachAndNotifyDestroyed:YES]; // Also, clear the pointer to make accidental use-after-free impossible. objc_storage_->native_node = nil; }
diff --git a/ui/accessibility/platform/browser_accessibility_cocoa.h b/ui/accessibility/platform/browser_accessibility_cocoa.h index 6d4814a..b4e1cf1 100644 --- a/ui/accessibility/platform/browser_accessibility_cocoa.h +++ b/ui/accessibility/platform/browser_accessibility_cocoa.h
@@ -57,7 +57,7 @@ // Clear this object's pointer to the wrapped BrowserAccessibility object // because the wrapped object has been deleted, but this object may // persist if the system still has references to it. -- (void)detach; +- (void)detachAndNotifyDestroyed:(BOOL)shouldNotify; // Invalidate children for a non-ignored ancestor (including self). - (void)childrenChanged;
diff --git a/ui/accessibility/platform/browser_accessibility_cocoa.mm b/ui/accessibility/platform/browser_accessibility_cocoa.mm index f4af734..551cc7ce 100644 --- a/ui/accessibility/platform/browser_accessibility_cocoa.mm +++ b/ui/accessibility/platform/browser_accessibility_cocoa.mm
@@ -586,12 +586,12 @@ return self; } -- (void)detach { +- (void)detachAndNotifyDestroyed:(BOOL)shouldNotify { if (!_owner) return; _owner = nullptr; - [super detach]; + [super detachAndNotifyDestroyed:shouldNotify]; } // Returns an array of BrowserAccessibilityCocoa objects, representing the
diff --git a/ui/accessibility/platform/browser_accessibility_mac.mm b/ui/accessibility/platform/browser_accessibility_mac.mm index 1bd8097..366fda2d 100644 --- a/ui/accessibility/platform/browser_accessibility_mac.mm +++ b/ui/accessibility/platform/browser_accessibility_mac.mm
@@ -88,6 +88,9 @@ new_native_obj, NSAccessibilityFocusedUIElementChangedNotification); } + // Detach the old native wrapper to avoid UAF, but suppress the notification + // so it won't interfere the VO changing focus to the new native object. + [old_native_obj detachAndNotifyDestroyed:NO]; // Postpone the old native wrapper destruction. It will be destroyed after // a delay so that VO is securely on the new focus first (otherwise the focus // event will not be announced). @@ -98,9 +101,9 @@ FROM_HERE, base::BindOnce( [](AXPlatformNodeCocoa* destroyed) { - if (destroyed && [destroyed instanceActive]) { - // Follow destruction pattern from NativeReleaseReference(). - [destroyed detach]; + if (destroyed) { + NSAccessibilityPostNotification( + destroyed, NSAccessibilityUIElementDestroyedNotification); } }, old_native_obj),
diff --git a/ui/display/BUILD.gn b/ui/display/BUILD.gn index eea9eb9..e598004 100644 --- a/ui/display/BUILD.gn +++ b/ui/display/BUILD.gn
@@ -94,6 +94,8 @@ "win/screen_win.h", "win/screen_win_display.cc", "win/screen_win_display.h", + "win/screen_win_headless.cc", + "win/screen_win_headless.h", "win/uwp_text_scale_factor.cc", "win/uwp_text_scale_factor.h", ] @@ -132,7 +134,10 @@ if (is_win) { # Don't conflict with Windows' "display.dll". output_name = "ui_display" - deps += [ "//ui/gfx/mojom:dxgi_info" ] + deps += [ + "//components/headless/screen_info", + "//ui/gfx/mojom:dxgi_info", + ] libs = [ "shcore.lib" ] ldflags = [ "/DELAYLOAD:shcore.dll" ] } @@ -285,6 +290,7 @@ if (is_win) { sources += [ "win/scaling_util_unittest.cc", + "win/screen_win_headless_unittest.cc", "win/screen_win_unittest.cc", ] } @@ -314,6 +320,10 @@ sources += [ "display_change_notifier_unittest.cc" ] } + if (is_win) { + deps += [ "//components/headless/screen_info" ] + } + if (is_chromeos) { sources += [ "manager/apply_content_protection_task_unittest.cc",
diff --git a/ui/display/win/DEPS b/ui/display/win/DEPS new file mode 100644 index 0000000..8371ff6 --- /dev/null +++ b/ui/display/win/DEPS
@@ -0,0 +1,5 @@ +specific_include_rules = { + "screen_win_headless.*\.cc": [ + "+components/headless/screen_info" + ] + }
diff --git a/ui/display/win/display_info.cc b/ui/display/win/display_info.cc index ab47557..1fe31906b 100644 --- a/ui/display/win/display_info.cc +++ b/ui/display/win/display_info.cc
@@ -13,6 +13,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "ui/display/win/display_config_helper.h" +#include "ui/display/win/screen_win_headless.h" namespace display::win::internal { @@ -49,20 +50,32 @@ label_(label), device_name_(FixedArrayToStringView(monitor_info.szDevice)) {} -DisplayInfo::DisplayInfo(const DisplayInfo& other) { - id_ = other.id_; - screen_rect_ = other.screen_rect_; - screen_work_rect_ = other.screen_work_rect_; - device_scale_factor_ = other.device_scale_factor_; - sdr_white_level_ = other.sdr_white_level_; - rotation_ = other.rotation_; - display_frequency_ = other.display_frequency_; - pixels_per_inch_ = other.pixels_per_inch_; - output_technology_ = other.output_technology_; - label_ = other.label_; - device_name_ = other.device_name_; +DisplayInfo::DisplayInfo( + int64_t id, + const MONITORINFOEX& monitor_info, + float device_scale_factor, + float sdr_white_level, + Display::Rotation rotation, + float display_frequency, + const gfx::Vector2dF& pixels_per_inch, + DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY output_technology, + const std::string& label) + : id_(id), + screen_rect_(monitor_info.rcMonitor), + screen_work_rect_(monitor_info.rcWork), + device_scale_factor_(device_scale_factor), + sdr_white_level_(sdr_white_level), + rotation_(rotation), + display_frequency_(display_frequency), + pixels_per_inch_(pixels_per_inch), + output_technology_(output_technology), + label_(label), + device_name_(FixedArrayToStringView(monitor_info.szDevice)) { + CHECK(VerifyHeadlessDisplayDeviceName(id, monitor_info)); } +DisplayInfo::DisplayInfo(const DisplayInfo& other) = default; + DisplayInfo::~DisplayInfo() = default; // static
diff --git a/ui/display/win/display_info.h b/ui/display/win/display_info.h index e97ea41..787ec93 100644 --- a/ui/display/win/display_info.h +++ b/ui/display/win/display_info.h
@@ -25,6 +25,19 @@ const gfx::Vector2dF& pixels_per_inch, DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY output_technology, const std::string& label); + + // This should only be used in headless mode when synthesized display ids are + // used in place of the ones derived from the real monitor information. + DisplayInfo(int64_t id, + const MONITORINFOEX& monitor_info, + float device_scale_factor, + float sdr_white_level, + Display::Rotation rotation, + float display_frequency, + const gfx::Vector2dF& pixels_per_inch, + DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY output_technology, + const std::string& label); + DisplayInfo(const DisplayInfo& other); ~DisplayInfo();
diff --git a/ui/display/win/screen_win.cc b/ui/display/win/screen_win.cc index fa26c22..3a0dc73 100644 --- a/ui/display/win/screen_win.cc +++ b/ui/display/win/screen_win.cc
@@ -773,8 +773,10 @@ } // static -int64_t ScreenWin::DisplayIdFromMonitorInfo(const MONITORINFOEX& monitor) { - return internal::DisplayInfo::DisplayIdFromMonitorInfo(monitor); +int64_t ScreenWin::DisplayIdFromMonitorInfo(const MONITORINFOEX& monitor_info) { + return g_instance + ? g_instance->GetDisplayIdFromMonitorInfo(monitor_info) + : internal::DisplayInfo::DisplayIdFromMonitorInfo(monitor_info); } // static @@ -999,6 +1001,11 @@ return MonitorInfoFromHMONITOR(::MonitorFromWindow(hwnd, default_options)); } +int64_t ScreenWin::GetDisplayIdFromMonitorInfo( + const MONITORINFOEX& monitor_info) const { + return internal::DisplayInfo::DisplayIdFromMonitorInfo(monitor_info); +} + HWND ScreenWin::GetRootWindow(HWND hwnd) const { return ::GetAncestor(hwnd, GA_ROOT); }
diff --git a/ui/display/win/screen_win.h b/ui/display/win/screen_win.h index 19aefcf..4de3099 100644 --- a/ui/display/win/screen_win.h +++ b/ui/display/win/screen_win.h
@@ -157,7 +157,7 @@ static ScreenWinDisplay GetScreenWinDisplayWithDisplayId(int64_t id); // Returns the display id for the given monitor info. - static int64_t DisplayIdFromMonitorInfo(const MONITORINFOEX& monitor); + static int64_t DisplayIdFromMonitorInfo(const MONITORINFOEX& monitor_info); // Updates the display infos to make sure they have the right scale factors. // This is called before handling WM_DPICHANGED messages, to be sure that we @@ -221,7 +221,7 @@ void UpdateFromDisplayInfos( const std::vector<internal::DisplayInfo>& display_infos); - // Virtual to support mocking by unit tests. + // Virtual to support mocking by unit tests and headless screen. virtual std::optional<MONITORINFOEX> MonitorInfoFromScreenPoint( const gfx::Point& screen_point) const; virtual std::optional<MONITORINFOEX> MonitorInfoFromScreenRect( @@ -229,17 +229,15 @@ virtual std::optional<MONITORINFOEX> MonitorInfoFromWindow( HWND hwnd, DWORD default_options) const; + virtual int64_t GetDisplayIdFromMonitorInfo( + const MONITORINFOEX& monitor_info) const; virtual HWND GetRootWindow(HWND hwnd) const; virtual int GetSystemMetrics(int metric) const; - - private: - void Initialize(); - void OnWndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); - void UpdateAllDisplaysAndNotify(); - void UpdateAllDisplaysIfPrimaryMonitorChanged(); + virtual void UpdateAllDisplaysAndNotify(); + virtual void UpdateAllDisplaysIfPrimaryMonitorChanged(); // Returns the ScreenWinDisplay closest to or enclosing |hwnd|. - ScreenWinDisplay GetScreenWinDisplayNearestHWND(HWND hwnd) const; + virtual ScreenWinDisplay GetScreenWinDisplayNearestHWND(HWND hwnd) const; // Returns the ScreenWinDisplay closest to or enclosing |screen_rect|. ScreenWinDisplay GetScreenWinDisplayNearestScreenRect( @@ -258,11 +256,16 @@ const gfx::Rect& dip_rect) const; // Returns the ScreenWinDisplay corresponding to the primary monitor. - ScreenWinDisplay GetPrimaryScreenWinDisplay() const; + virtual ScreenWinDisplay GetPrimaryScreenWinDisplay() const; - ScreenWinDisplay GetScreenWinDisplay( + // Returns the ScreenWinDisplay corresponding to the given monitor info. + virtual ScreenWinDisplay GetScreenWinDisplay( std::optional<MONITORINFOEX> monitor_info) const; + private: + void Initialize(); + void OnWndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam); + // Returns the result of calling |getter| with |value| on the global // ScreenWin if it exists, otherwise return the default ScreenWinDisplay. template <typename Getter, typename GetterType>
diff --git a/ui/display/win/screen_win_headless.cc b/ui/display/win/screen_win_headless.cc new file mode 100644 index 0000000..d788995b --- /dev/null +++ b/ui/display/win/screen_win_headless.cc
@@ -0,0 +1,363 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/display/win/screen_win_headless.h" + +#include <windows.h> + +#include <vector> + +#include "base/strings/strcat.h" +#include "base/strings/string_number_conversions_win.h" +#include "base/strings/string_util_win.h" +#include "components/headless/screen_info/headless_screen_info.h" +#include "ui/display/display_finder.h" +#include "ui/display/win/display_info.h" +#include "ui/display/win/dpi.h" + +namespace display::win { + +namespace { + +// Headless display ids are synthesized sequential numbers. +constexpr int64_t kHeadlessDisplayIdBase = 1; + +// Headless display device names are fakes that look similar to the real display +// device names. +constexpr WCHAR kHeadlessDisplayDeviceNamePrefix[] = LR"(\\.\HEADLESS_DISPLAY)"; + +std::wstring GetHeadlessDisplayDeviceNameFromDisplayId(int64_t id) { + return base::StrCat( + {kHeadlessDisplayDeviceNamePrefix, base::NumberToWString(id)}); +} + +int64_t GetHeadlessDisplayIdFromMonitorInfo(const MONITORINFOEX& monitor_info) { + CHECK(base::StartsWith(monitor_info.szDevice, + kHeadlessDisplayDeviceNamePrefix)); + int64_t id; + CHECK(base::StringToInt64( + &monitor_info.szDevice[std::size(kHeadlessDisplayDeviceNamePrefix) - 1], + &id)); + + return id; +} + +gfx::Vector2dF GetDisplayPhysicalPixelsPerInch(float device_scaling_factor) { + const int dpi = GetDPIFromScalingFactor(device_scaling_factor); + return gfx::Vector2dF(dpi, dpi); +} + +} // namespace + +ScreenWinHeadless::ScreenWinHeadless( + const std::vector<headless::HeadlessScreenInfo>& screen_infos) + : ScreenWin(/*initialize_from_system=*/false) { + CHECK(!screen_infos.empty()); + + UpdateFromDisplayInfos(DisplayInfosFromScreenInfo(screen_infos)); +} + +ScreenWinHeadless::~ScreenWinHeadless() = default; + +void ScreenWinHeadless::SetCursorScreenPointForTesting( + const gfx::Point& point) { + cursor_screen_point_ = point; +} + +gfx::Point ScreenWinHeadless::GetCursorScreenPoint() { + return cursor_screen_point_; +} + +bool ScreenWinHeadless::IsWindowUnderCursor(gfx::NativeWindow window) { + return GetWindowAtScreenPoint(GetCursorScreenPoint()) == window; +} + +gfx::NativeWindow ScreenWinHeadless::GetWindowAtScreenPoint( + const gfx::Point& point) { + // TODO(https://crbug.com/405276019): verify... + const std::vector<gfx::NativeWindow> windows = + GetNativeWindowsAtScreenPoint(point); + return !windows.empty() ? windows[0] : nullptr; +} + +gfx::NativeWindow ScreenWinHeadless::GetLocalProcessWindowAtPoint( + const gfx::Point& point, + const std::set<gfx::NativeWindow>& ignore) { + // TODO(https://crbug.com/405276019): verify... + for (gfx::NativeWindow window : GetNativeWindowsAtScreenPoint(point)) { + if (ignore.find(window) == ignore.end()) { + return window; + } + } + + return nullptr; +} + +int ScreenWinHeadless::GetNumDisplays() const { + return GetAllDisplays().size(); +} + +const std::vector<Display>& ScreenWinHeadless::GetAllDisplays() const { + return ScreenWin::GetAllDisplays(); +} + +Display ScreenWinHeadless::GetDisplayNearestWindow( + gfx::NativeWindow window) const { + if (window) { + return GetDisplayFromScreenRect(GetNativeWindowBoundsInScreen(window)); + } + + return GetPrimaryDisplay(); +} + +Display ScreenWinHeadless::GetDisplayNearestPoint( + const gfx::Point& point) const { + return GetDisplayFromScreenPoint(point); +} + +Display ScreenWinHeadless::GetDisplayMatching( + const gfx::Rect& match_rect) const { + return GetDisplayFromScreenRect(match_rect); +} + +Display ScreenWinHeadless::GetPrimaryDisplay() const { + // In headless the primary display is always the first display. + return GetNumDisplays() ? GetAllDisplays()[0] : Display::GetDefaultDisplay(); +} + +std::optional<MONITORINFOEX> ScreenWinHeadless::MonitorInfoFromScreenPoint( + const gfx::Point& screen_point) const { + // ScreenWin::MonitorInfoFromScreenPoint() uses Win32 ::MonitorFromPoint() + // with MONITOR_DEFAULTTONEAREST flag. + if (const Display* display = + FindDisplayNearestPoint(GetAllDisplays(), screen_point)) { + return GetMONITORINFOFromDisplayId(display->id()); + } + + return std::nullopt; +} + +std::optional<MONITORINFOEX> ScreenWinHeadless::MonitorInfoFromScreenRect( + const gfx::Rect& screen_rect) const { + // ScreenWin::MonitorInfoFromScreenRect() uses Win32 ::MonitorFromRect() with + // MONITOR_DEFAULTTONEAREST flag. + if (const Display* display = + FindDisplayWithBiggestIntersection(GetAllDisplays(), screen_rect)) { + return GetMONITORINFOFromDisplayId(display->id()); + } + + if (const Display* display = FindDisplayNearestPoint( + GetAllDisplays(), screen_rect.CenterPoint())) { + return GetMONITORINFOFromDisplayId(display->id()); + } + + return std::nullopt; +} + +std::optional<MONITORINFOEX> ScreenWinHeadless::MonitorInfoFromWindow( + HWND hwnd, + DWORD default_options) const { + CHECK(hwnd); + const gfx::Rect bounds = GetHeadlessWindowBounds(hwnd); + + // ScreenWin::MonitorInfoFromWindow() calls Win32 ::MonitorFromWindow() so + // replicate its behavior according to + // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-monitorfromwindow + if (const Display* display = + FindDisplayWithBiggestIntersection(GetAllDisplays(), bounds)) { + return GetMONITORINFOFromDisplayId(display->id()); + } + + if (default_options == MONITOR_DEFAULTTONEAREST) { + if (const Display* display = + FindDisplayNearestPoint(GetAllDisplays(), bounds.CenterPoint())) { + return GetMONITORINFOFromDisplayId(display->id()); + } + } else if (default_options == MONITOR_DEFAULTTOPRIMARY) { + return GetMONITORINFOFromDisplayId(GetPrimaryDisplay().id()); + } + + return std::nullopt; +} + +HWND ScreenWinHeadless::GetRootWindow(HWND hwnd) const { + // Headless windows don't have hierarchy, so return self. + return hwnd; +} + +int64_t ScreenWinHeadless::GetDisplayIdFromMonitorInfo( + const MONITORINFOEX& monitor_info) const { + // This will crash if called with the real Windows monitor info. + return GetHeadlessDisplayIdFromMonitorInfo(monitor_info); +} + +void ScreenWinHeadless::UpdateAllDisplaysAndNotify() { + // Ignore all display update requests because the underlying implementation + // requests display infos from the system and overrides headless screen + // configuration. Headless screen configuration is defined in ctor and never + // changes. +} + +void ScreenWinHeadless::UpdateAllDisplaysIfPrimaryMonitorChanged() { + // Headless primary monitor never changes, so intercept and ignore. +} + +void ScreenWinHeadless::OnColorProfilesChanged() { + // Just ignore as we don't expect any on the fly color profile changes in + // headless mode. +} + +std::vector<gfx::NativeWindow> ScreenWinHeadless::GetNativeWindowsAtScreenPoint( + const gfx::Point& point) const { + NOTREACHED(); +} + +gfx::Rect ScreenWinHeadless::GetNativeWindowBoundsInScreen( + gfx::NativeWindow window) const { + NOTREACHED(); +} + +gfx::Rect ScreenWinHeadless::GetHeadlessWindowBounds( + gfx::AcceleratedWidget window) const { + NOTREACHED(); +} + +ScreenWinDisplay ScreenWinHeadless::GetScreenWinDisplayNearestHWND( + HWND hwnd) const { + return GetScreenWinDisplay( + MonitorInfoFromWindow(hwnd, MONITOR_DEFAULTTONEAREST)); +} + +ScreenWinDisplay ScreenWinHeadless::GetPrimaryScreenWinDisplay() const { + // ScreenWin::GetPrimaryScreenWinDisplay() searches the ScreenWinDisplay + // table for a display with origin at (0,0), however, for headless primary + // display is always the first registered display. + const int64_t id = GetPrimaryDisplay().id(); + return GetScreenWinDisplayWithDisplayId(id); +} + +ScreenWinDisplay ScreenWinHeadless::GetScreenWinDisplay( + std::optional<MONITORINFOEX> monitor_info) const { + // ScreenWin::GetScreenWinDisplay() calls + // DisplayInfo::DisplayIdFromMonitorInfo() to derive display id from monitor + // info. Headless display ids are synthesized, so retrieve display id from + // the headless display device name. + if (monitor_info) { + const int64_t id = GetHeadlessDisplayIdFromMonitorInfo(*monitor_info); + return GetScreenWinDisplayWithDisplayId(id); + } + + return GetPrimaryScreenWinDisplay(); +} + +std::vector<internal::DisplayInfo> +ScreenWinHeadless::DisplayInfosFromScreenInfo( + const std::vector<headless::HeadlessScreenInfo>& screen_infos) { + CHECK(!screen_infos.empty()); + + std::optional<float> forced_device_scale_factor; + if (Display::HasForceDeviceScaleFactor()) { + forced_device_scale_factor = Display::GetForcedDeviceScaleFactor(); + } + + bool is_primary = true; + std::vector<internal::DisplayInfo> display_infos; + for (const auto& screen_info : screen_infos) { + static int64_t synthesized_display_id = kHeadlessDisplayIdBase; + + MONITORINFOEX monitor_info; + monitor_info.cbSize = sizeof(monitor_info); + monitor_info.rcMonitor = screen_info.bounds.ToRECT(); + + if (screen_info.work_area_insets.IsEmpty()) { + monitor_info.rcWork = monitor_info.rcMonitor; + } else { + gfx::Rect work_area = screen_info.bounds; + work_area.Inset(screen_info.work_area_insets); + monitor_info.rcWork = work_area.ToRECT(); + } + + monitor_info.dwFlags = is_primary ? MONITORINFOF_PRIMARY : 0; + + const std::wstring device_name = + GetHeadlessDisplayDeviceNameFromDisplayId(synthesized_display_id); + CHECK_LT(device_name.length() + 1, std::size(monitor_info.szDevice)); + wcscpy(monitor_info.szDevice, device_name.c_str()); + + const float device_scale_factor = + forced_device_scale_factor.value_or(screen_info.device_pixel_ratio); + + // Maintain display id to monitor info association for all the + // MonitorInfoFromScreen*() functions below. + headless_monitor_info_.insert({synthesized_display_id, monitor_info}); + + internal::DisplayInfo display_info( + synthesized_display_id, monitor_info, device_scale_factor, + /*sdr_white_level=*/200.0, + /*rotation=*/Display::DegreesToRotation(screen_info.rotation), + /*display_frequency=*/60.0, + /*pixels_per_inch=*/ + GetDisplayPhysicalPixelsPerInch(screen_info.device_pixel_ratio), + /*output_technology=*/screen_info.is_internal + ? DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL + : DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER, + screen_info.label); + + display_infos.push_back(std::move(display_info)); + + ++synthesized_display_id; + is_primary = false; + } + + return display_infos; +} + +Display ScreenWinHeadless::GetDisplayFromScreenPoint( + const gfx::Point& point) const { + if (const Display* display = + FindDisplayNearestPoint(GetAllDisplays(), point)) { + return *display; + } + + return GetPrimaryDisplay(); +} + +Display ScreenWinHeadless::GetDisplayFromScreenRect( + const gfx::Rect& rect) const { + if (const Display* display = + FindDisplayWithBiggestIntersection(GetAllDisplays(), rect)) { + return *display; + } + + if (const Display* display = + FindDisplayNearestPoint(GetAllDisplays(), rect.CenterPoint())) { + return *display; + } + + return GetPrimaryDisplay(); +} + +std::optional<MONITORINFOEX> +ScreenWinHeadless::GetMONITORINFOFromDisplayIdForTest(int64_t id) const { + return GetMONITORINFOFromDisplayId(id); +} + +std::optional<MONITORINFOEX> ScreenWinHeadless::GetMONITORINFOFromDisplayId( + int64_t id) const { + auto it = headless_monitor_info_.find(id); + if (it == headless_monitor_info_.cend()) { + return std::nullopt; + } + + return it->second; +} + +namespace internal { +bool VerifyHeadlessDisplayDeviceName(int64_t id, + const MONITORINFOEX& monitor_info) { + return GetHeadlessDisplayDeviceNameFromDisplayId(id) == monitor_info.szDevice; +} +} // namespace internal + +} // namespace display::win
diff --git a/ui/display/win/screen_win_headless.h b/ui/display/win/screen_win_headless.h new file mode 100644 index 0000000..ecef9e0d --- /dev/null +++ b/ui/display/win/screen_win_headless.h
@@ -0,0 +1,109 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_DISPLAY_WIN_SCREEN_WIN_HEADLESS_H_ +#define UI_DISPLAY_WIN_SCREEN_WIN_HEADLESS_H_ + +#include <windows.h> + +#include <optional> +#include <string_view> +#include <vector> + +#include "base/containers/flat_map.h" +#include "ui/display/win/screen_win.h" +#include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/native_widget_types.h" + +namespace headless { +struct HeadlessScreenInfo; +} + +namespace display::win { + +class DISPLAY_EXPORT ScreenWinHeadless : public ScreenWin { + public: + explicit ScreenWinHeadless( + const std::vector<headless::HeadlessScreenInfo>& screen_infos); + + ScreenWinHeadless(const ScreenWinHeadless&) = delete; + ScreenWinHeadless& operator=(const ScreenWinHeadless&) = delete; + + ~ScreenWinHeadless() override; + + // Screen: + gfx::Point GetCursorScreenPoint() override; + void SetCursorScreenPointForTesting(const gfx::Point& point) override; + bool IsWindowUnderCursor(gfx::NativeWindow window) override; + gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override; + gfx::NativeWindow GetLocalProcessWindowAtPoint( + const gfx::Point& point, + const std::set<gfx::NativeWindow>& ignore) override; + int GetNumDisplays() const override; + const std::vector<Display>& GetAllDisplays() const override; + Display GetDisplayNearestWindow(gfx::NativeWindow window) const override; + Display GetDisplayNearestPoint(const gfx::Point& point) const override; + Display GetDisplayMatching(const gfx::Rect& match_rect) const override; + Display GetPrimaryDisplay() const override; + + // ScreenWin: + std::optional<MONITORINFOEX> MonitorInfoFromScreenPoint( + const gfx::Point& screen_point) const override; + std::optional<MONITORINFOEX> MonitorInfoFromScreenRect( + const gfx::Rect& screen_rect) const override; + std::optional<MONITORINFOEX> MonitorInfoFromWindow( + HWND hwnd, + DWORD default_options) const override; + int64_t GetDisplayIdFromMonitorInfo( + const MONITORINFOEX& monitor_info) const override; + HWND GetRootWindow(HWND hwnd) const override; + void UpdateAllDisplaysAndNotify() override; + void UpdateAllDisplaysIfPrimaryMonitorChanged() override; + + ScreenWinDisplay GetScreenWinDisplayNearestHWND(HWND hwnd) const override; + ScreenWinDisplay GetPrimaryScreenWinDisplay() const override; + ScreenWinDisplay GetScreenWinDisplay( + std::optional<MONITORINFOEX> monitor_info) const override; + + // ColorProfileReader::Client: + void OnColorProfilesChanged() override; + + std::optional<MONITORINFOEX> GetMONITORINFOFromDisplayIdForTest( + int64_t id) const; + + protected: + // These are exposed for \\ui\views. + virtual std::vector<gfx::NativeWindow> GetNativeWindowsAtScreenPoint( + const gfx::Point& point) const; + virtual gfx::Rect GetNativeWindowBoundsInScreen( + gfx::NativeWindow window) const; + virtual gfx::Rect GetHeadlessWindowBounds( + gfx::AcceleratedWidget window) const; + + private: + std::vector<internal::DisplayInfo> DisplayInfosFromScreenInfo( + const std::vector<headless::HeadlessScreenInfo>& screen_infos); + + Display GetDisplayFromScreenPoint(const gfx::Point& point) const; + Display GetDisplayFromScreenRect(const gfx::Rect& rect) const; + + std::optional<MONITORINFOEX> GetMONITORINFOFromDisplayId(int64_t id) const; + + // Maps display id to a fake Windows monitor info that correlates to + // a headless display. + base::flat_map<int64_t, MONITORINFOEX> headless_monitor_info_; + + gfx::Point cursor_screen_point_; +}; + +namespace internal { +// Exposed for internal::DisplayInfo::ctor check only! +bool VerifyHeadlessDisplayDeviceName(int64_t id, + const MONITORINFOEX& monitor_info); +} // namespace internal + +} // namespace display::win + +#endif // UI_DISPLAY_WIN_SCREEN_WIN_HEADLESS_H_
diff --git a/ui/display/win/screen_win_headless_unittest.cc b/ui/display/win/screen_win_headless_unittest.cc new file mode 100644 index 0000000..2c4467f --- /dev/null +++ b/ui/display/win/screen_win_headless_unittest.cc
@@ -0,0 +1,729 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/display/win/screen_win_headless.h" + +#include <windows.h> + +#include <algorithm> +#include <string> +#include <string_view> +#include <vector> + +#include "base/containers/adapters.h" +#include "base/containers/flat_map.h" +#include "components/headless/screen_info/headless_screen_info.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/display/win/screen_win_display.h" +#include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/point_f.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gfx/geometry/vector2d_f.h" +#include "ui/gfx/native_widget_types.h" + +using headless::HeadlessScreenInfo; + +namespace display::win { + +namespace { + +class TestScreenWinHeadless : public ScreenWinHeadless { + public: + explicit TestScreenWinHeadless( + const std::vector<HeadlessScreenInfo>& screen_infos) + : ScreenWinHeadless(screen_infos) {} + + TestScreenWinHeadless(const TestScreenWinHeadless&) = delete; + TestScreenWinHeadless& operator=(const TestScreenWinHeadless&) = delete; + + ~TestScreenWinHeadless() override = default; + + gfx::NativeWindow AddWindow(const gfx::Rect& bounds) { + HWND hwnd = reinterpret_cast<HWND>(++last_hwnd_); + windows_.insert({hwnd, bounds}); + return GetNativeWindowFromHWND(hwnd); + } + + // win::ScreenWin: + HWND GetHWNDFromNativeWindow(gfx::NativeWindow window) const override { + return reinterpret_cast<HWND>(window); + } + + gfx::NativeWindow GetNativeWindowFromHWND(HWND hwnd) const override { + return reinterpret_cast<gfx::NativeWindow>(hwnd); + } + + // The following two methods are protected in ScreenWin and not overridden by + // ScreenWinHeadless because the base class does the right thing, so expose + // them here for testing. + gfx::Rect ScreenToDIPRectInWindow( + gfx::NativeWindow window, + const gfx::Rect& screen_rect) const override { + return ScreenWin::ScreenToDIPRectInWindow(window, screen_rect); + } + + gfx::Rect DIPToScreenRectInWindow(gfx::NativeWindow window, + const gfx::Rect& dip_rect) const override { + return ScreenWin::DIPToScreenRectInWindow(window, dip_rect); + } + + // win::ScreenWinHeadless: + std::vector<gfx::NativeWindow> GetNativeWindowsAtScreenPoint( + const gfx::Point& point) const override { + std::vector<gfx::NativeWindow> windows; + // Assume that recently created windows are higher in z-order. + for (const auto& [hwnd, bounds] : base::Reversed(windows_)) { + if (bounds.Contains(point)) { + windows.push_back(GetNativeWindowFromHWND(hwnd)); + } + } + + return windows; + } + + gfx::Rect GetNativeWindowBoundsInScreen( + gfx::NativeWindow window) const override { + return GetWindowBounds(GetHWNDFromNativeWindow(window)); + } + + gfx::Rect GetHeadlessWindowBounds( + gfx::AcceleratedWidget window) const override { + return GetWindowBounds(window); + } + + private: + gfx::Rect GetWindowBounds(HWND hwnd) const { + CHECK(hwnd); + auto it = windows_.find(hwnd); + CHECK(it != windows_.cend()); + return it->second; + } + + // A sequentially increasing integer value used as a substitute for a window + // handle. + int last_hwnd_ = 0; + + base::flat_map<HWND, gfx::Rect> windows_; +}; + +class ScreenWinHeadlessTest : public testing::Test { + public: + ScreenWinHeadlessTest(const ScreenWinHeadlessTest&) = delete; + ScreenWinHeadlessTest& operator=(const ScreenWinHeadlessTest&) = delete; + + protected: + ScreenWinHeadlessTest() = default; + ~ScreenWinHeadlessTest() override = default; + + // Return specified or default headless screen configuration. + std::vector<HeadlessScreenInfo> GetScreenInfos( + std::string_view screen_info_spec) { + std::vector<HeadlessScreenInfo> screen_infos; + + if (!screen_info_spec.empty()) { + auto screen_info_or_error = + HeadlessScreenInfo::FromString(screen_info_spec); + CHECK(screen_info_or_error.has_value()) << screen_info_or_error.error(); + screen_infos = screen_info_or_error.value(); + } else { + screen_infos.push_back(HeadlessScreenInfo()); + } + + return screen_infos; + } + + std::unique_ptr<TestScreenWinHeadless> CreateHeadlessScreen( + std::string_view screen_info_spec) { + return std::make_unique<TestScreenWinHeadless>( + GetScreenInfos(screen_info_spec)); + } +}; + +TEST_F(ScreenWinHeadlessTest, DefaultScreen) { + auto screen = CreateHeadlessScreen(""); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + const Display& display = screen->GetAllDisplays()[0]; + EXPECT_THAT(display.bounds(), testing::Eq(gfx::Rect(0, 0, 800, 600))); + EXPECT_THAT(display.work_area(), testing::Eq(gfx::Rect(0, 0, 800, 600))); + EXPECT_THAT(display.device_scale_factor(), testing::Eq(1.0f)); + EXPECT_THAT(display.rotation(), testing::Eq(Display::Rotation::ROTATE_0)); + EXPECT_THAT(display.color_depth(), testing::Eq(24)); + EXPECT_TRUE(display.label().empty()); + EXPECT_FALSE(display.IsInternal()); +} + +TEST_F(ScreenWinHeadlessTest, SpecifiedScreen) { + auto screen = CreateHeadlessScreen("{1600x1200 label='Primary Screen'}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + const Display& display = screen->GetAllDisplays()[0]; + EXPECT_THAT(display.bounds(), testing::Eq(gfx::Rect(0, 0, 1600, 1200))); + EXPECT_THAT(display.work_area(), testing::Eq(gfx::Rect(0, 0, 1600, 1200))); + EXPECT_THAT(display.device_scale_factor(), testing::Eq(1.0f)); + EXPECT_THAT(display.rotation(), testing::Eq(Display::Rotation::ROTATE_0)); + EXPECT_THAT(display.color_depth(), testing::Eq(24)); + EXPECT_THAT(display.label(), testing::Eq("Primary Screen")); + EXPECT_FALSE(display.IsInternal()); +} + +TEST_F(ScreenWinHeadlessTest, MultipleScreens) { + auto screen = CreateHeadlessScreen("{label=#1}{600x800 label=#2}"); + ASSERT_EQ(screen->GetNumDisplays(), 2); + + const Display& display1 = screen->GetAllDisplays()[0]; + EXPECT_THAT(display1.bounds(), testing::Eq(gfx::Rect(0, 0, 800, 600))); + EXPECT_THAT(display1.rotation(), testing::Eq(Display::Rotation::ROTATE_0)); + EXPECT_THAT(display1.label(), testing::Eq("#1")); + + const Display& display2 = screen->GetAllDisplays()[1]; + EXPECT_THAT(display2.bounds(), testing::Eq(gfx::Rect(800, 0, 600, 800))); + EXPECT_THAT(display2.rotation(), testing::Eq(Display::Rotation::ROTATE_0)); + EXPECT_THAT(display2.label(), testing::Eq("#2")); +} + +// ScreenWin::MonitorInfoFrom*() overrides tests ---------------------- + +TEST_F(ScreenWinHeadlessTest, MonitorInfoFromScreenPoint) { + auto screen = CreateHeadlessScreen("{}{}"); + ASSERT_EQ(screen->GetNumDisplays(), 2); + + EXPECT_EQ(screen->MonitorInfoFromScreenPoint(gfx::Point(-1, -1))->dwFlags, + static_cast<DWORD>(MONITORINFOF_PRIMARY)); + + EXPECT_EQ(screen->MonitorInfoFromScreenPoint(gfx::Point(0, 0))->dwFlags, + static_cast<DWORD>(MONITORINFOF_PRIMARY)); + + EXPECT_EQ(screen->MonitorInfoFromScreenPoint(gfx::Point(799, 300))->dwFlags, + static_cast<DWORD>(MONITORINFOF_PRIMARY)); + + EXPECT_EQ(screen->MonitorInfoFromScreenPoint(gfx::Point(1599, 599))->dwFlags, + static_cast<DWORD>(0)); + + EXPECT_EQ(screen->MonitorInfoFromScreenPoint(gfx::Point(1601, 601))->dwFlags, + static_cast<DWORD>(0)); +} + +TEST_F(ScreenWinHeadlessTest, MonitorInfoFromScreenRect) { + auto screen = CreateHeadlessScreen("{}{}"); + ASSERT_EQ(screen->GetNumDisplays(), 2); + + EXPECT_EQ(screen->MonitorInfoFromScreenRect(gfx::Rect(-200, -100, 200, 100)) + ->dwFlags, + static_cast<DWORD>(MONITORINFOF_PRIMARY)); + + EXPECT_EQ( + screen->MonitorInfoFromScreenRect(gfx::Rect(0, 0, 200, 100))->dwFlags, + static_cast<DWORD>(MONITORINFOF_PRIMARY)); + + EXPECT_EQ( + screen->MonitorInfoFromScreenRect(gfx::Rect(400, 300, 200, 100))->dwFlags, + static_cast<DWORD>(MONITORINFOF_PRIMARY)); + + EXPECT_EQ(screen->MonitorInfoFromScreenRect(gfx::Rect(1500, 500, 200, 100)) + ->dwFlags, + static_cast<DWORD>(0)); + + EXPECT_EQ(screen->MonitorInfoFromScreenRect(gfx::Rect(1601, 601, 200, 100)) + ->dwFlags, + static_cast<DWORD>(0)); +} + +TEST_F(ScreenWinHeadlessTest, MonitorInfoFromWindow) { + auto screen = CreateHeadlessScreen("{}{}"); + ASSERT_EQ(screen->GetNumDisplays(), 2); + + // Window is on the primary screen. + HWND hwnd1 = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(0, 0, 400, 300))); + EXPECT_EQ( + screen->MonitorInfoFromWindow(hwnd1, MONITOR_DEFAULTTONULL)->dwFlags, + static_cast<DWORD>(MONITORINFOF_PRIMARY)); + + // Window is on the secondary screen. + HWND hwnd2 = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(800, 0, 400, 300))); + EXPECT_EQ( + screen->MonitorInfoFromWindow(hwnd2, MONITOR_DEFAULTTONULL)->dwFlags, + static_cast<DWORD>(0)); + + // Window is north west of the primary screen. + HWND hwnd3 = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(-400, -300, 400, 300))); + EXPECT_FALSE( + screen->MonitorInfoFromWindow(hwnd3, MONITOR_DEFAULTTONULL).has_value()); + EXPECT_EQ( + screen->MonitorInfoFromWindow(hwnd3, MONITOR_DEFAULTTONEAREST)->dwFlags, + static_cast<DWORD>(MONITORINFOF_PRIMARY)); + + // Window is south east of the secondary screen. + HWND hwnd4 = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(1600, 600, 400, 300))); + EXPECT_FALSE( + screen->MonitorInfoFromWindow(hwnd4, MONITOR_DEFAULTTONULL).has_value()); + EXPECT_EQ( + screen->MonitorInfoFromWindow(hwnd4, MONITOR_DEFAULTTONEAREST)->dwFlags, + static_cast<DWORD>(0)); + EXPECT_EQ( + screen->MonitorInfoFromWindow(hwnd4, MONITOR_DEFAULTTOPRIMARY)->dwFlags, + static_cast<DWORD>(MONITORINFOF_PRIMARY)); +} + +// display::win::ScreenWin static methods tests ----------------------- + +TEST_F(ScreenWinHeadlessTest, ScreenToDIPPoint) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=1.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + EXPECT_EQ(ScreenWin::ScreenToDIPPoint(gfx::PointF(100, 200)), + gfx::PointF(100, 200)); +} + +TEST_F(ScreenWinHeadlessTest, ScreenToDIPPoint2x) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=2.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + EXPECT_EQ(ScreenWin::ScreenToDIPPoint(gfx::PointF(100, 200)), + gfx::PointF(50, 100)); +} + +TEST_F(ScreenWinHeadlessTest, DIPToScreenPoint) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=1.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + EXPECT_EQ(ScreenWin::DIPToScreenPoint(gfx::Point(100, 200)), + gfx::Point(100, 200)); +} + +TEST_F(ScreenWinHeadlessTest, DIPToScreenPoint2x) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=2.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + EXPECT_EQ(ScreenWin::DIPToScreenPoint(gfx::Point(100, 200)), + gfx::Point(200, 400)); +} + +TEST_F(ScreenWinHeadlessTest, ClientToDIPPoint) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=1.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + HWND hwnd = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(0, 0, 400, 300))); + + EXPECT_EQ(ScreenWin::ClientToDIPPoint(hwnd, gfx::Point(100, 200)), + gfx::Point(100, 200)); +} + +TEST_F(ScreenWinHeadlessTest, ClientToDIPPoint2x) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=2.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + HWND hwnd = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(0, 0, 400, 300))); + + EXPECT_EQ(ScreenWin::ClientToDIPPoint(hwnd, gfx::Point(100, 200)), + gfx::Point(50, 100)); +} + +TEST_F(ScreenWinHeadlessTest, DIPToClientPoint) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=1.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + HWND hwnd = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(0, 0, 400, 300))); + + EXPECT_EQ(ScreenWin::DIPToClientPoint(hwnd, gfx::Point(100, 200)), + gfx::Point(100, 200)); +} + +TEST_F(ScreenWinHeadlessTest, DIPToClientPoint2x) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=2.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + HWND hwnd = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(0, 0, 400, 300))); + + EXPECT_EQ(ScreenWin::DIPToClientPoint(hwnd, gfx::Point(50, 100)), + gfx::Point(100, 200)); +} + +TEST_F(ScreenWinHeadlessTest, ScreenToDIPRect) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=1.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + HWND hwnd = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(0, 0, 400, 300))); + + EXPECT_EQ(ScreenWin::ScreenToDIPRect(hwnd, gfx::Rect(0, 0, 100, 200)), + gfx::Rect(0, 0, 100, 200)); + + EXPECT_EQ(ScreenWin::ScreenToDIPRect(nullptr, gfx::Rect(0, 0, 100, 200)), + gfx::Rect(0, 0, 100, 200)); +} + +TEST_F(ScreenWinHeadlessTest, ScreenToDIPRect2x) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=2.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + HWND hwnd = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(0, 0, 400, 300))); + + EXPECT_EQ(ScreenWin::ScreenToDIPRect(hwnd, gfx::Rect(0, 0, 100, 200)), + gfx::Rect(0, 0, 50, 100)); + + EXPECT_EQ(ScreenWin::ScreenToDIPRect(nullptr, gfx::Rect(0, 0, 100, 200)), + gfx::Rect(0, 0, 50, 100)); +} + +TEST_F(ScreenWinHeadlessTest, DIPToScreenRect) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=1.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + HWND hwnd = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(0, 0, 400, 300))); + + EXPECT_EQ(ScreenWin::DIPToScreenRect(hwnd, gfx::Rect(0, 0, 100, 200)), + gfx::Rect(0, 0, 100, 200)); + + EXPECT_EQ(ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(0, 0, 100, 200)), + gfx::Rect(0, 0, 100, 200)); +} + +TEST_F(ScreenWinHeadlessTest, DIPToScreenRect2x) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=2.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + HWND hwnd = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(0, 0, 400, 300))); + + EXPECT_EQ(ScreenWin::DIPToScreenRect(hwnd, gfx::Rect(0, 0, 50, 100)), + gfx::Rect(0, 0, 100, 200)); + + EXPECT_EQ(ScreenWin::DIPToScreenRect(nullptr, gfx::Rect(0, 0, 50, 100)), + gfx::Rect(0, 0, 100, 200)); +} + +TEST_F(ScreenWinHeadlessTest, ClientToDIPRect) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=1.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + HWND hwnd = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(0, 0, 400, 300))); + + EXPECT_EQ(ScreenWin::ClientToDIPRect(hwnd, gfx::Rect(0, 0, 100, 200)), + gfx::Rect(0, 0, 100, 200)); +} + +TEST_F(ScreenWinHeadlessTest, ClientToDIPRect2x) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=2.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + HWND hwnd = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(0, 0, 400, 300))); + + EXPECT_EQ(ScreenWin::ClientToDIPRect(hwnd, gfx::Rect(0, 0, 100, 200)), + gfx::Rect(0, 0, 50, 100)); +} + +TEST_F(ScreenWinHeadlessTest, DIPToClientRect) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=1.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + HWND hwnd = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(0, 0, 400, 300))); + + EXPECT_EQ(ScreenWin::DIPToClientRect(hwnd, gfx::Rect(0, 0, 100, 200)), + gfx::Rect(0, 0, 100, 200)); +} + +TEST_F(ScreenWinHeadlessTest, DIPToClientRect2x) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=2.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + HWND hwnd = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(0, 0, 400, 300))); + + EXPECT_EQ(ScreenWin::DIPToClientRect(hwnd, gfx::Rect(0, 0, 50, 100)), + gfx::Rect(0, 0, 100, 200)); +} + +TEST_F(ScreenWinHeadlessTest, ScreenToDIPSize) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=1.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + HWND hwnd = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(0, 0, 400, 300))); + + EXPECT_EQ(ScreenWin::ScreenToDIPSize(hwnd, gfx::Size(100, 200)), + gfx::Size(100, 200)); +} + +TEST_F(ScreenWinHeadlessTest, ScreenToDIPSize2x) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=2.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + HWND hwnd = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(0, 0, 400, 300))); + + EXPECT_EQ(ScreenWin::ScreenToDIPSize(hwnd, gfx::Size(100, 200)), + gfx::Size(50, 100)); +} + +TEST_F(ScreenWinHeadlessTest, DIPToScreenSize) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=1.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + HWND hwnd = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(0, 0, 400, 300))); + + EXPECT_EQ(ScreenWin::DIPToScreenSize(hwnd, gfx::Size(100, 200)), + gfx::Size(100, 200)); +} + +TEST_F(ScreenWinHeadlessTest, DIPToScreenSize2x) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=2.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + HWND hwnd = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(0, 0, 400, 300))); + + EXPECT_EQ(ScreenWin::DIPToScreenSize(hwnd, gfx::Size(50, 100)), + gfx::Size(100, 200)); +} + +TEST_F(ScreenWinHeadlessTest, GetPixelsPerInch) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=1.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + EXPECT_EQ(ScreenWin::GetPixelsPerInch(gfx::PointF(400, 300)), + gfx::Vector2dF(96, 96)); +} + +TEST_F(ScreenWinHeadlessTest, GetPixelsPerInch2x) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=2.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + EXPECT_EQ(ScreenWin::GetPixelsPerInch(gfx::PointF(400, 300)), + gfx::Vector2dF(192, 192)); +} + +TEST_F(ScreenWinHeadlessTest, GetScreenWinDisplayWithDisplayId) { + auto screen = CreateHeadlessScreen("{label=#1}{label=#2}"); + ASSERT_EQ(screen->GetNumDisplays(), 2); + + const int64_t id1 = screen->GetAllDisplays()[0].id(); + EXPECT_EQ(ScreenWin::GetScreenWinDisplayWithDisplayId(id1).display().id(), + id1); + + const int64_t id2 = screen->GetAllDisplays()[1].id(); + EXPECT_EQ(ScreenWin::GetScreenWinDisplayWithDisplayId(id2).display().id(), + id2); + + // Unknown display id should result in primary display. + EXPECT_EQ(ScreenWin::GetScreenWinDisplayWithDisplayId(-1).display().id(), + id1); +} + +TEST_F(ScreenWinHeadlessTest, DisplayIdFromMonitorInfo) { + auto screen = CreateHeadlessScreen("{}{}"); + ASSERT_EQ(screen->GetNumDisplays(), 2); + + const int64_t id1 = screen->GetAllDisplays()[0].id(); + auto monitor_info1 = screen->GetMONITORINFOFromDisplayIdForTest(id1); + ASSERT_TRUE(monitor_info1.has_value()); + EXPECT_EQ(ScreenWin::DisplayIdFromMonitorInfo(*monitor_info1), id1); + + const int64_t id2 = screen->GetAllDisplays()[1].id(); + auto monitor_info2 = screen->GetMONITORINFOFromDisplayIdForTest(id2); + ASSERT_TRUE(monitor_info2.has_value()); + EXPECT_EQ(ScreenWin::DisplayIdFromMonitorInfo(*monitor_info2), id2); +} + +TEST_F(ScreenWinHeadlessTest, GetScaleFactorForHWND) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=1.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + HWND hwnd = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(0, 0, 400, 300))); + EXPECT_EQ(ScreenWin::GetScaleFactorForHWND(hwnd), 1.0); +} + +TEST_F(ScreenWinHeadlessTest, GetScaleFactorForHWND2x) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=2.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + HWND hwnd = screen->GetHWNDFromNativeWindow( + screen->AddWindow(gfx::Rect(0, 0, 400, 300))); + EXPECT_EQ(ScreenWin::GetScaleFactorForHWND(hwnd), 2.0); +} + +// display::Screen interface methods tests ---------------------------- + +TEST_F(ScreenWinHeadlessTest, GetCursorScreenPoint) { + auto screen = CreateHeadlessScreen(""); + + EXPECT_EQ(screen->GetCursorScreenPoint(), gfx::Point()); + + static constexpr gfx::Point kCursorScreenPoint(123, 456); + screen->SetCursorScreenPointForTesting(kCursorScreenPoint); + EXPECT_EQ(screen->GetCursorScreenPoint(), kCursorScreenPoint); +} + +TEST_F(ScreenWinHeadlessTest, IsWindowUnderCursor) { + auto screen = CreateHeadlessScreen(""); + + gfx::NativeWindow window1 = screen->AddWindow(gfx::Rect(0, 0, 400, 300)); + EXPECT_TRUE(screen->IsWindowUnderCursor(window1)); + + gfx::NativeWindow window2 = screen->AddWindow(gfx::Rect(800, 0, 400, 300)); + EXPECT_FALSE(screen->IsWindowUnderCursor(window2)); +} + +TEST_F(ScreenWinHeadlessTest, GetWindowAtScreenPoint) { + auto screen = CreateHeadlessScreen(""); + + EXPECT_EQ(screen->GetWindowAtScreenPoint(gfx::Point(0, 0)), nullptr); + + gfx::NativeWindow window1 = screen->AddWindow(gfx::Rect(0, 0, 400, 300)); + gfx::NativeWindow window2 = screen->AddWindow(gfx::Rect(10, 10, 400, 300)); + + EXPECT_EQ(screen->GetWindowAtScreenPoint(gfx::Point(0, 0)), window1); + EXPECT_EQ(screen->GetWindowAtScreenPoint(gfx::Point(10, 10)), window2); +} + +TEST_F(ScreenWinHeadlessTest, GetLocalProcessWindowAtPoint) { + auto screen = CreateHeadlessScreen(""); + + gfx::NativeWindow window1 = screen->AddWindow(gfx::Rect(0, 0, 400, 300)); + gfx::NativeWindow window2 = screen->AddWindow(gfx::Rect(10, 10, 400, 300)); + + EXPECT_EQ(screen->GetLocalProcessWindowAtPoint(gfx::Point(0, 0), + std::set<gfx::NativeWindow>()), + window1); + + EXPECT_EQ(screen->GetLocalProcessWindowAtPoint(gfx::Point(10, 10), + std::set<gfx::NativeWindow>()), + window2); + + EXPECT_EQ(screen->GetLocalProcessWindowAtPoint( + gfx::Point(10, 10), std::set<gfx::NativeWindow>({window2})), + window1); + + EXPECT_EQ( + screen->GetLocalProcessWindowAtPoint( + gfx::Point(10, 10), std::set<gfx::NativeWindow>({window1, window2})), + nullptr); +} + +TEST_F(ScreenWinHeadlessTest, GetNumDisplays) { + auto screen = CreateHeadlessScreen("{label='#1'}{label='#2'}"); + EXPECT_EQ(screen->GetNumDisplays(), 2); +} + +TEST_F(ScreenWinHeadlessTest, GetAllDisplays) { + auto screen = CreateHeadlessScreen("{label='#1'}{label='#2'}"); + + const std::vector<Display>& displays = screen->GetAllDisplays(); + ASSERT_THAT(displays, testing::SizeIs(2)); + + EXPECT_THAT(displays[0].label(), testing::StrEq("#1")); + EXPECT_THAT(displays[1].label(), testing::StrEq("#2")); +} + +TEST_F(ScreenWinHeadlessTest, GetDisplayNearestWindow) { + auto screen = CreateHeadlessScreen("{label='#1'}{label='#2'}"); + ASSERT_EQ(screen->GetNumDisplays(), 2); + + gfx::NativeWindow window1 = screen->AddWindow(gfx::Rect(0, 0, 400, 300)); + Display display1 = screen->GetDisplayNearestWindow(window1); + EXPECT_THAT(display1.label(), testing::StrEq("#1")); + + gfx::NativeWindow window2 = screen->AddWindow(gfx::Rect(800, 0, 400, 300)); + Display display2 = screen->GetDisplayNearestWindow(window2); + EXPECT_THAT(display2.label(), testing::StrEq("#2")); +} + +TEST_F(ScreenWinHeadlessTest, GetDisplayNearestPoint) { + auto screen = CreateHeadlessScreen( + "{label='#1'}{label='#2'}{0,600 label='#3'}{label='#4'}"); + ASSERT_EQ(screen->GetNumDisplays(), 4); + + EXPECT_THAT(screen->GetDisplayNearestPoint(gfx::Point(1, 1)).label(), + testing::StrEq("#1")); + EXPECT_THAT(screen->GetDisplayNearestPoint(gfx::Point(801, 1)).label(), + testing::StrEq("#2")); + EXPECT_THAT(screen->GetDisplayNearestPoint(gfx::Point(1, 601)).label(), + testing::StrEq("#3")); + EXPECT_THAT(screen->GetDisplayNearestPoint(gfx::Point(801, 601)).label(), + testing::StrEq("#4")); +} + +TEST_F(ScreenWinHeadlessTest, GetDisplayMatching) { + auto screen = CreateHeadlessScreen( + "{label='#1'}{label='#2'}{0,600 label='#3'}{label='#4'}"); + ASSERT_EQ(screen->GetNumDisplays(), 4); + + EXPECT_THAT(screen->GetDisplayMatching(gfx::Rect(1, 1, 400, 300)).label(), + testing::StrEq("#1")); + EXPECT_THAT(screen->GetDisplayMatching(gfx::Rect(801, 1, 400, 300)).label(), + testing::StrEq("#2")); + EXPECT_THAT(screen->GetDisplayMatching(gfx::Rect(1, 601, 400, 300)).label(), + testing::StrEq("#3")); + EXPECT_THAT(screen->GetDisplayMatching(gfx::Rect(801, 601, 400, 300)).label(), + testing::StrEq("#4")); +} + +TEST_F(ScreenWinHeadlessTest, GetPrimaryDisplay) { + auto screen = + CreateHeadlessScreen("{label='#1'}{label='#2'}{label='#3'}{label='#4'}"); + ASSERT_EQ(screen->GetNumDisplays(), 4); + + Display display = screen->GetPrimaryDisplay(); + EXPECT_THAT(display.label(), testing::StrEq("#1")); +} + +TEST_F(ScreenWinHeadlessTest, ScreenToDIPRectInWindow) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=1.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + gfx::NativeWindow window = screen->AddWindow(gfx::Rect(10, 20, 400, 300)); + EXPECT_EQ( + screen->ScreenToDIPRectInWindow(window, gfx::Rect(10, 20, 100, 200)), + gfx::Rect(10, 20, 100, 200)); +} + +TEST_F(ScreenWinHeadlessTest, ScreenToDIPRectInWindow2x) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=2.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + gfx::NativeWindow window = screen->AddWindow(gfx::Rect(10, 20, 400, 300)); + EXPECT_EQ( + screen->ScreenToDIPRectInWindow(window, gfx::Rect(10, 20, 100, 200)), + gfx::Rect(5, 10, 50, 100)); +} + +TEST_F(ScreenWinHeadlessTest, DIPToScreenRectInWindow) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=1.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + gfx::NativeWindow window = screen->AddWindow(gfx::Rect(10, 20, 400, 300)); + EXPECT_EQ( + screen->DIPToScreenRectInWindow(window, gfx::Rect(10, 20, 100, 200)), + gfx::Rect(10, 20, 100, 200)); +} + +TEST_F(ScreenWinHeadlessTest, DIPToScreenRectInWindow2x) { + auto screen = CreateHeadlessScreen("{devicePixelRatio=2.0}"); + ASSERT_EQ(screen->GetNumDisplays(), 1); + + gfx::NativeWindow window = screen->AddWindow(gfx::Rect(10, 20, 400, 300)); + EXPECT_EQ(screen->DIPToScreenRectInWindow(window, gfx::Rect(5, 10, 50, 100)), + gfx::Rect(10, 20, 100, 200)); +} + +} // namespace + +} // namespace display::win
diff --git a/ui/gl/gl_bindings.h b/ui/gl/gl_bindings.h index b51afc9..20e5940 100644 --- a/ui/gl/gl_bindings.h +++ b/ui/gl/gl_bindings.h
@@ -120,20 +120,19 @@ // GL_ANGLE_shader_pixel_local_storage #define GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE 0x96E0 -#define GL_MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_ANGLE 0x96E1 -#define GL_MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE 0x96E2 -#define GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE 0x96E3 -#define GL_LOAD_OP_ZERO_ANGLE 0x96E4 -#define GL_LOAD_OP_CLEAR_ANGLE 0x96E5 -#define GL_LOAD_OP_LOAD_ANGLE 0x96E6 -#define GL_STORE_OP_STORE_ANGLE 0x96E7 -#define GL_PIXEL_LOCAL_FORMAT_ANGLE 0x96E8 -#define GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE 0x96E9 -#define GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE 0x96EA -#define GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE 0x96EB -#define GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE 0x96EC -#define GL_PIXEL_LOCAL_CLEAR_VALUE_INT_ANGLE 0x96ED -#define GL_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_ANGLE 0x96EE +#define GL_MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE 0x96E1 +#define GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE 0x96E2 +#define GL_LOAD_OP_ZERO_ANGLE 0x96E3 +#define GL_LOAD_OP_CLEAR_ANGLE 0x96E4 +#define GL_LOAD_OP_LOAD_ANGLE 0x96E5 +#define GL_STORE_OP_STORE_ANGLE 0x96E6 +#define GL_PIXEL_LOCAL_FORMAT_ANGLE 0x96E7 +#define GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE 0x96E8 +#define GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE 0x96E9 +#define GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE 0x96EA +#define GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE 0x96EB +#define GL_PIXEL_LOCAL_CLEAR_VALUE_INT_ANGLE 0x96EC +#define GL_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_ANGLE 0x96ED // GL_EXT_occlusion_query_boolean #define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn index a92ee0c2..f24cdf14 100644 --- a/ui/views/BUILD.gn +++ b/ui/views/BUILD.gn
@@ -889,9 +889,12 @@ "widget/desktop_aura/desktop_native_cursor_manager_win.h", "widget/desktop_aura/desktop_screen_win.cc", "widget/desktop_aura/desktop_screen_win.h", + "widget/desktop_aura/desktop_screen_win_headless.cc", + "widget/desktop_aura/desktop_screen_win_headless.h", "widget/desktop_aura/desktop_window_tree_host_win.cc", ] deps += [ + "//components/headless/screen_info", "//ui/events:dom_keyboard_layout", "//ui/events:keyboard_hook", ]
diff --git a/ui/views/event_monitor_mac.h b/ui/views/event_monitor_mac.h index 694d98c7..513f642 100644 --- a/ui/views/event_monitor_mac.h +++ b/ui/views/event_monitor_mac.h
@@ -10,11 +10,13 @@ #include "base/memory/weak_ptr.h" #include "ui/gfx/native_widget_types.h" +#include "ui/views/cocoa/native_widget_mac_ns_window_host.h" #include "ui/views/event_monitor.h" namespace views { -class EventMonitorMac : public EventMonitor { +class EventMonitorMac : public EventMonitor, + public views::NativeWidgetMacEventMonitor::Client { public: EventMonitorMac(ui::EventObserver* event_observer, gfx::NativeWindow target_window, @@ -29,7 +31,15 @@ gfx::Point GetLastMouseLocation() override; private: + // views::NativeWidgetMacEventMonitor::Client + void NativeWidgetMacEventMonitorOnEvent(ui::Event* event, + bool* event_handled) override; + const std::set<ui::EventType> types_; + raw_ptr<ui::EventObserver> event_observer_; + + // For remote cocoa use. + std::unique_ptr<views::NativeWidgetMacEventMonitor> event_monitor_; struct ObjCStorage; std::unique_ptr<ObjCStorage> objc_storage_;
diff --git a/ui/views/event_monitor_mac.mm b/ui/views/event_monitor_mac.mm index a7ba313..1bd913c 100644 --- a/ui/views/event_monitor_mac.mm +++ b/ui/views/event_monitor_mac.mm
@@ -45,10 +45,24 @@ EventMonitorMac::EventMonitorMac(ui::EventObserver* event_observer, gfx::NativeWindow target_native_window, const std::set<ui::EventType>& types) - : types_(types), objc_storage_(std::make_unique<ObjCStorage>()) { + : types_(types), + event_observer_(event_observer), + objc_storage_(std::make_unique<ObjCStorage>()) { DCHECK(event_observer); NSWindow* target_window = target_native_window.GetNativeNSWindow(); + // For Progressive Web App (PWA) windows, we use a different event monitoring + // path. When the target window is inside PWA, we register + // `NativeWidgetMacEventMonitor` for remote cocoa. These events are processed + // through the NativeWidgetMacEventMonitorOnEvent() method defined below, + // bypassing the NSEvent block-based monitoring approach that follows. + auto* host = views::NativeWidgetMacNSWindowHost::GetFromNativeWindow( + target_native_window); + if (host && host->application_host()) { + event_monitor_ = host->AddEventMonitor(this); + return; + } + // Capture a WeakPtr. This allows the block to detect another event monitor // for the same event deleting |this|. base::WeakPtr<EventMonitorMac> weak_ptr = factory_.GetWeakPtr(); @@ -73,6 +87,17 @@ handler:block]; } +void EventMonitorMac::NativeWidgetMacEventMonitorOnEvent(ui::Event* ui_event, + bool* was_handled) { + if (*was_handled || !ui_event) { + return; + } + + if (types_.find(ui_event->type()) != types_.end()) { + event_observer_->OnEvent(*ui_event); + } +} + EventMonitorMac::~EventMonitorMac() { [NSEvent removeMonitor:objc_storage_->monitor]; }
diff --git a/ui/views/widget/desktop_aura/DEPS b/ui/views/widget/desktop_aura/DEPS new file mode 100644 index 0000000..c26169d --- /dev/null +++ b/ui/views/widget/desktop_aura/DEPS
@@ -0,0 +1,5 @@ +specific_include_rules = { + "desktop_screen_win_headless\.cc": [ + "+components/headless/screen_info" + ] +}
diff --git a/ui/views/widget/desktop_aura/desktop_screen_win.cc b/ui/views/widget/desktop_aura/desktop_screen_win.cc index e31c5b4..0778559 100644 --- a/ui/views/widget/desktop_aura/desktop_screen_win.cc +++ b/ui/views/widget/desktop_aura/desktop_screen_win.cc
@@ -6,9 +6,13 @@ #include <memory> +#include "base/check_deref.h" +#include "base/command_line.h" #include "ui/aura/window.h" #include "ui/aura/window_tree_host.h" +#include "ui/gfx/switches.h" #include "ui/views/widget/desktop_aura/desktop_screen.h" +#include "ui/views/widget/desktop_aura/desktop_screen_win_headless.h" #include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h" namespace views { @@ -47,6 +51,13 @@ //////////////////////////////////////////////////////////////////////////////// std::unique_ptr<display::Screen> CreateDesktopScreen() { + const base::CommandLine& command_line = + CHECK_DEREF(base::CommandLine::ForCurrentProcess()); + + if (command_line.HasSwitch(switches::kHeadless)) { + return std::make_unique<DesktopScreenWinHeadless>(); + } + return std::make_unique<DesktopScreenWin>(); }
diff --git a/ui/views/widget/desktop_aura/desktop_screen_win.h b/ui/views/widget/desktop_aura/desktop_screen_win.h index ddb8d11..cd5e1e1 100644 --- a/ui/views/widget/desktop_aura/desktop_screen_win.h +++ b/ui/views/widget/desktop_aura/desktop_screen_win.h
@@ -5,7 +5,6 @@ #ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_SCREEN_WIN_H_ #define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_SCREEN_WIN_H_ -#include "base/memory/raw_ptr.h" #include "ui/display/win/screen_win.h" #include "ui/views/views_export.h"
diff --git a/ui/views/widget/desktop_aura/desktop_screen_win_headless.cc b/ui/views/widget/desktop_aura/desktop_screen_win_headless.cc new file mode 100644 index 0000000..c6862f7 --- /dev/null +++ b/ui/views/widget/desktop_aura/desktop_screen_win_headless.cc
@@ -0,0 +1,105 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/views/widget/desktop_aura/desktop_screen_win_headless.h" + +#include <memory> +#include <string> +#include <vector> + +#include "base/check_deref.h" +#include "base/command_line.h" +#include "base/notimplemented.h" +#include "components/headless/screen_info/headless_screen_info.h" +#include "ui/aura/window.h" +#include "ui/aura/window_tree_host.h" +#include "ui/base/ui_base_switches.h" +#include "ui/views/widget/desktop_aura/desktop_screen.h" +#include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h" +#include "ui/views/win/hwnd_util.h" + +namespace views { + +namespace { + +std::vector<headless::HeadlessScreenInfo> GetScreenInfo() { + std::vector<headless::HeadlessScreenInfo> screen_info; + + const base::CommandLine& command_line = + CHECK_DEREF(base::CommandLine::ForCurrentProcess()); + + if (command_line.HasSwitch(switches::kScreenInfo)) { + const std::string switch_value = + command_line.GetSwitchValueASCII(switches::kScreenInfo); + auto screen_info_or_error = + headless::HeadlessScreenInfo::FromString(switch_value); + CHECK(screen_info_or_error.has_value()) << screen_info_or_error.error(); + screen_info = screen_info_or_error.value(); + } else { + screen_info.push_back(headless::HeadlessScreenInfo()); + } + + return screen_info; +} + +} // namespace + +DesktopScreenWinHeadless::DesktopScreenWinHeadless() + : display::win::ScreenWinHeadless(GetScreenInfo()) { + CHECK(!display::Screen::HasScreen()); + display::Screen::SetScreenInstance(this); +} + +DesktopScreenWinHeadless::~DesktopScreenWinHeadless() { + display::Screen::SetScreenInstance(nullptr); +} + +HWND DesktopScreenWinHeadless::GetHWNDFromNativeWindow( + gfx::NativeWindow window) const { + aura::WindowTreeHost* host = window->GetHost(); + return host ? host->GetAcceleratedWidget() : nullptr; +} + +gfx::NativeWindow DesktopScreenWinHeadless::GetNativeWindowFromHWND( + HWND hwnd) const { + return ::IsWindow(hwnd) + ? DesktopWindowTreeHostWin::GetContentWindowForHWND(hwnd) + : gfx::NativeWindow(); +} + +bool DesktopScreenWinHeadless::IsNativeWindowOccluded( + gfx::NativeWindow window) const { + return window->GetHost()->GetNativeWindowOcclusionState() == + aura::Window::OcclusionState::OCCLUDED; +} + +std::optional<bool> DesktopScreenWinHeadless::IsWindowOnCurrentVirtualDesktop( + gfx::NativeWindow window) const { + CHECK(window); + return window->GetHost()->on_current_workspace(); +} + +gfx::Rect DesktopScreenWinHeadless::GetNativeWindowBoundsInScreen( + gfx::NativeWindow window) const { + CHECK(window); + return window->GetBoundsInScreen(); +} + +gfx::Rect DesktopScreenWinHeadless::GetHeadlessWindowBounds( + gfx::AcceleratedWidget window) const { + CHECK(window); + return views::GetHeadlessWindowBounds(window); +} + +std::vector<gfx::NativeWindow> +DesktopScreenWinHeadless::GetNativeWindowsAtScreenPoint( + const gfx::Point& point) const { + std::vector<gfx::NativeWindow> windows; + // TODO(https://crbug.com/405276019): Finalize implementation and add the + // relevant tests. + NOTIMPLEMENTED_LOG_ONCE(); + return windows; +} + +} // namespace views
diff --git a/ui/views/widget/desktop_aura/desktop_screen_win_headless.h b/ui/views/widget/desktop_aura/desktop_screen_win_headless.h new file mode 100644 index 0000000..2a7f363d --- /dev/null +++ b/ui/views/widget/desktop_aura/desktop_screen_win_headless.h
@@ -0,0 +1,43 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_SCREEN_WIN_HEADLESS_H_ +#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_SCREEN_WIN_HEADLESS_H_ + +#include <vector> + +#include "ui/display/win/screen_win_headless.h" +#include "ui/gfx/geometry/point.h" +#include "ui/views/views_export.h" + +namespace views { + +class VIEWS_EXPORT DesktopScreenWinHeadless + : public display::win::ScreenWinHeadless { + public: + DesktopScreenWinHeadless(); + DesktopScreenWinHeadless(const DesktopScreenWinHeadless&) = delete; + DesktopScreenWinHeadless& operator=(const DesktopScreenWinHeadless&) = delete; + ~DesktopScreenWinHeadless() override; + + private: + // display::win::ScreenWin: + HWND GetHWNDFromNativeWindow(gfx::NativeWindow window) const override; + gfx::NativeWindow GetNativeWindowFromHWND(HWND hwnd) const override; + bool IsNativeWindowOccluded(gfx::NativeWindow window) const override; + std::optional<bool> IsWindowOnCurrentVirtualDesktop( + gfx::NativeWindow window) const override; + + // display::win::ScreenWinHeadless: + gfx::Rect GetNativeWindowBoundsInScreen( + gfx::NativeWindow window) const override; + gfx::Rect GetHeadlessWindowBounds( + gfx::AcceleratedWidget window) const override; + std::vector<gfx::NativeWindow> GetNativeWindowsAtScreenPoint( + const gfx::Point& point) const override; +}; + +} // namespace views + +#endif // UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_SCREEN_WIN_HEADLESS_H_
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_list_v2.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_list_v2.ts index ee8b9cb3..004adbb27 100644 --- a/ui/webui/resources/cr_components/certificate_manager/certificate_list_v2.ts +++ b/ui/webui/resources/cr_components/certificate_manager/certificate_list_v2.ts
@@ -102,6 +102,7 @@ noCollapse: boolean = false; hideIfEmpty: boolean = false; private expanded_: boolean = true; + private hideEverything_: boolean; private certificates_: SummaryCertInfo[] = []; private hasCerts_: boolean;
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_manager.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_manager.ts index 6a8c591..0b70b93 100644 --- a/ui/webui/resources/cr_components/certificate_manager/certificate_manager.ts +++ b/ui/webui/resources/cr_components/certificate_manager/certificate_manager.ts
@@ -163,6 +163,7 @@ private errorDialogModel_: CertificatesError|CertificatesImportError|null; private activeDialogAnchor_: HTMLElement|null; private isKiosk_: boolean; + private tabNames_: string[]; override connectedCallback() {
diff --git a/ui/webui/resources/cr_components/certificate_manager/certificate_manager_v2.ts b/ui/webui/resources/cr_components/certificate_manager/certificate_manager_v2.ts index 70af51e..6c96964 100644 --- a/ui/webui/resources/cr_components/certificate_manager/certificate_manager_v2.ts +++ b/ui/webui/resources/cr_components/certificate_manager/certificate_manager_v2.ts
@@ -254,6 +254,7 @@ } private selectedPage_: Page; + private userSubpageLists_: SubpageCertificateList[]; private toastMessage_: string; private showInfoDialog_: boolean = false; private infoDialogTitle_: string; @@ -261,6 +262,7 @@ private showPasswordDialog_: boolean = false; private passwordEntryResolver_: PromiseResolver<PasswordResult>|null = null; private showConfirmationDialog_: boolean = false; + private showSearch_: boolean; private confirmationDialogTitle_: string; private confirmationDialogMessage_: string; private confirmationDialogResolver_: PromiseResolver<ConfirmationResult>|
diff --git a/ui/webui/resources/cr_components/certificate_manager/local_certs_section_v2.ts b/ui/webui/resources/cr_components/certificate_manager/local_certs_section_v2.ts index 45cfd910..fa64831 100644 --- a/ui/webui/resources/cr_components/certificate_manager/local_certs_section_v2.ts +++ b/ui/webui/resources/cr_components/certificate_manager/local_certs_section_v2.ts
@@ -100,6 +100,7 @@ private numSystemCertsString_: string; private importOsCertsEnabled_: boolean; private importOsCertsEnabledManaged_: boolean; + private showViewOsCertsLinkRow_: boolean; // </if> override ready() {
diff --git a/ui/webui/resources/cr_elements/focus_row_mixin.ts b/ui/webui/resources/cr_elements/focus_row_mixin.ts index 2890198..bfc98940 100644 --- a/ui/webui/resources/cr_elements/focus_row_mixin.ts +++ b/ui/webui/resources/cr_elements/focus_row_mixin.ts
@@ -83,6 +83,8 @@ declare private row_: VirtualFocusRow|null; declare private mouseFocused_: boolean; + declare id: string; + // For notifying when the row is in focus. declare isFocused: boolean;
diff --git a/v8 b/v8 index 7d37a54..5c9986d 160000 --- a/v8 +++ b/v8
@@ -1 +1 @@ -Subproject commit 7d37a54be8c122951b6b553a58c664a38252d8b4 +Subproject commit 5c9986d77733643967d10a216bcb594ccfe04b07