diff --git a/DEPS b/DEPS index bb3a0f9..14f10c2 100644 --- a/DEPS +++ b/DEPS
@@ -305,11 +305,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. - 'src_internal_revision': '86a4a8afd51091e4227435859e44c9be53d99e77', + 'src_internal_revision': '1f6db40eb209591b24ffd779aea31c890eab5392', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'b1e89bda2bdee3ed53f7db5aca2bea2e9b4e3801', + 'skia_revision': 'bb3b6bd4be0dd757165a5723e1794f7ad2211d49', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -317,7 +317,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '7a7681cc8f888e72663530ca2cc997d9febd08e0', + 'angle_revision': '62861200bff6e265d6518ef1faa0f2eb90439dbc', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -377,7 +377,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': '36df0d4649cfdcce5557ce85f43dc6e9d4712dd4', + 'crossbench_revision': '02fdfd11a339e4eff97c2ef1b83c0e46b7e4476d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling CrossBench # and whatever else without interference from each other. @@ -397,7 +397,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': '5784d5e1f6e3739f966d781b31a4677345300d8b', + 'devtools_frontend_revision': '3e5b3d89cc270b6f1acb093fbafb0f7e421ce505', # 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. @@ -537,7 +537,7 @@ # If you change this, also update the libc++ revision in # //buildtools/deps_revisions.gni. - 'libcxx_revision': '4b4a57f5cf627639c041368120af9d69ed40032c', + 'libcxx_revision': 'b77132b512d5411f8393fd3decb3abaeaf1d3ec8', # GN CIPD package version. 'gn_version': 'git_revision:81b24e01531ecf0eff12ec9359a555ec3944ec4e', @@ -1190,7 +1190,7 @@ 'packages': [ { 'package': 'chromium/chrome/android/orderfiles/arm', - 'version': 'odHSRKf-lqZUhAzYJBTn06ZkrAmld0Lk9DfHS4iqXkYC', + 'version': '-rOfgav0B89L-dsSMLBPzh3v8-cSms3U0aBk87ueRusC', }, ], 'condition': 'checkout_android', @@ -1201,7 +1201,7 @@ 'packages': [ { 'package': 'chromium/chrome/android/orderfiles/arm64', - 'version': 'pYFjfo7uufXiZgxj6Ux6O5pptoO8pSPGCj8A7atjVREC', + 'version': 'YpEADcBXBPOatmNhfHm4_Xw0e13GTQf-Jkywy_8idtAC', }, ], 'condition': 'checkout_android', @@ -1212,7 +1212,7 @@ 'packages': [ { 'package': 'chromium/android_webview/tools/orderfiles/arm64', - 'version': 'aieguWx_NJsW3t7Z8jZYXo8d3PXv3o62E29oGinvVhwC', + 'version': '5hYYpvtCPy4swjywiVxlVI69GRrr_knsPk_4PAV7X50C', }, ], 'condition': 'checkout_android', @@ -1708,7 +1708,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'PiWEvpu3FVuQ4igamM9CqOVI0KJOH5cB7U_n-diCCFgC', + 'version': 'u-4GkHeumu0D2o8hkQbMGiMzvACyw_8TYdEfox0QyWYC', }, ], 'condition': 'checkout_android and non_git_source', @@ -2908,7 +2908,7 @@ 'dep_type': 'cipd', }, - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@5557290e35deb7e7e21a6f4d36d487034ef75171', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@80a8334f002c4116b87738d477880e3d38dd445c', 'src/third_party/glslang/src': '{chromium_git}/external/github.com/KhronosGroup/glslang@a57276bf558f5cf94d3a9854ebdf5a2236849a5a', '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@01e0577914a75a2569c846778c2f93aa8e6feddd', @@ -2960,7 +2960,7 @@ Var('chromium_git') + '/webpagereplay.git' + '@' + Var('webpagereplay_revision'), 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'f6a1ab593b6a0fa6c7e41d65cb84c8e80b5a5890', + Var('webrtc_git') + '/src.git' + '@' + 'dfcd6e3b19ad85c5a43e30927e9a250a92e3a927', # 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. @@ -3093,7 +3093,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/boca_app/app', - 'version': 'xbgNtV2kRNxxoSAipwPzBobmXp9EgCQQe_QqUR-FbqQC', + 'version': 'P2tMhg4ib0AZJ4AN33kNM5uJvyJYVI6zfERI-VjYub0C', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -3148,7 +3148,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/projector_app/app', - 'version': 'WY34MthaHSoLRlNn_4PdHqa8cnu0_Tt0N0gATLiyhWAC', + 'version': 'rUTCmEf_AUepZRyzLAeG3rRQDYv1_qe-ZzqMrI8pPuwC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -3741,7 +3741,7 @@ 'src/ios_internal': { 'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' + - '9a03b3ecb0093146ef15ae88856b4a5663c9d119', + '81bfcfd0e372697e9f8107b3a59db56caef28472', 'condition': 'checkout_ios and checkout_src_internal', },
diff --git a/android_webview/browser/gfx/begin_frame_source_webview_unittest.cc b/android_webview/browser/gfx/begin_frame_source_webview_unittest.cc index 68f8b9f..7440e757 100644 --- a/android_webview/browser/gfx/begin_frame_source_webview_unittest.cc +++ b/android_webview/browser/gfx/begin_frame_source_webview_unittest.cc
@@ -205,12 +205,12 @@ // Re-Add observer inside OnBeginFrame so it will trigger missed BeginFrame EXPECT_CALL(observer_, OnBeginFrame(testing::_)) - .WillRepeatedly(testing::Invoke([&](const viz::BeginFrameArgs& args) { + .WillRepeatedly([&](const viz::BeginFrameArgs& args) { if (args.type == viz::BeginFrameArgs::MISSED) return; begin_frame_source_.RemoveObserver(&observer_); begin_frame_source_.AddObserver(&observer_); - })); + }); test_begin_frame_source_.OnBeginFrame(BeginFrameArgsForTesting(1));
diff --git a/android_webview/common/aw_feature_map.cc b/android_webview/common/aw_feature_map.cc index 1d43f5d..3eb289a 100644 --- a/android_webview/common/aw_feature_map.cc +++ b/android_webview/common/aw_feature_map.cc
@@ -64,7 +64,6 @@ &features::kWebViewSkipInterceptsForPrefetch, &features::kWebViewStartupTasksYieldToNative, &features::kWebViewTestFeature, - &features::kWebViewUseBackgroundThreadForGms, &features::kWebViewUseInitialNetworkStateAtStartup, &features::kWebViewUseMetricsUploadService, &features::kWebViewUseMetricsUploadServiceOnlySdkRuntime,
diff --git a/android_webview/common/aw_features.cc b/android_webview/common/aw_features.cc index 421489c..874f6c6 100644 --- a/android_webview/common/aw_features.cc +++ b/android_webview/common/aw_features.cc
@@ -257,11 +257,6 @@ BASE_FEATURE(kAndroidMetricsAsyncMetricLogging, base::FEATURE_DISABLED_BY_DEFAULT); -// Tells the Google Service, GMS, to use a background thread for its -// Service bind and connection calls. -BASE_FEATURE(kWebViewUseBackgroundThreadForGms, - base::FEATURE_DISABLED_BY_DEFAULT); - // Reduce when the app's copy of the finch seed expires. This makes WebView more // aggressive in requesting a new copy of its finch seed. BASE_FEATURE(kWebViewReducedSeedExpiration, base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/android_webview/common/aw_features.h b/android_webview/common/aw_features.h index 9bbe404..58af20c 100644 --- a/android_webview/common/aw_features.h +++ b/android_webview/common/aw_features.h
@@ -65,7 +65,6 @@ extern const base::FeatureParam<double> kWebViewCodeCacheSizeLimitMultiplier; BASE_DECLARE_FEATURE(kWebViewConnectToComponentProviderInBackground); BASE_DECLARE_FEATURE(kAndroidMetricsAsyncMetricLogging); -BASE_DECLARE_FEATURE(kWebViewUseBackgroundThreadForGms); BASE_DECLARE_FEATURE(kWebViewReducedSeedExpiration); BASE_DECLARE_FEATURE(kWebViewReducedSeedRequestPeriod); BASE_DECLARE_FEATURE(kWebViewEarlyStartupTracing);
diff --git a/android_webview/common/aw_switches.cc b/android_webview/common/aw_switches.cc index be7a06c..c02a9f8 100644 --- a/android_webview/common/aw_switches.cc +++ b/android_webview/common/aw_switches.cc
@@ -125,9 +125,6 @@ const char kWebViewStartupTasksYieldToNative[] = "webview-startup-tasks-yield-to-native"; -const char kWebViewUseBackgroundThreadForGms[] = - "webview-use-background-thread-for-gms"; - const char kStartupNonBlockingWebViewConstructor[] = "startup-non-blocking-webview-constructor"; } // namespace switches
diff --git a/android_webview/common/aw_switches.h b/android_webview/common/aw_switches.h index d236b5f5..4bf1621 100644 --- a/android_webview/common/aw_switches.h +++ b/android_webview/common/aw_switches.h
@@ -34,7 +34,6 @@ extern const char kWebViewUseStartupTasksLogic[]; extern const char kWebViewUseStartupTasksLogicP2[]; extern const char kWebViewStartupTasksYieldToNative[]; -extern const char kWebViewUseBackgroundThreadForGms[]; extern const char kStartupNonBlockingWebViewConstructor[]; } // namespace switches
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java index 6f30bc2..1f173f7 100644 --- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java +++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -1119,10 +1119,6 @@ Flag.baseFeature( AwFeatures.WEBVIEW_USE_RENDERING_HEURISTIC, "Apply smoothing Skia options when WebView detects it's running on a TV device."), - Flag.commandLine( - AwSwitches.WEBVIEW_USE_BACKGROUND_THREAD_FOR_GMS, - "Tells the Google Service, GMS, to use a background thread for its Service bind and" - + " connection calls."), Flag.baseFeature( UiBaseFeatures.SEND_EMPTY_GESTURE_SCROLL_UPDATE, "Send GestureScrollUpdates together with TouchMoves, including empty GSUs for 0"
diff --git a/android_webview/java/src/org/chromium/android_webview/common/WebViewCachedFlags.java b/android_webview/java/src/org/chromium/android_webview/common/WebViewCachedFlags.java index 7b60895..4c0774a 100644 --- a/android_webview/java/src/org/chromium/android_webview/common/WebViewCachedFlags.java +++ b/android_webview/java/src/org/chromium/android_webview/common/WebViewCachedFlags.java
@@ -92,8 +92,6 @@ DefaultState.DISABLED, AwFeatures.WEBVIEW_STARTUP_TASKS_YIELD_TO_NATIVE, DefaultState.DISABLED, - AwFeatures.WEBVIEW_USE_BACKGROUND_THREAD_FOR_GMS, - DefaultState.DISABLED, AwFeatures.WEBVIEW_REDUCED_SEED_EXPIRATION, DefaultState.DISABLED, AwFeatures.WEBVIEW_REDUCED_SEED_REQUEST_PERIOD,
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 913d1f9..3b42a7b 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -92,7 +92,7 @@ // Enables a setting to automatically sign out a user when their account signs // in on a new device. -BASE_FEATURE(kAutoSignOut, base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kAutoSignOut, base::FEATURE_ENABLED_BY_DEFAULT); // Enables params tuning experiment for autocorrect on ChromeOS. BASE_FEATURE(kAutocorrectParamsTuning, base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/buildtools/deps_revisions.gni b/buildtools/deps_revisions.gni index 95307056..78024f8 100644 --- a/buildtools/deps_revisions.gni +++ b/buildtools/deps_revisions.gni
@@ -5,5 +5,5 @@ declare_args() { # Used to cause full rebuilds on libc++ rolls. This should be kept in sync # with the libcxx_revision var in //DEPS. - libcxx_revision = "4b4a57f5cf627639c041368120af9d69ed40032c" + libcxx_revision = "b77132b512d5411f8393fd3decb3abaeaf1d3ec8" }
diff --git a/buildtools/third_party/libc++/libcxx_headers.gni b/buildtools/third_party/libc++/libcxx_headers.gni index 8a042d7..b96123a 100644 --- a/buildtools/third_party/libc++/libcxx_headers.gni +++ b/buildtools/third_party/libc++/libcxx_headers.gni
@@ -11,7 +11,7 @@ import("//buildtools/deps_revisions.gni") assert( - libcxx_revision == "4b4a57f5cf627639c041368120af9d69ed40032c", + libcxx_revision == "b77132b512d5411f8393fd3decb3abaeaf1d3ec8", "libcxx_headers.gni and third_party/libc++ are out of sync.$0x0A$0x0AIf you were messing around with the libc++ repository, run:$0x0A`buildtools/third_party/libc++/generate_libcxx_headers.py`$0x0A$0x0AIf the script doesn't resolve the error, file a bug to msta@ with reproduction details.$0x0A") libcxx_headers = [
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index da582a5..6a9b0e94 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -264,7 +264,6 @@ "raster/raster_query_queue.h", "raster/raster_source.cc", "raster/raster_source.h", - "raster/scoped_grcontext_access.h", "raster/single_thread_task_graph_runner.cc", "raster/single_thread_task_graph_runner.h", "raster/staging_buffer_pool.cc",
diff --git a/cc/raster/scoped_grcontext_access.h b/cc/raster/scoped_grcontext_access.h deleted file mode 100644 index 66344ea..0000000 --- a/cc/raster/scoped_grcontext_access.h +++ /dev/null
@@ -1,30 +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 CC_RASTER_SCOPED_GRCONTEXT_ACCESS_H_ -#define CC_RASTER_SCOPED_GRCONTEXT_ACCESS_H_ - -#include "base/memory/raw_ptr.h" -#include "components/viz/common/gpu/raster_context_provider.h" -#include "gpu/command_buffer/client/raster_interface.h" - -// The following class is needed to correctly reset GL state when using a -// GrContext on a RasterInterface enabled context. -class ScopedGrContextAccess { - public: - explicit ScopedGrContextAccess(viz::RasterContextProvider* context_provider) - : context_provider_(context_provider) { - gpu::raster::RasterInterface* ri = context_provider_->RasterInterface(); - ri->BeginGpuRaster(); - } - ~ScopedGrContextAccess() { - gpu::raster::RasterInterface* ri = context_provider_->RasterInterface(); - ri->EndGpuRaster(); - } - - private: - raw_ptr<viz::RasterContextProvider> context_provider_; -}; - -#endif // CC_RASTER_SCOPED_GRCONTEXT_ACCESS_H_
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc index c94cead5..801679c 100644 --- a/cc/tiles/gpu_image_decode_cache.cc +++ b/cc/tiles/gpu_image_decode_cache.cc
@@ -36,7 +36,6 @@ #include "cc/base/histograms.h" #include "cc/base/switches.h" #include "cc/paint/paint_flags.h" -#include "cc/raster/scoped_grcontext_access.h" #include "cc/raster/tile_task.h" #include "cc/tiles/mipmap_util.h" #include "cc/tiles/raster_dark_mode_filter.h"
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/AutofillKeyboardAccessoryIntegrationTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/AutofillKeyboardAccessoryIntegrationTest.java index 28052ed..4f80a218 100644 --- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/AutofillKeyboardAccessoryIntegrationTest.java +++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/AutofillKeyboardAccessoryIntegrationTest.java
@@ -64,6 +64,7 @@ import java.util.function.Supplier; /** Integration tests for autofill keyboard accessory. */ +// TODO(crbug.com/447076444): Enable Keyboard Accessory revamp flag @RunWith(ChromeJUnit4ClassRunner.class) @Batch(Batch.PER_CLASS) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) @@ -226,19 +227,16 @@ mHelper.clickNode("NAME_FIRST", 1, FocusedFieldType.FILLABLE_NON_SEARCH_FIELD); mHelper.waitForKeyboardAccessoryToBeShown(true); - for (int i = 0; i < mHelper.getAccessoryBarView().getAdapter().getItemCount(); i++) { - performOnRecyclerViewNthItem( - withId(R.id.bar_items_view), - i, - createClickActionWithFlags(MotionEvent.FLAG_WINDOW_IS_OBSCURED, false)); - onView(withId(R.id.keyboard_accessory)).check(matches(isDisplayed())); - performOnRecyclerViewNthItem( - withId(R.id.bar_items_view), - i, - createClickActionWithFlags( - MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED, false)); - onView(withId(R.id.keyboard_accessory)).check(matches(isDisplayed())); - } + performOnRecyclerViewNthItem( + withId(R.id.bar_items_view), + 0, + createClickActionWithFlags(MotionEvent.FLAG_WINDOW_IS_OBSCURED, false)); + onView(withId(R.id.keyboard_accessory)).check(matches(isDisplayed())); + performOnRecyclerViewNthItem( + withId(R.id.bar_items_view), + 0, + createClickActionWithFlags(MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED, false)); + onView(withId(R.id.keyboard_accessory)).check(matches(isDisplayed())); // Close the accessory by clicking on one of the suggestions. onView(withId(R.id.bar_items_view)).perform(actionOnItemAtPosition(0, click())); @@ -267,6 +265,7 @@ @Test @SmallTest + @DisableFeatures({ChromeFeatureList.AUTOFILL_ANDROID_DESKTOP_KEYBOARD_ACCESSORY_REVAMP}) @DisableIf.Build( sdk_equals = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, message = "crbug.com/377939398") @@ -303,6 +302,7 @@ @Test @MediumTest + @DisableFeatures({ChromeFeatureList.AUTOFILL_ANDROID_DESKTOP_KEYBOARD_ACCESSORY_REVAMP}) public void testSheetHasMinimumSizeWhenTriggeredBySuggestion() throws TimeoutException { MultiWindowUtils.getInstance().setIsInMultiWindowModeForTesting(true); startAtTestPage(MultiWindowKeyboard::new);
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingIntegrationTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingIntegrationTest.java index 98fb078..9651dd8 100644 --- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingIntegrationTest.java +++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingIntegrationTest.java
@@ -44,7 +44,9 @@ import org.chromium.base.test.util.CriteriaHelper; import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.DisabledTest; +import org.chromium.base.test.util.Features.DisableFeatures; import org.chromium.base.test.util.Restriction; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.keyboard_accessory.button_group_component.KeyboardAccessoryButtonGroupView; import org.chromium.chrome.browser.layouts.LayoutTestUtils; @@ -60,8 +62,10 @@ import java.util.concurrent.atomic.AtomicReference; /** Integration tests for keyboard accessory and accessory sheet with other Chrome components. */ +// TODO(crbug.com/447076444): Enable Keyboard Accessory revamp flag @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +@DisableFeatures({ChromeFeatureList.AUTOFILL_ANDROID_DESKTOP_KEYBOARD_ACCESSORY_REVAMP}) public class ManualFillingIntegrationTest { @Rule public final FreshCtaTransitTestRule mActivityTestRule =
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingUiCaptureTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingUiCaptureTest.java index 5a370ba9..3e9050e 100644 --- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingUiCaptureTest.java +++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingUiCaptureTest.java
@@ -40,9 +40,13 @@ * like shadows, padding and RTL differences. Logic integration tests involving all filling * components belong into {@link ManualFillingIntegrationTest}. */ +// TODO(crbug.com/447076444): Enable Keyboard Accessory revamp flag @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) -@Features.DisableFeatures({ChromeFeatureList.EDGE_TO_EDGE_BOTTOM_CHIN}) +@Features.DisableFeatures({ + ChromeFeatureList.EDGE_TO_EDGE_BOTTOM_CHIN, + ChromeFeatureList.AUTOFILL_ANDROID_DESKTOP_KEYBOARD_ACCESSORY_REVAMP +}) public class ManualFillingUiCaptureTest { @Rule public final FreshCtaTransitTestRule mActivityTestRule =
diff --git a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java index 76697ef..3d7e028 100644 --- a/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java +++ b/chrome/android/features/keyboard_accessory/junit/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryControllerTest.java
@@ -25,6 +25,7 @@ import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.ANIMATE_SUGGESTIONS_FROM_TOP; import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.ANIMATION_LISTENER; import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.BAR_ITEMS; +import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.BAR_ITEMS_FIXED; import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.HAS_STICKY_LAST_ITEM; import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.HAS_SUGGESTIONS; import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.OBFUSCATED_CHILD_AT_CALLBACK; @@ -635,13 +636,35 @@ mCoordinator.setSuggestions(List.of(mock(AutofillSuggestion.class)), mMockAutofillDelegate); - assertThat(mModel.get(BAR_ITEMS).size(), is(3)); + assertThat(mModel.get(BAR_ITEMS), contains(instanceOf(AutofillBarItem.class))); assertThat( - mModel.get(BAR_ITEMS), - contains( - instanceOf(AutofillBarItem.class), - instanceOf(SheetOpenerBarItem.class), - instanceOf(DismissBarItem.class))); + mModel.get(BAR_ITEMS_FIXED), + contains(instanceOf(SheetOpenerBarItem.class), instanceOf(DismissBarItem.class))); + } + + @Test + public void testLargeFormFactorHasFixedItems() { + when(mMockIsLargeFormFactorSupplier.get()).thenReturn(true); + Provider<Action[]> generationProvider = new Provider<>(GENERATE_PASSWORD_AUTOMATIC); + mCoordinator.registerActionProvider(generationProvider); + AutofillSuggestion suggestion = + new AutofillSuggestion.Builder() + .setLabel("Suggestion") + .setSubLabel("") + .setSuggestionType(SuggestionType.AUTOCOMPLETE_ENTRY) + .setFeatureForIph("") + .build(); + Action generationAction = new Action(GENERATE_PASSWORD_AUTOMATIC, (a) -> {}); + + mCoordinator.setSuggestions(List.of(suggestion), mMockAutofillDelegate); + generationProvider.notifyObservers(new Action[] {generationAction}); + + assertThat(mModel.get(BAR_ITEMS).size(), is(2)); + assertThat(mModel.get(BAR_ITEMS).get(0).getAction(), is(generationAction)); + assertThat(mModel.get(BAR_ITEMS).get(1), instanceOf(AutofillBarItem.class)); + assertThat( + mModel.get(BAR_ITEMS_FIXED), + contains(instanceOf(SheetOpenerBarItem.class), instanceOf(DismissBarItem.class))); } private int getGenerationImpressionCount() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java index ad1d512..6628294 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java
@@ -1819,6 +1819,26 @@ .check(matches(hasBackgroundColor(R.color.iph_highlight_blue))); } + /** Tests the location permission subpage of the PageInfo UI. */ + @Test + @MediumTest + @Features.EnableFeatures(PermissionsAndroidFeatureList.APPROXIMATE_GEOLOCATION_PERMISSION) + public void testShowLocationPermissionSubpage() throws IOException { + addSomePermissions(mTestServerRule.getServer().getURL("/")); + loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml)); + onView(withId(R.id.page_info_permissions_row)).perform(click()); + onViewWaiting(allOf(withText("Control this site's access to your device"), isDisplayed())); + + onView(withText("Location")).perform(click()); + onViewWaiting(allOf(withText(R.string.website_settings_device_location), isDisplayed())); + onViewWaiting( + allOf( + withText( + "Sites usually use your location for relevant features or info," + + " like local news or nearby shops"), + isDisplayed())); + } + /** * Tests the permissions page of the PageInfo UI with permissions and a particular permission * row highlight. @@ -1865,6 +1885,32 @@ }); } + /** Tests that navigation between nested subpages works as expected. */ + @Test + @MediumTest + @Features.EnableFeatures(PermissionsAndroidFeatureList.APPROXIMATE_GEOLOCATION_PERMISSION) + public void testNestedSubpageNavigation() throws IOException { + addSomePermissions(mTestServerRule.getServer().getURL("/")); + loadUrlAndOpenPageInfo(mTestServerRule.getServer().getURL(sSimpleHtml)); + PageInfoController controller = PageInfoController.getLastPageInfoController(); + + // Open first subpage. + onView(withId(R.id.page_info_permissions_row)).perform(click()); + onViewWaiting(allOf(withText("Control this site's access to your device"), isDisplayed())); + + // Open second subpage + onView(withText("Location")).perform(click()); + onViewWaiting(allOf(withText(R.string.website_settings_device_location), isDisplayed())); + + // Verify back button press takes you back to the first subpage. + controller.exitSubpage(); + onViewWaiting(allOf(withText("Control this site's access to your device"), isDisplayed())); + + // Verify another back button press takes you back to the main page info view. + controller.exitSubpage(); + onViewWaiting(allOf(withId(R.id.page_info_permissions_row), isDisplayed())); + } + /** Tests the summary string of the history page of the PageInfo UI. */ @Test @MediumTest
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index d30a58e..e9d5aa7 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -495,15 +495,6 @@ <message name="IDS_HISTORY_SYNC_HISTORY_PROMO" desc="Text of the sync hystory promo. This will show up if a user is not logged in and has no synced tabs."> Browse across devices </message> - <message translateable="false" name="IDS_HISTORY_SYNC_HISTORY_PROMO_DESC" desc="Description of the sync hystory promo. Further tells users to sign in and sync hystory to see synced tabs from other devices."> - To get your tabs from your other devices, sign in and sync history. You can stop syncing anytime in settings. Google may personalize Search and other services based on your history. - </message> - <message translateable="false" name="IDS_HISTORY_SIGNED_IN_SYNC_HISTORY_PROMO" desc="Text of the sync hystory promo. This will show up if a user is not logged in and has no synced tabs."> - Continue from another device - </message> - <message translateable="false" name="IDS_HISTORY_SIGNED_IN_SYNC_HISTORY_PROMO_DESC" desc="Description of the sync hystory promo. Further tells users to sign in and sync hystory to see synced tabs from other devices."> - To get your tabs from your other devices, sync your tabs and History to . You can stop syncing anytime in settings. Google may personalize Search and other services based on your History. - </message> <message name="IDS_RECENT_TABS_SYNC_HISTORY_PROMO_BODY_SIGNED_OUT" desc="Body of the sync hystory promo for signed out users. Tells users to sign in and sync hystory to see synced tabs, passwords, and other data from other devices."> To get your tabs from your other devices, sign in and sync history. You’ll also get your passwords and more on all your devices. You can stop syncing anytime in settings. Google may personalize Search and other services based on your history. </message>
diff --git a/chrome/app/profiles_strings.grdp b/chrome/app/profiles_strings.grdp index b63ac27..f1868a5d 100644 --- a/chrome/app/profiles_strings.grdp +++ b/chrome/app/profiles_strings.grdp
@@ -1202,14 +1202,20 @@ <message name="IDS_HISTORY_SYNC_DISABLED_ERROR_DESCRIPTION" desc="Message that is shown in an error dialog when a user tries to sign in to use a service that requires history sync opt in (e.g. sharing/joining tab groups), but sync is disabled."> Your organization turned off saving history and tabs in your Google Account </message> - <!-- History Sync Opt-in Expansion Pill Desktop --> + <!-- Avatar Button Promos Desktop --> <message name="IDS_AVATAR_BUTTON_SYNC_HISTORY" desc="The avatar button label for the history sync promo. When clicked, it opens the profile menu with the sync button."> Sync history? </message> - <message name="IDS_AVATAR_BUTTON_SYNC_PROMO" desc="The avatar button label for the sync promo. When clicked, it opens the profile menu with the sync button."> + <message name="IDS_AVATAR_BUTTON_SYNC_PROMO" desc="The avatar button label for the sync promo. When clicked, it opens the profile menu with the sync button. This is also used to Batch Upload as well."> Back up your stuff? </message> - <!-- Profile Menu Sync Promo Desktop --> + <message name="IDS_AVATAR_BUTTON_BATCH_UPLOAD_PROMO" desc="The avatar button label for the Batch Upload promo. When clicked, it opens the profile menu with a button that would open the Batch Upload."> + Save in account? + </message> + <message name="IDS_AVATAR_BUTTON_BATCH_UPLOAD_PROMO_WITH_BOOKMARK_CLEANUP_PROMO" desc="The avatar button label for the Batch Upload promo with an emphasis on Bookmarks. When clicked, it opens the profile menu with a button that would open the Batch Upload."> + Clean up bookmarks? + </message> + <!-- Profile Menu Promos Desktop --> <message name="IDS_PROFILE_MENU_SYNC_PROMO_SYNC_HISTORY_DESCRIPTION" desc="The description for the sync promo in the profile menu opened from the 'Sync history?' history sync opt-in identity pill."> To easily get back to sites you’ve visited, sync your history and tabs to <ph name="ACCOUNT_EMAIL">$1<ex>elisa.beckett@gmail.com</ex></ph> </message> @@ -1222,6 +1228,15 @@ <message name="IDS_PROFILE_MENU_BUTTON_LABEL_WITH_SYNC_PROMO" desc="The button label in the Profile Menu identity section for users that can see the Sync Promo in the Avatar button. When clicked, it opens the turn on sync dialog."> Continue </message> + <message name="IDS_PROFILE_MENU_PROMO_DESCRIPTION_WITH_BATCH_UPLOAD" desc="The description of the identity section in the Profile Menu for users that can see the Batch Upload promo in the Avatar button, when having local data. This describes the action presented right below it in the button."> + To get your passwords, bookmarks, and more on all your devices, save them in your Google Account + </message> + <message name="IDS_PROFILE_MENU_PROMO_BUTTON_WITH_BATCH_UPLOAD" desc="The button label in the Profile Menu identity section for users that can see the Batch Upload promo in the Avatar button, when having local data. When clicked, it opens the Batch Upload dialog."> + Save in account + </message> + <message name="IDS_PROFILE_MENU_PROMO_DESCRIPTION_WITH_BATCH_UPLOAD_BOOKMARK_CLEANUP" desc="The description of the identity section in the Profile Menu for users that can see the Batch Upload promo in the Avatar button with the emphasis on Bookmarks cleanup, when having local data. This describes the action presented right below it in the button."> + To clean up any duplicate bookmarks, save them in your Google Account + </message> </if> <message name="IDS_SIGN_IN_BENEFITS_IPH_TEXT" desc="Text of the IPH bubble announcing benefits for users who signed in before the sync-to-signin migration."> While you're signed in, you can use the bookmarks, extensions, and more saved in your Google Account on all your devices
diff --git a/chrome/app/profiles_strings_grdp/IDS_AVATAR_BUTTON_BATCH_UPLOAD_PROMO.png.sha1 b/chrome/app/profiles_strings_grdp/IDS_AVATAR_BUTTON_BATCH_UPLOAD_PROMO.png.sha1 new file mode 100644 index 0000000..8aa54ca3 --- /dev/null +++ b/chrome/app/profiles_strings_grdp/IDS_AVATAR_BUTTON_BATCH_UPLOAD_PROMO.png.sha1
@@ -0,0 +1 @@ +efc56f5a456d2157dc68a809823cbcea458dacd7 \ No newline at end of file
diff --git a/chrome/app/profiles_strings_grdp/IDS_AVATAR_BUTTON_BATCH_UPLOAD_PROMO_WITH_BOOKMARK_CLEANUP_PROMO.png.sha1 b/chrome/app/profiles_strings_grdp/IDS_AVATAR_BUTTON_BATCH_UPLOAD_PROMO_WITH_BOOKMARK_CLEANUP_PROMO.png.sha1 new file mode 100644 index 0000000..3cc4b88b --- /dev/null +++ b/chrome/app/profiles_strings_grdp/IDS_AVATAR_BUTTON_BATCH_UPLOAD_PROMO_WITH_BOOKMARK_CLEANUP_PROMO.png.sha1
@@ -0,0 +1 @@ +0a83a01e22b9cf6b15eec179d2a66343c4b447f4 \ No newline at end of file
diff --git a/chrome/app/profiles_strings_grdp/IDS_PROFILE_MENU_PROMO_BUTTON_WITH_BATCH_UPLOAD.png.sha1 b/chrome/app/profiles_strings_grdp/IDS_PROFILE_MENU_PROMO_BUTTON_WITH_BATCH_UPLOAD.png.sha1 new file mode 100644 index 0000000..b8cc7348 --- /dev/null +++ b/chrome/app/profiles_strings_grdp/IDS_PROFILE_MENU_PROMO_BUTTON_WITH_BATCH_UPLOAD.png.sha1
@@ -0,0 +1 @@ +a297929b798c04f8127006239f12dea77bf38b1b \ No newline at end of file
diff --git a/chrome/app/profiles_strings_grdp/IDS_PROFILE_MENU_PROMO_DESCRIPTION_WITH_BATCH_UPLOAD.png.sha1 b/chrome/app/profiles_strings_grdp/IDS_PROFILE_MENU_PROMO_DESCRIPTION_WITH_BATCH_UPLOAD.png.sha1 new file mode 100644 index 0000000..ccebae8 --- /dev/null +++ b/chrome/app/profiles_strings_grdp/IDS_PROFILE_MENU_PROMO_DESCRIPTION_WITH_BATCH_UPLOAD.png.sha1
@@ -0,0 +1 @@ +93db8978f9d99c2855bcb9d4261a7b6c35c3d7cf \ No newline at end of file
diff --git a/chrome/app/profiles_strings_grdp/IDS_PROFILE_MENU_PROMO_DESCRIPTION_WITH_BATCH_UPLOAD_BOOKMARK_CLEANUP.png.sha1 b/chrome/app/profiles_strings_grdp/IDS_PROFILE_MENU_PROMO_DESCRIPTION_WITH_BATCH_UPLOAD_BOOKMARK_CLEANUP.png.sha1 new file mode 100644 index 0000000..51de49d --- /dev/null +++ b/chrome/app/profiles_strings_grdp/IDS_PROFILE_MENU_PROMO_DESCRIPTION_WITH_BATCH_UPLOAD_BOOKMARK_CLEANUP.png.sha1
@@ -0,0 +1 @@ +937d60265af4061e6aa6ce9cfe9736b79b8c2a9a \ No newline at end of file
diff --git a/chrome/app_shim/app_shim_controller.mm b/chrome/app_shim/app_shim_controller.mm index d7595e4..8edc68e 100644 --- a/chrome/app_shim/app_shim_controller.mm +++ b/chrome/app_shim/app_shim_controller.mm
@@ -282,9 +282,9 @@ std::move(feature_list), {"AppShimLaunchChromeSilently", "AppShimNotificationAttribution", "DcheckIsFatal", "DisallowSpaceCharacterInURLHostParsing", - "MojoBindingsInlineSLS", "MojoInlineMessagePayloads", "MojoIpcz", - "MojoIpczMemV2", "MojoTaskPerMessage", "StandardCompliantHostCharacters", - "UseAdHocSigningForWebAppShims", + "UseIDNAContextJRules", "MojoBindingsInlineSLS", + "MojoInlineMessagePayloads", "MojoIpcz", "MojoIpczMemV2", + "MojoTaskPerMessage", "UseAdHocSigningForWebAppShims", "SonomaAccessibilityActivationRefinements", "FeatureParamWithCache", "UseMachVouchers"}); }
diff --git a/chrome/browser/apps/app_preload_service/app_preload_service_browsertest.cc b/chrome/browser/apps/app_preload_service/app_preload_service_browsertest.cc index 15688ff..8272999 100644 --- a/chrome/browser/apps/app_preload_service/app_preload_service_browsertest.cc +++ b/chrome/browser/apps/app_preload_service/app_preload_service_browsertest.cc
@@ -43,9 +43,6 @@ AppPreloadServiceBrowserTest() : startup_check_resetter_( AppPreloadService::DisablePreloadsOnStartupForTesting()) { - feature_list_.InitWithFeatures( - {/*enabled_features=*/features::kAppPreloadService}, - /*disabled_features=*/{}); AppPreloadServiceFactory::SkipApiKeyCheckForTesting(true); } @@ -124,7 +121,6 @@ } private: - base::test::ScopedFeatureList feature_list_; net::EmbeddedTestServer https_server_; std::map<std::string, std::string> manifest_responses_; std::optional<proto::AppPreloadListResponse> apps_proto_;
diff --git a/chrome/browser/apps/app_preload_service/app_preload_service_factory.cc b/chrome/browser/apps/app_preload_service/app_preload_service_factory.cc index 70c244c..a07e21c 100644 --- a/chrome/browser/apps/app_preload_service/app_preload_service_factory.cc +++ b/chrome/browser/apps/app_preload_service/app_preload_service_factory.cc
@@ -49,10 +49,6 @@ // static bool AppPreloadServiceFactory::IsAvailable(Profile* profile) { - if (!base::FeatureList::IsEnabled(features::kAppPreloadService)) { - return false; - } - // Ensure that the build uses the Google-internal file containing the // official API keys, which are required to make queries to the Almanac. if (!google_apis::IsGoogleChromeAPIKeyUsed() && !g_skip_api_key_check) {
diff --git a/chrome/browser/apps/app_preload_service/app_preload_service_unittest.cc b/chrome/browser/apps/app_preload_service/app_preload_service_unittest.cc index 659a47f..e54ce8b 100644 --- a/chrome/browser/apps/app_preload_service/app_preload_service_unittest.cc +++ b/chrome/browser/apps/app_preload_service/app_preload_service_unittest.cc
@@ -56,8 +56,8 @@ AppPreloadServiceTest() : startup_check_resetter_( AppPreloadService::DisablePreloadsOnStartupForTesting()) { - scoped_feature_list_.InitWithFeatures( - {features::kAppPreloadService, kAppPreloadServiceEnableShelfPin}, {}); + scoped_feature_list_.InitWithFeatures({kAppPreloadServiceEnableShelfPin}, + {}); AppPreloadServiceFactory::SkipApiKeyCheckForTesting(true); }
diff --git a/chrome/browser/autofill/autofill_browsertest.cc b/chrome/browser/autofill/autofill_browsertest.cc index 4eceee4..e650c86 100644 --- a/chrome/browser/autofill/autofill_browsertest.cc +++ b/chrome/browser/autofill/autofill_browsertest.cc
@@ -31,6 +31,7 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/webdata_services/web_data_service_factory.h" +#include "chrome/test/base/chrome_test_utils.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/test_switches.h" #include "chrome/test/base/ui_test_utils.h" @@ -201,9 +202,9 @@ // of parsed profiles. int AggregateProfilesIntoAutofillPrefs(const std::string& filename) { std::string data; - base::FilePath data_file = - ui_test_utils::GetTestFilePath(base::FilePath().AppendASCII("autofill"), - base::FilePath().AppendASCII(filename)); + base::FilePath data_file = chrome_test_utils::GetTestFilePath( + base::FilePath().AppendASCII("autofill"), + base::FilePath().AppendASCII(filename)); { base::ScopedAllowBlockingForTesting allow_blocking; CHECK(base::ReadFileToString(data_file, &data));
diff --git a/chrome/browser/compose/chrome_compose_client.cc b/chrome/browser/compose/chrome_compose_client.cc index f32aba63..a38ea7c9 100644 --- a/chrome/browser/compose/chrome_compose_client.cc +++ b/chrome/browser/compose/chrome_compose_client.cc
@@ -44,6 +44,7 @@ #include "components/autofill/core/browser/filling/filling_product.h" #include "components/autofill/core/browser/foundations/autofill_client.h" #include "components/autofill/core/browser/suggestions/suggestion.h" +#include "components/autofill/core/browser/suggestions/suggestion_hiding_reason.h" #include "components/autofill/core/common/aliases.h" #include "components/autofill/core/common/form_field_data.h" #include "components/compose/core/browser/compose_features.h"
diff --git a/chrome/browser/extensions/api/autofill_private/autofill_ai_util.cc b/chrome/browser/extensions/api/autofill_private/autofill_ai_util.cc index 6253b7c3..7292f139 100644 --- a/chrome/browser/extensions/api/autofill_private/autofill_ai_util.cc +++ b/chrome/browser/extensions/api/autofill_private/autofill_ai_util.cc
@@ -24,6 +24,7 @@ #include "components/autofill/core/browser/data_model/autofill_ai/entity_type_names.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/integrators/autofill_ai/autofill_ai_labels.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/chrome/browser/keyboard_accessory/android/internal/java/res/layout/keyboard_accessory.xml b/chrome/browser/keyboard_accessory/android/internal/java/res/layout/keyboard_accessory.xml index 7cb98ff..0041059 100644 --- a/chrome/browser/keyboard_accessory/android/internal/java/res/layout/keyboard_accessory.xml +++ b/chrome/browser/keyboard_accessory/android/internal/java/res/layout/keyboard_accessory.xml
@@ -38,12 +38,18 @@ <androidx.recyclerview.widget.RecyclerView android:id="@+id/bar_items_view" - android:layout_width="match_parent" + android:layout_width="0dp" + android:layout_weight="1" android:layout_height="match_parent" android:requiresFadingEdge="horizontal" android:fadingEdgeLength="@dimen/keyboard_accessory_scroll_shadow_width" android:clipToPadding="false"/> + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/fixed_bar_items_view" + android:layout_width="wrap_content" + android:layout_height="match_parent" /> + </LinearLayout> </org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryView>
diff --git a/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryCoordinator.java b/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryCoordinator.java index 90d125ae..8d385cb5 100644 --- a/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryCoordinator.java +++ b/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryCoordinator.java
@@ -223,6 +223,13 @@ createUiConfiguration( context, AutofillImageFetcherFactory.getForProfile(profile)))); + mView.setFixedBarItemsAdapter( + createBarItemsAdapter( + mModel.get(KeyboardAccessoryProperties.BAR_ITEMS_FIXED), + mView, + createUiConfiguration( + context, + AutofillImageFetcherFactory.getForProfile(profile)))); mView.setFeatureEngagementTracker(TrackerFactory.getTrackerForProfile(profile)); mEdgeToEdgePadObserver = new EdgeToEdgePadObserver(
diff --git a/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMediator.java b/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMediator.java index d0ffab4f..271f2ae 100644 --- a/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMediator.java +++ b/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMediator.java
@@ -7,6 +7,7 @@ import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.ANIMATE_SUGGESTIONS_FROM_TOP; import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.ANIMATION_LISTENER; import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.BAR_ITEMS; +import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.BAR_ITEMS_FIXED; import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.DISABLE_ANIMATIONS_FOR_TESTING; import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.DISMISS_ITEM; import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.HAS_STICKY_LAST_ITEM; @@ -121,15 +122,7 @@ void setSuggestions(List<AutofillSuggestion> suggestions, AutofillDelegate delegate) { List<BarItem> retainedItems = collectItemsToRetain(AccessoryAction.AUTOFILL_SUGGESTION); retainedItems.addAll(toBarItems(suggestions, delegate)); - retainedItems.add(retainedItems.size(), mModel.get(SHEET_OPENER_ITEM)); - // TODO(crbug.com/441006939): Show dismiss on first launch too. - if (mIsLargeFormFactorSupplier.get() - && ChromeFeatureList.isEnabled( - ChromeFeatureList.AUTOFILL_ANDROID_DESKTOP_KEYBOARD_ACCESSORY_REVAMP)) { - retainedItems.add(retainedItems.size(), mModel.get(DISMISS_ITEM)); - } - mModel.get(BAR_ITEMS).set(retainedItems); - mModel.set(HAS_SUGGESTIONS, barHasSuggestions()); + setBarContents(retainedItems); } private boolean barHasSuggestions() { @@ -153,19 +146,39 @@ retainedItems.addAll( typeId == AccessoryAction.CREDMAN_CONDITIONAL_UI_REENTRY ? retainedItems.size() : 0, toBarItems(actions)); - retainedItems.add(retainedItems.size(), mModel.get(SHEET_OPENER_ITEM)); + setBarContents(retainedItems); + TraceEvent.end("KeyboardAccessoryMediator#onItemAvailable"); + } + + /** + * Sets the contents of the accessory bar. + * + * <p>This method updates the fixed items, adds the sheet opener to the scrollable items if not + * present in the fixed ones, and then sets the final scrollable item list on the model, + * updating the suggestion state. + * + * @param scrollableItems The list of {@link BarItem}s to be set on the scrollable part of the + * bar. + */ + private void setBarContents(List<BarItem> scrollableItems) { + // TODO(crbug.com/441006939): Show dismiss on first launch too. + List<BarItem> fixedBarItems = new ArrayList<BarItem>(); if (mIsLargeFormFactorSupplier.get() && ChromeFeatureList.isEnabled( ChromeFeatureList.AUTOFILL_ANDROID_DESKTOP_KEYBOARD_ACCESSORY_REVAMP)) { - retainedItems.add(mModel.get(DISMISS_ITEM)); + fixedBarItems.add(mModel.get(SHEET_OPENER_ITEM)); + fixedBarItems.add(mModel.get(DISMISS_ITEM)); + } else { + scrollableItems.add(mModel.get(SHEET_OPENER_ITEM)); } - mModel.get(BAR_ITEMS).set(retainedItems); + mModel.get(BAR_ITEMS_FIXED).set(fixedBarItems); + mModel.get(BAR_ITEMS).set(scrollableItems); mModel.set(HAS_SUGGESTIONS, barHasSuggestions()); - TraceEvent.end("KeyboardAccessoryMediator#onItemAvailable"); } private List<BarItem> collectItemsToRetain(@AccessoryAction int actionType) { List<BarItem> retainedItems = new ArrayList<>(); + // Fallback sheet menu and dismiss button are never retained. for (BarItem item : mModel.get(BAR_ITEMS)) { if (item.getAction() == null) continue; if (item.getAction().getActionType() == AccessoryAction.DISMISS) continue; @@ -326,7 +339,8 @@ || propertyKey == HAS_SUGGESTIONS || propertyKey == HAS_STICKY_LAST_ITEM || propertyKey == ANIMATE_SUGGESTIONS_FROM_TOP - || propertyKey == ANIMATION_LISTENER) { + || propertyKey == ANIMATION_LISTENER + || propertyKey == BAR_ITEMS_FIXED) { return; } assert false : "Every property update needs to be handled explicitly!";
diff --git a/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMetricsRecorder.java b/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMetricsRecorder.java index 23be8b9..5359336 100644 --- a/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMetricsRecorder.java +++ b/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryMetricsRecorder.java
@@ -55,6 +55,7 @@ } if (propertyKey == KeyboardAccessoryProperties.STYLE || propertyKey == KeyboardAccessoryProperties.SKIP_CLOSING_ANIMATION + || propertyKey == KeyboardAccessoryProperties.BAR_ITEMS_FIXED || propertyKey == KeyboardAccessoryProperties.DISABLE_ANIMATIONS_FOR_TESTING || propertyKey == KeyboardAccessoryProperties.SHOW_SWIPING_IPH || propertyKey == KeyboardAccessoryProperties.OBFUSCATED_CHILD_AT_CALLBACK
diff --git a/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryProperties.java b/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryProperties.java index bbe8def..dd1bb55 100644 --- a/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryProperties.java +++ b/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryProperties.java
@@ -48,6 +48,8 @@ */ @NullMarked class KeyboardAccessoryProperties { + static final ReadableObjectPropertyKey<ListModel<BarItem>> BAR_ITEMS_FIXED = + new ReadableObjectPropertyKey<>("bar_items_fixed"); static final ReadableObjectPropertyKey<ListModel<BarItem>> BAR_ITEMS = new ReadableObjectPropertyKey<>("bar_items"); static final WritableBooleanPropertyKey VISIBLE = new WritableBooleanPropertyKey("visible"); @@ -81,6 +83,7 @@ static PropertyModel.Builder defaultModelBuilder() { return new PropertyModel.Builder( DISABLE_ANIMATIONS_FOR_TESTING, + BAR_ITEMS_FIXED, BAR_ITEMS, VISIBLE, SKIP_CLOSING_ANIMATION, @@ -94,6 +97,7 @@ HAS_STICKY_LAST_ITEM, ANIMATE_SUGGESTIONS_FROM_TOP, ANIMATION_LISTENER) + .with(BAR_ITEMS_FIXED, new ListModel<>()) .with(BAR_ITEMS, new ListModel<>()) .with(VISIBLE, false) .with(SKIP_CLOSING_ANIMATION, false)
diff --git a/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryView.java b/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryView.java index b9cd230..2c6b24cb 100644 --- a/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryView.java +++ b/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryView.java
@@ -63,6 +63,7 @@ private boolean mAnimateSuggestionsFromTop; protected RecyclerView mBarItemsView; + protected RecyclerView mFixedBarItemsView; /** Interface that allows to react to animations. */ interface AnimationListener { @@ -238,6 +239,9 @@ mBarItemsView = findViewById(R.id.bar_items_view); initializeHorizontalRecyclerView(mBarItemsView); + mFixedBarItemsView = findViewById(R.id.fixed_bar_items_view); + mFixedBarItemsView.setLayoutManager( + new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false)); // Apply RTL layout changes to the view's children: int layoutDirection = isLayoutRtl() ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR; @@ -408,18 +412,26 @@ } void setBarItemsAdapter(RecyclerView.Adapter adapter) { + registerAdapter(adapter, mBarItemsView); + } + + void setFixedBarItemsAdapter(RecyclerView.Adapter adapter) { + registerAdapter(adapter, mFixedBarItemsView); + } + + private void registerAdapter(RecyclerView.Adapter adapter, RecyclerView view) { // Make sure the view updates the fallback icon padding whenever new items arrive. adapter.registerAdapterDataObserver( new RecyclerView.AdapterDataObserver() { @Override public void onItemRangeChanged(int positionStart, int itemCount) { super.onItemRangeChanged(positionStart, itemCount); - mBarItemsView.scrollToPosition(0); - mBarItemsView.invalidateItemDecorations(); + view.scrollToPosition(0); + view.invalidateItemDecorations(); onItemsChanged(); } }); - mBarItemsView.setAdapter(adapter); + view.setAdapter(adapter); } private void show() {
diff --git a/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryViewBinder.java b/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryViewBinder.java index 6e6b44d..5d92a8ec 100644 --- a/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryViewBinder.java +++ b/chrome/browser/keyboard_accessory/android/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/bar_component/KeyboardAccessoryViewBinder.java
@@ -9,6 +9,7 @@ import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.ANIMATE_SUGGESTIONS_FROM_TOP; import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.ANIMATION_LISTENER; import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.BAR_ITEMS; +import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.BAR_ITEMS_FIXED; import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.DISABLE_ANIMATIONS_FOR_TESTING; import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.DISMISS_ITEM; import static org.chromium.chrome.browser.keyboard_accessory.bar_component.KeyboardAccessoryProperties.HAS_STICKY_LAST_ITEM; @@ -377,8 +378,8 @@ * @param propertyKey A {@link PropertyKey}. */ static void bind(PropertyModel model, KeyboardAccessoryView view, PropertyKey propertyKey) { - if (propertyKey == BAR_ITEMS) { - // Intentionally empty. The adapter will observe changes to BAR_ITEMS. + if (propertyKey == BAR_ITEMS || propertyKey == BAR_ITEMS_FIXED) { + // Intentionally empty. The adapter will observe changes to bar items. } else if (propertyKey == DISABLE_ANIMATIONS_FOR_TESTING) { if (model.get(DISABLE_ANIMATIONS_FOR_TESTING)) { view.disableAnimationsForTesting(); // IN-TEST
diff --git a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc index 36fe36d..df59ecf 100644 --- a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc +++ b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
@@ -9,11 +9,13 @@ #include <cstdint> #include <memory> #include <string> +#include <string_view> #include <vector> #include "base/allocator/partition_alloc_support.h" #include "base/command_line.h" #include "base/compiler_specific.h" +#include "base/containers/fixed_flat_map.h" #include "base/cpu.h" #include "base/feature_list.h" #include "base/functional/bind.h" @@ -455,216 +457,209 @@ } using enum UmaLinuxDistro; - // This array must be kept sorted since it is binary searched. - constexpr std::pair<const char*, UmaLinuxDistro> kDistroPrefixes[] = { - {"alma", kAlma}, - {"alpine", kAlpine}, - {"alter", kAlter}, - {"amazon", kAmazon}, - {"anarchy", kAnarchy}, - {"antergos", kAntergos}, - {"antix", kAntiX}, - {"aoscos", kAoscOs}, - {"aperio", kAperio}, - {"apricity", kApricity}, - {"arch", kArch}, - {"arcolinux", kArcoLinux}, - {"artix", kArtix}, - {"arya", kArya}, - {"asteroidos", kAsteroidOs}, - {"ataraxia", kJanus}, - {"bedrock", kBedrock}, - {"bitrig", kBitrig}, - {"blackarch", kBlackArch}, - {"blag", kBlag}, - {"blankon", kBlankOn}, - {"bluelight", kBlueLight}, - {"bodhi", kBodhi}, - {"bonsai", kBonsai}, - {"bunsenlabs", kBunsenLabs}, - {"calculate", kCalculate}, - {"carbs", kCarbs}, - {"cblmariner", kCblMariner}, - {"celos", kCelOs}, - {"centos", kCentOs}, - {"chakra", kChakra}, - {"chaletos", kChaletOs}, - {"chapeau", kChapeau}, - {"cleanjaro", kCleanjaro}, - {"clearlinux", kClearLinux}, - {"clearos", kClearOs}, - {"clover", kClover}, - {"condres", kCondres}, - {"containerlinux", kContainerLinux}, - {"crux", kCrux}, - {"crystallinux", kCrystalLinux}, - {"cucumber", kCucumber}, - {"cyberos", kCyberOs}, - {"dahlia", kDahlia}, - {"darkos", kDarkOs}, - {"debian", kDebian}, - {"deepin", kDeepin}, - {"desaos", kDesaOs}, - {"devuan", kDevuan}, - {"dracos", kDracOs}, - {"drauger", kDrauger}, - {"elementary", kElementary}, - {"endeavouros", kEndeavourOs}, - {"endless", kEndless}, - {"eurolinux", kEuroLinux}, - {"exherbo", kExherbo}, - {"fedora", kFedora}, - {"feren", kFeren}, - {"frugalware", kFrugalware}, - {"funtoo", kFuntoo}, - {"galliumos", kGalliumOs}, - {"garuda", kGaruda}, - {"gentoo", kGentoo}, - {"glaucus", kGlaucus}, - {"gnewsense", kGnewSense}, - {"gnome", kGnome}, - {"gobolinux", kGoboLinux}, - {"grombyang", kGrombyang}, - {"hash", kHash}, - {"huayra", kHuayra}, - {"hyperbola", kHyperbola}, - {"i3buntu", kUbuntu}, - {"iglu", kIglu}, - {"instantos", kInstantOs}, - {"itc", kItc}, - {"janus", kJanus}, - {"kaisen", kKaisen}, - {"kali", kKali}, - {"kaos", kKaOs}, - {"kde", kKde}, - {"kibojoe", kKibojoe}, - {"kogaion", kKogaion}, - {"korora", kKorora}, - {"kslinux", kKsLinux}, - {"kubuntu", kKubuntu}, - {"langitketujuh", kLangitKetujuh}, - {"laxeros", kLaxerOs}, - {"lede", kLede}, - {"libreelec", kLibreElec}, - {"linuxlite", kLinuxLite}, - {"linuxmint", kLinuxMint}, - {"liveraizo", kLiveRaizo}, - {"lmde", kLmde}, - {"lubuntu", kLubuntu}, - {"lunar", kLunar}, - {"mageia", kMageia}, - {"magpieos", kMagpieOs}, - {"mandrake", kMandriva}, - {"mandriva", kMandriva}, - {"manjaro", kManjaro}, - {"maui", kMaui}, - {"mer", kMer}, - {"minix", kMinix}, - {"mint", kLinuxMint}, - {"mx", kMx}, - {"namib", kNamib}, - {"neptune", kNeptune}, - {"netrunner", kNetrunner}, - {"nitrux", kNitrux}, - {"nixos", kNixOs}, - {"nurunner", kNurunner}, - {"nutyx", kNutyX}, - {"obarun", kObarun}, - {"obrevenge", kObRevenge}, - {"openeuler", kOpenEuler}, - {"openindiana", kOpenIndiana}, - {"openmamba", kOpenMamba}, - {"openmandriva", kOpenMandriva}, - {"opensourcemediacenter", kOpenSourceMediaCenter}, - {"openstage", kOpenStage}, - {"opensuse", kOpenSuse}, - {"opensuseleap", kOpenSuseLeap}, - {"opensusetumbleweed", kOpenSuseTumbleweed}, - {"openwrt", kOpenWrt}, - {"oracle", kOracle}, - {"oselbrus", kOsElbrus}, - {"osmc", kOpenSourceMediaCenter}, - {"parabola", kParabola}, - {"pardus", kPardus}, - {"parrot", kParrot}, - {"parsix", kParsix}, - {"pclinuxos", kPcLinuxOs}, - {"pengwin", kPengwin}, - {"pentoo", kPentoo}, - {"peppermint", kPeppermint}, - {"pisi", kPisi}, - {"pnmlinux", kPnmLinux}, - {"popos", kPopOs}, - {"porteus", kPorteus}, - {"postmarketos", kPostMarketOs}, - {"precisepuppy", kPuppy}, - {"proxmox", kProxmox}, - {"puffos", kPuffOs}, - {"puppy", kPuppy}, - {"pureos", kPureOs}, - {"qubes", kQubes}, - {"qubyt", kQubyt}, - {"quibian", kQuibian}, - {"quirkywerewolf", kPuppy}, - {"radix", kRadix}, - {"raspbian", kRaspbian}, - {"reborn", kReborn}, - {"redcore", kRedcore}, - {"redhat", kRedhat}, - {"redstar", kRedStar}, - {"refracteddevuan", kRefractedDevuan}, - {"regata", kRegata}, - {"regolith", kRegolith}, - {"rhel", kRedhat}, - {"rocky", kRocky}, - {"rosa", kRosa}, - {"sabayon", kSabayon}, - {"sabotage", kSabotage}, - {"sailfish", kSailfish}, - {"salentos", kSalentOs}, - {"scientific", kScientific}, - {"semc", kSemc}, - {"septor", kSeptor}, - {"serene", kSerene}, - {"sharklinux", kSharkLinux}, - {"siduction", kSiduction}, - {"skiffos", kSkiffOs}, - {"slackware", kSlackware}, - {"slitaz", kSliTaz}, - {"smartos", kSmartOs}, - {"solus", kSolus}, - {"sourcemage", kSourceMage}, - {"sparky", kSparky}, - {"star", kStar}, - {"steamos", kSteamOs}, - {"suse", kOpenSuse}, - {"swagarch", kSwagArch}, - {"t2", kT2}, - {"tails", kTails}, - {"tearch", kTeArch}, - {"trisquel", kTrisquel}, - {"ubuntu", kUbuntu}, - {"univention", kUnivention}, - {"venom", kVenom}, - {"vnux", kVnux}, - {"void", kVoid}, - {"whpnmlinux", kPnmLinux}, - {"xferience", kXferience}, - {"xubuntu", kXubuntu}, - {"zorin", kZorin}, - }; - struct Compare { - bool operator()(const std::string& string, - const std::pair<const char*, UmaLinuxDistro>& pair) { - return string < pair.first; - } - }; + static constexpr auto kDistroPrefixes = + base::MakeFixedFlatMap<std::string_view, UmaLinuxDistro>({ + {"alma", kAlma}, + {"alpine", kAlpine}, + {"alter", kAlter}, + {"amazon", kAmazon}, + {"anarchy", kAnarchy}, + {"antergos", kAntergos}, + {"antix", kAntiX}, + {"aoscos", kAoscOs}, + {"aperio", kAperio}, + {"apricity", kApricity}, + {"arch", kArch}, + {"arcolinux", kArcoLinux}, + {"artix", kArtix}, + {"arya", kArya}, + {"asteroidos", kAsteroidOs}, + {"ataraxia", kJanus}, + {"bedrock", kBedrock}, + {"bitrig", kBitrig}, + {"blackarch", kBlackArch}, + {"blag", kBlag}, + {"blankon", kBlankOn}, + {"bluelight", kBlueLight}, + {"bodhi", kBodhi}, + {"bonsai", kBonsai}, + {"bunsenlabs", kBunsenLabs}, + {"calculate", kCalculate}, + {"carbs", kCarbs}, + {"cblmariner", kCblMariner}, + {"celos", kCelOs}, + {"centos", kCentOs}, + {"chakra", kChakra}, + {"chaletos", kChaletOs}, + {"chapeau", kChapeau}, + {"cleanjaro", kCleanjaro}, + {"clearlinux", kClearLinux}, + {"clearos", kClearOs}, + {"clover", kClover}, + {"condres", kCondres}, + {"containerlinux", kContainerLinux}, + {"crux", kCrux}, + {"crystallinux", kCrystalLinux}, + {"cucumber", kCucumber}, + {"cyberos", kCyberOs}, + {"dahlia", kDahlia}, + {"darkos", kDarkOs}, + {"debian", kDebian}, + {"deepin", kDeepin}, + {"desaos", kDesaOs}, + {"devuan", kDevuan}, + {"dracos", kDracOs}, + {"drauger", kDrauger}, + {"elementary", kElementary}, + {"endeavouros", kEndeavourOs}, + {"endless", kEndless}, + {"eurolinux", kEuroLinux}, + {"exherbo", kExherbo}, + {"fedora", kFedora}, + {"feren", kFeren}, + {"frugalware", kFrugalware}, + {"funtoo", kFuntoo}, + {"galliumos", kGalliumOs}, + {"garuda", kGaruda}, + {"gentoo", kGentoo}, + {"glaucus", kGlaucus}, + {"gnewsense", kGnewSense}, + {"gnome", kGnome}, + {"gobolinux", kGoboLinux}, + {"grombyang", kGrombyang}, + {"hash", kHash}, + {"huayra", kHuayra}, + {"hyperbola", kHyperbola}, + {"i3buntu", kUbuntu}, + {"iglu", kIglu}, + {"instantos", kInstantOs}, + {"itc", kItc}, + {"janus", kJanus}, + {"kaisen", kKaisen}, + {"kali", kKali}, + {"kaos", kKaOs}, + {"kde", kKde}, + {"kibojoe", kKibojoe}, + {"kogaion", kKogaion}, + {"korora", kKorora}, + {"kslinux", kKsLinux}, + {"kubuntu", kKubuntu}, + {"langitketujuh", kLangitKetujuh}, + {"laxeros", kLaxerOs}, + {"lede", kLede}, + {"libreelec", kLibreElec}, + {"linuxlite", kLinuxLite}, + {"linuxmint", kLinuxMint}, + {"liveraizo", kLiveRaizo}, + {"lmde", kLmde}, + {"lubuntu", kLubuntu}, + {"lunar", kLunar}, + {"mageia", kMageia}, + {"magpieos", kMagpieOs}, + {"mandrake", kMandriva}, + {"mandriva", kMandriva}, + {"manjaro", kManjaro}, + {"maui", kMaui}, + {"mer", kMer}, + {"minix", kMinix}, + {"mint", kLinuxMint}, + {"mx", kMx}, + {"namib", kNamib}, + {"neptune", kNeptune}, + {"netrunner", kNetrunner}, + {"nitrux", kNitrux}, + {"nixos", kNixOs}, + {"nurunner", kNurunner}, + {"nutyx", kNutyX}, + {"obarun", kObarun}, + {"obrevenge", kObRevenge}, + {"openeuler", kOpenEuler}, + {"openindiana", kOpenIndiana}, + {"openmamba", kOpenMamba}, + {"openmandriva", kOpenMandriva}, + {"opensourcemediacenter", kOpenSourceMediaCenter}, + {"openstage", kOpenStage}, + {"opensuse", kOpenSuse}, + {"opensuseleap", kOpenSuseLeap}, + {"opensusetumbleweed", kOpenSuseTumbleweed}, + {"openwrt", kOpenWrt}, + {"oracle", kOracle}, + {"oselbrus", kOsElbrus}, + {"osmc", kOpenSourceMediaCenter}, + {"parabola", kParabola}, + {"pardus", kPardus}, + {"parrot", kParrot}, + {"parsix", kParsix}, + {"pclinuxos", kPcLinuxOs}, + {"pengwin", kPengwin}, + {"pentoo", kPentoo}, + {"peppermint", kPeppermint}, + {"pisi", kPisi}, + {"pnmlinux", kPnmLinux}, + {"popos", kPopOs}, + {"porteus", kPorteus}, + {"postmarketos", kPostMarketOs}, + {"precisepuppy", kPuppy}, + {"proxmox", kProxmox}, + {"puffos", kPuffOs}, + {"puppy", kPuppy}, + {"pureos", kPureOs}, + {"qubes", kQubes}, + {"qubyt", kQubyt}, + {"quibian", kQuibian}, + {"quirkywerewolf", kPuppy}, + {"radix", kRadix}, + {"raspbian", kRaspbian}, + {"reborn", kReborn}, + {"redcore", kRedcore}, + {"redhat", kRedhat}, + {"redstar", kRedStar}, + {"refracteddevuan", kRefractedDevuan}, + {"regata", kRegata}, + {"regolith", kRegolith}, + {"rhel", kRedhat}, + {"rocky", kRocky}, + {"rosa", kRosa}, + {"sabayon", kSabayon}, + {"sabotage", kSabotage}, + {"sailfish", kSailfish}, + {"salentos", kSalentOs}, + {"scientific", kScientific}, + {"semc", kSemc}, + {"septor", kSeptor}, + {"serene", kSerene}, + {"sharklinux", kSharkLinux}, + {"siduction", kSiduction}, + {"skiffos", kSkiffOs}, + {"slackware", kSlackware}, + {"slitaz", kSliTaz}, + {"smartos", kSmartOs}, + {"solus", kSolus}, + {"sourcemage", kSourceMage}, + {"sparky", kSparky}, + {"star", kStar}, + {"steamos", kSteamOs}, + {"suse", kOpenSuse}, + {"swagarch", kSwagArch}, + {"t2", kT2}, + {"tails", kTails}, + {"tearch", kTeArch}, + {"trisquel", kTrisquel}, + {"ubuntu", kUbuntu}, + {"univention", kUnivention}, + {"venom", kVenom}, + {"vnux", kVnux}, + {"void", kVoid}, + {"whpnmlinux", kPnmLinux}, + {"xferience", kXferience}, + {"xubuntu", kXubuntu}, + {"zorin", kZorin}, + }); std::string trimmed = TrimLinuxDistro(base::ToLowerASCII(distro)); - auto* it = std::upper_bound(kDistroPrefixes, std::end(kDistroPrefixes), - trimmed, Compare()); - if (it != kDistroPrefixes && - base::StartsWith(trimmed, (UNSAFE_TODO(--it))->first)) { + if (auto it = kDistroPrefixes.upper_bound(trimmed); + it > kDistroPrefixes.begin() && + base::StartsWith(trimmed, (--it)->first)) { base::UmaHistogramEnumeration("Linux.Distro3", it->second); } else { base::UmaHistogramEnumeration("Linux.Distro3", UmaLinuxDistro::kOther);
diff --git a/chrome/browser/resources/history/synced_device_manager.css b/chrome/browser/resources/history/synced_device_manager.css index ea448ba3..dd011e615 100644 --- a/chrome/browser/resources/history/synced_device_manager.css +++ b/chrome/browser/resources/history/synced_device_manager.css
@@ -29,6 +29,7 @@ .sync-history-promo-avatar-illustration { content: url(./images/avatar_surrounding_illustration_light.svg); + height: 132px; width: 100%; } @@ -46,33 +47,6 @@ } } -#avatar { - /** The user avatar may be transparent, add a background */ - background-color: var(--md-background-color); - border: solid var(--md-background-color); - border-radius: 50%; - height: 64px; - /* To place the avatar at the center of the background image, - place it at top left point of its parent, - then shift it back by half its width and height. */ - left: 50%; - position: absolute; - top: 50%; - transform: translate(-50%, -50%); - width: 64px; -} - -#imageContainer { - align-self: center; - display: flex; - /* The height must be set so that the height of this relatively positioned - container is taken into account in the height calculator of the entire screen. */ - height: 162px; - justify-content: center; - /* Establishes a positioning context for absolute children. */ - position: relative; -} - #no-synced-tabs { height: 100%; } @@ -86,15 +60,6 @@ text-align: center; } -.history-sync-optin { - align-items: center; - display: flex; - flex-direction: column; - justify-content: center; - overflow-x: hidden; - text-align: center; -} - #turn-on-sync-promo { font-size: 215%; margin-top: 40px; @@ -110,24 +75,6 @@ margin: 24px 0; } -/* TODO: crbug.com/418144047 - align the style with the Figma mockups. */ -.sync-history-promo { - font-size: 215%; - font-weight: 500; - margin-top: 40px; -} - -.sync-history-promo-desc { - color: var(--cr-secondary-text-color); - font-size: 123%; - margin-top: 10px; - width: 80ch; -} - -#sync-history-button { - margin: 24px 0; -} - #synced-device-list { padding-top: var(--first-card-padding-top); } @@ -135,3 +82,95 @@ history-synced-device-card { margin-block-end: var(--card-padding-between); } + +<if expr="not is_chromeos"> +.history-sync-optin { + align-items: center; + display: flex; + flex-direction: column; + justify-content: center; + overflow-x: hidden; + text-align: center; +} + +.sync-history-promo { + margin-top: 12px; + color: #202124; + text-align: center; + font-size: 24px; + font-weight: 500; + line-height: 32px; +} + +.sync-history-promo-desc { + margin-top: 8px; + max-width: 684px; + color: #5E5E5E; + text-align: center; + font-size: 16px; + font-weight: 400; + line-height: 24px; +} + +#avatar { + /** The user avatar may be transparent, add a background */ + background-color: var(--md-background-color); + border: solid var(--md-background-color); + border-radius: 50%; + height: 64px; + /* To place the avatar at the center of the background image, + place it at top left point of its parent, + then shift it back by half its width and height. */ + left: 50%; + position: absolute; + top: 50%; + transform: translate(-50%, -50%); + width: 64px; +} + +.image-container { + align-self: center; + align-items: center; + display: flex; + /* The height must be set so that the height of this relatively positioned + container is taken into account in the height calculator of the entire screen. */ + height: 162px; + justify-content: center; + /* Establishes a positioning context for absolute children. */ + position: relative; + margin-top: 36px; +} + +.profile-row { + text-align: left; + align-items: center; + display: flex; + margin-top: 16px; +} + +.account-info-container { + padding-inline-start: 16px; +} + +.profile-icon { + border-radius: 20px; + height: 40px; + width: 40px; +} + +.account-name { + font-size: 13px; + line-height: 20px; +} + +.account-email { + color: #474747; + font-size: 12px; + font-weight: 400; + line-height: 16px; +} + +.action-button { + margin: 16px 0; +} +</if>
diff --git a/chrome/browser/resources/history/synced_device_manager.html.ts b/chrome/browser/resources/history/synced_device_manager.html.ts index ce340126..1fd8789 100644 --- a/chrome/browser/resources/history/synced_device_manager.html.ts +++ b/chrome/browser/resources/history/synced_device_manager.html.ts
@@ -3,6 +3,7 @@ // found in the LICENSE file. import {html} from '//resources/lit/v3_0/lit.rollup.js'; +import {HistorySignInState} from './constants.js'; import type {HistorySyncedDeviceManagerElement} from './synced_device_manager.js'; @@ -29,8 +30,10 @@ ?hidden="${!this.showNoSyncedMessage_()}"> ${this.noSyncedTabsMessage_()} </div> + <div id="sign-in-guide" - ?hidden="${!this.showSignInGuide_() || this.useHistorySyncOptinScreen_}"> + ?hidden="${!this.showSignInGuide_() + || this.replaceSyncPromosWithSignInPromos_}"> <div id="sync-promo-illustration"></div> <div id="turn-on-sync-promo">$i18n{turnOnSyncPromo}</div> <div id="turn-on-sync-promo-desc">$i18n{turnOnSyncPromoDesc}</div> @@ -40,33 +43,56 @@ </cr-button> </div> -${this.useHistorySyncOptinScreen_ ? html ` - <div class="history-sync-optin"> - ${this.isSignedOut_ ? html` - <!-- not signed in case --> - <div id="imageContainer"> - <img class="sync-history-illustration" alt="" /> - </div> - <div class="sync-history-promo">$i18n{turnOnSyncHistoryPromo}</div> - <div class="sync-history-promo-desc"> - $i18n{turnOnSyncHistoryPromoDesc} - </div> - <!-- for "account aware" case here will be a div with the account info --> - ` : html` - <!-- signed in case --> - <div id="imageContainer"> - <img class="sync-history-promo-avatar-illustration" alt="" /> - <img id="avatar" alt="" src="${this.accountImageSrc_}" /> - </div> - <div class="sync-history-promo">$i18n{turnOnSignedInSyncHistoryPromo}</div> - <div class="sync-history-promo-desc"> - $i18n{turnOnSignedInSyncHistoryPromoDesc} - </div> - `} - <cr-button id="sync-history-button" class="action-button"> - $i18n{turnOnSyncHistoryButton} - </cr-button> - </div>` : ''} +<if expr="not is_chromeos"> + ${this.shouldShowHistorySyncOptIn_() ? html` + <div id="history-sync-optin" class="history-sync-optin"> + ${this.isSignInState_(HistorySignInState.SIGNED_OUT) + || this.isSignInState_(HistorySignInState.WEB_ONLY_SIGNED_IN) ? html` + <div class="image-container"> + <img class="sync-history-illustration" alt=""> + </div> + <div class="sync-history-promo">$i18n{turnOnSyncHistoryPromo}</div> + <div class="sync-history-promo-desc"> + $i18n{syncHistoryPromoBodySignedOut} + </div> + ` : ''} + + ${this.isSignInState_(HistorySignInState.WEB_ONLY_SIGNED_IN) + && this.accountInfo_ ? html` + <div class="profile-row"> + <img id="profile-icon" class="profile-icon" + src="${this.accountInfo_.accountImageSrc.url}"> + <div class="account-info-container"> + <div id="account-name" class="account-name"> + ${this.accountInfo_.name}</div> + <div id="account-email" class="account-email"> + ${this.accountInfo_.email}</div> + </div> + </div> + ` : ''} + + ${this.isSignInState_(HistorySignInState.SIGNED_IN_NOT_SYNCING_TABS) + && this.accountInfo_ ? html` + <div class="image-container"> + <img class="sync-history-promo-avatar-illustration" alt=""> + <img id="avatar" src="${this.accountInfo_.accountImageSrc.url}" + alt=""> + </div> + <div class="sync-history-promo"> + $i18n{turnOnSyncHistoryPromo} + </div> + <div class="sync-history-promo-desc"> + $i18n{turnOnSignedInSyncHistoryPromoBodySignInSyncOff} + </div> + ` : ''} + + <cr-button id="sync-history-button" class="action-button" + @click="${this.onTurnOnHistorySyncClick_}"> + $i18n{turnOnSyncHistoryButton} + </cr-button> + </div> + ` : ''} +</if> <cr-lazy-render-lit id="menu" .template='${() => html` <cr-action-menu role-description="$i18n{menu}">
diff --git a/chrome/browser/resources/history/synced_device_manager.ts b/chrome/browser/resources/history/synced_device_manager.ts index 76d60d4..cb92d3d 100644 --- a/chrome/browser/resources/history/synced_device_manager.ts +++ b/chrome/browser/resources/history/synced_device_manager.ts
@@ -21,6 +21,9 @@ import {HistorySignInState, SYNCED_TABS_HISTOGRAM_NAME, SyncedTabsHistogram} from './constants.js'; import type {ForeignSession, ForeignSessionTab} from './externs.js'; import type {HistorySyncedDeviceCardElement} from './synced_device_card.js'; +// <if expr="not is_chromeos"> +import type {AccountInfo} from 'chrome://resources/cr_components/history/history.mojom-webui.js'; +// </if> import {getCss} from './synced_device_manager.css.js'; import {getHtml} from './synced_device_manager.html.js'; @@ -80,9 +83,11 @@ */ actionMenuModel_: {type: String}, - useHistorySyncOptinScreen_: {type: Boolean}, + replaceSyncPromosWithSignInPromos_: {type: Boolean}, - accountImageSrc_: {type: String}, + // <if expr="not is_chromeos"> + accountInfo_: {type: Object}, + // </if> }; } @@ -96,10 +101,12 @@ loadTimeData.getBoolean('isGuestSession'); private accessor signInAllowed_: boolean = loadTimeData.getBoolean('isSignInAllowed'); - protected accessor useHistorySyncOptinScreen_: boolean = - loadTimeData.getBoolean('useHistorySyncOptinScreen'); - protected accessor accountImageSrc_: string = - loadTimeData.getString('accountPictureUrl'); + protected accessor replaceSyncPromosWithSignInPromos_: boolean = + loadTimeData.getBoolean('replaceSyncPromosWithSignInPromos'); + // <if expr="not is_chromeos"> + protected accessor accountInfo_: AccountInfo|null = null; + private onAccountInfoDataReceivedListenerId_: number|null = null; + // </if> accessor signInState: HistorySignInState = HistorySignInState.SIGNED_OUT; accessor searchTerm: string = ''; @@ -133,11 +140,28 @@ BrowserServiceImpl.getInstance().recordHistogram( SYNCED_TABS_HISTOGRAM_NAME, SyncedTabsHistogram.INITIALIZED, SyncedTabsHistogram.LIMIT); + + // <if expr="not is_chromeos"> + this.onAccountInfoDataReceivedListenerId_ = + BrowserServiceImpl.getInstance() + .callbackRouter.sendAccountInfo.addListener( + this.handleAccountInfoChanged_.bind(this)); + + BrowserServiceImpl.getInstance().handler.requestAccountInfo().then( + ({accountInfo}) => this.handleAccountInfoChanged_(accountInfo)); + // </if> } override disconnectedCallback() { super.disconnectedCallback(); this.focusGrid_!.destroy(); + + // <if expr="not is_chromeos"> + assert(this.onAccountInfoDataReceivedListenerId_); + BrowserServiceImpl.getInstance().callbackRouter.removeListener( + this.onAccountInfoDataReceivedListenerId_); + this.onAccountInfoDataReceivedListenerId_ = null; + // </if> } configureSignInForTest(data: { @@ -199,6 +223,16 @@ BrowserServiceImpl.getInstance().startTurnOnSyncFlow(); } + // <if expr="not is_chromeos"> + protected onTurnOnHistorySyncClick_() { + BrowserServiceImpl.getInstance().handler.turnOnHistorySync(); + } + + private handleAccountInfoChanged_(accountInfo: AccountInfo) { + this.accountInfo_ = accountInfo; + } + // </if> + private onOpenMenu_(e: CustomEvent<{tag: string, target: HTMLElement}>) { this.actionMenuModel_ = e.detail.tag; this.$.menu.get().showAt(e.detail.target); @@ -267,8 +301,13 @@ this.syncedDevices_ = []; } - protected get isSignedOut_(): boolean { - return this.signInState === HistorySignInState.SIGNED_OUT; + protected isSignInState_(state: HistorySignInState): boolean { + return this.signInState === state; + } + + protected shouldShowHistorySyncOptIn_(): boolean { + return this.replaceSyncPromosWithSignInPromos_ && + !this.isSignInState_(HistorySignInState.SIGNED_IN_SYNCING_TABS); } /**
diff --git a/chrome/browser/signin/BUILD.gn b/chrome/browser/signin/BUILD.gn index 7bb65fb..f5cdc48ac 100644 --- a/chrome/browser/signin/BUILD.gn +++ b/chrome/browser/signin/BUILD.gn
@@ -29,7 +29,9 @@ "web_signin_interceptor.h", ] public_deps += [ + "//chrome/browser:browser_process", "//chrome/browser/search_engine_choice", + "//chrome/browser/ui/browser_window:browser_window", "//chrome/browser/ui/webui/signin:signin_utils", "//components/keyed_service/core", "//components/policy/core/browser", @@ -56,6 +58,7 @@ "//base", "//base:i18n", "//chrome/browser:browser_process", + "//chrome/browser/feature_engagement:feature_engagement", "//chrome/browser/new_tab_page/chrome_colors:generate_chrome_colors_info", "//chrome/browser/profiles", "//chrome/browser/profiles:profile_util", @@ -71,6 +74,7 @@ "//chrome/common:channel_info", "//chrome/common:constants", "//chrome/common/themes:autogenerated_theme_util", + "//components/feature_engagement/public:public", "//components/password_manager/core/browser", "//components/password_manager/core/common", "//components/policy:generated",
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl.cc b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl.cc index 3738a59..4c2ee48 100644 --- a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl.cc +++ b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl.cc
@@ -46,6 +46,9 @@ "Sec-Session-Google-Termination"; constexpr std::string_view kGoogleSessionTerminationSessionIdKey = "session_id"; +BASE_FEATURE(kUseDeviceBoundSessionsStorageMaskForDeletion, + base::FEATURE_ENABLED_BY_DEFAULT); + // Determines the precedence order of // `chrome::mojom::ResumeBlockedRequestsTrigger` when recording metrics. size_t GetResumeBlockedRequestsTriggerPriority( @@ -496,9 +499,14 @@ content::StoragePartition::StorageKeyMatcherFunction storage_key_matcher, const base::Time begin, const base::Time end) { - // Only terminate a session if cookies are cleared. - // TODO(b/296372836): introduce a specific data type for bound sessions. - if (!(remove_mask & content::StoragePartition::REMOVE_DATA_MASK_COOKIES)) { + const uint32_t storage_mask = + base::FeatureList::IsEnabled( + kUseDeviceBoundSessionsStorageMaskForDeletion) + ? content::StoragePartition::REMOVE_DATA_MASK_DEVICE_BOUND_SESSIONS + : content::StoragePartition::REMOVE_DATA_MASK_COOKIES; + + // Only terminate sessions if a relevant data type is cleared. + if (!(remove_mask & storage_mask)) { return; }
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl_browsertest.cc b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl_browsertest.cc index 2581e60..15aa886 100644 --- a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl_browsertest.cc +++ b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl_browsertest.cc
@@ -20,6 +20,8 @@ #include "base/strings/stringprintf.h" #include "base/task/bind_post_task.h" #include "base/test/scoped_feature_list.h" +#include "base/test/test_future.h" +#include "chrome/browser/browsing_data/chrome_browsing_data_remover_constants.h" #include "chrome/browser/chrome_browser_main.h" #include "chrome/browser/chrome_browser_main_extra_parts.h" #include "chrome/browser/profiles/profile.h" @@ -30,10 +32,17 @@ #include "chrome/common/renderer_configuration.mojom.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/content_settings/core/browser/cookie_settings.h" +#include "components/content_settings/core/common/pref_names.h" #include "components/signin/public/base/session_binding_test_utils.h" #include "components/signin/public/base/signin_switches.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/browsing_data_remover.h" +#include "content/public/browser/btm_service.h" #include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/browsing_data_remover_test_util.h" +#include "content/public/test/btm_service_test_utils.h" #include "crypto/scoped_fake_unexportable_key_provider.h" #include "crypto/signature_verifier.h" #include "google_apis/gaia/gaia_switches.h" @@ -49,22 +58,26 @@ #include "testing/gtest/include/gtest/gtest.h" namespace { -using net::CanonicalCookie; -using testing::AllOf; -using testing::AssertionFailure; -using testing::AssertionResult; -using testing::AssertionSuccess; -using testing::ElementsAre; -using testing::Eq; -using testing::Field; -using testing::IsEmpty; -using testing::Not; -using testing::Pointee; -using testing::UnorderedElementsAre; +using ::net::CanonicalCookie; +using ::testing::AllOf; +using ::testing::AssertionFailure; +using ::testing::AssertionResult; +using ::testing::AssertionSuccess; +using ::testing::ElementsAre; +using ::testing::Eq; +using ::testing::Field; +using ::testing::Gt; +using ::testing::IsEmpty; +using ::testing::Not; +using ::testing::Pointee; +using ::testing::SizeIs; +using ::testing::UnorderedElementsAre; using HeaderVector = net::HttpRequestHeaders::HeaderVector; constexpr std::string_view kDomain = "google.com"; constexpr std::string_view kSubdomain = "accounts.google.com"; +constexpr std::string_view kBouncerDomain = "bounce.com"; +constexpr std::string_view kOtherDomain = "other.com"; constexpr std::string_view KTriggerRegistrationPath = "/TriggerRegistration"; constexpr base::cstring_view kChallenge = "test_challenge"; @@ -472,6 +485,56 @@ return fake_server_host; } +void SetBlockThirdPartyCookies(Profile* profile, bool value) { + profile->GetPrefs()->SetInteger( + prefs::kCookieControlsMode, + static_cast<int>( + value ? content_settings::CookieControlsMode::kBlockThirdParty + : content_settings::CookieControlsMode::kOff)); +} + +testing::AssertionResult SimulateBtmBounce(BrowserWindowInterface* browser, + const GURL& initial_url, + const GURL& bounce_url, + const GURL& final_url) { + if (!ui_test_utils::NavigateToURLWithDisposition( + browser, initial_url, WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB | + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP)) { + return testing::AssertionFailure() + << "Failed to navigate to " << initial_url; + } + content::WebContents* web_contents = + browser->GetTabStripModel()->GetActiveWebContents(); + + if (!content::NavigateToURLFromRenderer(web_contents, bounce_url)) { + return testing::AssertionFailure() + << "Failed to navigate to " << bounce_url; + } + + content::CookieChangeObserver cookie_observer(web_contents); + testing::AssertionResult js_result = + content::ExecJs(web_contents, "document.cookie = 'bounce=stateful';", + content::EXECUTE_SCRIPT_NO_USER_GESTURE); + if (!js_result) { + return js_result; + } + cookie_observer.Wait(); + + content::BtmRedirectChainObserver final_observer( + content::BtmService::Get(web_contents->GetBrowserContext()), final_url); + if (!content::NavigateToURLFromRendererWithoutUserGesture(web_contents, + final_url)) { + return testing::AssertionFailure() << "Failed to navigate to " << final_url; + } + + // End redirect chain by closing the tab. + web_contents->Close(); + final_observer.Wait(); + + return testing::AssertionSuccess(); +} + } // namespace class BoundSessionCookieRefreshServiceImplBrowserTest @@ -480,7 +543,10 @@ public: void SetUp() override { embedded_https_test_server().SetCertHostnames( - {std::string(kDomain), std::string(kSubdomain)}); + {std::string(kDomain), std::string(kSubdomain), + std::string(kBouncerDomain), std::string(kOtherDomain)}); + embedded_https_test_server().ServeFilesFromSourceDirectory( + GetChromeTestDataDir()); CHECK(embedded_https_test_server().InitializeAndListen()); InProcessBrowserTest::SetUp(); } @@ -694,6 +760,54 @@ EXPECT_GT(new_throttler_params[0]->cookie_expiry_date, cookie_expiration); } +// Verifies that a bound session is deleted when the user cleares site data. +IN_PROC_BROWSER_TEST_F(BoundSessionCookieRefreshServiceImplBrowserTest, + ClearBrowsingDataDeletesSession) { + // Initialize a new session. + RegisterNewSession(); + ASSERT_THAT(service()->GetBoundSessionThrottlerParams(), Not(IsEmpty())); + + // Clear all site data. + content::BrowsingDataRemover* remover = + browser()->profile()->GetBrowsingDataRemover(); + content::BrowsingDataRemoverCompletionObserver observer(remover); + remover->RemoveAndReply( + base::Time(), base::Time::Max(), + chrome_browsing_data_remover::DATA_TYPE_SITE_DATA, + content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB, &observer); + observer.BlockUntilCompletion(); + + // The session should have been terminated. + EXPECT_THAT(service()->GetBoundSessionThrottlerParams(), IsEmpty()); +} + +// Verifies that unrelated BTM deletions do not terminate a bound session. +// Regression test for https://crbug.com/445561475. +IN_PROC_BROWSER_TEST_F(BoundSessionCookieRefreshServiceImplBrowserTest, + BtmDeletionDoesNotDeleteSession) { + // Enable third-party cookie blocking to activate the BTM deletion. + SetBlockThirdPartyCookies(browser()->profile(), true); + + // Initialize a new session. + RegisterNewSession(); + ASSERT_THAT(service()->GetBoundSessionThrottlerParams(), Not(IsEmpty())); + + // Perform a stateful bounce to make the storage eligible for BTM deletion. + ASSERT_TRUE(SimulateBtmBounce( + browser(), embedded_https_test_server().GetURL(kDomain, "/empty.html"), + embedded_https_test_server().GetURL(kBouncerDomain, "/title1.html"), + embedded_https_test_server().GetURL(kOtherDomain, "/empty.html"))); + + // Trigger BTM deletion. + base::test::TestFuture<const std::vector<std::string>&> deleted_sites; + content::BtmService::Get(browser()->profile()) + ->DeleteEligibleSitesImmediately(deleted_sites.GetCallback()); + EXPECT_THAT(deleted_sites.Get(), SizeIs(Gt(0))); + + // The session should not be terminated. + EXPECT_THAT(service()->GetBoundSessionThrottlerParams(), Not(IsEmpty())); +} + class BoundSessionCookieRefreshServiceImplFailingRotationBrowserTest : public BoundSessionCookieRefreshServiceImplBrowserTest { protected:
diff --git a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl_unittest.cc b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl_unittest.cc index 3e5be36..65091c6 100644 --- a/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl_unittest.cc +++ b/chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_impl_unittest.cc
@@ -1096,8 +1096,9 @@ base::flat_set<std::string>( {k1PSIDTSCookieName, k3PSIDTSCookieName}))) .Times(1); - ClearOriginData(content::StoragePartition::REMOVE_DATA_MASK_COOKIES, - url::Origin::Create(kTestGoogleURL)); + ClearOriginData( + content::StoragePartition::REMOVE_DATA_MASK_DEVICE_BOUND_SESSIONS, + url::Origin::Create(kTestGoogleURL)); VerifyNoBoundSession(); VerifySessionTerminationTriggerRecorded( SessionTerminationTrigger::kCookiesCleared); @@ -1110,7 +1111,7 @@ auto params = CreateTestBoundSessionParams(); service->RegisterNewBoundSession(params); - ClearOriginData(content::StoragePartition::REMOVE_DATA_MASK_CACHE_STORAGE, + ClearOriginData(content::StoragePartition::REMOVE_DATA_MASK_COOKIES, url::Origin::Create(kTestGoogleURL)); VerifyBoundSession(params); histogram_tester().ExpectTotalCount( @@ -1124,8 +1125,9 @@ auto params = CreateTestBoundSessionParams(); service->RegisterNewBoundSession(params); - ClearOriginData(content::StoragePartition::REMOVE_DATA_MASK_COOKIES, - url::Origin::Create(GURL("https://example.org"))); + ClearOriginData( + content::StoragePartition::REMOVE_DATA_MASK_DEVICE_BOUND_SESSIONS, + url::Origin::Create(GURL("https://example.org"))); VerifyBoundSession(params); histogram_tester().ExpectTotalCount( "Signin.BoundSessionCredentials.SessionTerminationTrigger", 0); @@ -1138,8 +1140,9 @@ auto params = CreateTestBoundSessionParams(); service->RegisterNewBoundSession(params); - ClearOriginData(content::StoragePartition::REMOVE_DATA_MASK_COOKIES, - url::Origin::Create(GURL("https://accounts.google.com"))); + ClearOriginData( + content::StoragePartition::REMOVE_DATA_MASK_DEVICE_BOUND_SESSIONS, + url::Origin::Create(GURL("https://accounts.google.com"))); VerifyBoundSession(params); histogram_tester().ExpectTotalCount( "Signin.BoundSessionCredentials.SessionTerminationTrigger", 0); @@ -1152,10 +1155,10 @@ auto params = CreateTestBoundSessionParams(); service->RegisterNewBoundSession(params); - ClearOriginData(content::StoragePartition::REMOVE_DATA_MASK_COOKIES, - url::Origin::Create(kTestGoogleURL), - base::Time::Now() - base::Seconds(5), - base::Time::Now() - base::Seconds(3)); + ClearOriginData( + content::StoragePartition::REMOVE_DATA_MASK_DEVICE_BOUND_SESSIONS, + url::Origin::Create(kTestGoogleURL), base::Time::Now() - base::Seconds(5), + base::Time::Now() - base::Seconds(3)); VerifyBoundSession(params); histogram_tester().ExpectTotalCount( "Signin.BoundSessionCredentials.SessionTerminationTrigger", 0); @@ -1766,8 +1769,9 @@ OnBoundSessionTerminated( kTestGoogleURL, base::flat_set<std::string>({"cookieC"}))) .WillOnce([this] { PruneDestroyedControllers(); }); - ClearOriginData(content::StoragePartition::REMOVE_DATA_MASK_COOKIES, - url::Origin::Create(kTestGoogleURL)); + ClearOriginData( + content::StoragePartition::REMOVE_DATA_MASK_DEVICE_BOUND_SESSIONS, + url::Origin::Create(kTestGoogleURL)); // all_params[0] and all_params[1] should have been terminated. VerifyBoundSessions({all_params[2]}); histogram_tester().ExpectUniqueSample(
diff --git a/chrome/browser/signin/signin_ui_util.cc b/chrome/browser/signin/signin_ui_util.cc index e4db3eb..78d482f 100644 --- a/chrome/browser/signin/signin_ui_util.cc +++ b/chrome/browser/signin/signin_ui_util.cc
@@ -29,11 +29,14 @@ #include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/signin_ui_delegate.h" +#include "chrome/browser/signin/signin_util.h" +#include "chrome/browser/sync/sync_service_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/browser/ui/browser_window/public/browser_window_features.h" #include "chrome/browser/ui/chrome_pages.h" +#include "chrome/browser/ui/signin/promos/signin_promo_tab_helper.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/webui/signin/turn_sync_on_helper.h" #include "chrome/common/pref_names.h" @@ -49,6 +52,7 @@ #include "components/signin/public/identity_manager/identity_utils.h" #include "components/signin/public/identity_manager/primary_account_mutator.h" #include "components/sync/base/features.h" +#include "components/sync/service/sync_service.h" #include "third_party/re2/src/re2/re2.h" #include "ui/gfx/font_list.h" #include "ui/gfx/text_elider.h" @@ -642,4 +646,63 @@ } } +void TriggerSignInForHistorySyncOptIn(Browser* browser, + Profile* profile, + signin_metrics::AccessPoint access_point) { +#if !BUILDFLAG(IS_CHROMEOS) + // Try to sign in or open a sign in tab if user input is needed. If the user + // is already signed in, this is a no-op. + signin_ui_util::SignInFromSingleAccountPromo( + profile, + signin_ui_util::GetSingleAccountForPromos( + IdentityManagerFactory::GetForProfile(profile)), + access_point); + syncer::SyncService* sync_service = + SyncServiceFactory::GetForProfile(profile); + if (!sync_service) { + return; + } + + // It is safe to pass a pointer to the sync service here because the callback + // is then owned by a tab helper, which is guaranteed to be destroyed before + // the sync service. + auto enable_history_sync = base::BindOnce(&signin_util::EnableHistorySync, + base::Unretained(sync_service)); + + switch (signin_util::GetSignedInState( + IdentityManagerFactory::GetForProfile(profile))) { + // If the sign in was already successful, enable history sync directly. + case signin_util::SignedInState::kSignedIn: + std::move(enable_history_sync).Run(); + return; + // These states require a sign in tab to be displayed. A tab helper attached + // to the tab will take care of turning on history sync once signed in. + case signin_util::SignedInState::kSignedOut: + case signin_util::SignedInState::kSignInPending: + case signin_util::SignedInState::kSyncPaused: + break; + case signin_util::SignedInState::kSyncing: + case signin_util::SignedInState::kWebOnlySignedIn: + return; + } + + content::WebContents* sign_in_tab_contents = + signin_ui_util::GetSignInTabWithAccessPoint(browser, access_point); + + // SignInFromSingleAccountPromo may fail to open a tab. Do not wait for a + // sign in event in that case. + if (!sign_in_tab_contents) { + return; + } + + SigninPromoTabHelper::GetForWebContents(*sign_in_tab_contents) + ->InitializeCallbackAfterSignIn(std::move(enable_history_sync), + access_point); +#else + // This is not expected to be called on ChromeOS as the screen that uses this + // function is never shown for ChromeOS. + NOTREACHED(); +#endif +} + } // namespace signin_ui_util
diff --git a/chrome/browser/signin/signin_ui_util.h b/chrome/browser/signin/signin_ui_util.h index f1e7ae4..ec8c6331 100644 --- a/chrome/browser/signin/signin_ui_util.h +++ b/chrome/browser/signin/signin_ui_util.h
@@ -17,6 +17,7 @@ struct AccountInfo; struct CoreAccountInfo; +class Browser; class Profile; class ProfileAttributesEntry; class ProfileAttributesStorage; @@ -28,6 +29,15 @@ // Utility functions to gather status information from the various signed in // services and construct messages suitable for showing in UI. namespace signin_ui_util { + +// Triggers the sign in flow for history sync opt-in. +// This will open the sign in tab or just sign in the user to Chrome (if they +// are already signed into Web), and enable history sync once the sign in was +// completed. +void TriggerSignInForHistorySyncOptIn(Browser* browser, + Profile* profile, + signin_metrics::AccessPoint access_point); + class SigninUiDelegate; // Returns the username of the primary account or an empty string if there is
diff --git a/chrome/browser/signin/signin_ui_util_browsertest.cc b/chrome/browser/signin/signin_ui_util_browsertest.cc index abb9d096..61579c1 100644 --- a/chrome/browser/signin/signin_ui_util_browsertest.cc +++ b/chrome/browser/signin/signin_ui_util_browsertest.cc
@@ -29,14 +29,17 @@ #include "chrome/browser/signin/signin_ui_delegate.h" #include "chrome/browser/signin/signin_ui_delegate_impl_dice.h" #include "chrome/browser/signin/signin_util.h" +#include "chrome/browser/sync/sync_service_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/signin/promos/signin_promo_tab_helper.h" #include "chrome/browser/ui/tabs/tab_enums.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "components/account_id/account_id.h" #include "components/google/core/common/google_util.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/signin/public/base/consent_level.h" #include "components/signin/public/base/signin_buildflags.h" #include "components/signin/public/base/signin_metrics.h" @@ -47,7 +50,10 @@ #include "components/signin/public/identity_manager/identity_test_utils.h" #include "components/signin/public/identity_manager/primary_account_mutator.h" #include "components/sync/base/features.h" +#include "components/sync/base/user_selectable_type.h" +#include "components/sync/test/test_sync_service.h" #include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_base.h" #include "google_apis/gaia/gaia_id.h" #include "google_apis/gaia/gaia_urls.h" #include "testing/gmock/include/gmock/gmock.h" @@ -88,6 +94,10 @@ ()); }; +std::unique_ptr<KeyedService> CreateTestSyncService(content::BrowserContext*) { + return std::make_unique<syncer::TestSyncService>(); +} + } // namespace class SigninUiUtilTestBase : public SigninBrowserTestBase { @@ -1001,4 +1011,151 @@ EXPECT_FALSE(chrome::FindBrowserWithProfile(new_profile)); } +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) + +class SigninUiUtilTest_HistorySyncOptinTest : public SigninUiUtilTestBase { + public: + // This setup happens before SetUpOnMainThread() as an initial startup. + void SetUpInProcessBrowserTestFixture() override { + SigninUiUtilTestBase::SetUpInProcessBrowserTestFixture(); + create_services_subscription_ = + BrowserContextDependencyManager::GetInstance() + ->RegisterCreateServicesCallbackForTesting(base::BindRepeating( + &SigninUiUtilTest_HistorySyncOptinTest::SetupTestFactories, + base::Unretained(this))); + } + + void SetupTestFactories(content::BrowserContext* context) { + SyncServiceFactory::GetInstance()->SetTestingFactory( + context, base::BindRepeating(&CreateTestSyncService)); + } + void ExpectTurnSyncOn(signin_metrics::AccessPoint access_point, + signin_metrics::PromoAction promo_action, + const CoreAccountId& account_id, + TurnSyncOnHelper::SigninAbortedMode signin_aborted_mode, + bool is_sync_promo, + bool user_already_signed_in) override {} + + protected: + syncer::TestSyncService* sync_service() { + return static_cast<syncer::TestSyncService*>( + SyncServiceFactory::GetForProfile(browser()->profile())); + } + + private: + base::CallbackListSubscription create_services_subscription_; + base::test::ScopedFeatureList feature_list_{ + syncer::kReplaceSyncPromosWithSignInPromos}; +}; + +IN_PROC_BROWSER_TEST_F(SigninUiUtilTest_HistorySyncOptinTest, + ShowSignInUiForHistorySyncOptin_SignedOut) { + sync_service()->GetUserSettings()->SetSelectedTypes(false, {}); + + TriggerSignInForHistorySyncOptIn(browser(), browser()->profile(), + signin_metrics::AccessPoint::kRecentTabs); + EXPECT_TRUE(SigninPromoTabHelper::GetForWebContents( + *browser()->tab_strip_model()->GetActiveWebContents()) + ->IsInitializedForTesting()); + // Signing in should also enable history sync. + identity_test_env()->MakeAccountAvailable( + signin::AccountAvailabilityOptionsBuilder() + .AsPrimary(signin::ConsentLevel::kSignin) + .WithAccessPoint(signin_metrics::AccessPoint::kRecentTabs) + .Build("test@email.com")); + + EXPECT_TRUE(sync_service()->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kHistory)); + EXPECT_TRUE(sync_service()->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kTabs)); + EXPECT_TRUE(sync_service()->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kSavedTabGroups)); +} + +IN_PROC_BROWSER_TEST_F(SigninUiUtilTest_HistorySyncOptinTest, + ShowSignInUiForHistorySyncOptin_WebSignedIn) { + // Sign in with an account, but only on the web. The primary account is not + // set. + AccountInfo info = signin::MakeAccountAvailable( + identity_manager(), + signin::AccountAvailabilityOptionsBuilder(test_url_loader_factory()) + .WithCookie() + .WithAccessPoint(signin_metrics::AccessPoint::kRecentTabs) + .Build("test@email.com")); + + sync_service()->GetUserSettings()->SetSelectedTypes(false, {}); + + TriggerSignInForHistorySyncOptIn(browser(), browser()->profile(), + signin_metrics::AccessPoint::kRecentTabs); + + // The sign in tab should not be shown: user is expected to be signed in + // silently by the TriggerSignInForHistorySyncOptIn(). + EXPECT_FALSE(SigninPromoTabHelper::GetForWebContents( + *browser()->tab_strip_model()->GetActiveWebContents()) + ->IsInitializedForTesting()); + EXPECT_TRUE(sync_service()->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kHistory)); + EXPECT_TRUE(sync_service()->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kTabs)); + EXPECT_TRUE(sync_service()->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kSavedTabGroups)); +} + +IN_PROC_BROWSER_TEST_F(SigninUiUtilTest_HistorySyncOptinTest, + ShowSignInUiForHistorySyncOptin_SignInPending) { + AccountInfo info = signin::MakePrimaryAccountAvailable( + GetIdentityManager(), "test@email.com", signin::ConsentLevel::kSignin); + + sync_service()->GetUserSettings()->SetSelectedTypes(false, {}); + + identity_test_env()->SetInvalidRefreshTokenForPrimaryAccount(); + + TriggerSignInForHistorySyncOptIn(browser(), browser()->profile(), + signin_metrics::AccessPoint::kRecentTabs); + + EXPECT_TRUE(SigninPromoTabHelper::GetForWebContents( + *browser()->tab_strip_model()->GetActiveWebContents()) + ->IsInitializedForTesting()); + + identity_manager()->GetAccountsMutator()->AddOrUpdateAccount( + info.gaia, info.email, "dummy_refresh_token", false, + signin_metrics::AccessPoint::kRecentTabs, + signin_metrics::SourceForRefreshTokenOperation:: + kDiceResponseHandler_Signin); + + EXPECT_TRUE(sync_service()->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kHistory)); + EXPECT_TRUE(sync_service()->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kTabs)); + EXPECT_TRUE(sync_service()->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kSavedTabGroups)); +} + +IN_PROC_BROWSER_TEST_F( + SigninUiUtilTest_HistorySyncOptinTest, + ShowSignInUiForHistorySyncOptin_SignedInWithoutHistorySync) { + identity_test_env()->MakePrimaryAccountAvailable( + "test@email.com", signin::ConsentLevel::kSignin); + + sync_service()->GetUserSettings()->SetSelectedTypes(false, {}); + + TriggerSignInForHistorySyncOptIn( + browser(), browser()->profile(), + signin_metrics::AccessPoint::kCollaborationShareTabGroup); + + EXPECT_TRUE( + GetIdentityManager()->HasPrimaryAccount(signin::ConsentLevel::kSignin)); + EXPECT_FALSE(SigninPromoTabHelper::GetForWebContents( + *browser()->tab_strip_model()->GetActiveWebContents()) + ->IsInitializedForTesting()); + + EXPECT_TRUE(sync_service()->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kHistory)); + EXPECT_TRUE(sync_service()->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kTabs)); + EXPECT_TRUE(sync_service()->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kSavedTabGroups)); +} +#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) + } // namespace signin_ui_util
diff --git a/chrome/browser/supervised_user/BUILD.gn b/chrome/browser/supervised_user/BUILD.gn index e55443e..59e71b3 100644 --- a/chrome/browser/supervised_user/BUILD.gn +++ b/chrome/browser/supervised_user/BUILD.gn
@@ -224,6 +224,7 @@ "//components/browser_ui/bottomsheet/android:java", "//components/browser_ui/bottomsheet/android:manager_java", "//components/browser_ui/bottomsheet/android/test:java", + "//components/policy/android:policy_java_test_support", "//components/signin/public/android:java", "//components/signin/public/android:signin_java_test_support", "//content/public/android:content_java",
diff --git a/chrome/browser/supervised_user/android/javatests/src/org/chromium/chrome/browser/supervised_user/IncognitoInteractionTest.java b/chrome/browser/supervised_user/android/javatests/src/org/chromium/chrome/browser/supervised_user/IncognitoInteractionTest.java index 3c3c14fa5..70a10956 100644 --- a/chrome/browser/supervised_user/android/javatests/src/org/chromium/chrome/browser/supervised_user/IncognitoInteractionTest.java +++ b/chrome/browser/supervised_user/android/javatests/src/org/chromium/chrome/browser/supervised_user/IncognitoInteractionTest.java
@@ -4,6 +4,10 @@ package org.chromium.chrome.browser.supervised_user; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + import androidx.test.filters.LargeTest; import org.junit.Before; @@ -26,7 +30,9 @@ import org.chromium.chrome.test.transit.FreshCtaTransitTestRule; import org.chromium.chrome.test.transit.ntp.RegularNewTabPageStation; import org.chromium.chrome.test.util.browser.signin.SigninTestRule; +import org.chromium.components.policy.test.annotations.Policies; import org.chromium.components.signin.test.util.TestAccounts; +import org.chromium.content_public.browser.LoadUrlParams; /** Verifies incognito tab related journeys for various types of supervised profiles. */ @RunWith(ChromeJUnit4ClassRunner.class) @@ -69,6 +75,34 @@ @Test @LargeTest @EnableFeatures({ChromeFeatureList.PROPAGATE_DEVICE_CONTENT_FILTERS_TO_SUPERVISED_USER}) + // This policy explicitly allows incognito mode, and has higher priority over local parental + // controls. + @Policies.Add({@Policies.Item(key = "IncognitoModeAvailability", string = "0")}) + public void incognitoTabsNotClosedWhenPolicyAllowsIncognito() throws Exception { + Profile profile = mActivityTestRule.getProfile(/* incognito= */ false); + ThreadUtils.runOnUiThreadBlocking( + () -> { + SupervisedUserServiceTestBridge.init(profile); + }); + + // Create a new incognito tab. This succeeds, as the device is not + // supervised. + Tab tab = mActivityTestRule.newIncognitoTabFromMenu(); + // Enable browser content filtering for the current profile. + ThreadUtils.runOnUiThreadBlocking( + () -> { + SupervisedUserServiceTestBridge.enableBrowserContentFilters(profile); + // Successfully load a URL in the incognito tab. That proves that the tab is not + // closed. If the tab was closed, the load would fail due to assertion error. + assertNotNull(tab.getWebContents()); + Tab.LoadUrlResult result = tab.loadUrl(new LoadUrlParams("about:blank")); + assertTrue(result.tabLoadStatus == Tab.TabLoadStatus.DEFAULT_PAGE_LOAD); + }); + } + + @Test + @LargeTest + @EnableFeatures({ChromeFeatureList.PROPAGATE_DEVICE_CONTENT_FILTERS_TO_SUPERVISED_USER}) public void incognitoTabsClosedWhenBrowserContentFilteringIsEnabledWithoutAccount() throws Exception { Profile profile = mActivityTestRule.getProfile(/* incognito= */ false); @@ -87,6 +121,7 @@ ThreadUtils.runOnUiThreadBlocking( () -> { SupervisedUserServiceTestBridge.enableBrowserContentFilters(profile); + assertNull(tab.getWebContents()); }); // Check that the incognito tab is no longer open. @@ -115,6 +150,7 @@ ThreadUtils.runOnUiThreadBlocking( () -> { SupervisedUserServiceTestBridge.enableBrowserContentFilters(profile); + assertNull(tab.getWebContents()); }); // Check that the incognito tab is no longer open. @@ -143,6 +179,7 @@ ThreadUtils.runOnUiThreadBlocking( () -> { SupervisedUserServiceTestBridge.enableSearchContentFilters(profile); + assertNull(tab.getWebContents()); }); // Check that the incognito tab is no longer open.
diff --git a/chrome/browser/sync/test/integration/BUILD.gn b/chrome/browser/sync/test/integration/BUILD.gn index 39cb2a5..f67d290b 100644 --- a/chrome/browser/sync/test/integration/BUILD.gn +++ b/chrome/browser/sync/test/integration/BUILD.gn
@@ -149,6 +149,7 @@ "single_client_webauthn_credentials_sync_test.cc", "sync_auth_test.cc", "sync_errors_test.cc", + "sync_os_crypt_async_migration_test.cc", # Tests with two clients can't run on Android because Android doesn't # support multiple profiles.
diff --git a/chrome/browser/sync/test/integration/passwords_helper.cc b/chrome/browser/sync/test/integration/passwords_helper.cc index a105130..52bc4efa 100644 --- a/chrome/browser/sync/test/integration/passwords_helper.cc +++ b/chrome/browser/sync/test/integration/passwords_helper.cc
@@ -227,6 +227,18 @@ return GetLogins(GetPasswordStoreInterface(index, store)).size(); } +std::vector<password_manager::PasswordForm> GetAllPasswordsForProfile( + int profile_index) { + std::vector<std::unique_ptr<password_manager::PasswordForm>> logins = + GetLogins(GetProfilePasswordStoreInterface(profile_index)); + std::vector<password_manager::PasswordForm> passwords; + passwords.reserve(logins.size()); + for (const auto& login : logins) { + passwords.push_back(*login); + } + return passwords; +} + int GetVerifierPasswordCount() { return GetLogins(GetVerifierProfilePasswordStoreInterface()).size(); }
diff --git a/chrome/browser/sync/test/integration/passwords_helper.h b/chrome/browser/sync/test/integration/passwords_helper.h index 21846f2a..798805f 100644 --- a/chrome/browser/sync/test/integration/passwords_helper.h +++ b/chrome/browser/sync/test/integration/passwords_helper.h
@@ -91,6 +91,10 @@ password_manager::PasswordForm::Store store = password_manager::PasswordForm::Store::kProfileStore); +// Gets all passwords from the password store of |profile_index|. +std::vector<password_manager::PasswordForm> GetAllPasswordsForProfile( + int profile_index); + // Returns the number of forms in the password store of the verifier profile. int GetVerifierPasswordCount();
diff --git a/chrome/browser/sync/test/integration/sync_os_crypt_async_migration_test.cc b/chrome/browser/sync/test/integration/sync_os_crypt_async_migration_test.cc new file mode 100644 index 0000000..90f47c30 --- /dev/null +++ b/chrome/browser/sync/test/integration/sync_os_crypt_async_migration_test.cc
@@ -0,0 +1,94 @@ +// 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 <algorithm> + +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/sync/test/integration/passwords_helper.h" +#include "chrome/browser/sync/test/integration/sync_service_impl_harness.h" +#include "chrome/browser/sync/test/integration/sync_test.h" +#include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h" +#include "components/password_manager/core/browser/password_store/password_store_interface.h" +#include "components/sync/base/features.h" +#include "content/public/test/browser_test.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +using passwords_helper::CreateTestPasswordForm; +using passwords_helper::GetAllPasswordsForProfile; +using passwords_helper::GetPasswordCount; +using passwords_helper::GetProfilePasswordStoreInterface; + +class SyncOSCryptAsyncMigrationTest : public SyncTest { + public: + SyncOSCryptAsyncMigrationTest() : SyncTest(SINGLE_CLIENT) {} + ~SyncOSCryptAsyncMigrationTest() override = default; + + void SetUpInProcessBrowserTestFixture() override { + switch (GetTestPreCount()) { + case 2: // PRE_PRE_Migrate + scoped_feature_list_.InitAndDisableFeature( + syncer::kSyncUseOsCryptAsync); + break; + case 1: // PRE_Migrate + scoped_feature_list_.InitAndEnableFeature(syncer::kSyncUseOsCryptAsync); + break; + case 0: // Migrate + scoped_feature_list_.InitAndDisableFeature( + syncer::kSyncUseOsCryptAsync); + break; + } + SyncTest::SetUpInProcessBrowserTestFixture(); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +IN_PROC_BROWSER_TEST_F(SyncOSCryptAsyncMigrationTest, PRE_PRE_Migrate) { + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + ASSERT_EQ(GetPasswordCount(0), 0); + + GetProfilePasswordStoreInterface(0)->AddLogin(CreateTestPasswordForm(0)); + + ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait()); +} + +IN_PROC_BROWSER_TEST_F(SyncOSCryptAsyncMigrationTest, PRE_Migrate) { + ASSERT_TRUE(SetupClients()); + ASSERT_TRUE(GetClient(0)->AwaitSyncSetupCompletion()); + ASSERT_EQ(GetPasswordCount(0), 1); + + GetProfilePasswordStoreInterface(0)->AddLogin(CreateTestPasswordForm(1)); + + ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait()); +} + +IN_PROC_BROWSER_TEST_F(SyncOSCryptAsyncMigrationTest, Migrate) { + ASSERT_TRUE(SetupClients()); + ASSERT_TRUE(GetClient(0)->AwaitSyncSetupCompletion()); + GetSyncService(0)->TriggerRefresh( + syncer::SyncService::TriggerRefreshSource::kUnknown, {syncer::PASSWORDS}); + ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait()); + ASSERT_EQ(GetPasswordCount(0), 2); + + std::vector<password_manager::PasswordForm> passwords = + GetAllPasswordsForProfile(0); + ASSERT_EQ(passwords.size(), 2u); + + // Sort by username to have a deterministic order. + std::sort(passwords.begin(), passwords.end(), + [](const password_manager::PasswordForm& a, + const password_manager::PasswordForm& b) { + return a.username_value < b.username_value; + }); + + EXPECT_EQ(passwords[0].username_value, u"username0"); + EXPECT_EQ(passwords[0].password_value, u"password0"); + EXPECT_EQ(passwords[1].username_value, u"username1"); + EXPECT_EQ(passwords[1].password_value, u"password1"); +} + +} // namespace
diff --git a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl_unittest.cc b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl_unittest.cc index 044dbfdeb..f217c6020 100644 --- a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl_unittest.cc +++ b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl_unittest.cc
@@ -773,7 +773,13 @@ SaveCardPromptOffer::kNotShownMaxStrikesReached, 1); } -TEST_P(SaveCardBubbleLoggingTest, Metrics_SaveButton) { +// TODO(https://crbug.com/448030345): Flaky on Linux ASan +#if BUILDFLAG(IS_LINUX) && defined(ADDRESS_SANITIZER) +#define MAYBE_Metrics_SaveButton DISABLED_Metrics_SaveButton +#else +#define MAYBE_Metrics_SaveButton Metrics_SaveButton +#endif +TEST_P(SaveCardBubbleLoggingTest, MAYBE_Metrics_SaveButton) { base::HistogramTester histogram_tester; TriggerFlow(); controller()->OnSaveButton({});
diff --git a/chrome/browser/ui/signin/dice_migration_service_browsertest.cc b/chrome/browser/ui/signin/dice_migration_service_browsertest.cc index 5ed3d133..8dbdc1e 100644 --- a/chrome/browser/ui/signin/dice_migration_service_browsertest.cc +++ b/chrome/browser/ui/signin/dice_migration_service_browsertest.cc
@@ -1589,6 +1589,7 @@ EXPECT_FALSE( GetIdentityManager()->HasPrimaryAccount(signin::ConsentLevel::kSignin)); // The user is signed in to the web only. + signin::WaitForRefreshTokensLoaded(GetIdentityManager()); EXPECT_THAT( GetIdentityManager()->GetAccountsWithRefreshTokens(), testing::ElementsAre(testing::Field(&AccountInfo::email, kTestEmail))); @@ -1661,6 +1662,7 @@ EXPECT_FALSE( GetIdentityManager()->HasPrimaryAccount(signin::ConsentLevel::kSignin)); // The user is signed in to the web only. + signin::WaitForRefreshTokensLoaded(GetIdentityManager()); EXPECT_THAT(GetIdentityManager()->GetAccountsWithRefreshTokens(), testing::ElementsAre( testing::Field(&AccountInfo::email, kEnterpriseTestEmail))); @@ -1701,6 +1703,7 @@ // The user is explicitly signed in. EXPECT_TRUE(IsExplicitlySignedIn()); // The user is signed in to the web. + signin::WaitForRefreshTokensLoaded(GetIdentityManager()); EXPECT_THAT(GetIdentityManager()->GetAccountsWithRefreshTokens(), testing::ElementsAre( testing::Field(&AccountInfo::email, kEnterpriseTestEmail))); @@ -1709,12 +1712,16 @@ histogram_tester_.ExpectUniqueSample(kForcedMigrationAccountManagedHistogram, true, 1); histogram_tester_.ExpectTotalCount(kSignoutReasonHistogram, 0); - // The toast is shown after the timer finishes. - ASSERT_TRUE( - GetDiceMigrationService()->GetDialogTriggerTimerForTesting().IsRunning()); - histogram_tester_.ExpectUniqueSample(kToastTriggerToShowHistogram, - ToastId::kDiceUserMigrated, 0); - FireDialogTriggerTimer(); + // The toast is shown after the timer finishes. However, it is possible that + // the timer has already finished and the toast is shown before the + // expectation below is checked. + if (GetDiceMigrationService() + ->GetDialogTriggerTimerForTesting() + .IsRunning()) { + histogram_tester_.ExpectUniqueSample(kToastTriggerToShowHistogram, + ToastId::kDiceUserMigrated, 0); + FireDialogTriggerTimer(); + } histogram_tester_.ExpectUniqueSample(kToastTriggerToShowHistogram, ToastId::kDiceUserMigrated, 1); }
diff --git a/chrome/browser/ui/views/data_sharing/collaboration_controller_delegate_desktop.cc b/chrome/browser/ui/views/data_sharing/collaboration_controller_delegate_desktop.cc index 19aa888..0be188725 100644 --- a/chrome/browser/ui/views/data_sharing/collaboration_controller_delegate_desktop.cc +++ b/chrome/browser/ui/views/data_sharing/collaboration_controller_delegate_desktop.cc
@@ -436,62 +436,17 @@ } Profile* profile = browser_->profile(); - syncer::SyncService* sync_service = - SyncServiceFactory::GetForProfile(profile); - // Try to sign in or open a sign in tab if user input is needed. If the user - // is already signed in, this is a no-op. - signin_ui_util::SignInFromSingleAccountPromo( + // This function uses `signin_util::GetSignedInState()` rather than + // `status.signin_status`. We cannot currently use `status.signin_status`, as + // it may not update in time after `SignInFromSingleAccountPromo` sets the + // primary account. + // TODO (crbug.com/443679624): Consider updating and using + // `status.signin_status` instead for consistency. + signin_ui_util::TriggerSignInForHistorySyncOptIn( + browser_, profile, - signin_ui_util::GetSingleAccountForPromos( - IdentityManagerFactory::GetForProfile(profile)), signin_metrics::AccessPoint::kCollaborationShareTabGroup); - - if (!sync_service) { - return; - } - - // It is safe to pass a pointer to the sync service here because the callback - // is then owned by a tab helper, which is guaranteed to be destroyed before - // the sync service. - auto enable_history_sync = base::BindOnce(&signin_util::EnableHistorySync, - base::Unretained(sync_service)); - - // We cannot currently use `status.signin_status`, as it may not update in - // time after `SignInFromSingleAccountPromo` sets the primary account. - // TODO (crbug.com/443679624): Update and use `status.signin_status` instead - // for consistency. - switch (signin_util::GetSignedInState( - IdentityManagerFactory::GetForProfile(profile))) { - // If the sign in was already successful, enable history sync directly. - case signin_util::SignedInState::kSignedIn: - std::move(enable_history_sync).Run(); - return; - // These states require a sign in tab to be displayed. A tab helper attached - // to the tab will take care of turning on history sync once signed in. - case signin_util::SignedInState::kSignedOut: - case signin_util::SignedInState::kSignInPending: - case signin_util::SignedInState::kSyncPaused: - break; - case signin_util::SignedInState::kSyncing: - case signin_util::SignedInState::kWebOnlySignedIn: - return; - } - - content::WebContents* sign_in_tab_contents = - signin_ui_util::GetSignInTabWithAccessPoint( - browser_, signin_metrics::AccessPoint::kCollaborationShareTabGroup); - - // SignInFromSingleAccountPromo may fail to open a tab. Do not wait for a - // sign in event in that case. - if (!sign_in_tab_contents) { - return; - } - - SigninPromoTabHelper::GetForWebContents(*sign_in_tab_contents) - ->InitializeCallbackAfterSignIn( - std::move(enable_history_sync), - signin_metrics::AccessPoint::kCollaborationShareTabGroup); } #endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
diff --git a/chrome/browser/ui/views/download/bubble/download_toolbar_ui_controller.cc b/chrome/browser/ui/views/download/bubble/download_toolbar_ui_controller.cc index b20c1dd..d2bb48c 100644 --- a/chrome/browser/ui/views/download/bubble/download_toolbar_ui_controller.cc +++ b/chrome/browser/ui/views/download/bubble/download_toolbar_ui_controller.cc
@@ -41,6 +41,7 @@ #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/grit/generated_resources.h" #include "components/autofill/content/browser/content_autofill_client.h" +#include "components/autofill/core/browser/suggestions/suggestion_hiding_reason.h" #include "components/feature_engagement/public/feature_constants.h" #include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/safe_browsing_policy_handler.h"
diff --git a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view_pixel_browsertest.cc b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view_pixel_browsertest.cc index 74ab7f5d..401dca6 100644 --- a/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view_pixel_browsertest.cc +++ b/chrome/browser/ui/views/profiles/dice_web_signin_interception_bubble_view_pixel_browsertest.cc
@@ -387,13 +387,8 @@ std::unique_ptr<base::ScopedEnvironmentVariableOverride> scoped_env_override_; }; -#if BUILDFLAG(IS_WIN) -#define MAYBE_InvokeUi_default DISABLED_InvokeUi_default -#else -#define MAYBE_InvokeUi_default InvokeUi_default -#endif IN_PROC_BROWSER_TEST_P(DiceWebSigninInterceptionBubblePixelTest, - MAYBE_InvokeUi_default) { + InvokeUi_default) { ShowAndVerifyUi(); }
diff --git a/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc index 8365480b..db7f0d35 100644 --- a/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc +++ b/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc
@@ -766,13 +766,14 @@ return GURL("chrome://history-sync-optin?launch_context=0"); } + // TODO(crbug.com/447584795): Add retry logic. void RejectHistoryOptin() { ASSERT_TRUE(base::FeatureList::IsEnabled( syncer::kReplaceSyncPromosWithSignInPromos)); constexpr char kRejectHistory[] = "(() => {" " const historySyncOptinApp = " - " document.querySelector('history-sync-optin-app');" + " document.querySelector('history-sync-optin-app');" " const rejectButton = " " historySyncOptinApp.shadowRoot.querySelector('#rejectButton');" " rejectButton.click();" @@ -782,6 +783,23 @@ EXPECT_EQ(true, content::EvalJs(web_contents(), kRejectHistory)); } + // TODO(crbug.com/447584795): Add retry logic. + void AcceptHistoryOptin() { + ASSERT_TRUE(base::FeatureList::IsEnabled( + syncer::kReplaceSyncPromosWithSignInPromos)); + constexpr char kAcceptHistory[] = + "(() => {" + " const historySyncOptinApp = " + " document.querySelector('history-sync-optin-app');" + " const acceptButton = " + " historySyncOptinApp.shadowRoot.querySelector('#acceptButton');" + " acceptButton.click();" + " return true;" + "})();"; + + EXPECT_EQ(true, content::EvalJs(web_contents(), kAcceptHistory)); + } + protected: const GURL kLocalProfileCreationUrl = AppendProfileCustomizationQueryParams( GURL("chrome://profile-customization"), @@ -2970,12 +2988,7 @@ public testing::WithParamInterface< LoginUIService::SyncConfirmationUIClosedResult> { public: - SupervisedUserProfileIPHTest() { - // TODO(crbug.com/447099373): Fix the tests to work with the feature - // enabled. - scoped_feature_list_.InitAndDisableFeature( - syncer::kReplaceSyncPromosWithSignInPromos); - } + SupervisedUserProfileIPHTest() = default; protected: LoginUIService::SyncConfirmationUIClosedResult GetSyncConfirmationResult() { @@ -2987,8 +3000,6 @@ return HasPromoBeenShown( browser, feature_engagement::kIPHSupervisedUserProfileSigninFeature); } - - base::test::ScopedFeatureList scoped_feature_list_; }; std::string SyncConfirmationResultToString( @@ -3018,6 +3029,13 @@ IN_PROC_BROWSER_TEST_P(SupervisedUserProfileIPHTest, ShowIphWhenCustomizationBubbleIsSkipped) { + if (base::FeatureList::IsEnabled( + syncer::kReplaceSyncPromosWithSignInPromos) && + GetSyncConfirmationResult() == LoginUIService::CONFIGURE_SYNC_FIRST) { + // The history optin screen does not have a settings button. + GTEST_SKIP(); + } + size_t initial_browser_count = BrowserList::GetInstance()->size(); auto scoped_iph_delay = AvatarToolbarButton::SetScopedIPHMinDelayAfterCreationForTesting( @@ -3025,8 +3043,12 @@ // Simulate a successful sign-in and wait for the sign-in to propagate to the // flow, resulting in sync confirmation screen getting displayed. + GURL target_url = + base::FeatureList::IsEnabled(syncer::kReplaceSyncPromosWithSignInPromos) + ? GetHistorySyncOptinURL() + : GetSyncConfirmationURL(); Profile* profile_being_created = SignInForNewProfile( - GetSyncConfirmationURL(), "joe@gmail.com", "Joe", kNoHostedDomainFound, + target_url, "joe@gmail.com", "Joe", kNoHostedDomainFound, /*start_on_management_page=*/false, /*is_supervised_profile=*/true); @@ -3040,11 +3062,27 @@ ThemeSyncableService::ThemeSyncState::kApplied); // Pick an action from the Sync screen. - LoginUIServiceFactory::GetForProfile(profile_being_created) - ->SyncConfirmationUIClosed(GetSyncConfirmationResult()); + BrowserAddedWaiter browser_waiter = + BrowserAddedWaiter(initial_browser_count + 1); + if (base::FeatureList::IsEnabled( + syncer::kReplaceSyncPromosWithSignInPromos)) { + switch (GetSyncConfirmationResult()) { + case LoginUIService::SyncConfirmationUIClosedResult::ABORT_SYNC: + RejectHistoryOptin(); + break; + case LoginUIService::SyncConfirmationUIClosedResult:: + SYNC_WITH_DEFAULT_SETTINGS: + AcceptHistoryOptin(); + break; + default: + NOTREACHED(); + } + } else { + LoginUIServiceFactory::GetForProfile(profile_being_created) + ->SyncConfirmationUIClosed(GetSyncConfirmationResult()); + } - BrowserWindowInterface* const new_browser = - BrowserAddedWaiter(initial_browser_count + 1).Wait(); + BrowserWindowInterface* new_browser = browser_waiter.Wait(); CHECK(new_browser); ASSERT_TRUE(content::WaitForLoadStop( new_browser->GetTabStripModel()->GetActiveWebContents()));
diff --git a/chrome/browser/ui/webui/history/browsing_history_handler.cc b/chrome/browser/ui/webui/history/browsing_history_handler.cc index e06daf80..31edc9e 100644 --- a/chrome/browser/ui/webui/history/browsing_history_handler.cc +++ b/chrome/browser/ui/webui/history/browsing_history_handler.cc
@@ -27,13 +27,17 @@ #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/history/history_utils.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/signin/identity_manager_factory.h" +#include "chrome/browser/signin/signin_ui_util.h" #include "chrome/browser/supervised_user/supervised_user_service_factory.h" #include "chrome/browser/sync/device_info_sync_service_factory.h" #include "chrome/browser/sync/sync_service_factory.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/chrome_pages.h" +#include "chrome/browser/ui/profiles/profile_view_utils.h" #include "chrome/browser/ui/url_identity.h" #include "chrome/browser/ui/webui/favicon_source.h" +#include "chrome/browser/ui/webui/signin/signin_utils.h" #include "chrome/browser/ui/webui/top_chrome/top_chrome_web_ui_controller.h" #include "chrome/common/buildflags.h" #include "chrome/common/pref_names.h" @@ -49,6 +53,7 @@ #include "components/keyed_service/core/service_access_type.h" #include "components/prefs/pref_service.h" #include "components/query_parser/snippet.h" +#include "components/signin/public/identity_manager/account_info.h" #include "components/strings/grit/components_strings.h" #include "components/supervised_user/core/browser/supervised_user_preferences.h" #include "components/supervised_user/core/browser/supervised_user_service.h" @@ -72,6 +77,19 @@ namespace { +#if !BUILDFLAG(IS_CHROMEOS) +history::mojom::AccountInfoPtr CreateAccountInfoDataMojo( + const AccountInfo& info) { + history::mojom::AccountInfoPtr account_info_mojo = + history::mojom::AccountInfo::New(); + account_info_mojo->name = info.full_name; + account_info_mojo->email = info.email; + account_info_mojo->account_image_src = + GURL(signin::GetAccountPictureUrl(info)); + return account_info_mojo; +} +#endif + // Identifiers for the type of device from which a history entry originated. static const char kDeviceTypeLaptop[] = "laptop"; static const char kDeviceTypePhone[] = "phone"; @@ -327,6 +345,8 @@ : profile_(profile), web_contents_(web_contents), page_handler_(this, std::move(pending_page_handler)), + identity_manager_( + CHECK_DEREF(IdentityManagerFactory::GetForProfile(profile))), clock_(base::DefaultClock::GetInstance()), browsing_history_service_(nullptr) {} @@ -464,6 +484,20 @@ chrome::ShowClearBrowsingDataDialog(browser); } +void BrowsingHistoryHandler::TurnOnHistorySync() { +#if !BUILDFLAG(IS_CHROMEOS) + Browser* browser = chrome::FindBrowserWithTab(web_contents_); + if (browser) { + signin_ui_util::TriggerSignInForHistorySyncOptIn( + browser, profile_, signin_metrics::AccessPoint::kRecentTabs); + } +#else + // This is not expected to be called on ChromeOS as the screen that uses this + // function is never shown for ChromeOS (using <if expr="not is_chromeos">). + NOTREACHED(); +#endif +} + void BrowsingHistoryHandler::RemoveBookmark(const std::string& url) { BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile_); bookmarks::RemoveAllBookmarks(model, GURL(url), FROM_HERE); @@ -544,3 +578,38 @@ Profile* BrowsingHistoryHandler::GetProfile() { return profile_; } + +void BrowsingHistoryHandler::RequestAccountInfo( + RequestAccountInfoCallback callback) { +#if !BUILDFLAG(IS_CHROMEOS) + AccountInfo account_info = + signin_ui_util::GetSingleAccountForPromos(&identity_manager_.get()); + std::move(callback).Run(CreateAccountInfoDataMojo(account_info)); + + if (!identity_manager_observation_.IsObserving()) { + identity_manager_observation_.Observe(&identity_manager_.get()); + } +#else + // This is not expected to be called on ChromeOS as the screen that uses this + // function is never shown for ChromeOS (using <if expr="not is_chromeos">). + NOTREACHED(); +#endif +} + +void BrowsingHistoryHandler::OnExtendedAccountInfoUpdated( + const AccountInfo& info) { +#if !BUILDFLAG(IS_CHROMEOS) + AccountInfo account_to_display = + signin_ui_util::GetSingleAccountForPromos(&identity_manager_.get()); + + if (info.IsEmpty() || !info.IsValid() || + info.account_id != account_to_display.account_id) { + return; + } + page_->SendAccountInfo(CreateAccountInfoDataMojo(info)); +#else + // This is not expected to be called on ChromeOS as the screen that uses this + // function is never shown for ChromeOS (using <if expr="not is_chromeos">). + NOTREACHED(); +#endif +}
diff --git a/chrome/browser/ui/webui/history/browsing_history_handler.h b/chrome/browser/ui/webui/history/browsing_history_handler.h index e282adf..cf32780 100644 --- a/chrome/browser/ui/webui/history/browsing_history_handler.h +++ b/chrome/browser/ui/webui/history/browsing_history_handler.h
@@ -16,11 +16,14 @@ #include "base/functional/callback.h" #include "base/gtest_prod_util.h" #include "base/memory/raw_ptr.h" +#include "base/memory/raw_ref.h" #include "base/memory/weak_ptr.h" #include "base/time/clock.h" #include "base/values.h" #include "chrome/browser/history/profile_based_browsing_history_driver.h" +#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/webui/top_chrome/top_chrome_web_ui_controller.h" +#include "components/signin/public/identity_manager/identity_manager.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" @@ -33,7 +36,8 @@ // The handler for Javascript messages related to the "history" view. class BrowsingHistoryHandler : public history::mojom::PageHandler, - public ProfileBasedBrowsingHistoryDriver { + public ProfileBasedBrowsingHistoryDriver, + public signin::IdentityManager::Observer { public: BrowsingHistoryHandler( mojo::PendingReceiver<history::mojom::PageHandler> pending_page_handler, @@ -86,6 +90,10 @@ // ProfileBasedBrowsingHistoryDriver implementation. Profile* GetProfile() override; + // history::mojom::PageHandler: + void RequestAccountInfo(RequestAccountInfoCallback callback) override; + void TurnOnHistorySync() override; + // For tests. This does not take the ownership of the clock. |clock| must // outlive the BrowsingHistoryHandler instance. void set_clock(base::Clock* clock) { clock_ = clock; } @@ -99,6 +107,12 @@ return browsing_history_service_.get(); } +#if defined(UNIT_TEST) + bool is_observing_identity_manager_for_testing() const { + return identity_manager_observation_.IsObserving(); + } +#endif + protected: virtual void SendHistoryQuery(int count, const std::string& query, @@ -111,11 +125,19 @@ base::WeakPtr<TopChromeWebUIController::Embedder> side_panel_embedder_; + // signin::IdentityManager::Observer: + void OnExtendedAccountInfoUpdated(const AccountInfo& info) override; + raw_ptr<Profile> profile_; raw_ptr<content::WebContents> web_contents_; - + // Interface to send information to the web ui page. mojo::Remote<history::mojom::Page> page_; + // Allows handling received messages from the web ui page. mojo::Receiver<history::mojom::PageHandler> page_handler_; + const base::raw_ref<signin::IdentityManager> identity_manager_; + base::ScopedObservation<signin::IdentityManager, + signin::IdentityManager::Observer> + identity_manager_observation_{this}; // The clock used to vend times. raw_ptr<base::Clock> clock_;
diff --git a/chrome/browser/ui/webui/history/browsing_history_handler_unittest.cc b/chrome/browser/ui/webui/history/browsing_history_handler_unittest.cc index 29b66cf5..f31dd49 100644 --- a/chrome/browser/ui/webui/history/browsing_history_handler_unittest.cc +++ b/chrome/browser/ui/webui/history/browsing_history_handler_unittest.cc
@@ -24,12 +24,16 @@ #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" #include "components/history/core/browser/browsing_history_service.h" +#include "components/signin/public/identity_manager/identity_manager.h" +#include "components/signin/public/identity_manager/identity_test_utils.h" #include "components/sync/base/data_type.h" #include "content/public/browser/web_contents.h" #include "content/public/test/test_web_ui.h" +#include "mojo/public/cpp/bindings/receiver.h" #include "net/http/http_status_code.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "testing/gmock/include/gmock/gmock.h" @@ -64,6 +68,28 @@ return out_time; } +class MockHistoryPage : public history::mojom::Page { + public: + MockHistoryPage() = default; + ~MockHistoryPage() override = default; + + void FlushForTesting() { receiver_.FlushForTesting(); } + + mojo::PendingRemote<history::mojom::Page> BindAndGetRemote() { + return receiver_.BindNewPipeAndPassRemote(); + } + + MOCK_METHOD(void, OnHistoryDeleted, (), (override)); + MOCK_METHOD(void, OnHasOtherFormsChanged, (bool), (override)); + MOCK_METHOD(void, + SendAccountInfo, + (history::mojom::AccountInfoPtr), + (override)); + + private: + mojo::Receiver<history::mojom::Page> receiver_{this}; +}; + class BrowsingHistoryHandlerWithWebUIForTesting : public BrowsingHistoryHandler { public: @@ -109,6 +135,9 @@ handler_ = std::make_unique<BrowsingHistoryHandlerWithWebUIForTesting>( mojo::PendingReceiver<history::mojom::PageHandler>(), profile(), web_contents()); + + mock_page_ = std::make_unique<MockHistoryPage>(); + handler_->SetPage(mock_page_->BindAndGetRemote()); } void MockHistoryServiceCall( @@ -172,6 +201,7 @@ void TearDown() override { handler_.reset(); web_ui_.reset(); + mock_page_.reset(); ChromeRenderViewHostTestHarness::TearDown(); } @@ -187,10 +217,12 @@ BrowsingHistoryHandlerWithWebUIForTesting* handler() { return handler_.get(); } + MockHistoryPage* mock_page() { return mock_page_.get(); } private: std::unique_ptr<content::TestWebUI> web_ui_; std::unique_ptr<BrowsingHistoryHandlerWithWebUIForTesting> handler_; + std::unique_ptr<MockHistoryPage> mock_page_; }; TEST_F(BrowsingHistoryHandlerTest, HostPrefixParameter) { @@ -273,4 +305,71 @@ } #endif +#if !BUILDFLAG(IS_CHROMEOS) +TEST_F(BrowsingHistoryHandlerTest, RequestAccountInfo) { + // Check that the account info is sent to the page. + signin::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(profile()); + AccountInfo account_info = signin::MakePrimaryAccountAvailable( + identity_manager, "test@example.com", signin::ConsentLevel::kSignin); + account_info.full_name = "Test User"; + signin::UpdateAccountInfoForAccount(identity_manager, account_info); + + base::MockCallback<BrowsingHistoryHandler::RequestAccountInfoCallback> + callback; + history::mojom::AccountInfoPtr account_info_ptr; + EXPECT_CALL(callback, Run(_)) + .WillOnce(testing::Invoke( + [&](history::mojom::AccountInfoPtr ptr) { + account_info_ptr = std::move(ptr); + })); + + handler()->RequestAccountInfo(callback.Get()); + + ASSERT_TRUE(account_info_ptr); + EXPECT_EQ("test@example.com", account_info_ptr->email); + EXPECT_EQ("Test User", account_info_ptr->name); +} + +TEST_F(BrowsingHistoryHandlerTest, TurnOnHistorySync) { + // This test doesn't create a Browser instance, so FindBrowserWithTab + // returns nullptr. TurnOnHistorySync should handle this without crashing. + handler()->TurnOnHistorySync(); +} + +TEST_F(BrowsingHistoryHandlerTest, ObservesIdentityManagerOnlyAfterRequest) { + // Check that the identity manager is only observed after RequestAccountInfo + // is called. + ASSERT_FALSE(handler()->is_observing_identity_manager_for_testing()); + handler()->RequestAccountInfo(base::DoNothing()); + EXPECT_TRUE(handler()->is_observing_identity_manager_for_testing()); +} + +TEST_F(BrowsingHistoryHandlerTest, SendsUpdatedInfoOnAccountChange) { + // Check that the account info is sent to the page when it is updated. + signin::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(profile()); + AccountInfo account_info = signin::MakePrimaryAccountAvailable( + identity_manager, "test@example.com", signin::ConsentLevel::kSignin); + + base::MockCallback<BrowsingHistoryHandler::RequestAccountInfoCallback> + callback; + EXPECT_CALL(callback, Run(::testing::_)); + handler()->RequestAccountInfo(callback.Get()); + + EXPECT_CALL(*mock_page(), SendAccountInfo(_)); + // Update the account info with all the necessary fields for + // AccountInfo::isValid() to be true. + account_info.hosted_domain = "example.com"; + account_info.full_name = "Test User"; + account_info.given_name = "Test"; + account_info.picture_url = "http://example.com/test.jpg"; + ASSERT_TRUE(account_info.IsValid()); + + signin::UpdateAccountInfoForAccount(identity_manager, account_info); + + mock_page()->FlushForTesting(); +} +#endif + } // namespace history
diff --git a/chrome/browser/ui/webui/history/history_ui.cc b/chrome/browser/ui/webui/history/history_ui.cc index 57d3c64..6204e42e 100644 --- a/chrome/browser/ui/webui/history/history_ui.cc +++ b/chrome/browser/ui/webui/history/history_ui.cc
@@ -80,7 +80,7 @@ profile, chrome::kChromeUIHistoryHost); source->AddBoolean( - "useHistorySyncOptinScreen", + "replaceSyncPromosWithSignInPromos", base::FeatureList::IsEnabled(syncer::kReplaceSyncPromosWithSignInPromos)); HistoryUtil::PopulateCommonSourceForHistory(source, profile); @@ -98,23 +98,15 @@ {"turnOnSyncPromo", IDS_HISTORY_TURN_ON_SYNC_PROMO}, {"turnOnSyncPromoDesc", IDS_HISTORY_TURN_ON_SYNC_PROMO_DESC}, {"turnOnSyncHistoryPromo", IDS_HISTORY_SYNC_HISTORY_PROMO}, - {"turnOnSyncHistoryPromoDesc", IDS_HISTORY_SYNC_HISTORY_PROMO_DESC}, {"syncHistoryPromoBodySignedOut", IDS_RECENT_TABS_SYNC_HISTORY_PROMO_BODY_SIGNED_OUT}, {"syncHistoryPromoBodyPendingSignIn", IDS_RECENT_TABS_SYNC_HISTORY_PROMO_BODY_PENDING_SIGN_IN}, - {"turnOnSignedInSyncHistoryPromo", - IDS_HISTORY_SIGNED_IN_SYNC_HISTORY_PROMO}, }; source->AddLocalizedStrings(kStrings); source->AddLocalizedString("turnOnSyncHistoryButton", IDS_HISTORY_SYNC_HISTORY_BUTTON); - source->AddLocalizedString("turnOnSignedInSyncHistoryPromoDesc", - IDS_HISTORY_SIGNED_IN_SYNC_HISTORY_PROMO_DESC); - source->AddLocalizedString( - "syncHistoryPromoBodySignInSyncOff", - IDS_RECENT_TABS_SYNC_HISTORY_PROMO_BODY_SIGNED_IN_SYNC_OFF); source->AddString("accountPictureUrl", profiles::GetPlaceholderAvatarIconUrl()); @@ -163,6 +155,13 @@ identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin); AccountInfo account_info = signin_ui_util::GetSingleAccountForPromos(identity_manager); + source->AddString( + "turnOnSignedInSyncHistoryPromoBodySignInSyncOff", + l10n_util::GetStringFUTF16( + IDS_RECENT_TABS_SYNC_HISTORY_PROMO_BODY_SIGNED_IN_SYNC_OFF, + base::UTF8ToUTF16(account_info.email))); + source->AddString("accountName", account_info.full_name); + source->AddString("accountEmail", account_info.email); if (!has_primary_account && !account_info.IsEmpty()) { source->AddString("turnOnSyncButton", l10n_util::GetStringFUTF16(
diff --git a/chrome/browser/ui/webui/signin/history_sync_optin_service.cc b/chrome/browser/ui/webui/signin/history_sync_optin_service.cc index 753e1ac..3d8abd04a 100644 --- a/chrome/browser/ui/webui/signin/history_sync_optin_service.cc +++ b/chrome/browser/ui/webui/signin/history_sync_optin_service.cc
@@ -25,7 +25,10 @@ base::OnceClosure history_optin_completed_closure) { CHECK(profile); Browser* browser = chrome::FindLastActiveWithProfile(profile); - CHECK(browser); + if (!browser) { + // The browser has been closed in the meantime, nothing to do. + return; + } browser->GetFeatures() .signin_view_controller() ->ShowModalHistorySyncOptInDialog(
diff --git a/chrome/browser/webauthn/fake_magic_arch.cc b/chrome/browser/webauthn/fake_magic_arch.cc index 0d90373..415470f51 100644 --- a/chrome/browser/webauthn/fake_magic_arch.cc +++ b/chrome/browser/webauthn/fake_magic_arch.cc
@@ -9,6 +9,8 @@ #include "base/check.h" #include "base/compiler_specific.h" #include "base/containers/span.h" +#include "base/numerics/byte_conversions.h" +#include "base/strings/string_view_util.h" #include "chrome/browser/webauthn/fake_recovery_key_store.h" #include "chrome/browser/webauthn/fake_security_domain_service.h" #include "components/trusted_vault/proto/recovery_key_store.pb.h" @@ -34,9 +36,8 @@ } std::string AsLEBytes(int32_t v) { - char bytes[4]; - UNSAFE_TODO(memcpy(bytes, &v, sizeof(bytes))); - return std::string(bytes, 4); + auto bytes = base::I32ToNativeEndian(v); + return std::string(base::as_string_view(base::span(bytes))); } std::array<uint8_t, 32> HashPIN(std::string_view pin,
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt index 5e8d512..b936d5f8 100644 --- a/chrome/build/android-arm64.pgo.txt +++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@ -chrome-android64-main-1759113631-521584a48aec18ff4eea09014493dc27f7252e65-2f699256a0e8b7b022ab3d1e89a4cfe12889ad2d.profdata +chrome-android64-main-1759132778-32017b01783ae95a5e834b568ee9fb965957d085-6da4010a623148651c081aac49c112dff7c8e9c0.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 219bd19b..bea8a3a8 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1759125565-0d63a609ba0ba612a73583edde60935f4fb5e8e0-991eb366bc494b9ca2d65e6baec7d48417fce7cc.profdata +chrome-mac-arm-main-1759139876-a06bb3fcef0f8533d8a8afc1b651a0e8d39d2d0c-cb6b4fd665b860fe9f8b54646d4c9ebc4055a14e.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 6f466db3..0a7ad17 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1759103625-4ca4b90f47e9dc0669be9e5d38275a1c02566fae-a6fc5852b1a8e7a53a92b8b50a32fd00e47437a0.profdata +chrome-mac-main-1759125565-2000367fc9931e9fc798ee2286f2f9295994f9f5-991eb366bc494b9ca2d65e6baec7d48417fce7cc.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt index a54dbf1..9e62e4317 100644 --- a/chrome/build/win-arm64.pgo.txt +++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@ -chrome-win-arm64-main-1759103625-a297ead0d3eaca8d3d33266de6bdd0f76dc5c05f-a6fc5852b1a8e7a53a92b8b50a32fd00e47437a0.profdata +chrome-win-arm64-main-1758693376-1940a11ef9cfe1538d7dfb3e4c1f721e3173b8ab-53fab56d338a7984a7d12554ffd25f0f93972cb0.profdata \ No newline at end of file
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 17c9374..4bd70d8 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1759103625-fd46c7417b5ce6e7c7e85564f7ff841b9b87dfb6-a6fc5852b1a8e7a53a92b8b50a32fd00e47437a0.profdata +chrome-win32-main-1759114126-8896ff2e1c2de669a0b13d182c694a8885a14c15-55b57e7b202fac8c64c3bc5c6e2afcf41c5eaf1e.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 9d1eddde..eea8f31 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1759114126-9a64c1f7ddb04078c2d4d3df577d5dc00b3dc246-55b57e7b202fac8c64c3bc5c6e2afcf41c5eaf1e.profdata +chrome-win64-main-1759125565-7ba1074ee2f926b899ebbdf0c1be9146e43dd978-991eb366bc494b9ca2d65e6baec7d48417fce7cc.profdata
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index d0a05dc..79f91f60 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -42,10 +42,6 @@ &kGlicActor, "actor-paint-stability-subsequent-paint-timeout", base::Milliseconds(500)}; -#if BUILDFLAG(IS_CHROMEOS) -BASE_FEATURE(kAppPreloadService, base::FEATURE_ENABLED_BY_DEFAULT); -#endif // BUILDFLAG(IS_CHROMEOS) - #if BUILDFLAG(IS_WIN) // When enabled, notifications from PWA's will use the PWA icon and name, // as long as the PWA is on the start menu. b/40285965.
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index 7a2fd458..7f7af90 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -44,10 +44,6 @@ extern const base::FeatureParam<base::TimeDelta>( kActorPaintStabilitySubsequentPaintTimeout); -#if BUILDFLAG(IS_CHROMEOS) -COMPONENT_EXPORT(CHROME_FEATURES) BASE_DECLARE_FEATURE(kAppPreloadService); -#endif - #if BUILDFLAG(IS_WIN) COMPONENT_EXPORT(CHROME_FEATURES) BASE_DECLARE_FEATURE(kAppSpecificNotifications);
diff --git a/chrome/test/data/webui/history/history_synced_tabs_test.ts b/chrome/test/data/webui/history/history_synced_tabs_test.ts index 928925a..1cb3f7c 100644 --- a/chrome/test/data/webui/history/history_synced_tabs_test.ts +++ b/chrome/test/data/webui/history/history_synced_tabs_test.ts
@@ -8,6 +8,10 @@ import {assertEquals, assertFalse, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {microtasksFinished} from 'chrome://webui-test/test_util.js'; +// <if expr="not is_chromeos"> +import { isChildVisible } from 'chrome://webui-test/test_util.js'; +// </if> + import {TestBrowserService} from './test_browser_service.js'; import {createSession, createWindow} from './test_util.js'; @@ -350,3 +354,118 @@ assertEquals(0, cards.length); }); }); + +// <if expr="not is_chromeos"> +// history-sync-optin elements is not shown for ChromeOS. +suite('<history-sync-optin>', function() { + let element: HistorySyncedDeviceManagerElement; + let testService: TestBrowserService; + + setup(function() { + document.body.innerHTML = window.trustedTypes!.emptyHTML; + window.history.replaceState({}, '', '/'); + testService = new TestBrowserService(); + BrowserServiceImpl.setInstance(testService); + + // history-sync-optin elements are only shown when the + // replaceSyncPromosWithSignInPromos is true + loadTimeData.overrideValues({ + replaceSyncPromosWithSignInPromos: true, + }); + + // Need to ensure lazy_load.html has been imported so that the device + // manager custom element is defined. + return ensureLazyLoaded().then(() => { + element = document.createElement('history-synced-device-manager'); + // |signInState| is generally set after |searchTerm| in Polymer 2. Set in + // the same order in tests, in order to catch regressions like + // https://crbug.com/915641. + element.searchTerm = ''; + element.configureSignInForTest({ + // Setting the sign in state to WEB_ONLY_SIGNED_IN, because user's name, + // email and profile icon are only shown on the page when the sign in + // state is WEB_ONLY_SIGNED_IN. + signInState: HistorySignInState.WEB_ONLY_SIGNED_IN, + signInAllowed: true, + guestSession: false, + }); + document.body.appendChild(element); + }); + }); + + test('check history sync optin elements are visible', async () => { + await microtasksFinished(); + + // The old promo should not be visible. + assertFalse(isChildVisible(element, '#turn-on-sync-promo')); + + // The new promo elements for WEB_ONLY_SIGNED_IN state are shown correctly. + assertTrue(isChildVisible(element, '#sync-history-button')); + assertTrue(isChildVisible(element, '#history-sync-optin')); + assertTrue(isChildVisible(element, '#account-name')); + assertTrue(isChildVisible(element, '#account-email')); + assertTrue(isChildVisible(element, '#profile-icon')); + }); + + test('initializes account info', async () => { + await testService.handler.whenCalled('requestAccountInfo'); + await microtasksFinished(); + + assertEquals( + 'Test User', + element.shadowRoot.querySelector<HTMLElement>( + '#account-name')!.textContent!.trim()); + assertEquals( + 'test@google.com', + element.shadowRoot.querySelector<HTMLElement>( + '#account-email')!.textContent!.trim()); + assertEquals( + 'http://example.com/image.png', + element.shadowRoot.querySelector<HTMLImageElement>( + '#profile-icon')!.src); + }); + + test('updates account info', async () => { + await testService.handler.whenCalled('requestAccountInfo'); + await microtasksFinished(); + + const newAccountInfo = { + name: 'Test User 2', + email: 'test2@google.com', + accountImageSrc: {url: 'http://image.com/img2.png'}, + }; + + testService.pageRemote.sendAccountInfo(newAccountInfo); + await microtasksFinished(); + + assertEquals( + newAccountInfo.name, + element.shadowRoot.querySelector<HTMLElement>( + '#account-name')!.textContent!.trim()); + assertEquals( + newAccountInfo.email, + element.shadowRoot.querySelector<HTMLElement>( + '#account-email')!.textContent!.trim()); + assertEquals( + newAccountInfo.accountImageSrc.url, + element.shadowRoot.querySelector<HTMLImageElement>( + '#profile-icon')!.src); + }); + + test('calls turnOnHistorySync when button is clicked', async () => { + element.configureSignInForTest({ + // For the sake of diversity, using other signin state in this test, + // different from WEB_ONLY_SIGN_IN + signInState: HistorySignInState.SIGNED_IN_NOT_SYNCING_TABS, + signInAllowed: true, + guestSession: false, + }); + const button = + element.shadowRoot.querySelector<HTMLElement>('#sync-history-button'); + assertTrue(!!button); + button.click(); + + await testService.handler.whenCalled('turnOnHistorySync'); + }); +}); +// </if>
diff --git a/chrome/test/data/webui/history/test_browser_service.ts b/chrome/test/data/webui/history/test_browser_service.ts index 06f34ac..5fa5d22 100644 --- a/chrome/test/data/webui/history/test_browser_service.ts +++ b/chrome/test/data/webui/history/test_browser_service.ts
@@ -3,7 +3,11 @@ // found in the LICENSE file. import type {BrowserService, ForeignSession} from 'chrome://history/history.js'; -import {PageCallbackRouter, PageHandlerRemote} from 'chrome://resources/cr_components/history/history.mojom-webui.js'; +import { + PageCallbackRouter, + PageHandlerRemote, + type PageRemote, +} from 'chrome://resources/cr_components/history/history.mojom-webui.js'; import {assertTrue} from 'chrome://webui-test/chai_assert.js'; import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js'; import {TestMock} from 'chrome://webui-test/test_mock.js'; @@ -14,6 +18,7 @@ BrowserService { handler: TestMock<PageHandlerRemote>&PageHandlerRemote; callbackRouter: PageCallbackRouter; + pageRemote: PageRemote; histogramMap: {[key: string]: {[key: string]: number}} = {}; actionMap: {[key: string]: number} = {}; private foreignSessions_: ForeignSession[] = []; @@ -34,6 +39,7 @@ this.handler = TestMock.fromClass(PageHandlerRemote); this.callbackRouter = new PageCallbackRouter(); + this.pageRemote = this.callbackRouter.$.bindNewPipeAndPassRemote(); this.handler.setResultFor('queryHistory', Promise.resolve({ results: { @@ -41,6 +47,14 @@ value: [], }, })); + + this.handler.setResultFor('requestAccountInfo', Promise.resolve({ + accountInfo: { + name: 'Test User', + email: 'test@google.com', + accountImageSrc: {url: 'http://example.com/image.png'}, + }, + })); } @@ -112,5 +126,6 @@ } removeBookmark() {} + startTurnOnSyncFlow() {} }
diff --git a/chromeos/ash/components/sync_wifi/wifi_configuration_bridge.cc b/chromeos/ash/components/sync_wifi/wifi_configuration_bridge.cc index a4f3677c9..d968862 100644 --- a/chromeos/ash/components/sync_wifi/wifi_configuration_bridge.cc +++ b/chromeos/ash/components/sync_wifi/wifi_configuration_bridge.cc
@@ -205,11 +205,7 @@ // Mark the changes as processed. batch->TakeMetadataChangesFrom(std::move(metadata_change_list)); Commit(std::move(batch)); - metrics_recorder_->RecordTotalCount(entries_.size()); - // If zero networks are synced log the reason. - if (entries_.size() == 0) { - local_network_collector_->RecordZeroNetworksEligibleForSync(); - } + RecordNetworkMetrics(); } std::optional<syncer::ModelError> @@ -253,11 +249,7 @@ batch->TakeMetadataChangesFrom(std::move(metadata_change_list)); Commit(std::move(batch)); - metrics_recorder_->RecordTotalCount(entries_.size()); - // If zero networks are synced log the reason. - if (entries_.size() == 0) { - local_network_collector_->RecordZeroNetworksEligibleForSync(); - } + RecordNetworkMetrics(); return std::nullopt; } @@ -335,6 +327,14 @@ weak_ptr_factory_.InvalidateWeakPtrs(); } +void WifiConfigurationBridge::RecordNetworkMetrics() { + metrics_recorder_->RecordTotalCount(entries_.size()); + // If zero networks are synced log the reason. + if (entries_.empty()) { + local_network_collector_->RecordZeroNetworksEligibleForSync(); + } +} + void WifiConfigurationBridge::OnStoreCreated( const std::optional<syncer::ModelError>& error, std::unique_ptr<syncer::DataTypeStore> store) { @@ -376,22 +376,17 @@ weak_ptr_factory_.GetWeakPtr())); } - int entries_size = entries_.size(); // Do not log the total network count during OOBE. It returns 0 even if there // are networks synced since MergeFullSyncData has not executed yet. if (pref_service_->GetBoolean(kIsFirstRun)) { pref_service_->SetBoolean(kIsFirstRun, false); - // This is only meant to filter out 0's that are logged during OOBE. If the - // entries_size is greater than zero it should be logged. - if (entries_size == 0) { + // This is only meant to filter out 0's that are logged during OOBE. If + // entries is not empty, the histogram will be logged.. + if (entries_.empty()) { return; } } - metrics_recorder_->RecordTotalCount(entries_size); - // If zero networks are synced log the reason. - if (entries_size == 0) { - local_network_collector_->RecordZeroNetworksEligibleForSync(); - } + RecordNetworkMetrics(); } void WifiConfigurationBridge::FixAutoconnect() { @@ -540,11 +535,7 @@ NET_LOG(EVENT) << "Saved network " << NetworkId(NetworkStateFromNetworkIdentifier(id)) << " to sync."; - metrics_recorder_->RecordTotalCount(entries_.size()); - // If zero networks are synced log the reason. - if (entries_.size() == 0) { - local_network_collector_->RecordZeroNetworksEligibleForSync(); - } + RecordNetworkMetrics(); } void WifiConfigurationBridge::OnNetworkCreated(const std::string& guid) {
diff --git a/chromeos/ash/components/sync_wifi/wifi_configuration_bridge.h b/chromeos/ash/components/sync_wifi/wifi_configuration_bridge.h index eba3885..805677a 100644 --- a/chromeos/ash/components/sync_wifi/wifi_configuration_bridge.h +++ b/chromeos/ash/components/sync_wifi/wifi_configuration_bridge.h
@@ -111,6 +111,8 @@ private: void Commit(std::unique_ptr<syncer::DataTypeStore::WriteBatch> batch); + void RecordNetworkMetrics(); + // Callbacks for DataTypeStore. void OnStoreCreated(const std::optional<syncer::ModelError>& error, std::unique_ptr<syncer::DataTypeStore> store);
diff --git a/components/autofill/content/browser/content_autofill_driver_factory_unittest.cc b/components/autofill/content/browser/content_autofill_driver_factory_unittest.cc index c96d2437..3be89b2 100644 --- a/components/autofill/content/browser/content_autofill_driver_factory_unittest.cc +++ b/components/autofill/content/browser/content_autofill_driver_factory_unittest.cc
@@ -45,7 +45,6 @@ using ::testing::AllOf; using ::testing::AtLeast; using ::testing::Between; -using ::testing::DoAll; using ::testing::Each; using ::testing::InSequence; using ::testing::Property; @@ -542,7 +541,7 @@ #define EXPECT_DRIVER_CREATED(driver_ptr_ptr) \ EXPECT_CALL(observer(), OnContentAutofillDriverCreated(Ref(factory()), \ HasState(kInactive))) \ - .WillOnce(DoAll(SaveArgPtr<1>((driver_ptr_ptr)))) + .WillOnce(SaveArgPtr<1>((driver_ptr_ptr))) #define EXPECT_LIFECYCLE_CHANGE(driver_matcher, from, to) \ EXPECT_CALL(observer(), \ OnContentAutofillDriverStateChanged( \
diff --git a/components/autofill/content/browser/content_autofill_driver_unittest.cc b/components/autofill/content/browser/content_autofill_driver_unittest.cc index 7c44553..bfbda0c4 100644 --- a/components/autofill/content/browser/content_autofill_driver_unittest.cc +++ b/components/autofill/content/browser/content_autofill_driver_unittest.cc
@@ -75,7 +75,6 @@ using ::autofill::test::SaveArgPtr; using ::testing::_; using ::testing::AllOf; -using ::testing::DoAll; using ::testing::ElementsAre; using ::testing::Eq; using ::testing::Field; @@ -439,7 +438,7 @@ } std::vector<FormData> augmented_forms; EXPECT_CALL(manager(target_rfh), OnFormsSeen(_, _)) - .WillOnce(DoAll(SaveArg<0>(&augmented_forms))); + .WillOnce(SaveArg<0>(&augmented_forms)); driver(source_rfh) .renderer_events() .FormsSeen(/*updated_forms=*/{std::move(form)}, @@ -610,8 +609,7 @@ TEST_F(ContentAutofillDriverTest, WithNewVersion) { FormData form = test::CreateTestAddressFormData(); std::vector<FormData> augmented_forms; - EXPECT_CALL(manager(), OnFormsSeen) - .WillOnce(DoAll(SaveArg<0>(&augmented_forms))); + EXPECT_CALL(manager(), OnFormsSeen).WillOnce(SaveArg<0>(&augmented_forms)); driver().renderer_events().FormsSeen(/*updated_forms=*/{form}, /*removed_forms=*/{}); ASSERT_EQ(augmented_forms.size(), 1u); @@ -737,8 +735,7 @@ FormData form = test::CreateTestAddressFormData(); std::vector<FormData> augmented_forms; - EXPECT_CALL(manager(), OnFormsSeen) - .WillOnce(DoAll(SaveArg<0>(&augmented_forms))); + EXPECT_CALL(manager(), OnFormsSeen).WillOnce(SaveArg<0>(&augmented_forms)); driver().renderer_events().FormsSeen(/*updated_forms=*/{form}, /*removed_forms=*/{});
diff --git a/components/autofill/core/browser/autofill_field.cc b/components/autofill/core/browser/autofill_field.cc index a108c098..a2496d2 100644 --- a/components/autofill/core/browser/autofill_field.cc +++ b/components/autofill/core/browser/autofill_field.cc
@@ -26,6 +26,7 @@ #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/heuristic_source.h" #include "components/autofill/core/browser/ml_model/field_classification_model_handler.h" +#include "components/autofill/core/browser/proto/api_v1.pb.h" #include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/common/autofill_constants.h" #include "components/autofill/core/common/autofill_features.h" @@ -36,9 +37,6 @@ namespace autofill { -using FieldPrediction = - AutofillQueryResponse::FormSuggestion::FieldSuggestion::FieldPrediction; - template <> struct DenseSetTraits<FieldPrediction::Source> : EnumDenseSetTraits<FieldPrediction::Source, @@ -540,9 +538,7 @@ } } -void AutofillField::MaybeAddServerPrediction( - AutofillQueryResponse::FormSuggestion::FieldSuggestion::FieldPrediction - prediction) { +void AutofillField::MaybeAddServerPrediction(FieldPrediction prediction) { overall_type_ = std::nullopt; if (server_predictions_.size() == 1 && server_predictions_[0].type() == NO_SERVER_DATA &&
diff --git a/components/autofill/core/browser/autofill_field.h b/components/autofill/core/browser/autofill_field.h index daf003a..34e13eb 100644 --- a/components/autofill/core/browser/autofill_field.h +++ b/components/autofill/core/browser/autofill_field.h
@@ -24,14 +24,17 @@ #include "components/autofill/core/browser/form_parsing/regex_patterns.h" #include "components/autofill/core/browser/heuristic_source.h" #include "components/autofill/core/browser/metrics/log_event.h" -#include "components/autofill/core/browser/proto/api_v1.pb.h" #include "components/autofill/core/browser/proto/password_requirements.pb.h" #include "components/autofill/core/common/form_field_data.h" #include "components/autofill/core/common/signatures.h" namespace autofill { -class FormStructure; +class AutofillQueryResponse_FormSuggestion_FieldSuggestion_FieldPrediction; +enum FormatString_Type : int; + +using FieldPrediction = + AutofillQueryResponse_FormSuggestion_FieldSuggestion_FieldPrediction; // Enum representing prediction sources that are recognized. enum class AutofillPredictionSource { @@ -191,15 +194,11 @@ FieldType heuristic_type(HeuristicSource s) const; FieldType server_type() const; bool server_type_prediction_is_override() const; - const std::vector< - AutofillQueryResponse::FormSuggestion::FieldSuggestion::FieldPrediction>& - server_predictions() const { + const std::vector<FieldPrediction>& server_predictions() const { return server_predictions_; } - const std::vector< - AutofillQueryResponse::FormSuggestion::FieldSuggestion::FieldPrediction>& - experimental_server_predictions() const { + const std::vector<FieldPrediction>& experimental_server_predictions() const { return experimental_server_predictions_; } HtmlFieldType html_type() const { return html_type_; } @@ -213,15 +212,11 @@ // Sets the server predictions to `predictions` after performing some // filtering. If `predictions` is empty, it creates a `NO_SERVER_DATA` // prediction. - void set_server_predictions( - std::vector<AutofillQueryResponse::FormSuggestion::FieldSuggestion:: - FieldPrediction> predictions); + void set_server_predictions(std::vector<FieldPrediction> predictions); // Adds `prediction` to the back of the existing `server_predictions_` if // the prediction's source passes various validity checks. If the only // existing server prediction is an empty one, it replaces that one. - void MaybeAddServerPrediction( - AutofillQueryResponse::FormSuggestion::FieldSuggestion::FieldPrediction - prediction); + void MaybeAddServerPrediction(FieldPrediction prediction); void set_possible_types(const FieldTypeSet& possible_types) { possible_types_ = possible_types; @@ -503,14 +498,10 @@ size_t rank_in_host_form_signature_group_ = 0; // The possible types of the field, as determined by the Autofill server. - std::vector< - AutofillQueryResponse::FormSuggestion::FieldSuggestion::FieldPrediction> - server_predictions_; + std::vector<FieldPrediction> server_predictions_; // Predictions from the Autofill server which are not intended for general // consumption. They are used for metrics and/or finch experiments. - std::vector< - AutofillQueryResponse::FormSuggestion::FieldSuggestion::FieldPrediction> - experimental_server_predictions_; + std::vector<FieldPrediction> experimental_server_predictions_; // Requirements the site imposes to passwords (for password generation). // Corresponds to the requirements determined by the Autofill server.
diff --git a/components/autofill/core/browser/autofill_type_unittest.cc b/components/autofill/core/browser/autofill_type_unittest.cc index 0c8ff17..1fc30de6 100644 --- a/components/autofill/core/browser/autofill_type_unittest.cc +++ b/components/autofill/core/browser/autofill_type_unittest.cc
@@ -13,15 +13,12 @@ namespace autofill { namespace { -using ::testing::AllOf; using ::testing::Contains; using ::testing::ElementsAre; using ::testing::IsEmpty; using ::testing::Not; using ::testing::ResultOf; using ::testing::UnorderedElementsAre; -using FieldPrediction = - AutofillQueryResponse::FormSuggestion::FieldSuggestion::FieldPrediction; template <typename... Ts> requires(sizeof...(Ts) == 0 || (std::same_as<Ts, FieldType> && ...))
diff --git a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc index 1f6b3af93..c781288 100644 --- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc +++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc
@@ -29,6 +29,7 @@ #include "components/autofill/core/browser/form_structure_sectioning_util.h" #include "components/autofill/core/browser/metrics/autofill_metrics.h" #include "components/autofill/core/browser/metrics/log_event.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_internals/log_message.h" #include "components/autofill/core/common/autofill_internals/logging_scope.h"
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 0e6d470..4466bf5 100644 --- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding_unittest.cc +++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding_unittest.cc
@@ -25,6 +25,7 @@ #include "components/autofill/core/browser/form_parsing/form_field_parser.h" #include "components/autofill/core/browser/metrics/log_event.h" #include "components/autofill/core/browser/proto/api_v1.pb.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/browser/test_utils/autofill_form_test_utils.h" #include "components/autofill/core/browser/test_utils/autofill_test_utils.h" #include "components/autofill/core/browser/test_utils/field_prediction_test_matchers.h"
diff --git a/components/autofill/core/browser/crowdsourcing/determine_possible_field_types.cc b/components/autofill/core/browser/crowdsourcing/determine_possible_field_types.cc index 1211d5f..339cad5 100644 --- a/components/autofill/core/browser/crowdsourcing/determine_possible_field_types.cc +++ b/components/autofill/core/browser/crowdsourcing/determine_possible_field_types.cc
@@ -33,6 +33,7 @@ #include "components/autofill/core/browser/data_quality/validation.h" #include "components/autofill/core/browser/field_type_utils.h" #include "components/autofill/core/browser/field_types.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_regex_constants.h" #include "components/autofill/core/common/autofill_regexes.h"
diff --git a/components/autofill/core/browser/crowdsourcing/determine_possible_field_types_unittest.cc b/components/autofill/core/browser/crowdsourcing/determine_possible_field_types_unittest.cc index 4b3275f..6498d0b 100644 --- a/components/autofill/core/browser/crowdsourcing/determine_possible_field_types_unittest.cc +++ b/components/autofill/core/browser/crowdsourcing/determine_possible_field_types_unittest.cc
@@ -18,6 +18,7 @@ #include "components/autofill/core/browser/form_parsing/determine_regex_types.h" #include "components/autofill/core/browser/foundations/test_autofill_client.h" #include "components/autofill/core/browser/geo/alternative_state_name_map_test_utils.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/browser/test_utils/autofill_test_utils.h" #include "components/autofill/core/browser/test_utils/valuables_data_test_utils.h" #include "components/autofill/core/common/autofill_features.h"
diff --git a/components/autofill/core/browser/crowdsourcing/server_prediction_overrides.cc b/components/autofill/core/browser/crowdsourcing/server_prediction_overrides.cc index bd6f45e..1894380 100644 --- a/components/autofill/core/browser/crowdsourcing/server_prediction_overrides.cc +++ b/components/autofill/core/browser/crowdsourcing/server_prediction_overrides.cc
@@ -16,6 +16,7 @@ #include "base/values.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/proto/api_v1.pb.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/common/signatures.h" namespace autofill {
diff --git a/components/autofill/core/browser/crowdsourcing/server_prediction_overrides_unittest.cc b/components/autofill/core/browser/crowdsourcing/server_prediction_overrides_unittest.cc index 211f4c6..1e59d6c8 100644 --- a/components/autofill/core/browser/crowdsourcing/server_prediction_overrides_unittest.cc +++ b/components/autofill/core/browser/crowdsourcing/server_prediction_overrides_unittest.cc
@@ -9,6 +9,7 @@ #include "base/base64.h" #include "components/autofill/core/browser/field_types.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/common/signatures.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/components/autofill/core/browser/data_manager/addresses/account_name_email_store.cc b/components/autofill/core/browser/data_manager/addresses/account_name_email_store.cc index 5a2ece26..db59a96 100644 --- a/components/autofill/core/browser/data_manager/addresses/account_name_email_store.cc +++ b/components/autofill/core/browser/data_manager/addresses/account_name_email_store.cc
@@ -35,9 +35,14 @@ identity_manager_(identity_manager), sync_service_(sync_service), pref_service_(pref_service) { - address_data_manager_observer_.Observe(&address_data_manager); identity_manager_observer_.Observe(&identity_manager); sync_service_observer_.Observe(&sync_service); + + pref_registrar_.Init(&pref_service_.get()); + pref_registrar_.Add( + prefs::kAutofillNameAndEmailProfileNotSelectedCounter, + base::BindRepeating(&AccountNameEmailStore::OnCounterPrefUpdated, + base::Unretained(this))); } AccountNameEmailStore::~AccountNameEmailStore() = default; @@ -45,7 +50,11 @@ void AccountNameEmailStore::OnExtendedAccountInfoRemoved( const AccountInfo& info) { if (!identity_manager_->HasPrimaryAccount(signin::ConsentLevel::kSignin)) { - RemoveAccountNameEmail(); + // Sign out - remove the profile until the user is signed in and autofill + // sync toggle enabled. + SoftRemoveAccountNameEmail(); + // TODO(crbug.com/356845298): Clear `kAutofillNameAndEmailProfileSignature` + // on sign out. } } @@ -79,7 +88,7 @@ } switch (reason.value()) { case ProfileUpdateBlockReason::kSyncOff: - RemoveAccountNameEmail(); + SoftRemoveAccountNameEmail(); return; case ProfileUpdateBlockReason::kDataNotLoaded: // Defer call. When data is loaded, `OnStateChanged` will be called again, @@ -108,32 +117,32 @@ UpdateOrCreateAccountNameEmail(extended_info.value()); } -void AccountNameEmailStore::OnAddressDataChanged() { - if (pref_service_->GetInteger( - prefs::kAutofillNameAndEmailProfileNotSelectedCounter) > - features::kAutofillNameAndEmailProfileNotSelectedThreshold.Get()) { - // Return the kAccountNameEmail profile is already considered removed. +void AccountNameEmailStore::ApplyChange(const AutofillProfileChange& change) { + if (change.data_model().record_type() != + AutofillProfile::RecordType::kAccountNameEmail) { return; } - - const std::vector<const AutofillProfile*> account_name_email_profiles = - address_data_manager_->GetProfilesByRecordType( - AutofillProfile::RecordType::kAccountNameEmail); - - if (identity_manager_->HasPrimaryAccount(signin::ConsentLevel::kSignin) && - account_name_email_profiles.empty()) { - // The `kAccountNameEmail` is available to all signed in users. If it isn't, - // that means that the user just removed it. Track this removal in prefs to - // ensure that the profile isn't recreated. Independently of how the profile - // was removed, the removal is tracked as if the user rejected a - // `kAccountNameEmail` suggestion too many times. - pref_service_->SetInteger( - prefs::kAutofillNameAndEmailProfileNotSelectedCounter, - features::kAutofillNameAndEmailProfileNotSelectedThreshold.Get() + 1); + switch (change.type()) { + case AutofillProfileChange::REMOVE: + // REMOVE indicates a hard removal, thus the pref needs to be set. + pref_service_->SetInteger( + prefs::kAutofillNameAndEmailProfileNotSelectedCounter, + features::kAutofillNameAndEmailProfileNotSelectedThreshold.Get() + 1); + return; + case AutofillProfileChange::ADD: + return; + case AutofillProfileChange::HIDE_IN_AUTOFILL: + // The HIDE_IN_AUTOFILL indicates that the kAccountNameEmail profile was + // soft removed, since `AddressDataManager` already removed it, there is + // nothing left to do. + return; + case AutofillProfileChange::UPDATE: + // kAccountNameEmail profile is read only. + NOTREACHED(); } } -void AccountNameEmailStore::RemoveAccountNameEmail() { +void AccountNameEmailStore::SoftRemoveAccountNameEmail() { const std::vector<const AutofillProfile*> account_name_email_profiles = address_data_manager_->GetProfilesByRecordType( AutofillProfile::RecordType::kAccountNameEmail); @@ -142,50 +151,60 @@ } CHECK_EQ(1u, account_name_email_profiles.size()); - address_data_manager_->RemoveProfile(account_name_email_profiles[0]->guid()); + address_data_manager_->RemoveProfile( + account_name_email_profiles[0]->guid(), + /*non_permanent_account_profile_removal=*/true); } void AccountNameEmailStore::UpdateOrCreateAccountNameEmail( const AccountInfo& info) { // During signin the `OnExtendedAccountInfoUpdated` method might call this // method with an empty `info.full_name` since not all data arrives all at - // once and `AccountInfo` is updated multiple times. The `kAccountNameEmail` - // profile and hash signature require non-empty `full_name` value. + // once and `AccountInfo` is updated multiple times. The kAccountNameEmail + // profile and hash signature require non-empty full_name value. if (info.IsEmpty() || info.full_name.empty()) { return; } CHECK(!info.email.empty()); - // Calculate hash and see if it's different than one cached in pref. const std::string new_hash = HashAccountInfo(info); - if (pref_service_->GetString(prefs::kAutofillNameAndEmailProfileSignature) == - new_hash) { - // Name exists and has not changed - nothing to do. - // This also (additionally) prevents recreation of Account Name Email - // profile after its explicit or silent deletion. + const bool hashes_different = + new_hash != + pref_service_->GetString(prefs::kAutofillNameAndEmailProfileSignature); + const bool was_hard_removed = + pref_service_->GetInteger( + prefs::kAutofillNameAndEmailProfileNotSelectedCounter) > + features::kAutofillNameAndEmailProfileNotSelectedThreshold.Get(); + + // TODO(crbug.com/356845298): Implement `PrefChangeRegistrar` to remove the + // kAccountNameEmail profile permanently when the counter exceedes the + // threshold. + if (!hashes_different && was_hard_removed) { + // User signed out and then signed in, but previously a hard remove had + // happened, thus no recreation should happen. return; } - // If the current `info` doesn't match the stored kAccountNameAndEmail - // profile, the existing profile should be deleted and a new created. const std::vector<const AutofillProfile*> account_name_email_profiles = address_data_manager_->GetProfilesByRecordType( AutofillProfile::RecordType::kAccountNameEmail); - if (!account_name_email_profiles.empty()) { - CHECK_EQ(1u, account_name_email_profiles.size()); - address_data_manager_->RemoveProfile( - account_name_email_profiles[0]->guid()); + const bool account_name_email_exists = !account_name_email_profiles.empty(); + if (!hashes_different && account_name_email_exists) { + // Hashes are the same and the kAccountNameEmail profile exists. + // This function was called as a side effect of the other, unrelated flow. + return; } - // If Account Name Email profile doesn't exist, create and add it. + if (account_name_email_exists) { + SoftRemoveAccountNameEmail(); + } address_data_manager_->AddProfile(AutofillProfile{info}); - - pref_service_->SetString(prefs::kAutofillNameAndEmailProfileSignature, - new_hash); - // Reset `kAutofillNameAndEmailProfileNotSelectedCounter` after the user - // changed their full name. - pref_service_->SetInteger( - prefs::kAutofillNameAndEmailProfileNotSelectedCounter, 0); + if (hashes_different) { + pref_service_->SetString(prefs::kAutofillNameAndEmailProfileSignature, + new_hash); + pref_service_->SetInteger( + prefs::kAutofillNameAndEmailProfileNotSelectedCounter, 0); + } } std::string AccountNameEmailStore::HashAccountInfo( @@ -217,4 +236,21 @@ } } +void AccountNameEmailStore::OnCounterPrefUpdated() { + if (pref_service_->GetInteger( + prefs::kAutofillNameAndEmailProfileNotSelectedCounter) <= + features::kAutofillNameAndEmailProfileNotSelectedThreshold.Get()) { + return; + } + + const std::vector<const AutofillProfile*> account_name_email_profiles = + address_data_manager_->GetProfilesByRecordType( + AutofillProfile::RecordType::kAccountNameEmail); + if (account_name_email_profiles.empty()) { + return; + } + CHECK_EQ(1u, account_name_email_profiles.size()); + address_data_manager_->RemoveProfile(account_name_email_profiles[0]->guid()); +} + } // namespace autofill
diff --git a/components/autofill/core/browser/data_manager/addresses/account_name_email_store.h b/components/autofill/core/browser/data_manager/addresses/account_name_email_store.h index 1a0c4c29..795ddff 100644 --- a/components/autofill/core/browser/data_manager/addresses/account_name_email_store.h +++ b/components/autofill/core/browser/data_manager/addresses/account_name_email_store.h
@@ -8,6 +8,7 @@ #include "base/memory/raw_ref.h" #include "base/scoped_observation.h" #include "components/autofill/core/browser/data_manager/addresses/address_data_manager.h" +#include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_service.h" #include "components/signin/public/identity_manager/account_info.h" #include "components/signin/public/identity_manager/identity_manager.h" @@ -19,7 +20,22 @@ // The kAccountNameEmail autofill profile is an un-syncable, locally stored, // profile generated automatically for the every signed in user with the // Autofill sync toggle enabled, unless they have deleted it or have not used -// it. +// it. There are two ways this profile can be removed: +// 1. Soft remove - which happens when the user does one of the following: +// - turns off the autofill sync toggle, +// - signs out. +// When the toggle is turned on again, or the user signs in again, the +// kAccountNameEmail profile reappears. +// 2. Hard remove - which happens when the user does one of the following: +// - explicitly removes profile from the autofill settings, +// - does not use the kAccountNameEmail profile during the first +// `kAutofillNameAndEmailProfileNotSelectedThreshold` times it was suggested, +// - accepts an import of an `AutofillProfile` that is a superset of +// kAccountNameEmail (`AutofillProfileImportType::kNameEmailSuperset` and +// `AutofillProfileImportType::kHomeWorkNameEmailMerge`). +// The profile will always be recreated after removal (including a hard remove) +// when the users account full name changes (assuming that other feature +// conditions are met). // // This profile is composed of 2 pieces of data: // - full name @@ -34,7 +50,6 @@ // `AccountNameEmailStore` is owned by and has the same lifetime as // `AddressDataManager`. class AccountNameEmailStore : public signin::IdentityManager::Observer, - public AddressDataManager::Observer, public syncer::SyncServiceObserver { public: AccountNameEmailStore(AddressDataManager& address_data_manager, @@ -44,10 +59,11 @@ ~AccountNameEmailStore() override; // IdentityManager::Observer: - // Called when the user signs out. Used to remove `kAccountNameEmail` profile. + // Called when the user signs out. Used to soft remove kAccountNameEmail + // profile. void OnExtendedAccountInfoRemoved(const AccountInfo& info) override; - // Called when the account's extended information (e.g., full name) is - // updated. Used to keep the `kAccountNameEmail` profile up to date. + // Called when the account's extended information (e.g. full name) is + // updated. Used to keep the kAccountNameEmail profile up to date. void OnExtendedAccountInfoUpdated(const AccountInfo& info) override; // syncer::SyncServiceObserver: @@ -59,15 +75,12 @@ // This prevents premature update/create without all of the relevant data. void MaybeUpdateOrCreateAccountNameEmail(); - // AddressDataManager::Observer: - // Called when the address data of the `AddressDataManager` changes. If - // `kAccountNameEmail` profile is missing but the user is still signed in, - // `kAutofillNameAndEmailProfileNotSelectedCounter` is set to - // `kAutofillNameAndEmailProfileNotSelectedThreshold` + 1. - void OnAddressDataChanged() override; + // Persists the `change` in prefs, if it applies to kAccountNameEmail + // profile. + void ApplyChange(const AutofillProfileChange& change); - // Removes the `kAccountNameEmail` autofill profile if it exists. - void RemoveAccountNameEmail(); + // Removes the kAccountNameEmail autofill profile if it exists. + void SoftRemoveAccountNameEmail(); private: friend class AccountNameEmailStoreTestApi; @@ -92,15 +105,16 @@ std::optional<ProfileUpdateBlockReason> GetBlockAccountNameEmailUpdateReason(); + // Called when `prefs::kAutofillNameAndEmailProfileNotSelectedCounter` pref is + // updated. If it's value exceeds + // `kAutofillNameAndEmailProfileNotSelectedThreshold` the kAccountNameEmail + // profile will be removed. + void OnCounterPrefUpdated(); + const raw_ref<AddressDataManager> address_data_manager_; const raw_ref<signin::IdentityManager> identity_manager_; const raw_ref<syncer::SyncService> sync_service_; - const raw_ref<PrefService> pref_service_; - - // Used to update `kAutofillNameAndEmailProfileNotSelectedCounter` pref in - // `OnAddressDataChanged` method. - base::ScopedObservation<AddressDataManager, AddressDataManager::Observer> - address_data_manager_observer_{this}; + raw_ref<PrefService> pref_service_; // Used to update the `kAccountNameEmail` profile when the account name // changes. @@ -114,6 +128,10 @@ // overridden `OnStateChanged(SyncService*)` method. base::ScopedObservation<syncer::SyncService, syncer::SyncServiceObserver> sync_service_observer_{this}; + + // Used to observe `prefs::kAutofillNameAndEmailProfileNotSelectedCounter` and + // possibly remove the kAccountNameEmail profile. + PrefChangeRegistrar pref_registrar_; }; } // namespace autofill
diff --git a/components/autofill/core/browser/data_manager/addresses/account_name_email_store_unittest.cc b/components/autofill/core/browser/data_manager/addresses/account_name_email_store_unittest.cc index 5a1be1b..365ea421 100644 --- a/components/autofill/core/browser/data_manager/addresses/account_name_email_store_unittest.cc +++ b/components/autofill/core/browser/data_manager/addresses/account_name_email_store_unittest.cc
@@ -78,6 +78,33 @@ signin::UpdateAccountInfoForAccount(identity_manager_.get(), info); } + void SimulateProfileRemoval( + const AutofillProfile* profile, + bool non_permanent_account_profile_removal = false) { + CHECK(profile); + // `TestAddressDataManager` does not send `AutofillProfileChange` + // notifications, so it has to be simulated. + AutofillProfileChange change(non_permanent_account_profile_removal + ? AutofillProfileChange::HIDE_IN_AUTOFILL + : AutofillProfileChange::REMOVE, + profile->guid(), *profile); + address_data_manager().RemoveProfile(profile->guid()); + account_name_email_store().ApplyChange(change); + } + + void SetAutofillSyncToggleStatus(bool syncing) { + syncer::UserSelectableTypeSet selected_sync_types = + sync_service().GetUserSettings()->GetSelectedTypes(); + if (syncing) { + selected_sync_types.Put(syncer::UserSelectableType::kAutofill); + } else { + selected_sync_types.Remove(syncer::UserSelectableType::kAutofill); + } + sync_service().GetUserSettings()->SetSelectedTypes( + /*sync_everything=*/false, selected_sync_types); + sync_service().FireStateChanged(); + } + AccountNameEmailStore& account_name_email_store() { return store_; } AddressDataManager& address_data_manager() { return test_adm_; } signin::IdentityManager& identity_manager() { return *identity_manager_; } @@ -142,12 +169,7 @@ base::UTF8ToUTF16(kTestName1), base::UTF8ToUTF16(kTestEmailAddress1)))); - syncer::UserSelectableTypeSet selected_sync_types = - sync_service().GetUserSettings()->GetSelectedTypes(); - selected_sync_types.Remove(syncer::UserSelectableType::kAutofill); - sync_service().GetUserSettings()->SetSelectedTypes( - /*sync_everything=*/false, selected_sync_types); - sync_service().FireStateChanged(); + SetAutofillSyncToggleStatus(false); EXPECT_THAT(address_data_manager().GetProfiles(), IsEmpty()); } @@ -183,24 +205,6 @@ signin::ConsentLevel::kSignin)))); } -// Tests that no new profile is created if hashes match. -TEST_F(AccountNameEmailStoreTest, EarlyReturnWhenHashesAreEqual) { - AccountInfo info; - info.full_name = kTestName1; - info.email = kTestEmailAddress1; - - const std::string hash = - test_api(&account_name_email_store()).HashAccountInfo(info); - - pref_service().SetString(prefs::kAutofillNameAndEmailProfileSignature, hash); - // Start profile creation after the hash is already set to the right value. - CreatePrimaryAccount(kTestName1, kTestEmailAddress1); - - EXPECT_EQ(hash, pref_service().GetString( - prefs::kAutofillNameAndEmailProfileSignature)); - EXPECT_THAT(address_data_manager().GetProfiles(), IsEmpty()); -} - // Tests that old profile is removed when new primary account is used. TEST_F(AccountNameEmailStoreTest, RemovingProfile) { CreatePrimaryAccount(kTestName1, kTestEmailAddress1); @@ -265,28 +269,41 @@ ContainerEq(address_data_manager().GetProfiles())); } -// Tests that the `OnAddressDataChanged` method will set -// `kAutofillNameAndEmailProfileNotSelectedCounter` pref to a value greater than -// `kAutofillNameAndEmailProfileNotSelectedThreshold` if the user is logged in -// but `kAccountNameEmail` profile was deleted. -TEST_F(AccountNameEmailStoreTest, OnAddressDataChanged_ProfileDeleted) { +// Tests that the `kAutofillNameAndEmailProfileNotSelectedCounter` pref is set +// to a value greater than `kAutofillNameAndEmailProfileNotSelectedThreshold` if +// there was a hard removal. +TEST_F(AccountNameEmailStoreTest, AccountNameEmailProfileRemoved) { CreatePrimaryAccount(kTestName1, kTestEmailAddress1); ASSERT_EQ(pref_service().GetInteger( prefs::kAutofillNameAndEmailProfileNotSelectedCounter), 0); - address_data_manager().RemoveProfile( - address_data_manager().GetProfiles()[0]->guid()); + SimulateProfileRemoval(address_data_manager().GetProfiles()[0]); EXPECT_GT(pref_service().GetInteger( prefs::kAutofillNameAndEmailProfileNotSelectedCounter), features::kAutofillNameAndEmailProfileNotSelectedThreshold.Get()); } -// Tests that the `OnAddressDataChanged` method will not change the value of the -// `kAutofillNameAndEmailProfileNotSelectedCounter` pref if a profile other than -// the `kAccountNameEmail` was deleted. -TEST_F(AccountNameEmailStoreTest, OnAddressDataChanged_PrefNotChanged) { +// Tests that the `kAutofillNameAndEmailProfileNotSelectedCounter` pref is not +// set, if the removal was soft. +TEST_F(AccountNameEmailStoreTest, AccountNameEmailProfileHidden) { + CreatePrimaryAccount(kTestName1, kTestEmailAddress1); + ASSERT_EQ(pref_service().GetInteger( + prefs::kAutofillNameAndEmailProfileNotSelectedCounter), + 0); + + SimulateProfileRemoval(address_data_manager().GetProfiles()[0], + /*non_permanent_account_profile_removal=*/true); + + EXPECT_EQ(pref_service().GetInteger( + prefs::kAutofillNameAndEmailProfileNotSelectedCounter), + 0); +} + +// Tests that removals of profiles other than kAccountNameEmail do not set the +// pref. +TEST_F(AccountNameEmailStoreTest, NotAccountNameEmailProfileRemoved) { CreatePrimaryAccount(kTestName1, kTestEmailAddress1); AutofillProfile profile{ @@ -298,27 +315,20 @@ prefs::kAutofillNameAndEmailProfileNotSelectedCounter), 0); - address_data_manager().RemoveProfile( - address_data_manager() - .GetProfilesByRecordType(AutofillProfile::RecordType::kAccount)[0] - ->guid()); + SimulateProfileRemoval(&profile); EXPECT_EQ(pref_service().GetInteger( prefs::kAutofillNameAndEmailProfileNotSelectedCounter), 0); } -// Tests that if `kAccountNameEmail` profile was removed and pref set to a -// number greater than the threshold, after the name change there will be new -// `kAccountNameEmail` profile and pref will be set to 0. +// Tests that if kAccountNameEmail profile was hard removed (thus pref +// set to a number greater than the threshold), after the name change there will +// be a new kAccountNameEmail profile and the +// `kAutofillNameAndEmailProfileNotSelectedCounter` pref will be set to 0. TEST_F(AccountNameEmailStoreTest, ProfileReappearsAfterNameChange) { CreatePrimaryAccount(kTestName1, kTestEmailAddress1); - - address_data_manager().RemoveProfile( - address_data_manager() - .GetProfilesByRecordType( - AutofillProfile::RecordType::kAccountNameEmail)[0] - ->guid()); + SimulateProfileRemoval(address_data_manager().GetProfiles()[0]); ASSERT_THAT(address_data_manager().GetProfiles(), IsEmpty()); ASSERT_GT(pref_service().GetInteger( @@ -339,6 +349,36 @@ 0); } +TEST_F(AccountNameEmailStoreTest, OnCounterPrefUpdated) { + ASSERT_EQ(pref_service().GetInteger( + prefs::kAutofillNameAndEmailProfileNotSelectedCounter), + 0); + CreatePrimaryAccount(kTestName1, kTestEmailAddress1); + ASSERT_THAT(address_data_manager().GetProfiles(), + ElementsAre(IsCorrectAccountNameEmail( + base::UTF8ToUTF16(kTestName1), + base::UTF8ToUTF16(kTestEmailAddress1)))); + + // Setting the pref to a value smaller or equal to + // `kAutofillNameAndEmailProfileNotSelectedThreshold`, shouldn't remove the + // profile. + pref_service().SetInteger( + prefs::kAutofillNameAndEmailProfileNotSelectedCounter, + features::kAutofillNameAndEmailProfileNotSelectedThreshold.Get()); + EXPECT_THAT(address_data_manager().GetProfiles(), + ElementsAre(IsCorrectAccountNameEmail( + base::UTF8ToUTF16(kTestName1), + base::UTF8ToUTF16(kTestEmailAddress1)))); + + // Setting the pref to a value greater than + // `kAutofillNameAndEmailProfileNotSelectedThreshold`, should remove the + // kAccountNameEmail profile. + pref_service().SetInteger( + prefs::kAutofillNameAndEmailProfileNotSelectedCounter, + features::kAutofillNameAndEmailProfileNotSelectedThreshold.Get() + 1); + EXPECT_THAT(address_data_manager().GetProfiles(), IsEmpty()); +} + // ChromeOS does not support signing out #if !BUILDFLAG(IS_CHROMEOS) // Tests that the `OnExtendedAccountInfoRemoved` method will remove @@ -356,6 +396,51 @@ EXPECT_THAT(address_data_manager().GetProfiles(), testing::IsEmpty()); } +// Tests that the kAccountNameEmail profile will be recreated on sign in after +// it has been deleted on sign out. +TEST_F(AccountNameEmailStoreTest, SignOutAndSignIn) { + CreatePrimaryAccount(kTestName1, kTestEmailAddress1); + ASSERT_THAT(address_data_manager().GetProfiles(), + ElementsAre(IsCorrectAccountNameEmail( + base::UTF8ToUTF16(kTestName1), + base::UTF8ToUTF16(kTestEmailAddress1)))); + // Sign out. + identity_test_env().EnableRemovalOfExtendedAccountInfo(); + identity_test_env().ClearPrimaryAccount(); + ASSERT_THAT(address_data_manager().GetProfiles(), IsEmpty()); + + // Sign in. + CreatePrimaryAccount(kTestName1, kTestEmailAddress1); + EXPECT_EQ(pref_service().GetInteger( + prefs::kAutofillNameAndEmailProfileNotSelectedCounter), + 0); + EXPECT_THAT( + address_data_manager().GetProfiles(), + ElementsAre(Property(&AutofillProfile::record_type, + AutofillProfile::RecordType::kAccountNameEmail))); +} + +// Tests that the kAccountNameEmail profile will not be recreated if the +// `kAutofillNameAndEmailProfileNotSelectedCounter` pref exceedes the threshold. +TEST_F(AccountNameEmailStoreTest, SingInAfterHardRemove) { + CreatePrimaryAccount(kTestName1, kTestEmailAddress1); + ASSERT_THAT( + address_data_manager().GetProfiles(), + ElementsAre(Property(&AutofillProfile::record_type, + AutofillProfile::RecordType::kAccountNameEmail))); + + SimulateProfileRemoval(address_data_manager().GetProfiles()[0]); + + identity_test_env().EnableRemovalOfExtendedAccountInfo(); + identity_test_env().ClearPrimaryAccount(); + + CreatePrimaryAccount(kTestName1, kTestEmailAddress1); + EXPECT_THAT(address_data_manager().GetProfiles(), IsEmpty()); + EXPECT_GT(pref_service().GetInteger( + prefs::kAutofillNameAndEmailProfileNotSelectedCounter), + features::kAutofillNameAndEmailProfileNotSelectedThreshold.Get()); +} + // Tests that the `OnExtendedAccountInfoRemoved` method will not remove // `kAccountNameEmail` profile if it is called with info of a wrong profile. TEST_F(AccountNameEmailStoreTest, OnExtendedAccountInfoRemoved_WrongInfo) { @@ -390,6 +475,77 @@ #endif // !BUILDFLAG(CHROME_OS) +// Tests that the kAccountNameEmail profile will be recreated after enabling +// autofill sync toggle. +TEST_F(AccountNameEmailStoreTest, AutofillSyncToggleOffAndOn) { + // Sign in and disable autofill sync toggle. + CreatePrimaryAccount(kTestName1, kTestEmailAddress1); + ASSERT_THAT(address_data_manager().GetProfiles(), + ElementsAre(IsCorrectAccountNameEmail( + base::UTF8ToUTF16(kTestName1), + base::UTF8ToUTF16(kTestEmailAddress1)))); + SetAutofillSyncToggleStatus(false); + ASSERT_THAT(address_data_manager().GetProfiles(), IsEmpty()); + + // Enable the autofill sync toggle. + SetAutofillSyncToggleStatus(true); + EXPECT_EQ(pref_service().GetInteger( + prefs::kAutofillNameAndEmailProfileNotSelectedCounter), + 0); + EXPECT_THAT( + address_data_manager().GetProfiles(), + ElementsAre(Property(&AutofillProfile::record_type, + AutofillProfile::RecordType::kAccountNameEmail))); +} + +// Tests that recreating the kAccountNameEmail profile will not alter the +// counter pref. +TEST_F(AccountNameEmailStoreTest, + SwitchingAutofillSyncToggleDoesntAlterCounter) { + const int test_counter_value = 5; + + // Sign in and disable autofill sync toggle. + CreatePrimaryAccount(kTestName1, kTestEmailAddress1); + pref_service().SetInteger( + prefs::kAutofillNameAndEmailProfileNotSelectedCounter, + test_counter_value); + SetAutofillSyncToggleStatus(false); + ASSERT_EQ(pref_service().GetInteger( + prefs::kAutofillNameAndEmailProfileNotSelectedCounter), + test_counter_value); + + // Enable the autofill sync toggle again, verify that the counter did not + // change. + SetAutofillSyncToggleStatus(true); + EXPECT_EQ(pref_service().GetInteger( + prefs::kAutofillNameAndEmailProfileNotSelectedCounter), + test_counter_value); +} + +// Tests that the kAccountNameEmail profile will not be recreated if the +// `kAutofillNameAndEmailProfileNotSelectedCounter` pref exceedes the threshold. +TEST_F(AccountNameEmailStoreTest, AutofillSyncToggleOnAfterHardRemove) { + // Sign in, explicitly remove the kAccountNameEmail profile and turn off + // autofill sync toggle. + CreatePrimaryAccount(kTestName1, kTestEmailAddress1); + ASSERT_THAT( + address_data_manager().GetProfiles(), + ElementsAre(Property(&AutofillProfile::record_type, + AutofillProfile::RecordType::kAccountNameEmail))); + SimulateProfileRemoval(address_data_manager().GetProfiles()[0]); + SetAutofillSyncToggleStatus(false); + ASSERT_GT(pref_service().GetInteger( + prefs::kAutofillNameAndEmailProfileNotSelectedCounter), + features::kAutofillNameAndEmailProfileNotSelectedThreshold.Get()); + + // Enabling the sync toggle again does not reset the pref. + SetAutofillSyncToggleStatus(true); + EXPECT_THAT(address_data_manager().GetProfiles(), IsEmpty()); + EXPECT_GT(pref_service().GetInteger( + prefs::kAutofillNameAndEmailProfileNotSelectedCounter), + features::kAutofillNameAndEmailProfileNotSelectedThreshold.Get()); +} + } // namespace } // namespace autofill
diff --git a/components/autofill/core/browser/data_manager/addresses/address_data_manager.cc b/components/autofill/core/browser/data_manager/addresses/address_data_manager.cc index 6677d43..e0b4b9e 100644 --- a/components/autofill/core/browser/data_manager/addresses/address_data_manager.cc +++ b/components/autofill/core/browser/data_manager/addresses/address_data_manager.cc
@@ -831,6 +831,9 @@ if (home_and_work_metadata_) { home_and_work_metadata_->ApplyChange(change); } + if (account_name_email_store_) { + account_name_email_store_->ApplyChange(change); + } is_ongoing = true; }
diff --git a/components/autofill/core/browser/data_model/autofill_ai/entity_instance.cc b/components/autofill/core/browser/data_model/autofill_ai/entity_instance.cc index b2db283..de7cdf9 100644 --- a/components/autofill/core/browser/data_model/autofill_ai/entity_instance.cc +++ b/components/autofill/core/browser/data_model/autofill_ai/entity_instance.cc
@@ -23,6 +23,7 @@ #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/geo/autofill_country.h" #include "components/autofill/core/browser/geo/country_names.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "third_party/abseil-cpp/absl/functional/overload.h" namespace autofill {
diff --git a/components/autofill/core/browser/data_model/autofill_ai/entity_instance_unittest.cc b/components/autofill/core/browser/data_model/autofill_ai/entity_instance_unittest.cc index 97ac60d..ab8f6be 100644 --- a/components/autofill/core/browser/data_model/autofill_ai/entity_instance_unittest.cc +++ b/components/autofill/core/browser/data_model/autofill_ai/entity_instance_unittest.cc
@@ -12,6 +12,7 @@ #include "components/autofill/core/browser/data_model/addresses/autofill_structured_address_component.h" #include "components/autofill/core/browser/data_model/autofill_ai/entity_type.h" #include "components/autofill/core/browser/field_types.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/browser/test_utils/autofill_test_utils.h" #include "components/autofill/core/common/autofill_features.h" #include "testing/gmock/include/gmock/gmock.h"
diff --git a/components/autofill/core/browser/filling/autofill_ai/field_filling_entity_util.cc b/components/autofill/core/browser/filling/autofill_ai/field_filling_entity_util.cc index 955aeed..a1189a87 100644 --- a/components/autofill/core/browser/filling/autofill_ai/field_filling_entity_util.cc +++ b/components/autofill/core/browser/filling/autofill_ai/field_filling_entity_util.cc
@@ -23,6 +23,7 @@ #include "components/autofill/core/browser/form_structure.h" #include "components/autofill/core/browser/foundations/autofill_client.h" #include "components/autofill/core/browser/permissions/autofill_ai/autofill_ai_permission_utils.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/common/form_field_data.h" #include "components/autofill/core/common/mojom/autofill_types.mojom-shared.h"
diff --git a/components/autofill/core/browser/filling/autofill_ai/field_filling_entity_util_unittest.cc b/components/autofill/core/browser/filling/autofill_ai/field_filling_entity_util_unittest.cc index d3cddb7..c3e5e84 100644 --- a/components/autofill/core/browser/filling/autofill_ai/field_filling_entity_util_unittest.cc +++ b/components/autofill/core/browser/filling/autofill_ai/field_filling_entity_util_unittest.cc
@@ -24,6 +24,7 @@ #include "components/autofill/core/browser/foundations/test_autofill_client.h" #include "components/autofill/core/browser/geo/alternative_state_name_map_test_utils.h" #include "components/autofill/core/browser/proto/api_v1.pb.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/browser/test_utils/autofill_test_utils.h" #include "components/autofill/core/browser/webdata/autofill_ai/entity_table.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service_test_helper.h"
diff --git a/components/autofill/core/browser/filling/form_filler_unittest.cc b/components/autofill/core/browser/filling/form_filler_unittest.cc index 0296c74..a41709a9 100644 --- a/components/autofill/core/browser/filling/form_filler_unittest.cc +++ b/components/autofill/core/browser/filling/form_filler_unittest.cc
@@ -37,6 +37,7 @@ #include "components/autofill/core/browser/heuristic_source.h" #include "components/autofill/core/browser/payments/credit_card_cvc_authenticator.h" #include "components/autofill/core/browser/payments/payments_autofill_client.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/browser/test_utils/autofill_form_test_utils.h" #include "components/autofill/core/browser/test_utils/autofill_test_utils.h" #include "components/autofill/core/common/autofill_clock.h"
diff --git a/components/autofill/core/browser/form_import/addresses/autofill_profile_import_process.cc b/components/autofill/core/browser/form_import/addresses/autofill_profile_import_process.cc index a2aef25..2f9c3ba4 100644 --- a/components/autofill/core/browser/form_import/addresses/autofill_profile_import_process.cc +++ b/components/autofill/core/browser/form_import/addresses/autofill_profile_import_process.cc
@@ -5,12 +5,12 @@ #include "components/autofill/core/browser/form_import/addresses/autofill_profile_import_process.h" #include <algorithm> -#include <map> +#include <vector> #include "base/check_deref.h" +#include "base/containers/span.h" #include "base/feature_list.h" -#include "base/strings/utf_string_conversions.h" -#include "components/autofill/core/browser/data_manager/addresses/address_data_cleaner.h" +#include "base/time/time.h" #include "components/autofill/core/browser/data_manager/addresses/address_data_manager.h" #include "components/autofill/core/browser/data_manager/addresses/home_and_work_metadata_store.h" #include "components/autofill/core/browser/data_model/addresses/autofill_profile.h" @@ -18,7 +18,6 @@ #include "components/autofill/core/browser/data_quality/addresses/profile_requirement_utils.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/metrics/profile_import_metrics.h" -#include "components/autofill/core/common/autofill_clock.h" #include "components/autofill/core/common/autofill_features.h" namespace autofill { @@ -142,193 +141,198 @@ void ProfileImportProcess::DetermineProfileImportType() { AutofillProfileComparator comparator(app_locale_); - bool is_mergeable_with_existing_profile = false; - int number_of_unchanged_profiles = 0; - int number_of_blocked_profile_updates = 0; - std::optional<AutofillProfile> migration_candidate; - - const bool account_name_email_home_work_merge = - CanCombineAccountNameEmailWithHomeWork(import_metadata(), - *address_data_manager_); - - // We don't offer an import if `observed_profile_` is a duplicate of an - // existing profile. - const std::vector<const AutofillProfile*> existing_profiles = - address_data_manager_->GetProfiles( - AddressDataManager::ProfileOrder::kMostRecentlyUsedFirstDesc); - - // If we have reason to believe that the country was complemented incorrectly, - // remove it. + // If there is reason to believe that the `observed_profile_`'s country was + // complemented incorrectly, remove the country. if (import_metadata_.did_complement_country && - ShouldCountryApproximationBeRemoved(observed_profile_, existing_profiles, + ShouldCountryApproximationBeRemoved(observed_profile_, + address_data_manager_->GetProfiles(), comparator)) { observed_profile_.ClearFields({ADDRESS_HOME_COUNTRY}); import_metadata_.did_complement_country = false; } - for (const AutofillProfile* existing_profile : existing_profiles) { - // If the existing profile is not mergeable with the observed profile, the - // existing profile is not altered by this import. - if (!comparator.AreMergeable(*existing_profile, observed_profile_)) { - ++number_of_unchanged_profiles; - continue; - } - - // The observed profile is mergeable with an existing profile. - // This information is used to determine if the observed profile classifies - // as an import of a new profile or the import of a duplicate profile. - is_mergeable_with_existing_profile = true; - - // Make a copy of the existing profile and merge it with the observation. - // The return value of |MergeDataFrom()| indicates if the existing profile - // was changed at all during that merge. - AutofillProfile merged_profile = *existing_profile; - if (!merged_profile.MergeDataFrom(observed_profile_, app_locale_)) { - ++number_of_unchanged_profiles; - // The `observed_profile_` is a duplicate of the `existing_profile`. - // Consider it for migration. - MaybeSetMigrationCandidate(migration_candidate, *existing_profile); - continue; - } - - // At this point, the observed profile was merged with (a copy of) the - // existing profile which changed in some way. - // Now, determine if the merge alters any settings-visible value, or if the - // merge can be considered as a silent update that does not need to get user - // confirmation. - if (AutofillProfileComparator::ProfilesHaveDifferentSettingsVisibleValues( - *existing_profile, merged_profile, app_locale_)) { - // Determine if the existing profile is blocked for updates. - bool is_blocked_for_update = - allow_only_silent_updates_ || - address_data_manager_->IsProfileUpdateBlocked( - existing_profile->guid()) || - base::FeatureList::IsEnabled( - features::test::kAutofillDisableProfileUpdates); - - if (is_blocked_for_update) { - ++number_of_blocked_profile_updates; - } - - // If a settings-visible value changed, the existing profile is the merge - // candidate if no other merge candidate has already been found and if the - // existing profile is not blocked for updates. - if (!merge_candidate_.has_value() && !is_blocked_for_update) { - merge_candidate_ = *existing_profile; - import_candidate_ = merged_profile; - } else { - // If there is already a merge candidate, the existing profile is not - // supposed to be changed. - ++number_of_unchanged_profiles; - } - continue; - } - // If the profile changed but all settings-visible values are maintained, - // the profile can be updated silently. Silent updates can also be disabled - // using a feature flag. - if (!base::FeatureList::IsEnabled( - features::test::kAutofillDisableSilentProfileUpdates)) { - merged_profile.usage_history().set_modification_date( - AutofillClock::Now()); - silently_updated_profiles_.emplace_back(merged_profile); - } else { - ++number_of_unchanged_profiles; - } - // The `observed_profile_` only differs from the `existing_profile` in a - // non-settings visible way. Consider it for migration. - MaybeSetMigrationCandidate(migration_candidate, merged_profile); + // Existing profiles that are not mergeable with the `observed_profile_` + // cannot be altered by this import. If none remain, no update prompts can be + // shown and the import corresponds to a new profile. + std::vector<const AutofillProfile*> mergeable_profiles = + address_data_manager_->GetProfiles( + AddressDataManager::ProfileOrder::kMostRecentlyUsedFirstDesc); + std::erase_if(mergeable_profiles, [&](const AutofillProfile* p) { + return !comparator.AreMergeable(*p, observed_profile_); + }); + if (mergeable_profiles.empty()) { + DetermineNewProfileImportType(); + return; } - // If the profile is not mergeable with an existing profile, the import - // corresponds to a new profile. - if (!is_mergeable_with_existing_profile) { - // There should be no import candidate yet. - DCHECK(!import_candidate_.has_value()); - if (allow_only_silent_updates_ || - address_data_manager_->IsNewProfileImportBlockedForDomain( - form_source_url_)) { - import_type_ = AutofillProfileImportType::kSuppressedNewProfile; - } else { - import_type_ = AutofillProfileImportType::kNewProfile; - import_candidate_ = observed_profile(); + // The `observed_profile_` is mergeable with some existing profiles. Create + // import candidates by merging `observed_profile_` into `mergeable_profiles`. + // Note that `mergeable_profiles`'s frecency ordering is retained. + std::vector<ImportCandidate> candidates = + GetImportCandidates(mergeable_profiles); + + // Collect all silently updatable profiles. + for (const ImportCandidate& candidate : candidates) { + if (QualifiesForSilentUpdate(candidate)) { + silently_updated_profiles_.push_back(candidate.merged_profile); } + } + + // Attempt to show an update prompt (prioritized over migrations). + auto update_candidate_it = std::ranges::find_if( + candidates, [&](auto& c) { return QualifiesForUpdateProfilePrompt(c); }); + if (update_candidate_it != candidates.end()) { + DetermineUpdateProfileImportType(*update_candidate_it); + return; + } + + // Attempt to show a migration prompt. + auto migrate_candidate_it = std::ranges::find_if( + candidates, [&](auto& c) { return QualifiesForMigrateProfilePrompt(c); }); + if (migrate_candidate_it != candidates.end()) { + DetermineMigrateProfileImportType(migrate_candidate_it->merged_profile); + return; + } + + // Neither an update nor a migration prompt could be shown. + DetermineSuppressedImportType(candidates); +} + +void ProfileImportProcess::DetermineNewProfileImportType() { + if (allow_only_silent_updates_ || + address_data_manager_->IsNewProfileImportBlockedForDomain( + form_source_url_)) { + import_type_ = AutofillProfileImportType::kSuppressedNewProfile; + return; + } + import_candidate_ = observed_profile(); + import_type_ = AutofillProfileImportType::kNewProfile; +} + +void ProfileImportProcess::DetermineSuppressedImportType( + base::span<const ImportCandidate> candidates) { + CHECK(!candidates.empty()); + // Even though the `observed_profile_` is mergeable with some existing + // profiles, none of the `candidates` qualified for an update or a migration + // prompt. From a user's perspective, nothing will happen. For metrics, + // break down further why the import was suppressed. + if (std::ranges::any_of(candidates, [](auto& c) { + return c.change == ImportCandidate::Change::kSettingVisibleChange; + })) { + // At least one of the `candidates` changed in a setting-visibile way. The + // fact that `DetermineSuppressedImportType()` was called means that an + // update prompt was suppressed, for example because of the strike database. + import_type_ = silently_updated_profiles_.empty() + ? AutofillProfileImportType::kSuppressedConfirmableMerge + : AutofillProfileImportType:: + kSuppressedConfirmableMergeAndSilentUpdate; } else { - bool silent_updates_present = !silently_updated_profiles_.empty(); + // Either all updates could be applied silently or a migration prompt was + // suppressed. No distinction is made for metrics. + import_type_ = silently_updated_profiles_.empty() + ? AutofillProfileImportType::kDuplicateImport + : AutofillProfileImportType::kSilentUpdate; + } +} - if (merge_candidate_.has_value()) { - switch (import_candidate_->record_type()) { - case AutofillProfile::RecordType::kAccountHome: - case AutofillProfile::RecordType::kAccountWork: - import_type_ = - account_name_email_home_work_merge - ? AutofillProfileImportType::kHomeWorkNameEmailMerge - : AutofillProfileImportType::kHomeAndWorkSuperset; - break; - case AutofillProfile::RecordType::kAccountNameEmail: - import_type_ = - account_name_email_home_work_merge - ? AutofillProfileImportType::kHomeWorkNameEmailMerge - : AutofillProfileImportType::kNameEmailSuperset; - break; - case AutofillProfile::RecordType::kAccount: - case AutofillProfile::RecordType::kLocalOrSyncable: - import_type_ = - silent_updates_present - ? AutofillProfileImportType::kConfirmableMergeAndSilentUpdate - : AutofillProfileImportType::kConfirmableMerge; - break; +void ProfileImportProcess::DetermineUpdateProfileImportType( + const ImportCandidate& update_candidate) { + import_candidate_ = update_candidate.merged_profile; + // By setting the `merge_candidate_`, an update prompt will be shown that + // displays the diff between the `import_candidate_` and the + // `merge_candidate_`. In some cases, this intentionally doesn't happen so + // that the new profile UI is triggered instead. This is done when the + // underlying profile that should get updated is read-only (e.g. the + // kAccountNameEmail profile). To the user, the flow feels like an update. + switch (update_candidate.existing_profile.record_type()) { + case AutofillProfile::RecordType::kAccountHome: + case AutofillProfile::RecordType::kAccountWork: + if (CanCombineAccountNameEmailWithHomeWork(import_metadata(), + *address_data_manager_)) { + import_type_ = AutofillProfileImportType::kHomeWorkNameEmailMerge; + } else { + import_type_ = AutofillProfileImportType::kHomeAndWorkSuperset; + merge_candidate_ = update_candidate.existing_profile; } - } else if (number_of_blocked_profile_updates > 0) { + break; + case AutofillProfile::RecordType::kAccountNameEmail: + import_type_ = CanCombineAccountNameEmailWithHomeWork( + import_metadata(), *address_data_manager_) + ? AutofillProfileImportType::kHomeWorkNameEmailMerge + : AutofillProfileImportType::kNameEmailSuperset; + break; + case AutofillProfile::RecordType::kAccount: + case AutofillProfile::RecordType::kLocalOrSyncable: import_type_ = - silent_updates_present - ? AutofillProfileImportType:: - kSuppressedConfirmableMergeAndSilentUpdate - : AutofillProfileImportType::kSuppressedConfirmableMerge; - } else if (!migration_candidate) { - import_type_ = silent_updates_present - ? AutofillProfileImportType::kSilentUpdate - : AutofillProfileImportType::kDuplicateImport; - } else { - import_type_ = - silent_updates_present - ? AutofillProfileImportType::kProfileMigrationAndSilentUpdate - : AutofillProfileImportType::kProfileMigration; - CHECK(migration_candidate.has_value()); - import_candidate_ = std::move(migration_candidate); - } + silently_updated_profiles_.empty() + ? AutofillProfileImportType::kConfirmableMerge + : AutofillProfileImportType::kConfirmableMergeAndSilentUpdate; + merge_candidate_ = update_candidate.existing_profile; + break; } +} - if (import_candidate_.has_value()) { - import_candidate_->usage_history().set_modification_date( - AutofillClock::Now()); +void ProfileImportProcess::DetermineMigrateProfileImportType( + const AutofillProfile& migration_candidate) { + import_candidate_ = migration_candidate; + import_type_ = + silently_updated_profiles_.empty() + ? AutofillProfileImportType::kProfileMigration + : AutofillProfileImportType::kProfileMigrationAndSilentUpdate; +} + +bool ProfileImportProcess::QualifiesForSilentUpdate( + const ImportCandidate& candidate) const { + return candidate.change == + ImportCandidate::Change::kNonSettingVisibleChange && + !base::FeatureList::IsEnabled( + features::test::kAutofillDisableSilentProfileUpdates); +} + +bool ProfileImportProcess::QualifiesForUpdateProfilePrompt( + const ImportCandidate& candidate) const { + return candidate.change == ImportCandidate::Change::kSettingVisibleChange && + !allow_only_silent_updates_ && + !address_data_manager_->IsProfileUpdateBlocked( + candidate.existing_profile.guid()) && + !base::FeatureList::IsEnabled( + features::test::kAutofillDisableProfileUpdates); +} + +bool ProfileImportProcess::QualifiesForMigrateProfilePrompt( + const ImportCandidate& candidate) const { + return candidate.change != ImportCandidate::Change::kSettingVisibleChange && + !allow_only_silent_updates_ && + IsEligibleForMigrationToAccount(*address_data_manager_, + candidate.existing_profile); +} + +std::vector<ProfileImportProcess::ImportCandidate> +ProfileImportProcess::GetImportCandidates( + base::span<const AutofillProfile*> mergeable_profiles) const { + std::vector<ImportCandidate> result; + result.reserve(mergeable_profiles.size()); + for (const AutofillProfile* merge_candidate : mergeable_profiles) { + AutofillProfile merged_profile = *merge_candidate; + const bool was_profile_altered = + merged_profile.MergeDataFrom(observed_profile_, app_locale_); + ImportCandidate::Change change_type = [&] { + if (!was_profile_altered) { + return ImportCandidate::Change::kNoChange; + } else if (AutofillProfileComparator:: + ProfilesHaveDifferentSettingsVisibleValues( + *merge_candidate, merged_profile, app_locale_)) { + return ImportCandidate::Change::kSettingVisibleChange; + } else { + return ImportCandidate::Change::kNonSettingVisibleChange; + } + }(); + result.push_back( + ImportCandidate{.change = change_type, + .existing_profile = *merge_candidate, + .merged_profile = std::move(merged_profile)}); } - - if (import_type_ == AutofillProfileImportType::kHomeWorkNameEmailMerge || - import_type_ == AutofillProfileImportType::kNameEmailSuperset) { - // Setting `merge_candidate_` to `std::nullopt` ensures that the save - // bubble will appear. Although `observed_profile` can be merged with - // with `kAccountNameEmail` profile this flow is supposed to create a - // new profile since the `kAccountNameEmail` profile, from the POV of - // import process, is read-only. The reasoning is the same in the case - // of `kHomeWorkNameEmailMerge`. - merge_candidate_ = std::nullopt; - // Resetting merge_candidate_ creates discrepancy between the real - // number of unchanged profiles and number stored in - // `number_of_unchanged_profiles` variable. In order to account for - // the fact that the `kAccountNameEmail` profile or a H/W profile will not - // be changed (and instead a new profile will be created) - // `number_of_unchanged_profiles` should be incremented. - ++number_of_unchanged_profiles; - } - - // At this point, all existing profiles are either unchanged, updated and/or - // one is the merge candidate. - // One of the unchanged or updated profiles might be considered for migration. - // In this case, `import_type()` is `kProfileMigrationAndMaybeSilentUpdates`. - DCHECK_EQ(existing_profiles.size(), - number_of_unchanged_profiles + silently_updated_profiles_.size() + - (merge_candidate_.has_value() ? 1 : 0)); - DCHECK_NE(import_type_, AutofillProfileImportType::kImportTypeUnspecified); + return result; } void ProfileImportProcess::DetermineSourceOfImportCandidate() { @@ -387,16 +391,6 @@ } } -void ProfileImportProcess::MaybeSetMigrationCandidate( - std::optional<AutofillProfile>& migration_candidate, - const AutofillProfile& profile) const { - if (migration_candidate || allow_only_silent_updates_ || - !IsEligibleForMigrationToAccount(*address_data_manager_, profile)) { - return; - } - migration_candidate = profile; -} - void ProfileImportProcess::ApplyImport() { // At this point, a user decision must have been supplied. DCHECK_NE(user_decision_, UserDecision::kUndefined); @@ -417,6 +411,12 @@ if (!confirmed_import_candidate_.has_value()) { return; } + // In case a new profile is created, make sure the modification date is + // updated correctly. Note that for update profile cases (such as the silent + // updates above), this is not necessary, since the AddressDataManager already + // takes care of it. + confirmed_import_candidate_->usage_history().set_modification_date( + base::Time::Now()); // Handle bubble-showing autofill profile import types. switch (import_type()) { case AutofillProfileImportType::kNewProfile: @@ -509,8 +509,6 @@ } confirmed_import_candidate_->FinalizeAfterImport(); - confirmed_import_candidate_->usage_history().set_modification_date( - AutofillClock::Now()); // The `confirmed_import_candidate_` has to have the same `guid` as the // original import candidate. DCHECK_EQ(import_candidate_->guid(), confirmed_import_candidate_->guid());
diff --git a/components/autofill/core/browser/form_import/addresses/autofill_profile_import_process.h b/components/autofill/core/browser/form_import/addresses/autofill_profile_import_process.h index 8c5f468..0d90f025 100644 --- a/components/autofill/core/browser/form_import/addresses/autofill_profile_import_process.h +++ b/components/autofill/core/browser/form_import/addresses/autofill_profile_import_process.h
@@ -9,16 +9,19 @@ #include <string> #include <vector> +#include "base/containers/span.h" #include "base/memory/raw_ptr.h" #include "components/autofill/core/browser/data_model/addresses/autofill_profile.h" #include "components/autofill/core/browser/foundations/autofill_client.h" +#include "services/metrics/public/cpp/ukm_source_id.h" #include "url/origin.h" namespace autofill { class AddressDataManager; -// Specifies the type of a profile form import. +// Specifies the type of a profile form import. The type is used for logging but +// also for deciding which UI to show. // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. enum class AutofillProfileImportType { @@ -246,30 +249,60 @@ const std::vector<const AutofillProfile*>& existing_profiles) const; private: - // Determines the import type of |observed_profile_| with respect to - // |existing_profiles|. Only the first profile in |existing_profiles| becomes - // a merge candidate in case there is a confirmable merge. - // TODO(crbug.com/354706653): Handle the kHomeAndWorkSuperset import type. + // Represents an existing profile and how it changes when merged with the + // `observed_profile_`. + struct ImportCandidate { + // Describes how `existing_profile` and `merged_profile` differ. + enum class Change { + kNoChange = 0, + kNonSettingVisibleChange = 1, + kSettingVisibleChange = 2, + } change; + // An existing profile, as saved in Autofill prior to form submission. + AutofillProfile existing_profile; + // The `existing_profile`, merged with `observed_profile_`. + AutofillProfile merged_profile; + }; + + // Determines the import type of `observed_profile_` with respect to + // `existing_profiles` and updates `merge_candidate_`, `import_candidate_` + // and/or `silently_updated_profiles_`. + // Only one profile can be updated in a user-visible way at a time. Updates + // are preferred over migrations and higher frecency profiles are preferred + // over lower frecency ones. void DetermineProfileImportType(); + // Helper functions for `DetermineProfileImportType()` that set the + // appropriate `import_type_` once the logic has determined that a certain + // flow should happen (new profile import, suppressing an import, ...). + // Also sets the `import_candidate_` and `merge_candidate_`, if necessary. + void DetermineNewProfileImportType(); + void DetermineSuppressedImportType( + base::span<const ImportCandidate> candidates); + void DetermineUpdateProfileImportType( + const ImportCandidate& update_candidate); + void DetermineMigrateProfileImportType( + const AutofillProfile& migration_candidate); + + // Predicates to classify whether a `candidates` qualifies for a certain flow. + // This checks for conditions like address completeness or strikes from + // repeatedly rejecting prompts. + bool QualifiesForSilentUpdate(const ImportCandidate& candidate) const; + bool QualifiesForUpdateProfilePrompt(const ImportCandidate& candidate) const; + bool QualifiesForMigrateProfilePrompt(const ImportCandidate& profile) const; + + // Merges the `mergeable_profiles` with the `observed_profile_` and determines + // how the merged profile differs from the original one (see + // `ImportCandidate::Change`). Constructs one `ImportCandidate` per + // `mergeable_profiles` and returns the result, preserving relative order. + // Assumes that mergeability has already been determined. + std::vector<ImportCandidate> GetImportCandidates( + base::span<const AutofillProfile*> mergeable_profiles) const; + // For new profile imports, sets the source of the `import_candidate_` // correctly, depending on the user's account storage eligiblity. void DetermineSourceOfImportCandidate(); - // If the observed profile is a duplicate (modulo silent updates) of an - // existing `kLocalOrSyncable` profile, eligible users are prompted to change - // its storage location to `kAccount`. - // This function checks whether the `profile` qualifies for migration and sets - // the `migration_candidate` accordingly. The conditions are: - // - `migration_candidate` not set yet. - // - The User eligible for account profile storage. - // - `profile` is of source `kLocalOrSyncable` and not blocked for migration. - // - The `profile`'s country isn't set to an unsupported country. - // - Not only silent updates are allowed. - void MaybeSetMigrationCandidate( - std::optional<AutofillProfile>& migration_candidate, - const AutofillProfile& profile) const; - // Computes the settings-visible profile difference between the // `import_candidate_` and the `confirmed_import_candidate_`. Logs all edited // types, depending on the import type. Returns the number of edited fields.
diff --git a/components/autofill/core/browser/form_import/addresses/autofill_profile_import_process_unittest.cc b/components/autofill/core/browser/form_import/addresses/autofill_profile_import_process_unittest.cc index d615289..1eb7c1d 100644 --- a/components/autofill/core/browser/form_import/addresses/autofill_profile_import_process_unittest.cc +++ b/components/autofill/core/browser/form_import/addresses/autofill_profile_import_process_unittest.cc
@@ -642,10 +642,6 @@ // The profile should be updateable with the observed profile. AutofillProfile updateable_profile = test::UpdateableStandardProfile(); - // Set a modification date and subsequently advance the test clock. - updateable_profile.usage_history().set_modification_date(base::Time::Now()); - AdvanceClock(base::Days(1)); - address_data_manager().AddProfile(updateable_profile); // Create the import process for the scenario that there is an existing @@ -676,8 +672,6 @@ ASSERT_EQ(resulting_profiles.size(), 1U); EXPECT_THAT(resulting_profiles, testing::UnorderedElementsAre(updated_profile)); - EXPECT_EQ(resulting_profiles.at(0).usage_history().modification_date(), - base::Time::Now()); } // Tests the scenario in which an observed profile can be merged with an
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 aa1b80a..f1580a8 100644 --- a/components/autofill/core/browser/form_import/form_data_importer.h +++ b/components/autofill/core/browser/form_import/form_data_importer.h
@@ -22,6 +22,7 @@ #include "components/autofill/core/browser/form_import/form_data_importer_utils.h" #include "components/autofill/core/browser/form_structure.h" #include "components/history/core/browser/history_service_observer.h" +#include "services/metrics/public/cpp/ukm_source_id.h" namespace history { class HistoryService;
diff --git a/components/autofill/core/browser/form_structure_rationalizer.cc b/components/autofill/core/browser/form_structure_rationalizer.cc index 36a42191..43a051e8 100644 --- a/components/autofill/core/browser/form_structure_rationalizer.cc +++ b/components/autofill/core/browser/form_structure_rationalizer.cc
@@ -17,6 +17,7 @@ #include "components/autofill/core/browser/form_structure_rationalization_engine.h" #include "components/autofill/core/browser/heuristic_source.h" #include "components/autofill/core/browser/logging/log_manager.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_internals/log_message.h" #include "components/autofill/core/common/autofill_internals/logging_scope.h"
diff --git a/components/autofill/core/browser/form_structure_rationalizer_unittest.cc b/components/autofill/core/browser/form_structure_rationalizer_unittest.cc index c1afd6b..a3afdbb4 100644 --- a/components/autofill/core/browser/form_structure_rationalizer_unittest.cc +++ b/components/autofill/core/browser/form_structure_rationalizer_unittest.cc
@@ -18,6 +18,7 @@ #include "components/autofill/core/browser/form_parsing/determine_regex_types.h" #include "components/autofill/core/browser/form_structure_test_api.h" #include "components/autofill/core/browser/heuristic_source.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/browser/test_utils/autofill_test_utils.h" #include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_payments_features.h"
diff --git a/components/autofill/core/browser/foundations/autofill_client.h b/components/autofill/core/browser/foundations/autofill_client.h index b373c9c..0bd01c9 100644 --- a/components/autofill/core/browser/foundations/autofill_client.h +++ b/components/autofill/core/browser/foundations/autofill_client.h
@@ -7,54 +7,54 @@ #include <memory> #include <optional> -#include <set> #include <string> #include <vector> #include "base/containers/span.h" #include "base/functional/callback_forward.h" #include "base/i18n/rtl.h" -#include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "base/types/id_type.h" #include "base/types/optional_ref.h" #include "build/build_config.h" -#include "components/autofill/core/browser/autofill_trigger_source.h" #include "components/autofill/core/browser/country_type.h" #include "components/autofill/core/browser/data_model/autofill_ai/entity_instance.h" -#include "components/autofill/core/browser/filling/filling_product.h" -#include "components/autofill/core/browser/integrators/fast_checkout/fast_checkout_client.h" -#include "components/autofill/core/browser/integrators/identity_credential/identity_credential_delegate.h" -#include "components/autofill/core/browser/integrators/password_form_classification.h" -#include "components/autofill/core/browser/integrators/password_manager/password_manager_delegate.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" #include "components/autofill/core/browser/ui/popup_open_enums.h" #include "components/autofill/core/common/aliases.h" -#include "components/autofill/core/common/form_data.h" -#include "components/autofill/core/common/form_field_data.h" -#include "components/autofill/core/common/form_interactions_flow.h" -#include "components/autofill/core/common/plus_address_survey_type.h" #include "components/autofill/core/common/unique_ids.h" -#include "components/device_reauth/device_authenticator.h" #include "components/profile_metrics/browser_profile_type.h" #include "components/security_state/core/security_state.h" -#include "components/translate/core/browser/language_state.h" -#include "services/metrics/public/cpp/ukm_source_id.h" -#include "ui/base/window_open_disposition.h" #include "ui/gfx/geometry/rect_f.h" -#include "ui/gfx/image/image.h" -#include "url/gurl.h" -#include "url/origin.h" class GoogleGroupsManager; +class GURL; class PrefService; +namespace device_reauth { +class DeviceAuthenticator; +} + namespace network { class SharedURLLoaderFactory; } +namespace one_time_tokens { +class SmsOtpBackend; +} + +namespace optimization_guide { +class ModelQualityLogsUploaderService; +class OptimizationGuideModelExecutor; +} // namespace optimization_guide + +namespace optimization_guide::proto { +class AnnotatedPageContent; +} + +namespace plus_addresses::hats { +enum class SurveyType; +} + namespace signin { class IdentityManager; } @@ -67,57 +67,63 @@ class SyncService; } -namespace one_time_tokens { -class SmsOtpBackend; -} - -namespace optimization_guide { -class ModelQualityLogsUploaderService; -class OptimizationGuideModelExecutor; -} - -namespace optimization_guide::proto { -class AnnotatedPageContent; -} +namespace translate { +class LanguageState; +class TranslateDriver; +} // namespace translate namespace ukm { class UkmRecorder; } +namespace url { +class Origin; +} + namespace version_info { enum class Channel; } namespace autofill { +class AutofillManager; class AddressNormalizer; class AutocompleteHistoryManager; class AutofillAblationStudy; -class AutofillComposeDelegate; -class AutofillCrowdsourcingManager; -class AutofillDriverFactory; -class AutofillOptimizationGuideDecider; -#if BUILDFLAG(IS_ANDROID) -class AutofillSnackbarControllerImpl; -#endif // BUILDFLAG(IS_ANDROID) -class AutofillSuggestionDelegate; class AutofillPlusAddressDelegate; class AutofillAiManager; class AutofillAiModelCache; class AutofillAiModelExecutor; +class AutofillComposeDelegate; +class AutofillCrowdsourcingManager; +class AutofillDriverFactory; +class AutofillOptimizationGuideDecider; class AutofillProfile; +#if BUILDFLAG(IS_ANDROID) +class AutofillSnackbarControllerImpl; +#endif // BUILDFLAG(IS_ANDROID) +class AutofillSuggestionDelegate; +enum class AutofillTriggerSource; +class IdentityCredentialDelegate; class EntityDataManager; +class FastCheckoutClient; class FieldClassificationModelHandler; +enum class FillingProduct; class FormDataImporter; +class FormFieldData; +struct FormInteractionsFlowId; class LogManager; class OtpFieldDetector; +struct PasswordFormClassification; +class PasswordManagerDelegate; class PersonalDataManager; +struct SelectOption; +struct Suggestion; +enum class SuggestionHidingReason; +enum class SuggestionType; class SingleFieldFillRouter; -class StrikeDatabase; class ValuablesDataManager; class VotesUploader; -struct Suggestion; -enum class WebauthnDialogState; namespace autofill_metrics { class FormInteractionsUkmLogger;
diff --git a/components/autofill/core/browser/foundations/autofill_manager.cc b/components/autofill/core/browser/foundations/autofill_manager.cc index 99e9140..34f34f29 100644 --- a/components/autofill/core/browser/foundations/autofill_manager.cc +++ b/components/autofill/core/browser/foundations/autofill_manager.cc
@@ -38,6 +38,7 @@ #include "components/autofill/core/common/autofill_switches.h" #include "components/language_detection/core/constants.h" #include "components/optimization_guide/machine_learning_tflite_buildflags.h" +#include "components/translate/core/browser/language_state.h" #include "components/translate/core/common/language_detection_details.h" #include "third_party/abseil-cpp/absl/cleanup/cleanup.h" #include "third_party/abseil-cpp/absl/functional/overload.h"
diff --git a/components/autofill/core/browser/foundations/browser_autofill_manager.cc b/components/autofill/core/browser/foundations/browser_autofill_manager.cc index 1145533..3cb750b 100644 --- a/components/autofill/core/browser/foundations/browser_autofill_manager.cc +++ b/components/autofill/core/browser/foundations/browser_autofill_manager.cc
@@ -97,6 +97,7 @@ #include "components/autofill/core/browser/foundations/autofill_client.h" #include "components/autofill/core/browser/geo/phone_number_i18n.h" #include "components/autofill/core/browser/integrators/compose/autofill_compose_delegate.h" +#include "components/autofill/core/browser/integrators/identity_credential/identity_credential_delegate.h" #include "components/autofill/core/browser/integrators/one_time_tokens/otp_manager_impl.h" #include "components/autofill/core/browser/integrators/optimization_guide/autofill_optimization_guide_decider.h" #include "components/autofill/core/browser/integrators/password_manager/password_manager_delegate.h"
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 d683e09c..95d05bbb 100644 --- a/components/autofill/core/browser/foundations/browser_autofill_manager_unittest.cc +++ b/components/autofill/core/browser/foundations/browser_autofill_manager_unittest.cc
@@ -98,6 +98,7 @@ #include "components/autofill/core/browser/payments/test_credit_card_save_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/proto/server.pb.h" #include "components/autofill/core/browser/single_field_fillers/mock_single_field_fill_router.h" #include "components/autofill/core/browser/strike_databases/payments/test_credit_card_save_strike_database.h" #include "components/autofill/core/browser/studies/autofill_experiments.h"
diff --git a/components/autofill/core/browser/foundations/test_autofill_client.h b/components/autofill/core/browser/foundations/test_autofill_client.h index c68748b..474ba6a 100644 --- a/components/autofill/core/browser/foundations/test_autofill_client.h +++ b/components/autofill/core/browser/foundations/test_autofill_client.h
@@ -79,6 +79,8 @@ #include "services/metrics/public/cpp/delegating_ukm_recorder.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" +#include "url/gurl.h" +#include "url/origin.h" #if BUILDFLAG(BUILD_WITH_TFLITE_LIB) #include "components/autofill/core/browser/ml_model/field_classification_model_handler.h" @@ -284,7 +286,7 @@ } url::Origin GetLastCommittedPrimaryMainFrameOrigin() const override { - return url::Origin::Create(last_committed_primary_main_frame_url_); + return last_committed_primary_main_frame_origin_; } security_state::SecurityLevel GetSecurityLevelForUmaHistograms() override { @@ -557,6 +559,7 @@ void set_last_committed_primary_main_frame_url(const GURL& url) { last_committed_primary_main_frame_url_ = url; + last_committed_primary_main_frame_origin_ = url::Origin::Create(url); } void SetVariationConfigCountryCode( @@ -732,6 +735,8 @@ // The last URL submitted in the primary main frame by the user. Set in the // constructor. GURL last_committed_primary_main_frame_url_{"https://example.test"}; + url::Origin last_committed_primary_main_frame_origin_ = + url::Origin::Create(last_committed_primary_main_frame_url_); std::optional<AutofillClient::SuggestionUiSessionId> suggestion_ui_session_id_;
diff --git a/components/autofill/core/browser/geo/alternative_state_name_map.cc b/components/autofill/core/browser/geo/alternative_state_name_map.cc index 8df7532..0659ea7 100644 --- a/components/autofill/core/browser/geo/alternative_state_name_map.cc +++ b/components/autofill/core/browser/geo/alternative_state_name_map.cc
@@ -7,6 +7,7 @@ #include "base/no_destructor.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "components/autofill/core/browser/proto/states.pb.h" namespace autofill {
diff --git a/components/autofill/core/browser/geo/alternative_state_name_map.h b/components/autofill/core/browser/geo/alternative_state_name_map.h index ecda175..6b5ce58 100644 --- a/components/autofill/core/browser/geo/alternative_state_name_map.h +++ b/components/autofill/core/browser/geo/alternative_state_name_map.h
@@ -8,16 +8,18 @@ #include <map> #include <optional> #include <string> +#include <vector> #include "base/i18n/case_conversion.h" #include "base/no_destructor.h" #include "base/synchronization/lock.h" #include "base/thread_annotations.h" #include "base/types/strong_alias.h" -#include "components/autofill/core/browser/proto/states.pb.h" namespace autofill { +class StateEntry; + // AlternativeStateNameMap encapsulates mappings from state names in the // profiles to their localized and the abbreviated names. //
diff --git a/components/autofill/core/browser/geo/alternative_state_name_map_test_utils.cc b/components/autofill/core/browser/geo/alternative_state_name_map_test_utils.cc index f8c5aad..405c7610 100644 --- a/components/autofill/core/browser/geo/alternative_state_name_map_test_utils.cc +++ b/components/autofill/core/browser/geo/alternative_state_name_map_test_utils.cc
@@ -5,10 +5,9 @@ #include "components/autofill/core/browser/geo/alternative_state_name_map_test_utils.h" #include "base/strings/utf_string_conversions.h" +#include "components/autofill/core/browser/proto/states.pb.h" -namespace autofill { - -namespace test { +namespace autofill::test { void PopulateStateEntry(const TestStateEntry& test_state_entry, StateEntry* state_entry) { @@ -72,5 +71,4 @@ return serialized_output; } -} // namespace test -} // namespace autofill +} // namespace autofill::test
diff --git a/components/autofill/core/browser/geo/alternative_state_name_map_test_utils.h b/components/autofill/core/browser/geo/alternative_state_name_map_test_utils.h index 0b560c2..36a2df1 100644 --- a/components/autofill/core/browser/geo/alternative_state_name_map_test_utils.h +++ b/components/autofill/core/browser/geo/alternative_state_name_map_test_utils.h
@@ -5,11 +5,15 @@ #ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_GEO_ALTERNATIVE_STATE_NAME_MAP_TEST_UTILS_H_ #define COMPONENTS_AUTOFILL_CORE_BROWSER_GEO_ALTERNATIVE_STATE_NAME_MAP_TEST_UTILS_H_ +#include <string> +#include <vector> + #include "components/autofill/core/browser/geo/alternative_state_name_map.h" -#include "components/autofill/core/browser/proto/states.pb.h" namespace autofill { +class StateEntry; + namespace test { namespace internal {
diff --git a/components/autofill/core/browser/geo/alternative_state_name_map_unittest.cc b/components/autofill/core/browser/geo/alternative_state_name_map_unittest.cc index 996db24..cd79a63 100644 --- a/components/autofill/core/browser/geo/alternative_state_name_map_unittest.cc +++ b/components/autofill/core/browser/geo/alternative_state_name_map_unittest.cc
@@ -3,13 +3,14 @@ // found in the LICENSE file. #include "components/autofill/core/browser/geo/alternative_state_name_map.h" + #include "base/strings/utf_string_conversions.h" #include "components/autofill/core/browser/geo/alternative_state_name_map_test_utils.h" +#include "components/autofill/core/browser/proto/states.pb.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -namespace autofill { -namespace test { +namespace autofill::test { // Tests that map is not empty when an entry has been added to it. TEST(AlternativeStateNameMapTest, IsEntryAddedToMap) { @@ -97,5 +98,4 @@ testing::UnorderedElementsAreArray({"Bayern"})); } -} // namespace test -} // namespace autofill +} // namespace autofill::test
diff --git a/components/autofill/core/browser/geo/alternative_state_name_map_updater.cc b/components/autofill/core/browser/geo/alternative_state_name_map_updater.cc index ee85280..89590e4 100644 --- a/components/autofill/core/browser/geo/alternative_state_name_map_updater.cc +++ b/components/autofill/core/browser/geo/alternative_state_name_map_updater.cc
@@ -22,6 +22,7 @@ #include "base/task/thread_pool.h" #include "components/autofill/core/browser/data_manager/addresses/address_data_manager.h" #include "components/autofill/core/browser/geo/country_data.h" +#include "components/autofill/core/browser/proto/states.pb.h" #include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_l10n_util.h" #include "components/autofill/core/common/autofill_prefs.h"
diff --git a/components/autofill/core/browser/geo/alternative_state_name_map_updater_unittest.cc b/components/autofill/core/browser/geo/alternative_state_name_map_updater_unittest.cc index 135944c8c..90d70869 100644 --- a/components/autofill/core/browser/geo/alternative_state_name_map_updater_unittest.cc +++ b/components/autofill/core/browser/geo/alternative_state_name_map_updater_unittest.cc
@@ -19,6 +19,7 @@ #include "components/autofill/core/browser/geo/alternative_state_name_map.h" #include "components/autofill/core/browser/geo/alternative_state_name_map_test_utils.h" #include "components/autofill/core/browser/geo/mock_alternative_state_name_map_updater.h" +#include "components/autofill/core/browser/proto/states.pb.h" #include "components/autofill/core/browser/test_utils/autofill_test_utils.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/autofill/core/common/autofill_features.h"
diff --git a/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_import_utils.cc b/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_import_utils.cc index fc866ca..284b70d 100644 --- a/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_import_utils.cc +++ b/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_import_utils.cc
@@ -24,6 +24,7 @@ #include "components/autofill/core/browser/filling/autofill_ai/select_date_matching.h" #include "components/autofill/core/browser/form_processing/autofill_ai/determine_attribute_types.h" #include "components/autofill/core/browser/form_structure.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/common/dense_set.h" #include "components/autofill/core/common/form_field_data.h"
diff --git a/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_import_utils_unittest.cc b/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_import_utils_unittest.cc index 85b702f7..e27177d 100644 --- a/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_import_utils_unittest.cc +++ b/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_import_utils_unittest.cc
@@ -20,6 +20,7 @@ #include "components/autofill/core/browser/data_model/autofill_ai/entity_type_names.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/form_structure.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/browser/test_utils/autofill_test_utils.h" #include "components/autofill/core/common/autofill_features.h" #include "components/autofill/core/common/autofill_test_utils.h"
diff --git a/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_manager_unittest.cc b/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_manager_unittest.cc index f8f0f444..bcfa370c 100644 --- a/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_manager_unittest.cc +++ b/components/autofill/core/browser/integrators/autofill_ai/autofill_ai_manager_unittest.cc
@@ -25,6 +25,7 @@ #include "components/autofill/core/browser/form_structure_test_api.h" #include "components/autofill/core/browser/foundations/test_autofill_client.h" #include "components/autofill/core/browser/integrators/autofill_ai/autofill_ai_manager_test_api.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/browser/strike_databases/payments/test_strike_database.h" #include "components/autofill/core/browser/suggestions/suggestion_type.h" #include "components/autofill/core/browser/test_utils/autofill_form_test_utils.h"
diff --git a/components/autofill/core/browser/integrators/plus_addresses/autofill_plus_address_delegate.h b/components/autofill/core/browser/integrators/plus_addresses/autofill_plus_address_delegate.h index 78d1c981..0d6724ac 100644 --- a/components/autofill/core/browser/integrators/plus_addresses/autofill_plus_address_delegate.h +++ b/components/autofill/core/browser/integrators/plus_addresses/autofill_plus_address_delegate.h
@@ -11,6 +11,7 @@ #include "base/containers/flat_map.h" #include "base/functional/callback_forward.h" +#include "components/autofill/core/browser/autofill_field.h" #include "components/autofill/core/browser/foundations/autofill_client.h" #include "components/autofill/core/browser/integrators/password_form_classification.h" #include "components/autofill/core/browser/suggestions/suggestion_hiding_reason.h"
diff --git a/components/autofill/core/browser/metrics/form_interactions_ukm_logger.h b/components/autofill/core/browser/metrics/form_interactions_ukm_logger.h index 710f1ae..1e42f81 100644 --- a/components/autofill/core/browser/metrics/form_interactions_ukm_logger.h +++ b/components/autofill/core/browser/metrics/form_interactions_ukm_logger.h
@@ -16,6 +16,7 @@ #include "components/autofill/core/browser/foundations/autofill_client.h" #include "components/autofill/core/browser/metrics/autofill_metrics.h" #include "components/autofill/core/browser/metrics/prediction_quality_metrics.h" +#include "components/autofill/core/common/form_interactions_flow.h" #include "services/metrics/public/cpp/ukm_recorder.h" #include "services/metrics/public/cpp/ukm_source_id.h"
diff --git a/components/autofill/core/browser/metrics/log_event.h b/components/autofill/core/browser/metrics/log_event.h index 4f39f7e..f582b84 100644 --- a/components/autofill/core/browser/metrics/log_event.h +++ b/components/autofill/core/browser/metrics/log_event.h
@@ -11,14 +11,14 @@ #include "base/types/id_type.h" #include "components/autofill/core/browser/filling/field_filling_skip_reason.h" #include "components/autofill/core/browser/heuristic_source.h" -#include "components/autofill/core/browser/proto/api_v1.pb.h" #include "components/autofill/core/browser/studies/autofill_ablation_study.h" #include "components/autofill/core/common/is_required.h" namespace autofill { -using FieldPrediction = - AutofillQueryResponse::FormSuggestion::FieldSuggestion::FieldPrediction; +enum AutofillQueryResponse_FormSuggestion_FieldSuggestion_FieldPrediction_Source : int; +using FieldPredictionSource = + AutofillQueryResponse_FormSuggestion_FieldSuggestion_FieldPrediction_Source; // An identifier to connect the various sub-events of filling together. using FillEventId = base::IdTypeU32<class FillEventIdClass>; @@ -138,10 +138,10 @@ struct ServerPredictionFieldLogEvent { std::optional<FieldType> server_type1 = static_cast<FieldType>(internal::IsRequired()); // nocheck - FieldPrediction::Source prediction_source1 = internal::IsRequired(); + FieldPredictionSource prediction_source1 = internal::IsRequired(); std::optional<FieldType> server_type2 = static_cast<FieldType>(internal::IsRequired()); // nocheck - FieldPrediction::Source prediction_source2 = internal::IsRequired(); + FieldPredictionSource prediction_source2 = internal::IsRequired(); bool server_type_prediction_is_override = internal::IsRequired(); size_t rank_in_field_signature_group = internal::IsRequired(); };
diff --git a/components/autofill/core/browser/metrics/stored_profile_metrics.cc b/components/autofill/core/browser/metrics/stored_profile_metrics.cc index db49c37..b848b35 100644 --- a/components/autofill/core/browser/metrics/stored_profile_metrics.cc +++ b/components/autofill/core/browser/metrics/stored_profile_metrics.cc
@@ -71,6 +71,7 @@ count_and_log(AutofillProfileRecordTypeCategory::kAccountNonChrome); count_and_log(AutofillProfileRecordTypeCategory::kAccountHome); count_and_log(AutofillProfileRecordTypeCategory::kAccountWork); + count_and_log(AutofillProfileRecordTypeCategory::kAccountNameEmail); base::UmaHistogramCounts1M("Autofill.StoredProfileCount.Total", profiles.size()); }
diff --git a/components/autofill/core/browser/metrics/stored_profile_metrics_unittest.cc b/components/autofill/core/browser/metrics/stored_profile_metrics_unittest.cc index afed760..b082274 100644 --- a/components/autofill/core/browser/metrics/stored_profile_metrics_unittest.cc +++ b/components/autofill/core/browser/metrics/stored_profile_metrics_unittest.cc
@@ -38,6 +38,7 @@ AutofillProfileRecordTypeCategory::kAccountNonChrome, AutofillProfileRecordTypeCategory::kAccountHome, AutofillProfileRecordTypeCategory::kAccountWork, + AutofillProfileRecordTypeCategory::kAccountNameEmail, })); // Tests that no profile count metrics for the corresponding category are
diff --git a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_cache_impl.cc b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_cache_impl.cc index 103c542..413888f 100644 --- a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_cache_impl.cc +++ b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_cache_impl.cc
@@ -19,6 +19,7 @@ #include "base/task/thread_pool.h" #include "components/autofill/core/browser/data_model/data_model_utils.h" #include "components/autofill/core/browser/field_types.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/common/signatures.h" #include "components/history/core/browser/history_service.h" #include "components/leveldb_proto/public/proto_database.h"
diff --git a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_cache_impl_unittest.cc b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_cache_impl_unittest.cc index 0a919dd..169a505 100644 --- a/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_cache_impl_unittest.cc +++ b/components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_cache_impl_unittest.cc
@@ -15,6 +15,7 @@ #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/ml_model/autofill_ai/autofill_ai_model_cache.h" #include "components/autofill/core/browser/proto/autofill_ai_model_cache.pb.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/common/signatures.h" #include "components/leveldb_proto/public/proto_database_provider.h" #include "testing/gmock/include/gmock/gmock.h"
diff --git a/components/autofill/core/browser/suggestions/identity_credential_suggestion_utils.cc b/components/autofill/core/browser/suggestions/identity_credential_suggestion_utils.cc index bdfc158..8b025da 100644 --- a/components/autofill/core/browser/suggestions/identity_credential_suggestion_utils.cc +++ b/components/autofill/core/browser/suggestions/identity_credential_suggestion_utils.cc
@@ -4,6 +4,8 @@ #include "components/autofill/core/browser/suggestions/identity_credential_suggestion_utils.h" +#include "components/autofill/core/common/form_data.h" + namespace autofill { std::vector<Suggestion> GetIdentityCredentialSuggestionsForType(
diff --git a/components/autofill/core/browser/suggestions/payments/iban_suggestion_generator.cc b/components/autofill/core/browser/suggestions/payments/iban_suggestion_generator.cc index 72df142..7f5245ce 100644 --- a/components/autofill/core/browser/suggestions/payments/iban_suggestion_generator.cc +++ b/components/autofill/core/browser/suggestions/payments/iban_suggestion_generator.cc
@@ -8,6 +8,7 @@ #include "base/containers/to_vector.h" #include "base/functional/function_ref.h" #include "base/strings/string_util.h" +#include "components/autofill/core/browser/autofill_field.h" #include "components/autofill/core/browser/data_manager/payments/payments_data_manager.h" #include "components/autofill/core/browser/integrators/optimization_guide/autofill_optimization_guide_decider.h" #include "components/autofill/core/browser/payments/iban_manager.h"
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 e9fa7b1..5e2655a 100644 --- a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.cc +++ b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.cc
@@ -771,63 +771,6 @@ CreditCard::VirtualCardEnrollmentState::kEnrolled; } -// Returns the local and server cards ordered by the Autofill ranking. -// If `suppress_disused_cards`, local expired disused cards are removed. -// If `prefix_match`, cards are matched with the contents of `trigger_field`. -// If `include_virtual_cards`, virtual cards will be added when possible. -std::vector<CreditCard> GetOrderedCardsToSuggest( - const AutofillClient& client, - const FormFieldData& trigger_field, - FieldType trigger_field_type, - bool suppress_disused_cards, - bool prefix_match, - bool require_non_empty_value_on_trigger_field, - bool include_virtual_cards) { - std::vector<const CreditCard*> available_cards = GetCreditCardsToSuggest( - client.GetPersonalDataManager().payments_data_manager()); - // If a card has available card linked offers on the last committed url, rank - // it to the top. - if (std::map<std::string, const AutofillOfferData*> card_linked_offers_map = - GetCardLinkedOffers(client); - !card_linked_offers_map.empty()) { - std::ranges::stable_sort( - available_cards, - [&card_linked_offers_map](const CreditCard* a, const CreditCard* b) { - return base::Contains(card_linked_offers_map, a->guid()) && - !base::Contains(card_linked_offers_map, b->guid()); - }); - } - // Suppress disused credit cards when triggered from an empty field. - if (suppress_disused_cards) { - const base::Time min_last_used = - AutofillClock::Now() - kDisusedDataModelTimeDelta; - RemoveExpiredLocalCreditCardsNotUsedSinceTimestamp(min_last_used, - available_cards); - } - std::vector<CreditCard> cards_to_suggest; - std::u16string field_contents = - base::i18n::ToLower(SanitizeCreditCardFieldValue(trigger_field.value())); - for (const CreditCard* credit_card : available_cards) { - std::u16string suggested_value = credit_card->GetInfo( - trigger_field_type, - client.GetPersonalDataManager().payments_data_manager().app_locale()); - if (require_non_empty_value_on_trigger_field && suggested_value.empty()) { - continue; - } - if (prefix_match && - !IsValidPaymentsSuggestionForFieldContents( - /*suggestion_canon=*/base::i18n::ToLower(suggested_value), - field_contents, trigger_field_type)) { - continue; - } - if (include_virtual_cards && - ShouldShowVirtualCardOption(credit_card, client)) { - cards_to_suggest.push_back(CreditCard::CreateVirtualCard(*credit_card)); - } - cards_to_suggest.push_back(*credit_card); - } - return cards_to_suggest; -} // Creates a suggestion for the given `credit_card`. `virtual_card_option` // suggests whether the suggestion is a virtual card option. @@ -1816,4 +1759,63 @@ }); } } + +// Returns the local and server cards ordered by the Autofill ranking. +// If `suppress_disused_cards`, local expired disused cards are removed. +// If `prefix_match`, cards are matched with the contents of `trigger_field`. +// If `include_virtual_cards`, virtual cards will be added when possible. +std::vector<CreditCard> GetOrderedCardsToSuggest( + const AutofillClient& client, + const FormFieldData& trigger_field, + FieldType trigger_field_type, + bool suppress_disused_cards, + bool prefix_match, + bool require_non_empty_value_on_trigger_field, + bool include_virtual_cards) { + std::vector<const CreditCard*> available_cards = GetCreditCardsToSuggest( + client.GetPersonalDataManager().payments_data_manager()); + // If a card has available card linked offers on the last committed url, rank + // it to the top. + if (std::map<std::string, const AutofillOfferData*> card_linked_offers_map = + GetCardLinkedOffers(client); + !card_linked_offers_map.empty()) { + std::ranges::stable_sort( + available_cards, + [&card_linked_offers_map](const CreditCard* a, const CreditCard* b) { + return base::Contains(card_linked_offers_map, a->guid()) && + !base::Contains(card_linked_offers_map, b->guid()); + }); + } + // Suppress disused credit cards when triggered from an empty field. + if (suppress_disused_cards) { + const base::Time min_last_used = + AutofillClock::Now() - kDisusedDataModelTimeDelta; + RemoveExpiredLocalCreditCardsNotUsedSinceTimestamp(min_last_used, + available_cards); + } + std::vector<CreditCard> cards_to_suggest; + std::u16string field_contents = + base::i18n::ToLower(SanitizeCreditCardFieldValue(trigger_field.value())); + for (const CreditCard* credit_card : available_cards) { + std::u16string suggested_value = credit_card->GetInfo( + trigger_field_type, + client.GetPersonalDataManager().payments_data_manager().app_locale()); + if (require_non_empty_value_on_trigger_field && suggested_value.empty()) { + continue; + } + if (prefix_match && + !IsValidPaymentsSuggestionForFieldContents( + /*suggestion_canon=*/base::i18n::ToLower(suggested_value), + field_contents, trigger_field_type)) { + continue; + } + if (include_virtual_cards && + ShouldShowVirtualCardOption(credit_card, client)) { + cards_to_suggest.push_back(CreditCard::CreateVirtualCard(*credit_card)); + } + cards_to_suggest.push_back(*credit_card); + } + return cards_to_suggest; +} + } // namespace autofill
diff --git a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.h b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.h index 9e887bb9..5c9c937 100644 --- a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.h +++ b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.h
@@ -237,6 +237,22 @@ const std::u16string& autofilled_last_four_digits_in_form_for_filtering, std::vector<CreditCard>& cards_to_suggest); +// Function, shared between android touch-to-fill feature +// and CCSG. +// +// Returns the local and server cards ordered by the Autofill ranking. +// If `suppress_disused_cards`, local expired disused cards are removed. +// If `prefix_match`, cards are matched with the contents of `trigger_field`. +// If `include_virtual_cards`, virtual cards will be added when possible. +std::vector<CreditCard> GetOrderedCardsToSuggest( + const AutofillClient& client, + const FormFieldData& trigger_field, + FieldType trigger_field_type, + bool suppress_disused_cards, + bool prefix_match, + bool require_non_empty_value_on_trigger_field, + bool include_virtual_cards); + } // namespace autofill #endif // COMPONENTS_AUTOFILL_CORE_BROWSER_SUGGESTIONS_PAYMENTS_PAYMENTS_SUGGESTION_GENERATOR_H_
diff --git a/components/autofill/core/browser/suggestions/valuables/valuable_suggestion_generator.cc b/components/autofill/core/browser/suggestions/valuables/valuable_suggestion_generator.cc index 865719c..903049e 100644 --- a/components/autofill/core/browser/suggestions/valuables/valuable_suggestion_generator.cc +++ b/components/autofill/core/browser/suggestions/valuables/valuable_suggestion_generator.cc
@@ -10,6 +10,7 @@ #include "base/containers/to_vector.h" #include "base/i18n/case_conversion.h" #include "base/strings/utf_string_conversions.h" +#include "components/autofill/core/browser/autofill_field.h" #include "components/autofill/core/browser/data_manager/valuables/valuables_data_manager.h" #include "components/autofill/core/browser/data_model/valuables/loyalty_card.h" #include "components/autofill/core/browser/suggestions/suggestion.h"
diff --git a/components/autofill/core/browser/test_utils/autofill_test_utils.cc b/components/autofill/core/browser/test_utils/autofill_test_utils.cc index 858080e..1df4a3a 100644 --- a/components/autofill/core/browser/test_utils/autofill_test_utils.cc +++ b/components/autofill/core/browser/test_utils/autofill_test_utils.cc
@@ -40,6 +40,7 @@ #include "components/autofill/core/browser/integrators/optimization_guide/mock_autofill_optimization_guide_decider.h" #include "components/autofill/core/browser/metrics/suggestions_list_metrics.h" #include "components/autofill/core/browser/payments/card_unmask_challenge_option.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/browser/suggestions/suggestion.h" #include "components/autofill/core/browser/suggestions/suggestion_type.h" #include "components/autofill/core/browser/ui/autofill_external_delegate.h"
diff --git a/components/autofill/core/browser/ui/autofill_external_delegate.cc b/components/autofill/core/browser/ui/autofill_external_delegate.cc index 92b09ff6..a13a4ca 100644 --- a/components/autofill/core/browser/ui/autofill_external_delegate.cc +++ b/components/autofill/core/browser/ui/autofill_external_delegate.cc
@@ -45,6 +45,7 @@ #include "components/autofill/core/browser/foundations/browser_autofill_manager.h" #include "components/autofill/core/browser/integrators/autofill_ai/autofill_ai_manager.h" #include "components/autofill/core/browser/integrators/compose/autofill_compose_delegate.h" +#include "components/autofill/core/browser/integrators/identity_credential/identity_credential_delegate.h" #include "components/autofill/core/browser/integrators/one_time_tokens/otp_suggestion.h" #include "components/autofill/core/browser/integrators/plus_addresses/autofill_plus_address_delegate.h" #include "components/autofill/core/browser/metrics/autofill_in_devtools_metrics.h" @@ -69,6 +70,7 @@ #include "components/autofill/core/common/autofill_payments_features.h" #include "components/autofill/core/common/autofill_util.h" #include "components/autofill/core/common/mojom/autofill_types.mojom-shared.h" +#include "components/autofill/core/common/plus_address_survey_type.h" #include "components/autofill/core/common/signatures.h" #include "components/signin/public/base/signin_metrics.h" #include "components/strings/grit/components_strings.h"
diff --git a/components/autofill/core/browser/ui/autofill_external_delegate_unittest.cc b/components/autofill/core/browser/ui/autofill_external_delegate_unittest.cc index e6d2ff4c..caa51fe 100644 --- a/components/autofill/core/browser/ui/autofill_external_delegate_unittest.cc +++ b/components/autofill/core/browser/ui/autofill_external_delegate_unittest.cc
@@ -81,6 +81,7 @@ #include "components/autofill/core/common/form_field_data.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/plus_address_survey_type.h" #include "components/strings/grit/components_strings.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/components/autofill/core/browser/webdata/autofill_ai/entity_table.cc b/components/autofill/core/browser/webdata/autofill_ai/entity_table.cc index d82eab4..583f311 100644 --- a/components/autofill/core/browser/webdata/autofill_ai/entity_table.cc +++ b/components/autofill/core/browser/webdata/autofill_ai/entity_table.cc
@@ -26,6 +26,7 @@ #include "components/autofill/core/browser/data_model/autofill_ai/entity_instance.h" #include "components/autofill/core/browser/field_type_utils.h" #include "components/autofill/core/browser/field_types.h" +#include "components/autofill/core/browser/proto/server.pb.h" #include "components/autofill/core/browser/webdata/autofill_table_utils.h" #include "components/autofill/core/common/autofill_features.h" #include "components/os_crypt/async/common/encryptor.h"
diff --git a/components/autofill/core/browser/webdata/autofill_change.h b/components/autofill/core/browser/webdata/autofill_change.h index d5670ed..4e2ae758 100644 --- a/components/autofill/core/browser/webdata/autofill_change.h +++ b/components/autofill/core/browser/webdata/autofill_change.h
@@ -49,10 +49,21 @@ std::same_as<DataType, ServerCvc> class AutofillDataModelChange { public: - // The difference between `REMOVE` and `HIDE_IN_AUTOFILL` is that the latter - // does not actually remove the profile from the server, but instead marks - // it as uninteresting to Chrome. This profile may become visible again if - // it is updated in a different product. + // The difference between `REMOVE` and `HIDE_IN_AUTOFILL` is that the + // `HIDE_IN_AUTOFILL`: + // - For kAccount, kAccountHome and kAccountWork profiles, does not + // actually remove the profile from the server, but instead marks it as + // uninteresting to Chrome. This profile may become visible again if it is + // updated in a different product. + // + // - For kAccountNameEmail profile, removes the profile for the duration of + // the sign out or autofill sync toggle being off, but the profile may + // reappear once the user is signed in and autofill sync toggle is enabled + // again. See `AccountNameEmailStore` for the detailed description of this + // behaviour. + // + // - For kLocalOrSyncable profile, there is no difference. + // TODO(crbug.com/40100455): Consider renaming `HIDE_IN_AUTOFILL`. enum Type { ADD, UPDATE, REMOVE, HIDE_IN_AUTOFILL }; // The `type` input specifies the change type. The `key` input is the key
diff --git a/components/autofill/ios/browser/autofill_driver_ios_factory_unittest.mm b/components/autofill/ios/browser/autofill_driver_ios_factory_unittest.mm index 64fcd51..fd2a7a4 100644 --- a/components/autofill/ios/browser/autofill_driver_ios_factory_unittest.mm +++ b/components/autofill/ios/browser/autofill_driver_ios_factory_unittest.mm
@@ -29,7 +29,6 @@ using ::autofill::test::SaveArgPtr; using ::testing::_; using ::testing::AllOf; -using ::testing::DoAll; using ::testing::Each; using ::testing::Eq; using ::testing::InSequence; @@ -249,7 +248,7 @@ #define EXPECT_DRIVER_CREATED(driver_ptr_ptr) \ EXPECT_CALL(factory_observer(), \ OnAutofillDriverIOSCreated(Ref(factory()), HasState(kInactive))) \ - .WillOnce(DoAll(SaveArgPtr<1>((driver_ptr_ptr)))) + .WillOnce(SaveArgPtr<1>((driver_ptr_ptr))) #define EXPECT_LIFECYCLE_CHANGE(driver_matcher, from, to) \ EXPECT_CALL(factory_observer(), \ OnAutofillDriverIOSStateChanged( \
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/LocationPermissionSubpageSettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/LocationPermissionSubpageSettings.java index 38c2d08..0d8349b 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/LocationPermissionSubpageSettings.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/LocationPermissionSubpageSettings.java
@@ -4,10 +4,13 @@ package org.chromium.components.browser_ui.site_settings; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.os.Bundle; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; +import org.chromium.build.annotations.MonotonicNonNull; import org.chromium.build.annotations.NullMarked; import org.chromium.build.annotations.Nullable; import org.chromium.components.browser_ui.settings.EmbeddableSettingsPage; @@ -15,12 +18,15 @@ import org.chromium.components.content_settings.ContentSettingsType; import org.chromium.components.content_settings.SessionModel; +import java.util.Collection; + /** Subpage fragment showing durable location permission options of a site. */ @NullMarked public class LocationPermissionSubpageSettings extends BaseSiteSettingsFragment implements EmbeddableSettingsPage { public static final String RADIO_BUTTON_GROUP_KEY = "radio_button_group"; private final ObservableSupplierImpl<String> mPageTitle = new ObservableSupplierImpl<>(); + private @MonotonicNonNull Website mSite; @Override public void onCreatePreferences(@Nullable Bundle bundle, @Nullable String s) { @@ -34,10 +40,37 @@ } Website site = (Website) getArguments().getSerializable(SingleWebsiteSettings.EXTRA_SITE); - assert site != null; + WebsiteAddress address = + (WebsiteAddress) + getArguments().getSerializable(SingleWebsiteSettings.EXTRA_SITE_ADDRESS); + if (site != null && address == null) { + mSite = site; + setUpPreferences(); + } else if (address != null && site == null) { + WebsitePermissionsFetcher fetcher = + new WebsitePermissionsFetcher(getSiteSettingsDelegate()); + fetcher.fetchAllPreferences( + (Collection<Website> sites) -> { + // This method may be called after the activity has been destroyed. + // In that case, bail out. + if (getActivity() == null) return; + + mSite = + SingleWebsiteSettings + .mergePermissionAndStorageInfoForTopLevelOrigin( + address, sites); + setUpPreferences(); + }); + } else { + assert false : "Exactly one of EXTRA_SITE or EXTRA_SITE_ADDRESS must be provided."; + } + } + + private void setUpPreferences() { + assumeNonNull(mSite); PermissionInfo permissionInfo = - site.getPermissionInfo(ContentSettingsType.GEOLOCATION_WITH_OPTIONS); + mSite.getPermissionInfo(ContentSettingsType.GEOLOCATION_WITH_OPTIONS); assert permissionInfo != null; assert permissionInfo.getSessionModel() == SessionModel.DURABLE; @@ -46,7 +79,7 @@ LocationPermissionOptionsPreference radioPreference = findPreference(RADIO_BUTTON_GROUP_KEY); assert radioPreference != null; - radioPreference.initialize(getSiteSettingsDelegate().getBrowserContextHandle(), site); + radioPreference.initialize(getSiteSettingsDelegate().getBrowserContextHandle(), mSite); } @Override
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java index 555e25d..85e6fde1 100644 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
@@ -72,6 +72,9 @@ /** Notifies the observer that a permission was changed. */ void onPermissionChanged(); + + /** Notifies the observer that the location permission subpage was clicked. */ + void onLocationPermissionSubpageClicked(); } // SingleWebsiteSettings expects either EXTRA_SITE (a Website) or @@ -668,7 +671,6 @@ TwoActionSwitchPreference preference = new TwoActionSwitchPreference(getStyledContext()); preference.setPrimaryButtonClickListener( (v) -> { - // TODO(crbug.com/418936295): Launch subpage for page info. if (getSettingsNavigation() != null) { Bundle fragmentArgs = new Bundle(); fragmentArgs.putSerializable(EXTRA_SITE, mSite); @@ -677,6 +679,8 @@ getActivity(), LocationPermissionSubpageSettings.class, fragmentArgs); + } else if (mWebsiteSettingsObserver != null) { + mWebsiteSettingsObserver.onLocationPermissionSubpageClicked(); } else { assert false : "Not reached."; }
diff --git a/components/data_sharing/internal/group_data_model_unittest.cc b/components/data_sharing/internal/group_data_model_unittest.cc index ad44adf..4f9a5570 100644 --- a/components/data_sharing/internal/group_data_model_unittest.cc +++ b/components/data_sharing/internal/group_data_model_unittest.cc
@@ -253,12 +253,12 @@ size_t call_count = 0; EXPECT_CALL(observer_, OnGroupAdded(_, NotNullTime())) .Times(::testing::AtLeast(0)) - .WillRepeatedly(::testing::DoAll([&]() { + .WillRepeatedly([&]() { ++call_count; if (call_count == number_of_groups) { run_loop.Quit(); } - })); + }); run_loop.Run(); }
diff --git a/components/data_sharing/internal/personal_collaboration_data/personal_collaboration_data_service_impl_unittest.cc b/components/data_sharing/internal/personal_collaboration_data/personal_collaboration_data_service_impl_unittest.cc index e45cde0..9f611d8 100644 --- a/components/data_sharing/internal/personal_collaboration_data/personal_collaboration_data_service_impl_unittest.cc +++ b/components/data_sharing/internal/personal_collaboration_data/personal_collaboration_data_service_impl_unittest.cc
@@ -20,7 +20,6 @@ namespace { using testing::_; -using testing::Invoke; using testing::Return; using testing::ReturnRef; @@ -124,9 +123,9 @@ // Now, let the service initialize. The queued actions should be executed. base::RunLoop run_loop; - EXPECT_CALL(mock_observer, OnInitialized()).WillOnce(Invoke([&]() { + EXPECT_CALL(mock_observer, OnInitialized()).WillOnce([&]() { run_loop.Quit(); - })); + }); ON_CALL(mock_processor, IsTrackingMetadata()).WillByDefault(Return(true)); // The service queues a Put for key1, a Put for key2, then a Delete for key2.
diff --git a/components/enterprise/client_certificates/core/dm_server_client_unittest.cc b/components/enterprise/client_certificates/core/dm_server_client_unittest.cc index ec41ccb..b2f70fa 100644 --- a/components/enterprise/client_certificates/core/dm_server_client_unittest.cc +++ b/components/enterprise/client_certificates/core/dm_server_client_unittest.cc
@@ -50,8 +50,7 @@ void SetFailedJobReply(int net_error, int response_code) { EXPECT_CALL(job_creation_handler_, OnJobCreation) - .WillOnce( - DoAll(service_.SendJobResponseAsync(net_error, response_code))) + .WillOnce(service_.SendJobResponseAsync(net_error, response_code)) .RetiresOnSaturation(); }
diff --git a/components/history/core/browser/visit_database_unittest.cc b/components/history/core/browser/visit_database_unittest.cc index 3a69dd1..ab9d803f 100644 --- a/components/history/core/browser/visit_database_unittest.cc +++ b/components/history/core/browser/visit_database_unittest.cc
@@ -1489,7 +1489,8 @@ EXPECT_EQ(0, result.total_visits); } -TEST_F(VisitDatabaseTest, GetDailyVisitsToOrigin_404s) { +// TODO(crbug.com/448019671): This test is flaky and has been disabled. +TEST_F(VisitDatabaseTest, DISABLED_GetDailyVisitsToOrigin_404s) { base::Time begin_time = base::Time::Now(); base::Time end_time = begin_time + base::Days(10);
diff --git a/components/page_info/android/BUILD.gn b/components/page_info/android/BUILD.gn index cc9e0c8..489e7f5 100644 --- a/components/page_info/android/BUILD.gn +++ b/components/page_info/android/BUILD.gn
@@ -82,6 +82,7 @@ "java/src/org/chromium/components/page_info/PageInfoDialog.java", "java/src/org/chromium/components/page_info/PageInfoFeatures.java", "java/src/org/chromium/components/page_info/PageInfoHighlight.java", + "java/src/org/chromium/components/page_info/PageInfoLocationPermissionController.java", "java/src/org/chromium/components/page_info/PageInfoMainController.java", "java/src/org/chromium/components/page_info/PageInfoPermissionsController.java", "java/src/org/chromium/components/page_info/PageInfoPreferenceSubpageController.java",
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoLocationPermissionController.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoLocationPermissionController.java new file mode 100644 index 0000000..bf01e38 --- /dev/null +++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoLocationPermissionController.java
@@ -0,0 +1,71 @@ +// 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.components.page_info; + +import android.content.res.Resources; +import android.os.Bundle; +import android.view.View; +import android.view.ViewGroup; + +import androidx.fragment.app.Fragment; + +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; +import org.chromium.components.browser_ui.site_settings.LocationPermissionSubpageSettings; +import org.chromium.components.browser_ui.site_settings.SingleWebsiteSettings; +import org.chromium.components.browser_ui.site_settings.WebsiteAddress; +import org.chromium.components.embedder_support.util.Origin; + +/** Class for controlling the page info location permission subpage. */ +@NullMarked +public class PageInfoLocationPermissionController extends PageInfoPreferenceSubpageController { + private final PageInfoRowView mRowView; + private final String mPageUrl; + private @Nullable LocationPermissionSubpageSettings mSubPage; + + public PageInfoLocationPermissionController( + PageInfoRowView view, PageInfoControllerDelegate delegate, String pageUrl) { + super(delegate); + mRowView = view; + mPageUrl = pageUrl; + } + + @Override + public String getSubpageTitle() { + Resources resources = mRowView.getContext().getResources(); + return resources.getString(R.string.website_settings_device_location); + } + + @Override + public @Nullable View createViewForSubpage(ViewGroup parent) { + assert mSubPage == null; + if (!canCreateSubpageFragment()) return null; + + Bundle fragmentArgs = new Bundle(); + String origin = Origin.createOrThrow(mPageUrl).toString(); + WebsiteAddress address = WebsiteAddress.create(origin); + fragmentArgs.putSerializable(SingleWebsiteSettings.EXTRA_SITE_ADDRESS, address); + + mSubPage = + (LocationPermissionSubpageSettings) + Fragment.instantiate( + mRowView.getContext(), + LocationPermissionSubpageSettings.class.getName(), + fragmentArgs); + return addSubpageFragment(mSubPage); + } + + @Override + public void onSubpageRemoved() { + removeSubpageFragment(); + mSubPage = null; + } + + @Override + public void clearData() {} + + @Override + public void updateRowIfNeeded() {} +}
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoPermissionsController.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoPermissionsController.java index 19e35452..79e835e 100644 --- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoPermissionsController.java +++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoPermissionsController.java
@@ -272,4 +272,12 @@ mMainController.recordAction(PageInfoAction.PAGE_INFO_CHANGED_PERMISSION); mDataIsStale = true; } + + @Override + public void onLocationPermissionSubpageClicked() { + // TODO(crbug.com/418936295): Update location preference on preference changes. + mMainController.launchSubpage( + new PageInfoLocationPermissionController( + mRowView, getDelegate(), mMainController.getURL().getSpec())); + } }
diff --git a/components/page_load_metrics/browser/observers/use_counter/webdx_feature_maps.cc b/components/page_load_metrics/browser/observers/use_counter/webdx_feature_maps.cc index c616dc734..3697d8a5 100644 --- a/components/page_load_metrics/browser/observers/use_counter/webdx_feature_maps.cc +++ b/components/page_load_metrics/browser/observers/use_counter/webdx_feature_maps.cc
@@ -601,6 +601,8 @@ {CSSSampleId::kReadingFlow, WebDXFeature::kReadingFlow}, {CSSSampleId::kPrintColorAdjust, WebDXFeature::kPrintColorAdjust}, {CSSSampleId::kLineBreak, WebDXFeature::kLineBreak}, + {CSSSampleId::kFontLanguageOverride, + WebDXFeature::kFontLanguageOverride}, // Add new features above this line. }};
diff --git a/components/password_manager/core/browser/password_autofill_manager.cc b/components/password_manager/core/browser/password_autofill_manager.cc index 7c911455..866c5ce 100644 --- a/components/password_manager/core/browser/password_autofill_manager.cc +++ b/components/password_manager/core/browser/password_autofill_manager.cc
@@ -31,6 +31,7 @@ #include "components/autofill/core/browser/foundations/autofill_client.h" #include "components/autofill/core/browser/foundations/autofill_driver.h" #include "components/autofill/core/browser/foundations/browser_autofill_manager.h" +#include "components/autofill/core/browser/integrators/identity_credential/identity_credential_delegate.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/plus_addresses/core/browser/fake_plus_address_service.cc b/components/plus_addresses/core/browser/fake_plus_address_service.cc index 7a0b1bc..d7ba700 100644 --- a/components/plus_addresses/core/browser/fake_plus_address_service.cc +++ b/components/plus_addresses/core/browser/fake_plus_address_service.cc
@@ -14,6 +14,7 @@ #include "base/strings/to_string.h" #include "components/autofill/core/browser/autofill_field.h" #include "components/autofill/core/browser/filling/filling_product.h" +#include "components/autofill/core/browser/suggestions/suggestion.h" #include "components/autofill/core/browser/suggestions/suggestion_type.h" #include "components/autofill/core/common/form_data.h" #include "components/feature_engagement/public/feature_constants.h"
diff --git a/components/signin/internal/identity_manager/account_capabilities_list.h b/components/signin/internal/identity_manager/account_capabilities_list.h index 66d6979d..a03847d1d 100644 --- a/components/signin/internal/identity_manager/account_capabilities_list.h +++ b/components/signin/internal/identity_manager/account_capabilities_list.h
@@ -21,6 +21,9 @@ // should be removed from this file and included transitively instead. #include "build/build_config.h" +// The server-side documentation and definition for a given capability can be +// found at go/capability-alias (eg. go/capability-alias/ge2dinbnmnqxa). + // clang-format off // keep-sorted start newline_separated=yes sticky_prefixes=#if group_prefixes=#endif // clang-format on
diff --git a/components/supervised_user/core/browser/supervised_user_service.cc b/components/supervised_user/core/browser/supervised_user_service.cc index 6b58708..b47c0c0 100644 --- a/components/supervised_user/core/browser/supervised_user_service.cc +++ b/components/supervised_user/core/browser/supervised_user_service.cc
@@ -290,6 +290,8 @@ // Also disables incognito mode. SetSettingsServiceActive(true); + // TODO(crbug.com/447414264): Check if tabs should be closed in the first + // place. platform_delegate_->CloseIncognitoTabs(); remote_web_approvals_manager_.AddApprovalRequestCreator( @@ -419,7 +421,9 @@ settings_service_->SetSuspended(true); content_filters_service_->SetSearchFiltersEnabled(true); - platform_delegate_->CloseIncognitoTabs(); + if (platform_delegate_->ShouldCloseIncognitoTabs()) { + platform_delegate_->CloseIncognitoTabs(); + } // OnSearchContentFiltersChanged reattributes the synthetic field trial // groups and then reloads search pages. @@ -447,7 +451,9 @@ RemoveURLFilterPrefChangeHandlers(); settings_service_->SetSuspended(true); content_filters_service_->SetBrowserFiltersEnabled(true); - platform_delegate_->CloseIncognitoTabs(); + if (platform_delegate_->ShouldCloseIncognitoTabs()) { + platform_delegate_->CloseIncognitoTabs(); + } // Add handlers that will prevent unsupported url filter changes. AddURLFilterPrefChangeSentinels();
diff --git a/components/sync_user_events/user_event_sync_bridge.cc b/components/sync_user_events/user_event_sync_bridge.cc index c46b236..78e5a8f6 100644 --- a/components/sync_user_events/user_event_sync_bridge.cc +++ b/components/sync_user_events/user_event_sync_bridge.cc
@@ -263,18 +263,22 @@ int64_t new_global_id) { DCHECK_NE(old_global_id, new_global_id); - // When a navigation's global_id is updated, we need to find all in-flight - // events that were associated with the old id and update them to the new id. - // This is accomplished by extracting the nodes from the multimap, updating - // the navigation_id, and re-recording the event. - auto range = in_flight_nav_linked_events_.equal_range(old_global_id); - for (auto it = range.first; it != range.second;) { - auto node = in_flight_nav_linked_events_.extract(it++); - CHECK(!node.empty()); - CHECK_EQ(old_global_id, node.mapped().navigation_id()); - node.mapped().set_navigation_id(new_global_id); - RecordUserEvent( - std::make_unique<UserEventSpecifics>(std::move(node.mapped()))); + // Store specifics in a temp vector while erasing, as |RecordUserEvent()| will + // insert new values into |in_flight_nav_linked_events_|. While insert should + // not invalidate a std::multimap's iterator, and the updated global_id should + // not be within our given range, this approach seems less error prone. + std::vector<std::unique_ptr<UserEventSpecifics>> affected; + + auto [begin, end] = in_flight_nav_linked_events_.equal_range(old_global_id); + for (auto iter = begin; iter != end;) { + DCHECK_EQ(old_global_id, iter->second.navigation_id()); + affected.emplace_back(std::make_unique<UserEventSpecifics>(iter->second)); + iter = in_flight_nav_linked_events_.erase(iter); + } + + for (std::unique_ptr<UserEventSpecifics>& specifics : affected) { + specifics->set_navigation_id(new_global_id); + RecordUserEvent(std::move(specifics)); } }
diff --git a/components/viz/service/display_embedder/compositor_gpu_thread.cc b/components/viz/service/display_embedder/compositor_gpu_thread.cc index 6505ef0..381a4f4 100644 --- a/components/viz/service/display_embedder/compositor_gpu_thread.cc +++ b/components/viz/service/display_embedder/compositor_gpu_thread.cc
@@ -149,15 +149,6 @@ // GL resources with the contexts created on gpu main thread. auto context = gl::init::CreateGLContext(share_group.get(), surface.get(), attribs); - - if (!context && !features::UseGles2ForOopR()) { - LOG(ERROR) << "Failed to create GLES3 context, fallback to GLES2."; - attribs.client_major_es_version = 2; - attribs.client_minor_es_version = 0; - context = - gl::init::CreateGLContext(share_group.get(), surface.get(), attribs); - } - if (!context) { LOG(ERROR) << "Failed to create shared context"; return nullptr;
diff --git a/components/viz/test/test_raster_interface.cc b/components/viz/test/test_raster_interface.cc index fab0d9f..94cb38e 100644 --- a/components/viz/test/test_raster_interface.cc +++ b/components/viz/test/test_raster_interface.cc
@@ -96,37 +96,6 @@ return gpu::SyncToken(); } -GLuint TestRasterInterface::CreateAndConsumeForGpuRaster( - const gpu::Mailbox& mailbox) { - NOTREACHED(); -} - -GLuint TestRasterInterface::CreateAndConsumeForGpuRaster( - const scoped_refptr<gpu::ClientSharedImage>& shared_image) { - NOTREACHED(); -} - -void TestRasterInterface::DeleteGpuRasterTexture(GLuint texture) { - NOTREACHED(); -} - -void TestRasterInterface::BeginGpuRaster() { - NOTREACHED(); -} - -void TestRasterInterface::EndGpuRaster() { - NOTREACHED(); -} - -void TestRasterInterface::BeginSharedImageAccessDirectCHROMIUM(GLuint texture, - GLenum mode) { - NOTREACHED(); -} - -void TestRasterInterface::EndSharedImageAccessDirectCHROMIUM(GLuint texture) { - NOTREACHED(); -} - void TestRasterInterface::GenSyncTokenCHROMIUM(GLbyte* sync_token) { // Don't return a valid sync token if context is lost. This matches behavior // of CommandBufferProxyImpl.
diff --git a/components/viz/test/test_raster_interface.h b/components/viz/test/test_raster_interface.h index 69adf55..9057a9b 100644 --- a/components/viz/test/test_raster_interface.h +++ b/components/viz/test/test_raster_interface.h
@@ -145,15 +145,6 @@ int src_y, int plane_index, void* dst_pixels) override; - GLuint CreateAndConsumeForGpuRaster(const gpu::Mailbox& mailbox) override; - GLuint CreateAndConsumeForGpuRaster( - const scoped_refptr<gpu::ClientSharedImage>& shared_image) override; - void DeleteGpuRasterTexture(GLuint texture) override; - void BeginGpuRaster() override; - void EndGpuRaster() override; - void BeginSharedImageAccessDirectCHROMIUM(GLuint texture, - GLenum mode) override; - void EndSharedImageAccessDirectCHROMIUM(GLuint texture) override; void TraceBeginCHROMIUM(const char* category_name, const char* trace_name) override {} void TraceEndCHROMIUM() override {}
diff --git a/content/browser/indexed_db/BUILD.gn b/content/browser/indexed_db/BUILD.gn index 0174fe0..b9df275 100644 --- a/content/browser/indexed_db/BUILD.gn +++ b/content/browser/indexed_db/BUILD.gn
@@ -37,6 +37,8 @@ "instance/backing_store.h", "instance/backing_store_pre_close_task_queue.cc", "instance/backing_store_pre_close_task_queue.h", + "instance/backing_store_util.cc", + "instance/backing_store_util.h", "instance/bucket_context.cc", "instance/bucket_context.h", "instance/bucket_context_handle.cc", @@ -139,8 +141,6 @@ "instance/backing_store_test_base.cc", "instance/backing_store_test_base.h", "instance/backing_store_unittest.cc", - "instance/backing_store_util.cc", - "instance/backing_store_util.h", "instance/bucket_context_unittest.cc", "instance/database_unittest.cc", "instance/fake_transaction.cc",
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc index 546b21d..4b9dcc65 100644 --- a/content/browser/indexed_db/indexed_db_browsertest.cc +++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -29,6 +29,7 @@ #include "base/test/bind.h" #include "base/test/gmock_expected_support.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/run_until.h" #include "base/test/scoped_feature_list.h" #include "base/test/test_future.h" #include "base/test/thread_test_helper.h" @@ -44,6 +45,7 @@ #include "content/browser/browser_main_loop.h" #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" #include "content/browser/indexed_db/instance/bucket_context.h" +#include "content/browser/indexed_db/instance/leveldb/backing_store.h" #include "content/browser/indexed_db/instance/leveldb/cleanup_scheduler.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/browser_context.h" @@ -683,8 +685,11 @@ : public IndexedDBLevelDBOnlyTest { public: IndexedDBBrowserTestsWithCleanupScheduler() { - scoped_feature_list_.InitAndEnableFeature( - content::indexed_db::level_db::kIdbInSessionDbCleanup); + scoped_feature_list_.InitWithFeatures( + /*enabled_features=*/ + {content::indexed_db::level_db::kIdbInSessionDbCleanup, + content::indexed_db::level_db::kIdbVerifyInSessionDbCleanup}, + /*disabled_features=*/{}); } protected: @@ -695,6 +700,7 @@ // More details in `index_deletion_regression_tests.js`. IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestsWithCleanupScheduler, RollbackTrasactionDuringTombstoneSweep) { + base::HistogramTester histograms; const GURL kTestUrl = GetTestUrl("indexeddb", "index_deletion_regression_tests.html"); EXPECT_TRUE(NavigateToURL(shell(), kTestUrl)); @@ -709,12 +715,23 @@ ASSERT_TRUE( ExecJs(shell(), base::StringPrintf("runRollbackTest(%d, %d)", num_entries, delay_for_sweeper_run))); + + // The transaction rollback interrupts the cleanup, and cleanup will be + // completed after a short delay. + EXPECT_TRUE(base::test::RunUntil([&]() { + return histograms.GetBucketCount( + "IndexedDB.LevelDB.InSessionCleanupVerificationEvent", + level_db::BackingStore::InSessionCleanupVerificationEvent:: + kMatchedSnapshot) > 0; + })); } // Regression test for crbug.com/413540372. // More details in `index_deletion_regression_tests.js`. IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestsWithCleanupScheduler, TransactionInterleavedWithSweeper) { + base::HistogramTester histograms; + const GURL kTestUrl = GetTestUrl("indexeddb", "index_deletion_regression_tests.html"); EXPECT_TRUE(NavigateToURL(shell(), kTestUrl)); @@ -735,6 +752,21 @@ shell(), base::StringPrintf("runInterleavedTest(%d, %d, %d)", num_entries, delay_before_interleaved_updates, delay_to_finish_sweeper))); + + histograms.ExpectTotalCount("IndexedDB.LevelDB.InSessionCleanupSnapshotTime", + 2); + histograms.ExpectTotalCount( + "IndexedDB.LevelDB.InSessionCleanupVerificationEvent", 2); + histograms.ExpectBucketCount( + "IndexedDB.LevelDB.InSessionCleanupVerificationEvent", + level_db::BackingStore::InSessionCleanupVerificationEvent:: + kCleanupStarted, + 1); + histograms.ExpectBucketCount( + "IndexedDB.LevelDB.InSessionCleanupVerificationEvent", + level_db::BackingStore::InSessionCleanupVerificationEvent:: + kMatchedSnapshot, + 1); } class IndexedDBBrowserTestWithCorruptLevelDB : public
diff --git a/content/browser/indexed_db/indexed_db_unittest.cc b/content/browser/indexed_db/indexed_db_unittest.cc index c808eda..2c19d07 100644 --- a/content/browser/indexed_db/indexed_db_unittest.cc +++ b/content/browser/indexed_db/indexed_db_unittest.cc
@@ -1572,7 +1572,7 @@ MockMojoFactoryClient client; mojo::PendingAssociatedRemote<blink::mojom::IDBDatabase> pending_database; EXPECT_CALL(client, MockedOpenSuccess) - .WillOnce(testing::DoAll(MoveArgPointee<0>(&pending_database))); + .WillOnce(MoveArgPointee<0>(&pending_database)); mojo::AssociatedRemote<blink::mojom::IDBTransaction> transaction_remote; factory_remote_->Open(client.CreateInterfacePtrAndBind(), database_callbacks.CreateInterfacePtrAndBind(), @@ -2062,8 +2062,7 @@ MockMojoDatabaseCallbacks database_callbacks; base::RunLoop run_loop; EXPECT_CALL(client, DeleteSuccess) - .WillOnce( - testing::DoAll(::base::test::RunClosure(run_loop.QuitClosure()))); + .WillOnce(::base::test::RunClosure(run_loop.QuitClosure())); mojo::AssociatedRemote<blink::mojom::IDBTransaction> transaction_remote; factory_remote->DeleteDatabase(client.CreateInterfacePtrAndBind(), u"db", /*force_close=*/false); @@ -2096,8 +2095,7 @@ MockMojoDatabaseCallbacks database_callbacks; base::RunLoop run_loop; EXPECT_CALL(client, DeleteSuccess) - .WillOnce( - testing::DoAll(::base::test::RunClosure(run_loop.QuitClosure()))); + .WillOnce(::base::test::RunClosure(run_loop.QuitClosure())); mojo::AssociatedRemote<blink::mojom::IDBTransaction> transaction_remote; factory_remote->DeleteDatabase(client.CreateInterfacePtrAndBind(), u"db", /*force_close=*/false); @@ -2233,8 +2231,7 @@ MockMojoDatabaseCallbacks database_callbacks; base::RunLoop run_loop; EXPECT_CALL(client, Error) - .WillOnce( - testing::DoAll(::base::test::RunClosure(run_loop.QuitClosure()))); + .WillOnce(::base::test::RunClosure(run_loop.QuitClosure())); mojo::AssociatedRemote<blink::mojom::IDBTransaction> transaction_remote; factory_remote->Open(client.CreateInterfacePtrAndBind(), database_callbacks.CreateInterfacePtrAndBind(), u"db", @@ -2273,8 +2270,7 @@ MockMojoDatabaseCallbacks database_callbacks; base::RunLoop run_loop; EXPECT_CALL(client, MockedUpgradeNeeded) - .WillOnce( - testing::DoAll(::base::test::RunClosure(run_loop.QuitClosure()))); + .WillOnce(::base::test::RunClosure(run_loop.QuitClosure())); mojo::AssociatedRemote<blink::mojom::IDBTransaction> transaction_remote; factory_remote->Open(client.CreateInterfacePtrAndBind(), database_callbacks.CreateInterfacePtrAndBind(), @@ -2332,8 +2328,7 @@ base::RunLoop run_loop; EXPECT_CALL(client, MockedUpgradeNeeded( _, _, blink::mojom::IDBDataLoss::None, _, _)) - .WillOnce( - testing::DoAll(::base::test::RunClosure(run_loop.QuitClosure()))); + .WillOnce(::base::test::RunClosure(run_loop.QuitClosure())); mojo::AssociatedRemote<blink::mojom::IDBTransaction> transaction_remote; factory_remote->Open(client.CreateInterfacePtrAndBind(), database_callbacks.CreateInterfacePtrAndBind(), @@ -2365,8 +2360,7 @@ MockMojoDatabaseCallbacks database_callbacks; EXPECT_CALL(client, MockedUpgradeNeeded( _, _, blink::mojom::IDBDataLoss::Total, _, _)) - .WillOnce( - testing::DoAll(::base::test::RunClosure(run_loop.QuitClosure()))); + .WillOnce(::base::test::RunClosure(run_loop.QuitClosure())); mojo::AssociatedRemote<blink::mojom::IDBTransaction> transaction_remote; factory_remote->Open(client.CreateInterfacePtrAndBind(), database_callbacks.CreateInterfacePtrAndBind(),
diff --git a/content/browser/indexed_db/instance/backing_store_unittest.cc b/content/browser/indexed_db/instance/backing_store_unittest.cc index c11dc4c..912101d 100644 --- a/content/browser/indexed_db/instance/backing_store_unittest.cc +++ b/content/browser/indexed_db/instance/backing_store_unittest.cc
@@ -13,6 +13,7 @@ #include "base/strings/utf_string_conversions.h" #include "content/browser/indexed_db/indexed_db_value.h" #include "content/browser/indexed_db/instance/backing_store_test_base.h" +#include "content/browser/indexed_db/instance/backing_store_util.h" #include "content/browser/indexed_db/instance/bucket_context.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/indexeddb/indexeddb_key.h" @@ -95,6 +96,121 @@ } } +TEST_P(BackingStoreTest, Snapshots) { + auto db_creation_result = backing_store()->CreateOrOpenDatabase(u"name"); + ASSERT_TRUE(db_creation_result.has_value()); + BackingStore::Database& db = **db_creation_result; + + StatusOr<base::DictValue> empty_snapshot = SnapshotDatabase(db); + ASSERT_TRUE(empty_snapshot.has_value()); + + { + std::unique_ptr<BackingStore::Transaction> transaction = + CreateAndBeginTransaction( + db, blink::mojom::IDBTransactionMode::VersionChange); + + EXPECT_TRUE(transaction + ->CreateObjectStore(1, u"object_store_name", + IndexedDBKeyPath(u"object_store_key"), + /*auto_increment=*/true) + .ok()); + CommitTransactionAndVerify(*transaction); + } + + int total_record_count = 0; + auto add_records = [&](size_t num_records) { + std::unique_ptr<BackingStore::Transaction> transaction = + db.CreateTransaction(blink::mojom::IDBTransactionDurability::Relaxed, + blink::mojom::IDBTransactionMode::ReadWrite); + + transaction->Begin(CreateDummyLock()); + + for (size_t i = 0; i < num_records; ++i) { + IndexedDBKey key(i + total_record_count, + blink::mojom::IDBKeyType::Number); + EXPECT_TRUE(transaction->PutRecord(1, key, value1_.Clone()).has_value()); + } + total_record_count += num_records; + CommitTransactionAndVerify(*transaction); + }; + add_records(100); + + StatusOr<base::DictValue> snapshot = SnapshotDatabase(db); + ASSERT_TRUE(snapshot.has_value()); + + // Adding a record changes the snapshot. + add_records(3); + StatusOr<base::DictValue> snapshot2 = SnapshotDatabase(db); + ASSERT_TRUE(snapshot2.has_value()); + EXPECT_NE(*snapshot, *snapshot2); + + // Updating a value changes the snapshot. + { + std::unique_ptr<BackingStore::Transaction> transaction = + db.CreateTransaction(blink::mojom::IDBTransactionDurability::Relaxed, + blink::mojom::IDBTransactionMode::ReadWrite); + + transaction->Begin(CreateDummyLock()); + + IndexedDBKey key(15, blink::mojom::IDBKeyType::Number); + EXPECT_TRUE(transaction->PutRecord(1, key, value2_.Clone()).has_value()); + CommitTransactionAndVerify(*transaction); + }; + + StatusOr<base::DictValue> snapshot3 = SnapshotDatabase(db); + ASSERT_TRUE(snapshot3.has_value()); + EXPECT_NE(*snapshot2, *snapshot3); + + // Changing the updated value back to the original, snapshot should revert + // too. + { + std::unique_ptr<BackingStore::Transaction> transaction = + db.CreateTransaction(blink::mojom::IDBTransactionDurability::Relaxed, + blink::mojom::IDBTransactionMode::ReadWrite); + + transaction->Begin(CreateDummyLock()); + + IndexedDBKey key(15, blink::mojom::IDBKeyType::Number); + EXPECT_TRUE(transaction->PutRecord(1, key, value1_.Clone()).has_value()); + CommitTransactionAndVerify(*transaction); + }; + StatusOr<base::DictValue> snapshot4 = SnapshotDatabase(db); + ASSERT_TRUE(snapshot4.has_value()); + EXPECT_EQ(*snapshot2, *snapshot4); + + // Exercise the whole-store hashing code. + add_records(1000); + StatusOr<base::DictValue> snapshot5 = SnapshotDatabase(db); + ASSERT_TRUE(snapshot5.has_value()); + EXPECT_LT(snapshot5->DebugString().size(), snapshot4->DebugString().size()); + + add_records(2); + StatusOr<base::DictValue> snapshot6 = SnapshotDatabase(db); + ASSERT_TRUE(snapshot6.has_value()); + EXPECT_NE(*snapshot5, *snapshot6); + // Size should not have changed since the row would change the digest but not + // the size of the digest. Note that this sort of cheats because the digest is + // actually omitted from the debug string due to being a binary, but even if + // we were to encode it as a string (e.g. with base64), this check would pass. + EXPECT_EQ(snapshot6->DebugString().size(), snapshot5->DebugString().size()); + + // Delete all records and verify the snapshot works, and is distinct from the + // one for a database that lacks object stores/indices. + { + std::unique_ptr<BackingStore::Transaction> transaction = + db.CreateTransaction(blink::mojom::IDBTransactionDurability::Relaxed, + blink::mojom::IDBTransactionMode::ReadWrite); + + transaction->Begin(CreateDummyLock()); + + EXPECT_TRUE(transaction->DeleteRange(1, blink::IndexedDBKeyRange()).ok()); + CommitTransactionAndVerify(*transaction); + }; + StatusOr<base::DictValue> no_record_snapshot = SnapshotDatabase(db); + ASSERT_TRUE(no_record_snapshot.has_value()); + EXPECT_NE(*empty_snapshot, *no_record_snapshot); +} + // Deleting an index should delete the index metadata and the index data. TEST_P(BackingStoreTest, CreateAndDeleteIndex) { const int64_t object_store_id = 99; @@ -110,7 +226,6 @@ std::unique_ptr<BackingStore::Transaction> transaction = CreateAndBeginTransaction( **db, blink::mojom::IDBTransactionMode::VersionChange); - EXPECT_TRUE(transaction ->CreateObjectStore(object_store_id, u"object_store_name", object_store_key_path,
diff --git a/content/browser/indexed_db/instance/backing_store_util.cc b/content/browser/indexed_db/instance/backing_store_util.cc index d85f007..8bc1c8e 100644 --- a/content/browser/indexed_db/instance/backing_store_util.cc +++ b/content/browser/indexed_db/instance/backing_store_util.cc
@@ -5,6 +5,7 @@ #include "content/browser/indexed_db/instance/backing_store_util.h" #include "base/containers/to_vector.h" +#include "base/strings/string_number_conversions.h" #include "base/values.h" #include "content/browser/indexed_db/indexed_db_value.h" #include "content/browser/indexed_db/instance/backing_store.h" @@ -17,17 +18,34 @@ namespace { +// Converts an integer that may have different length or signedness to a +// base::Value, since base::Value only natively supports int. If it doesn't fit +// in an int, the output will be a string. +template <typename T> +base::Value ToIntValue(T value) { + T small_value = static_cast<int>(value); + if (value == small_value) { + return base::Value(static_cast<int>(small_value)); + } + return base::Value(base::NumberToString(value)); +} + +// When keys or values are longer than this number, or an object store has more +// records than this number, the contents will be hashed instead of stored +// verbatim. This limits total memory usage. +static const int kHashingThreshold = 256; + base::DictValue DatabaseMetadataToDictValue(const BackingStore::Database& db) { base::DictValue result; const blink::IndexedDBDatabaseMetadata& metadata = db.GetMetadata(); result.Set("name", metadata.name); - result.Set("version", static_cast<int>(metadata.version)); + result.Set("version", ToIntValue(metadata.version)); base::ListValue object_stores; for (const auto& [_, object_store] : metadata.object_stores) { base::DictValue object_store_dict; object_store_dict.Set("name", object_store.name); - object_store_dict.Set("id", static_cast<int>(object_store.id)); + object_store_dict.Set("id", ToIntValue(object_store.id)); object_store_dict.Set("auto_increment", object_store.auto_increment); auto key_path_to_dict = [](const blink::IndexedDBKeyPath& key_path) { @@ -53,7 +71,7 @@ for (const auto& [_, index] : object_store.indexes) { base::DictValue index_dict; index_dict.Set("name", index.name); - index_dict.Set("id", static_cast<int>(index.id)); + index_dict.Set("id", ToIntValue(index.id)); index_dict.Set("key_path", key_path_to_dict(index.key_path)); index_dict.Set("unique", index.unique); index_dict.Set("multi_entry", index.multi_entry); @@ -67,49 +85,99 @@ return result; } -base::ListValue CursorToListValue(std::unique_ptr<BackingStore::Cursor>& cursor, - bool include_primary_key, - size_t key_count) { - base::ListValue records = base::ListValue::with_capacity(key_count); +// Fully hashes keys and values from the cursor. For use when there are a lot of +// rows (high `key_count`). +StatusOr<base::BlobStorage> CursorToSummaryValue( + std::unique_ptr<BackingStore::Cursor>& cursor, + bool include_primary_key, + size_t key_count) { + crypto::hash::Hasher streaming_hasher(crypto::hash::HashKind::kSha256); + while (cursor) { - base::DictValue record; - std::string key_string = cursor->GetKey().DebugString(); - if (key_string.size() > 256) { - record.Set( - "key_hash", - base::ToVector(crypto::hash::Sha256(base::as_byte_span(key_string)))); - } else { - record.Set("key", std::move(key_string)); - } + streaming_hasher.Update(cursor->GetKey().DebugString()); if (include_primary_key) { - key_string = cursor->GetPrimaryKey().DebugString(); - if (key_string.size() > 256) { - record.Set("primary_key_hash", base::ToVector(crypto::hash::Sha256( - base::as_byte_span(key_string)))); - } else { - record.Set("primary_key", std::move(key_string)); - } + streaming_hasher.Update(cursor->GetPrimaryKey().DebugString()); } + streaming_hasher.Update(cursor->GetValue().bits); - record.Set("value_hash", - base::ToVector(crypto::hash::Sha256(cursor->GetValue().bits))); - - // Include some limited metadata for blobs (and other external objects). - base::ListValue external_objects; + std::vector<int64_t> object_data; + object_data.reserve(2 * cursor->GetValue().external_objects.size()); for (const IndexedDBExternalObject& object : cursor->GetValue().external_objects) { - base::DictValue object_dict; - object_dict.Set("type", static_cast<int>(object.object_type())); - object_dict.Set("size", static_cast<int>(object.size())); - external_objects.Append(std::move(object_dict)); + object_data.push_back(static_cast<int64_t>(object.object_type())); + object_data.push_back(object.size()); } - record.Set("external_objects", std::move(external_objects)); + streaming_hasher.Update(base::as_byte_span(object_data)); - records.Append(std::move(record)); StatusOr<bool> continue_result = cursor->Continue(); if (!continue_result.has_value()) { - records.Append(continue_result.error().ToString()); - return records; + return base::unexpected(continue_result.error()); + } + if (!*continue_result) { + break; + } + } + + base::BlobStorage digest(crypto::hash::kSha256Size); + streaming_hasher.Finish(digest); + return digest; +} + +// Turns the record pointed to by `Cursor` into a dictionary, and applies some +// "light" hashing to keys and values. +base::DictValue RecordToDictValue(BackingStore::Cursor& cursor, + bool include_primary_key) { + base::DictValue record; + std::string key_string = cursor.GetKey().DebugString(); + if (key_string.size() > kHashingThreshold) { + record.Set( + "key_digest", + base::ToVector(crypto::hash::Sha256(base::as_byte_span(key_string)))); + } else { + record.Set("key", std::move(key_string)); + } + if (include_primary_key) { + key_string = cursor.GetPrimaryKey().DebugString(); + if (key_string.size() > kHashingThreshold) { + record.Set( + "primary_key_digest", + base::ToVector(crypto::hash::Sha256(base::as_byte_span(key_string)))); + } else { + record.Set("primary_key", std::move(key_string)); + } + } + + IndexedDBValue value = std::move(cursor.GetValue()); + if (value.bits.size() > kHashingThreshold) { + record.Set("value_digest", + base::ToVector(crypto::hash::Sha256(value.bits))); + } else { + record.Set("value", std::move(value.bits)); + } + + // Include some limited metadata for blobs (and other external objects). + base::ListValue external_objects; + for (const IndexedDBExternalObject& object : value.external_objects) { + base::DictValue object_dict; + object_dict.Set("type", static_cast<int>(object.object_type())); + object_dict.Set("size", ToIntValue(object.size())); + external_objects.Append(std::move(object_dict)); + } + record.Set("external_objects", std::move(external_objects)); + + return record; +} + +StatusOr<base::ListValue> CursorToListValue( + std::unique_ptr<BackingStore::Cursor>& cursor, + bool include_primary_key, + size_t key_count) { + base::ListValue records = base::ListValue::with_capacity(key_count); + while (cursor) { + records.Append(RecordToDictValue(*cursor, include_primary_key)); + StatusOr<bool> continue_result = cursor->Continue(); + if (!continue_result.has_value()) { + return base::unexpected(continue_result.error()); } if (!*continue_result) { break; @@ -118,7 +186,7 @@ return records; } -base::DictValue IndexToDictValue( +StatusOr<base::DictValue> IndexToDictValue( const blink::IndexedDBObjectStoreMetadata& object_store, const blink::IndexedDBIndexMetadata& index, BackingStore::Transaction& txn) { @@ -128,27 +196,37 @@ StatusOr<uint32_t> key_count = txn.GetIndexKeyCount(object_store.id, index.id, /*key_range=*/{}); if (!key_count.has_value()) { - contents.Set("record_count_error", key_count.error().ToString()); - return contents; + return base::unexpected(key_count.error()); } - contents.Set("record_count", static_cast<int>(*key_count)); + contents.Set("record_count", ToIntValue(*key_count)); // Print all records via Cursor. StatusOr<std::unique_ptr<BackingStore::Cursor>> cursor = txn.OpenIndexCursor(object_store.id, index.id, /*key_range=*/{}, blink::mojom::IDBCursorDirection::Next); if (!cursor.has_value()) { - contents.Set("cursor_error", cursor.error().ToString()); - return contents; + return base::unexpected(cursor.error()); } - contents.Set( - "records", - CursorToListValue(*cursor, /*include_primary_key=*/true, *key_count)); + if (*key_count > kHashingThreshold) { + StatusOr<base::BlobStorage> records_digest = + CursorToSummaryValue(*cursor, /*include_primary_key=*/true, *key_count); + if (!records_digest.has_value()) { + return base::unexpected(records_digest.error()); + } + contents.Set("records_digest", *std::move(records_digest)); + } else { + StatusOr<base::ListValue> records = + CursorToListValue(*cursor, /*include_primary_key=*/true, *key_count); + if (!records.has_value()) { + return base::unexpected(records.error()); + } + contents.Set("records", std::move(*records)); + } return contents; } -base::DictValue ObjectStoreToDictValue( +StatusOr<base::DictValue> ObjectStoreToDictValue( const blink::IndexedDBObjectStoreMetadata& object_store, BackingStore::Transaction& txn) { base::DictValue contents; @@ -157,47 +235,75 @@ StatusOr<uint32_t> key_count = txn.GetObjectStoreKeyCount(object_store.id, /*key_range=*/{}); if (!key_count.has_value()) { - contents.Set("record_count_error", key_count.error().ToString()); - return contents; + return base::unexpected(key_count.error()); } - contents.Set("record_count", static_cast<int>(*key_count)); + contents.Set("record_count", ToIntValue(*key_count)); // Print all records via Cursor. StatusOr<std::unique_ptr<BackingStore::Cursor>> cursor = txn.OpenObjectStoreCursor(object_store.id, /*key_range=*/{}, blink::mojom::IDBCursorDirection::Next); if (!cursor.has_value()) { - contents.Set("cursor_error", cursor.error().ToString()); - return contents; + return base::unexpected(cursor.error()); } - contents.Set( - "records", - CursorToListValue(*cursor, /*include_primary_key=*/false, *key_count)); - base::ListValue indexes = - base::ListValue::with_capacity(object_store.indexes.size()); - for (const auto& [_, index] : object_store.indexes) { - indexes.Append(IndexToDictValue(object_store, index, txn)); + if (*key_count > kHashingThreshold) { + StatusOr<base::BlobStorage> records_digest = CursorToSummaryValue( + *cursor, /*include_primary_key=*/false, *key_count); + if (!records_digest.has_value()) { + return base::unexpected(records_digest.error()); + } + contents.Set("records_digest", *std::move(records_digest)); + } else { + StatusOr<base::ListValue> records = + CursorToListValue(*cursor, /*include_primary_key=*/false, *key_count); + if (!records.has_value()) { + return base::unexpected(records.error()); + } + contents.Set("records", *std::move(records)); + } + + base::DictValue indexes; + indexes.reserve(object_store.indexes.size()); + for (const auto& [id, index] : object_store.indexes) { + StatusOr<base::DictValue> index_dict = + IndexToDictValue(object_store, index, txn); + if (!index_dict.has_value()) { + return index_dict; + } + indexes.Set(base::NumberToString(id), std::move(*index_dict)); } contents.Set("indexes", std::move(indexes)); return contents; } -base::DictValue DatabaseContentsToDictValue(BackingStore::Database& db) { +StatusOr<base::DictValue> DatabaseContentsToDictValue( + BackingStore::Database& db) { base::DictValue contents; auto txn = - db.CreateTransaction(blink::mojom::IDBTransactionDurability::Default, + db.CreateTransaction(blink::mojom::IDBTransactionDurability::Relaxed, blink::mojom::IDBTransactionMode::ReadOnly); - if (!txn->Begin({}).ok()) { - contents.Set("error", "Failed to begin read-only transaction"); - return contents; + // Locks are assumed to be unnecessary as this is a synchronous operation + // that won't be interrupted. + std::vector<PartitionedLock> locks; + locks.emplace_back(PartitionedLockId{.partition = 0, .key = "unused"}, + base::DoNothing()); + Status status = txn->Begin(std::move(locks)); + if (!status.ok()) { + return base::unexpected(status); } - base::ListValue object_stores = - base::ListValue::with_capacity(db.GetMetadata().object_stores.size()); - for (const auto& [_, object_store] : db.GetMetadata().object_stores) { - object_stores.Append(ObjectStoreToDictValue(object_store, *txn)); + base::DictValue object_stores; + object_stores.reserve(db.GetMetadata().object_stores.size()); + for (const auto& [id, object_store] : db.GetMetadata().object_stores) { + StatusOr<base::DictValue> obj_store = + ObjectStoreToDictValue(object_store, *txn); + if (!obj_store.has_value()) { + return obj_store; + } + + object_stores.Set(base::NumberToString(id), std::move(*obj_store)); } contents.Set("object_stores", std::move(object_stores)); return contents; @@ -205,10 +311,20 @@ } // namespace -base::DictValue DumpDatabase(BackingStore::Database& db) { +StatusOr<base::DictValue> SnapshotDatabase(BackingStore::Database& db) { + StatusOr<base::DictValue> metadata = DatabaseMetadataToDictValue(db); + if (!metadata.has_value()) { + return metadata; + } + + StatusOr<base::DictValue> contents = DatabaseContentsToDictValue(db); + if (!contents.has_value()) { + return contents; + } + base::DictValue result; - result.Set("metadata", DatabaseMetadataToDictValue(db)); - result.Set("contents", DatabaseContentsToDictValue(db)); + result.Set("metadata", *std::move(metadata)); + result.Set("contents", *std::move(contents)); return result; }
diff --git a/content/browser/indexed_db/instance/backing_store_util.h b/content/browser/indexed_db/instance/backing_store_util.h index 196136a..2587caa 100644 --- a/content/browser/indexed_db/instance/backing_store_util.h +++ b/content/browser/indexed_db/instance/backing_store_util.h
@@ -7,6 +7,8 @@ #include "base/values.h" #include "content/browser/indexed_db/instance/backing_store.h" +#include "content/browser/indexed_db/status.h" +#include "content/common/content_export.h" namespace content::indexed_db { @@ -23,15 +25,11 @@ // the output. // // NB: the entire DB is loaded into a DictValue which can consume a lot of -// memory! To cut down on total memory requirements, all values and longer keys -// will be hashed. However a database with millions of records could still -// be problematic. If/when it's necessary to run this on production databases, -// further compression will be required. -// -// For now, this function is a utility for testing only. In the future, it's -// likely that this will be used for verifying database migrations in -// production. -base::DictValue DumpDatabase(BackingStore::Database& db); +// memory! To cut down on total memory requirements, hashing is applied to +// larger keys, values, and object stores. Care should still be taken to limit +// its usage and impact on real users. +CONTENT_EXPORT StatusOr<base::DictValue> SnapshotDatabase( + BackingStore::Database& db); } // namespace content::indexed_db
diff --git a/content/browser/indexed_db/instance/leveldb/backing_store.cc b/content/browser/indexed_db/instance/leveldb/backing_store.cc index 6907b0dc..200b0df 100644 --- a/content/browser/indexed_db/instance/leveldb/backing_store.cc +++ b/content/browser/indexed_db/instance/leveldb/backing_store.cc
@@ -17,6 +17,7 @@ #include <utility> #include <vector> +#include "base/byte_count.h" #include "base/check.h" #include "base/check_op.h" #include "base/containers/span.h" @@ -33,6 +34,7 @@ #include "base/memory/raw_ptr.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" +#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/no_destructor.h" #include "base/notreached.h" @@ -71,6 +73,7 @@ #include "content/browser/indexed_db/indexed_db_value.h" #include "content/browser/indexed_db/instance/active_blob_registry.h" #include "content/browser/indexed_db/instance/backing_store.h" +#include "content/browser/indexed_db/instance/backing_store_util.h" #include "content/browser/indexed_db/instance/bucket_context.h" #include "content/browser/indexed_db/instance/leveldb/cleanup_scheduler.h" #include "content/browser/indexed_db/instance/leveldb/compaction_task.h" @@ -127,6 +130,12 @@ "@1"; } +void LogVerificationEvent( + BackingStore::InSessionCleanupVerificationEvent event) { + base::UmaHistogramEnumeration( + "IndexedDB.LevelDB.InSessionCleanupVerificationEvent", event); +} + // Returns some configuration that is shared across leveldb DB instances. The // configuration is further tweaked in `CreateLevelDBState()`. leveldb_env::Options GetLevelDBOptions() { @@ -1582,6 +1591,7 @@ } backing_store->db()->scopes()->StartRecoveryAndCleanupTasks(); backing_store->bucket_context_ = &bucket_context; + backing_store->database_path_ = std::move(database_path); return {std::move(backing_store), status, std::move(data_loss_info), /*is_disk_full=*/false}; } @@ -2858,6 +2868,83 @@ txn->Commit().ok(); } +void BackingStore::OnCleanupStarted() { + static int cleanup_count = 0; + // Verification is a potentially expensive operation which is meant to catch + // errors in cleanup (particularly tombstone sweeping) before the in-session + // sweeper is launched to a broader audience. To limit the performance impact, + // it's only performed on databases under a certain size limit and only at + // most once per 100 cleanups (per restart). + if (!in_memory() && + base::FeatureList::IsEnabled(kIdbVerifyInSessionDbCleanup) && + (cleanup_count++ % 100 == 0) && + base::ComputeDirectorySize(database_path_) < base::MiB(25).InBytes()) { + CHECK(!dbs_snapshot_.has_value()); + LogVerificationEvent(InSessionCleanupVerificationEvent::kCleanupStarted); + StatusOr<base::ListValue> dbs_snapshot = + SnapshotAllDatabases(/*before_cleanup=*/true); + if (dbs_snapshot.has_value()) { + dbs_snapshot_ = *std::move(dbs_snapshot); + } + } +} + +void BackingStore::OnCleanupDone() { + if (dbs_snapshot_.has_value()) { + base::ListValue dbs_snapshot_before = *std::move(dbs_snapshot_); + dbs_snapshot_.reset(); + StatusOr<base::ListValue> dbs_snapshot_after = + SnapshotAllDatabases(/*before_cleanup=*/false); + if (!dbs_snapshot_after.has_value()) { + return; + } + if (*dbs_snapshot_after == dbs_snapshot_before) { + LogVerificationEvent(InSessionCleanupVerificationEvent::kMatchedSnapshot); + } else { + LogVerificationEvent( + InSessionCleanupVerificationEvent::kMismatchedSnapshot); + } + } + + // Update the timers for traditional sweeper. + UpdateEarliestSweepTime(); + UpdateEarliestCompactionTime(); +} + +StatusOr<base::ListValue> BackingStore::SnapshotAllDatabases( + bool before_cleanup) { + auto start = base::TimeTicks::Now(); + + base::ListValue dbs_snapshot; + StatusOr<std::vector<std::u16string>> names = GetDatabaseNames(); + if (!names.has_value()) { + return base::unexpected(names.error()); + } + for (const std::u16string& name : *names) { + StatusOr<std::unique_ptr<indexed_db::BackingStore::Database>> database = + CreateOrOpenDatabase(name); + if (!database.has_value()) { + LogVerificationEvent( + before_cleanup + ? InSessionCleanupVerificationEvent::kErrorOpeningBefore + : InSessionCleanupVerificationEvent::kErrorOpeningAfter); + return base::unexpected(database.error()); + } + StatusOr<base::DictValue> snapshot = SnapshotDatabase(**database); + if (!snapshot.has_value()) { + LogVerificationEvent( + before_cleanup + ? InSessionCleanupVerificationEvent::kErrorSnapshottingBefore + : InSessionCleanupVerificationEvent::kErrorSnapshottingAfter); + return base::unexpected(snapshot.error()); + } + dbs_snapshot.Append(*std::move(snapshot)); + } + base::UmaHistogramTimes("IndexedDB.LevelDB.InSessionCleanupSnapshotTime", + base::TimeTicks::Now() - start); + return dbs_snapshot; +} + Status BackingStore::Transaction::PutIndexDataForRecord( int64_t object_store_id, int64_t index_id,
diff --git a/content/browser/indexed_db/instance/leveldb/backing_store.h b/content/browser/indexed_db/instance/leveldb/backing_store.h index abd621a..cc6acd8 100644 --- a/content/browser/indexed_db/instance/leveldb/backing_store.h +++ b/content/browser/indexed_db/instance/leveldb/backing_store.h
@@ -478,14 +478,19 @@ void StopPreCloseTasks() override; StatusOr<std::unique_ptr<indexed_db::BackingStore::Database>> CreateOrOpenDatabase(const std::u16string& name) override; - uintptr_t GetIdentifierForMemoryDump() override; void FlushForTesting() override; - StatusOr<bool> DatabaseExists(std::u16string_view database_name) override; - StatusOr<std::vector<blink::mojom::IDBNameAndVersionPtr>> GetDatabaseNamesAndVersions() override; + int64_t GetInMemorySize() const override; + + // LevelDBCleanupScheduler::Delegate: + void OnCleanupStarted() override; + void OnCleanupDone() override; + Status GetCompleteMetadata( + std::vector<std::unique_ptr<blink::IndexedDBDatabaseMetadata>>* output) + override; base::FilePath GetBlobFileName(int64_t database_id, int64_t key) const; @@ -493,8 +498,6 @@ const std::string& origin_identifier() { return origin_identifier_; } - int64_t GetInMemorySize() const override; - #if DCHECK_IS_ON() int NumBlobFilesDeletedForTesting() { return num_blob_files_deleted_; } #endif @@ -532,6 +535,20 @@ bool is_first_attempt, bool create_if_missing); + // LINT.IfChange(InSessionCleanupVerificationEvent) + enum class InSessionCleanupVerificationEvent { + kCleanupStarted = 0, + kErrorOpeningBefore = 1, + kErrorSnapshottingBefore = 2, + kErrorOpeningAfter = 3, + kErrorSnapshottingAfter = 4, + kMatchedSnapshot = 5, + kMismatchedSnapshot = 6, + + kMaxValue = kMismatchedSnapshot, + }; + // LINT.ThenChange(//tools/metrics/histograms/metadata/storage/enums.xml:IndexedDbLevelDbCleanupVerificationEvent) + private: FRIEND_TEST_ALL_PREFIXES(LevelDbBackingStoreTestWithExternalObjects, ActiveBlobJournal); @@ -559,21 +576,16 @@ StatusOr<std::vector<std::u16string>> GetDatabaseNames(); - // LevelDBCleanupScheduler::Delegate: - // This function updates the next run timestamp for the - // tombstone sweeper in the database metadata. - // Virtual for testing. - // Returns if the update was successful. - bool UpdateEarliestSweepTime() override; - // This function updates the next run timestamp for the - // level db compaction in the database metadata. - // Virtual for testing. - // Returns if the update was successful. - bool UpdateEarliestCompactionTime() override; - // TODO(dmurph): Move this completely to IndexedDBMetadataFactory. - Status GetCompleteMetadata( - std::vector<std::unique_ptr<blink::IndexedDBDatabaseMetadata>>* output) - override; + // Updates the next run timestamp for the tombstone sweeper in the database + // metadata. Returns if writing the update to the LevelDB db was successful. + bool UpdateEarliestSweepTime(); + // Updates the next run timestamp for the level db compaction in the database + // metadata. Returns if writing the update to the LevelDB db was successful. + bool UpdateEarliestCompactionTime(); + + // Dumps and returns all the databases in this store. If an error Status is + // returned, this method will also log UMA to that effect. + StatusOr<base::ListValue> SnapshotAllDatabases(bool before_cleanup); // A helper function for V4 schema migration. // It iterates through all blob files. It will add to the db entry both the @@ -682,8 +694,15 @@ bool initialized_ = false; #endif + // Snapshot of all known DBs. Used for debugging/verification of potentially + // destructive cleanup operations. + std::optional<base::ListValue> dbs_snapshot_; + std::unique_ptr<BackingStorePreCloseTaskQueue> pre_close_task_queue_; + // Path to the leveldb database, or empty if in-memory. + base::FilePath database_path_; + base::WeakPtrFactory<BackingStore> weak_factory_{this}; };
diff --git a/content/browser/indexed_db/instance/leveldb/cleanup_scheduler.cc b/content/browser/indexed_db/instance/leveldb/cleanup_scheduler.cc index fd623a6..ef74976 100644 --- a/content/browser/indexed_db/instance/leveldb/cleanup_scheduler.cc +++ b/content/browser/indexed_db/instance/leveldb/cleanup_scheduler.cc
@@ -13,6 +13,7 @@ namespace content::indexed_db::level_db { BASE_FEATURE(kIdbInSessionDbCleanup, base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kIdbVerifyInSessionDbCleanup, base::FEATURE_DISABLED_BY_DEFAULT); namespace { constexpr base::TimeDelta kTimeBetweenRuns = base::Minutes(30); @@ -91,6 +92,7 @@ base::TimeTicks time_before_round = base::TimeTicks::Now(); switch (running_state_->cleanup_phase) { case Phase::kRunScheduled: + delegate_->OnCleanupStarted(); running_state_->cleanup_phase = Phase::kTombstoneSweeper; ABSL_FALLTHROUGH_INTENDED; case Phase::kTombstoneSweeper: @@ -136,9 +138,7 @@ last_run_ = base::TimeTicks::Now(); running_state_.reset(); - // Update the timers for traditional sweeper. - delegate_->UpdateEarliestSweepTime(); - delegate_->UpdateEarliestCompactionTime(); + delegate_->OnCleanupDone(); } bool LevelDBCleanupScheduler::RunTombstoneSweeper() {
diff --git a/content/browser/indexed_db/instance/leveldb/cleanup_scheduler.h b/content/browser/indexed_db/instance/leveldb/cleanup_scheduler.h index 57c9f41..6f63bc0 100644 --- a/content/browser/indexed_db/instance/leveldb/cleanup_scheduler.h +++ b/content/browser/indexed_db/instance/leveldb/cleanup_scheduler.h
@@ -25,6 +25,10 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kIdbInSessionDbCleanup); +// Whether to run extra checks before/after in-session cleanup. Check results +// are logged to histograms. +CONTENT_EXPORT BASE_DECLARE_FEATURE(kIdbVerifyInSessionDbCleanup); + class LevelDbTombstoneSweeper; // Sweeps the IndexedDB LevelDB database looking for index tombstones, followed @@ -55,20 +59,11 @@ }; // LINT.ThenChange(//tools/metrics/histograms/metadata/storage/enums.xml:LevelDBCleanupSchedulerPhase) - // Abstraction of backing store calls which are required - // by the scheduler. + // Implemented by the backing store. class Delegate { public: - // This function updates the next run timestamp for the - // tombstone sweeper in the database metadata. - // Virtual for testing. - // Returns `true` if the update was successful. - virtual bool UpdateEarliestSweepTime() = 0; - // This function updates the next run timestamp for the - // level db compaction in the database metadata. - // Virtual for testing. - // Returns `true` if the update was successful. - virtual bool UpdateEarliestCompactionTime() = 0; + virtual void OnCleanupStarted() = 0; + virtual void OnCleanupDone() = 0; virtual Status GetCompleteMetadata( std::vector<std::unique_ptr<blink::IndexedDBDatabaseMetadata>>* output) = 0;
diff --git a/content/browser/indexed_db/instance/leveldb/cleanup_scheduler_unittest.cc b/content/browser/indexed_db/instance/leveldb/cleanup_scheduler_unittest.cc index 0b9d038..945004b8 100644 --- a/content/browser/indexed_db/instance/leveldb/cleanup_scheduler_unittest.cc +++ b/content/browser/indexed_db/instance/leveldb/cleanup_scheduler_unittest.cc
@@ -43,9 +43,8 @@ void TearDown() override { scheduler_.reset(); } - bool UpdateEarliestSweepTime() override { return true; } - - bool UpdateEarliestCompactionTime() override { return true; } + void OnCleanupStarted() override {} + void OnCleanupDone() override {} Status GetCompleteMetadata( std::vector<std::unique_ptr<blink::IndexedDBDatabaseMetadata>>* out)
diff --git a/content/browser/indexed_db/instance/leveldb/leveldb_backing_store_unittest.cc b/content/browser/indexed_db/instance/leveldb/leveldb_backing_store_unittest.cc index 9961fc4a..fe2fed7 100644 --- a/content/browser/indexed_db/instance/leveldb/leveldb_backing_store_unittest.cc +++ b/content/browser/indexed_db/instance/leveldb/leveldb_backing_store_unittest.cc
@@ -25,6 +25,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/task/sequenced_task_runner.h" #include "base/test/bind.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/time/time.h" #include "base/unguessable_token.h" @@ -1197,4 +1198,79 @@ EXPECT_TRUE(backing_store()->ShouldRunCompaction()); } +TEST_F(LevelDbBackingStoreTest, InSessionCleanupVerification) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + /*enabled_features=*/ + {content::indexed_db::level_db::kIdbInSessionDbCleanup, + content::indexed_db::level_db::kIdbVerifyInSessionDbCleanup}, + /*disabled_features=*/{}); + + const int object_store_id = 1; + auto db_creation_result = backing_store()->CreateOrOpenDatabase(u"name"); + ASSERT_TRUE(db_creation_result.has_value()); + indexed_db::BackingStore::Database& db = **db_creation_result; + + { + auto txn = + db.CreateTransaction(blink::mojom::IDBTransactionDurability::Relaxed, + blink::mojom::IDBTransactionMode::VersionChange); + txn->Begin(CreateDummyLock()); + + EXPECT_TRUE(txn->CreateObjectStore(object_store_id, u"object_store_name", + IndexedDBKeyPath(u"object_store_key"), + /*auto_increment=*/true) + .ok()); + CommitTransactionAndVerify(*txn); + } + + { + auto txn = + db.CreateTransaction(blink::mojom::IDBTransactionDurability::Relaxed, + blink::mojom::IDBTransactionMode::ReadWrite); + txn->Begin(CreateDummyLock()); + EXPECT_TRUE(txn->PutRecord(object_store_id, IndexedDBKey("key"), + IndexedDBValue("value", {})) + .has_value()); + CommitTransactionAndVerify(*txn); + } + + // Verify that cleanup verification only occurs once in a while, not on every + // cleanup. + base::HistogramTester histograms; + + // Verify on first cleanup. + backing_store()->OnCleanupStarted(); + backing_store()->OnCleanupDone(); + histograms.ExpectBucketCount( + "IndexedDB.LevelDB.InSessionCleanupVerificationEvent", + level_db::BackingStore::InSessionCleanupVerificationEvent:: + kCleanupStarted, + 1); + + // Don't verify on next few cleanups. + for (int i = 0; i < 60; ++i) { + backing_store()->OnCleanupStarted(); + backing_store()->OnCleanupDone(); + } + + histograms.ExpectBucketCount( + "IndexedDB.LevelDB.InSessionCleanupVerificationEvent", + level_db::BackingStore::InSessionCleanupVerificationEvent:: + kCleanupStarted, + 1); + + // Verify again eventually. + for (int i = 0; i < 60; ++i) { + backing_store()->OnCleanupStarted(); + backing_store()->OnCleanupDone(); + } + + histograms.ExpectBucketCount( + "IndexedDB.LevelDB.InSessionCleanupVerificationEvent", + level_db::BackingStore::InSessionCleanupVerificationEvent:: + kCleanupStarted, + 2); +} + } // namespace content::indexed_db::level_db
diff --git a/content/browser/indexed_db/instance/sqlite/database_connection_unittest.cc b/content/browser/indexed_db/instance/sqlite/database_connection_unittest.cc index c9b0f9f..7d4056e 100644 --- a/content/browser/indexed_db/instance/sqlite/database_connection_unittest.cc +++ b/content/browser/indexed_db/instance/sqlite/database_connection_unittest.cc
@@ -254,7 +254,9 @@ ASSERT_TRUE(value.has_value()); EXPECT_EQ(value.value().bits, kValue.bits); - base::DictValue contents_before_corruption = DumpDatabase(*db); + StatusOr<base::DictValue> contents_before_corruption = + SnapshotDatabase(*db); + ASSERT_TRUE(contents_before_corruption.has_value()); // Close the database and then corrupt it. db.reset(); @@ -286,7 +288,9 @@ ASSERT_NO_FATAL_FAILURE(InitializeDbWithOneRecord(*db)); recovered_value = read_value(); #else - EXPECT_EQ(DumpDatabase(*db), contents_before_corruption); + StatusOr<base::DictValue> contents_after_recovery = SnapshotDatabase(*db); + ASSERT_TRUE(contents_after_recovery.has_value()); + EXPECT_EQ(*contents_after_recovery, *contents_before_corruption); #endif // Read works because the DB was recovered (or, on Fuchsia, was deleted,
diff --git a/content/browser/indexed_db/instance/transaction.cc b/content/browser/indexed_db/instance/transaction.cc index 85d080dfc..c410d3d 100644 --- a/content/browser/indexed_db/instance/transaction.cc +++ b/content/browser/indexed_db/instance/transaction.cc
@@ -1160,6 +1160,9 @@ const bool has_connection = (connection_.get() != nullptr); CHECK(has_connection, base::NotFatalUntil::M145); + const size_t num_transactions_across_all_connections = + database_->GetNumTransactionsAcrossAllConnections(); + // Histograms to diagnose memory leak crbug.com/381086791. // TODO(crbug.com/381086791): Remove after the leak is fixed. base::UmaHistogramEnumeration("IndexedDB.TransactionTimeout.Mode", mode_); @@ -1167,7 +1170,11 @@ is_commit_pending_); base::UmaHistogramCounts10000( "IndexedDB.TransactionTimeout.NumTransactionsInDB", - database_->GetNumTransactionsAcrossAllConnections()); + num_transactions_across_all_connections); + + // Note: There is a non-fatal CHECK above the validates that `has_connection` + // is always true. There is a condition here to avoid a crash if the non-fatal + // CHECK fails. if (has_connection) { base::UmaHistogramBoolean("IndexedDB.TransactionTimeout.IsConnected", connection_->IsConnected()); @@ -1176,6 +1183,32 @@ connection_->transactions().size()); } + // Same histograms as above, but only when there are a lot of transactions in + // the connection. + if (connection_->transactions().size() > 10000) { + base::UmaHistogramEnumeration( + "IndexedDB.TransactionTimeout.10kTransactions.Mode", mode_); + base::UmaHistogramBoolean( + "IndexedDB.TransactionTimeout.10kTransactions.CommitPending", + is_commit_pending_); + base::UmaHistogramCounts100000( + "IndexedDB.TransactionTimeout.10kTransactions.NumTransactionsInDB", + num_transactions_across_all_connections); + + // Note: There is a non-fatal CHECK above the validates that + // `has_connection` is always true. There is a condition here to avoid a + // crash if the non-fatal CHECK fails. + if (has_connection) { + base::UmaHistogramBoolean( + "IndexedDB.TransactionTimeout.10kTransactions.IsConnected", + connection_->IsConnected()); + base::UmaHistogramCounts100000( + "IndexedDB.TransactionTimeout.10kTransactions." + "NumTransactionsInConnection", + connection_->transactions().size()); + } + } + if (!IsTransactionBlockingOtherClients(/*consider_priority=*/true)) { return; }
diff --git a/content/browser/webid/delegation/dns_request_unittest.cc b/content/browser/webid/delegation/dns_request_unittest.cc index 8c3065f..1367927 100644 --- a/content/browser/webid/delegation/dns_request_unittest.cc +++ b/content/browser/webid/delegation/dns_request_unittest.cc
@@ -69,22 +69,22 @@ MockNetworkContext mock_network_context; mojo::Receiver<network::mojom::HostResolver> receiver(&mock_host_resolver); EXPECT_CALL(mock_network_context, CreateHostResolver(_, _)) - .WillOnce(Invoke([&](const std::optional<net::DnsConfigOverrides>&, - mojo::PendingReceiver<network::mojom::HostResolver> - pending_receiver) { + .WillOnce([&](const std::optional<net::DnsConfigOverrides>&, + mojo::PendingReceiver<network::mojom::HostResolver> + pending_receiver) { receiver.Bind(std::move(pending_receiver)); - })); + }); EXPECT_CALL(mock_host_resolver, ResolveHost(_, _, _, _)) - .WillOnce(WithArgs<3>( - Invoke([](mojo::PendingRemote<network::mojom::ResolveHostClient> - response_client) { + .WillOnce( + WithArgs<3>([](mojo::PendingRemote<network::mojom::ResolveHostClient> + response_client) { mojo::Remote<network::mojom::ResolveHostClient> client( std::move(response_client)); client->OnTextResults({"iss=record1"}); client->OnComplete(net::OK, net::ResolveErrorInfo(net::OK), net::AddressList(), {}); - }))); + })); DnsRequest dns_request(base::BindRepeating( [](network::mojom::NetworkContext* network_context) { @@ -96,7 +96,7 @@ base::MockCallback<DnsRequest::DnsRequestCallback> callback; EXPECT_CALL(callback, Run(testing::Optional(std::vector<std::string>{"iss=record1"}))) - .WillOnce(Invoke([&]() { run_loop.Quit(); })); + .WillOnce([&]() { run_loop.Quit(); }); dns_request.SendRequest("hostname", callback.Get()); run_loop.Run(); @@ -107,23 +107,23 @@ MockNetworkContext mock_network_context; mojo::Receiver<network::mojom::HostResolver> receiver(&mock_host_resolver); EXPECT_CALL(mock_network_context, CreateHostResolver(_, _)) - .WillOnce(Invoke([&](const std::optional<net::DnsConfigOverrides>&, - mojo::PendingReceiver<network::mojom::HostResolver> - pending_receiver) { + .WillOnce([&](const std::optional<net::DnsConfigOverrides>&, + mojo::PendingReceiver<network::mojom::HostResolver> + pending_receiver) { receiver.Bind(std::move(pending_receiver)); - })); + }); EXPECT_CALL(mock_host_resolver, ResolveHost(_, _, _, _)) - .WillOnce(WithArgs<3>( - Invoke([](mojo::PendingRemote<network::mojom::ResolveHostClient> - response_client) { + .WillOnce( + WithArgs<3>([](mojo::PendingRemote<network::mojom::ResolveHostClient> + response_client) { mojo::Remote<network::mojom::ResolveHostClient> client( std::move(response_client)); client->OnComplete( net::ERR_NAME_NOT_RESOLVED, net::ResolveErrorInfo(net::ERR_NAME_NOT_RESOLVED), net::AddressList(), {}); - }))); + })); DnsRequest dns_request(base::BindRepeating( [](network::mojom::NetworkContext* network_context) { @@ -133,9 +133,9 @@ base::RunLoop run_loop; base::MockCallback<DnsRequest::DnsRequestCallback> callback; - EXPECT_CALL(callback, Run(testing::Eq(std::nullopt))).WillOnce(Invoke([&]() { + EXPECT_CALL(callback, Run(testing::Eq(std::nullopt))).WillOnce([&]() { run_loop.Quit(); - })); + }); dns_request.SendRequest("hostname", callback.Get()); run_loop.Run(); @@ -147,9 +147,9 @@ base::RunLoop run_loop; base::MockCallback<DnsRequest::DnsRequestCallback> callback; - EXPECT_CALL(callback, Run(testing::Eq(std::nullopt))).WillOnce(Invoke([&]() { + EXPECT_CALL(callback, Run(testing::Eq(std::nullopt))).WillOnce([&]() { run_loop.Quit(); - })); + }); dns_request.SendRequest("hostname", callback.Get()); run_loop.Run(); @@ -160,22 +160,22 @@ MockNetworkContext mock_network_context; mojo::Receiver<network::mojom::HostResolver> receiver(&mock_host_resolver); EXPECT_CALL(mock_network_context, CreateHostResolver(_, _)) - .WillOnce(Invoke([&](const std::optional<net::DnsConfigOverrides>&, - mojo::PendingReceiver<network::mojom::HostResolver> - pending_receiver) { + .WillOnce([&](const std::optional<net::DnsConfigOverrides>&, + mojo::PendingReceiver<network::mojom::HostResolver> + pending_receiver) { receiver.Bind(std::move(pending_receiver)); - })); + }); EXPECT_CALL(mock_host_resolver, ResolveHost(_, _, _, _)) - .WillOnce(WithArgs<3>( - Invoke([](mojo::PendingRemote<network::mojom::ResolveHostClient> - response_client) { + .WillOnce( + WithArgs<3>([](mojo::PendingRemote<network::mojom::ResolveHostClient> + response_client) { mojo::Remote<network::mojom::ResolveHostClient> client( std::move(response_client)); client->OnTextResults({"iss=hello.coop", "iss=foo.com"}); client->OnComplete(net::OK, net::ResolveErrorInfo(net::OK), net::AddressList(), {}); - }))); + })); DnsRequest dns_request(base::BindRepeating( [](network::mojom::NetworkContext* network_context) { @@ -187,7 +187,7 @@ base::MockCallback<DnsRequest::DnsRequestCallback> callback; EXPECT_CALL(callback, Run(testing::Optional(std::vector<std::string>{ "iss=hello.coop", "iss=foo.com"}))) - .WillOnce(Invoke([&]() { run_loop.Quit(); })); + .WillOnce([&]() { run_loop.Quit(); }); dns_request.SendRequest("hostname", callback.Get()); run_loop.Run();
diff --git a/content/browser/webid/delegation/email_verification_request_unittest.cc b/content/browser/webid/delegation/email_verification_request_unittest.cc index 8e18f77..dcf7ac9 100644 --- a/content/browser/webid/delegation/email_verification_request_unittest.cc +++ b/content/browser/webid/delegation/email_verification_request_unittest.cc
@@ -82,14 +82,13 @@ EXPECT_CALL(*mock_dns_request_, SendRequest("email._web-identity.example.com", _)) - .WillOnce( - WithArgs<1>(Invoke([&](DnsRequest::DnsRequestCallback callback) { - std::move(callback).Run( - std::vector<std::string>{"iss=issuer.example.com"}); - }))); + .WillOnce(WithArgs<1>([&](DnsRequest::DnsRequestCallback callback) { + std::move(callback).Run( + std::vector<std::string>{"iss=issuer.example.com"}); + })); EXPECT_CALL(*mock_network_manager_, FetchWellKnown(kIssuerUrl, _)) - .WillOnce(WithArgs<1>(Invoke( + .WillOnce(WithArgs<1>( [&](IdpNetworkRequestManager::FetchWellKnownCallback callback) { IdpNetworkRequestManager::WellKnown well_known; well_known.issuance_endpoint = kIssuanceEndpoint; @@ -97,13 +96,13 @@ IdpNetworkRequestManager::FetchStatus{ IdpNetworkRequestManager::ParseStatus::kSuccess}, well_known); - }))); + })); EXPECT_CALL(*mock_network_manager_, SendTokenRequest(kIssuanceEndpoint, kEmail, _, _, _, _, _)) .WillOnce(WithArgs<2, 4>( - Invoke([&](const std::string& url_encoded_post_data, - IdpNetworkRequestManager::TokenRequestCallback callback) { + [&](const std::string& url_encoded_post_data, + IdpNetworkRequestManager::TokenRequestCallback callback) { base::StringPairs params; EXPECT_TRUE(base::SplitStringIntoKeyValuePairs( url_encoded_post_data, '=', '&', ¶ms)); @@ -159,7 +158,7 @@ IdpNetworkRequestManager::FetchStatus{ IdpNetworkRequestManager::ParseStatus::kSuccess}, std::move(result)); - }))); + })); base::test::TestFuture<std::optional<std::string>> future; std::string nonce = kNonce;
diff --git a/gpu/command_buffer/client/client_shared_image.cc b/gpu/command_buffer/client/client_shared_image.cc index 772d59a..5e240149 100644 --- a/gpu/command_buffer/client/client_shared_image.cc +++ b/gpu/command_buffer/client/client_shared_image.cc
@@ -301,7 +301,7 @@ switch (handle.type) { case gfx::SHARED_MEMORY_BUFFER: return MappableBufferSharedMemory::CreateFromHandle(std::move(handle), - size, format, usage); + size, format); #if BUILDFLAG(IS_APPLE) case gfx::IO_SURFACE_BUFFER: { bool is_read_only_cpu_usage = @@ -810,7 +810,7 @@ MappableBufferSharedMemory::AllocateForTesting( info.meta.size, info.meta.format, buffer_usage, &handle); auto mappable_buffer = MappableBufferSharedMemory::CreateFromHandle( - std::move(handle), info.meta.size, info.meta.format, buffer_usage); + std::move(handle), info.meta.size, info.meta.format); // Since the |mappable_buffer| here is always a shared memory, clear the // external sampler prefs if it is already set by client.
diff --git a/gpu/command_buffer/client/internal/mappable_buffer_shared_memory.cc b/gpu/command_buffer/client/internal/mappable_buffer_shared_memory.cc index 30466d8..35203f481 100644 --- a/gpu/command_buffer/client/internal/mappable_buffer_shared_memory.cc +++ b/gpu/command_buffer/client/internal/mappable_buffer_shared_memory.cc
@@ -24,7 +24,6 @@ MappableBufferSharedMemory::MappableBufferSharedMemory( const gfx::Size& size, viz::SharedImageFormat format, - gfx::BufferUsage usage, base::UnsafeSharedMemoryRegion shared_memory_region, base::WritableSharedMemoryMapping shared_memory_mapping, size_t offset, @@ -56,8 +55,7 @@ std::unique_ptr<MappableBufferSharedMemory> MappableBufferSharedMemory::CreateFromHandle(gfx::GpuMemoryBufferHandle handle, const gfx::Size& size, - viz::SharedImageFormat format, - gfx::BufferUsage usage) { + viz::SharedImageFormat format) { DCHECK(handle.region().IsValid()); CHECK(viz::HasEquivalentBufferFormat(format)); @@ -108,7 +106,7 @@ const uint32_t offset = handle.offset; const uint32_t stride = handle.stride; return base::WrapUnique(new MappableBufferSharedMemory( - size, format, usage, std::move(handle).region(), + size, format, std::move(handle).region(), base::WritableSharedMemoryMapping(), offset, stride)); }
diff --git a/gpu/command_buffer/client/internal/mappable_buffer_shared_memory.h b/gpu/command_buffer/client/internal/mappable_buffer_shared_memory.h index 67a3412..1f29b5bf 100644 --- a/gpu/command_buffer/client/internal/mappable_buffer_shared_memory.h +++ b/gpu/command_buffer/client/internal/mappable_buffer_shared_memory.h
@@ -35,7 +35,7 @@ const gfx::Size& size, viz::SharedImageFormat format, gfx::BufferUsage usage) { - return CreateFromHandle(std::move(handle), size, format, usage); + return CreateFromHandle(std::move(handle), size, format); } static base::OnceClosure AllocateForTesting( @@ -63,13 +63,11 @@ static std::unique_ptr<MappableBufferSharedMemory> CreateFromHandle( gfx::GpuMemoryBufferHandle handle, const gfx::Size& size, - viz::SharedImageFormat format, - gfx::BufferUsage usage); + viz::SharedImageFormat format); MappableBufferSharedMemory( const gfx::Size& size, viz::SharedImageFormat format, - gfx::BufferUsage usage, base::UnsafeSharedMemoryRegion shared_memory_region, base::WritableSharedMemoryMapping shared_memory_mapping, size_t offset,
diff --git a/gpu/command_buffer/client/raster_implementation.cc b/gpu/command_buffer/client/raster_implementation.cc index a951fff4..c583b39 100644 --- a/gpu/command_buffer/client/raster_implementation.cc +++ b/gpu/command_buffer/client/raster_implementation.cc
@@ -1900,36 +1900,6 @@ sync_token.release_count(), target_color_space, needs_mips); } -GLuint RasterImplementation::CreateAndConsumeForGpuRaster( - const gpu::Mailbox& mailbox) { - NOTREACHED(); -} - -GLuint RasterImplementation::CreateAndConsumeForGpuRaster( - const scoped_refptr<gpu::ClientSharedImage>& shared_image) { - NOTREACHED(); -} - -void RasterImplementation::DeleteGpuRasterTexture(GLuint texture) { - NOTREACHED(); -} - -void RasterImplementation::BeginGpuRaster() { - NOTREACHED(); -} -void RasterImplementation::EndGpuRaster() { - NOTREACHED(); -} - -void RasterImplementation::BeginSharedImageAccessDirectCHROMIUM(GLuint texture, - GLenum mode) { - NOTREACHED(); -} - -void RasterImplementation::EndSharedImageAccessDirectCHROMIUM(GLuint texture) { - NOTREACHED(); -} - void RasterImplementation::TraceBeginCHROMIUM(const char* category_name, const char* trace_name) { GPU_CLIENT_SINGLE_THREAD_CHECK();
diff --git a/gpu/command_buffer/client/raster_implementation.h b/gpu/command_buffer/client/raster_implementation.h index 41f272f..0d3fd52 100644 --- a/gpu/command_buffer/client/raster_implementation.h +++ b/gpu/command_buffer/client/raster_implementation.h
@@ -193,15 +193,6 @@ int src_y, int plane_index, void* dst_pixels) override; - GLuint CreateAndConsumeForGpuRaster(const gpu::Mailbox& mailbox) override; - GLuint CreateAndConsumeForGpuRaster( - const scoped_refptr<gpu::ClientSharedImage>& shared_image) override; - void DeleteGpuRasterTexture(GLuint texture) override; - void BeginGpuRaster() override; - void EndGpuRaster() override; - void BeginSharedImageAccessDirectCHROMIUM(GLuint texture, - GLenum mode) override; - void EndSharedImageAccessDirectCHROMIUM(GLuint texture) override; // ContextSupport implementation. void SetAggressivelyFreeResources(bool aggressively_free_resources) override;
diff --git a/gpu/command_buffer/client/raster_implementation_gles.cc b/gpu/command_buffer/client/raster_implementation_gles.cc index 67520c4..95076bc 100644 --- a/gpu/command_buffer/client/raster_implementation_gles.cc +++ b/gpu/command_buffer/client/raster_implementation_gles.cc
@@ -199,8 +199,9 @@ const auto& src_info = src_sk_pixmap.info(); const auto& src_row_bytes = src_sk_pixmap.rowBytes(); DCHECK_GE(src_row_bytes, src_info.minRowBytes()); - GLuint texture_id = CreateAndConsumeForGpuRaster(dest_mailbox); - BeginSharedImageAccessDirectCHROMIUM( + GLuint texture_id = + gl_->CreateAndTexStorage2DSharedImageCHROMIUM(dest_mailbox.name); + gl_->BeginSharedImageAccessDirectCHROMIUM( texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM); GLint old_align = 0; @@ -218,8 +219,8 @@ gl_->PixelStorei(GL_UNPACK_ROW_LENGTH, 0); gl_->PixelStorei(GL_UNPACK_ALIGNMENT, old_align); - EndSharedImageAccessDirectCHROMIUM(texture_id); - DeleteGpuRasterTexture(texture_id); + gl_->EndSharedImageAccessDirectCHROMIUM(texture_id); + gl_->DeleteTextures(1u, &texture_id); } void RasterImplementationGLES::WritePixelsYUV( @@ -303,8 +304,9 @@ GLenum format = dst_info.colorType() == kRGBA_8888_SkColorType ? GL_RGBA : GL_BGRA_EXT; gfx::Size dst_gfx_size(dst_info.width(), dst_info.height()); - GLuint texture_id = CreateAndConsumeForGpuRaster(source_mailbox); - BeginSharedImageAccessDirectCHROMIUM( + GLuint texture_id = + gl_->CreateAndTexStorage2DSharedImageCHROMIUM(source_mailbox.name); + gl_->BeginSharedImageAccessDirectCHROMIUM( texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM); // Convert bottom-left GL coordinates to top-left coordinates expected @@ -344,8 +346,8 @@ base::OnceCallback<void(bool)> readback_done, bool success) { DCHECK(texture_id); - EndSharedImageAccessDirectCHROMIUM(texture_id); - DeleteGpuRasterTexture(texture_id); + gl_->EndSharedImageAccessDirectCHROMIUM(texture_id); + gl_->DeleteTextures(1u, &texture_id); std::move(readback_done).Run(success); } @@ -365,8 +367,9 @@ const gfx::Point& paste_location, base::OnceCallback<void()> release_mailbox, base::OnceCallback<void(bool)> readback_done) { - GLuint shared_texture_id = CreateAndConsumeForGpuRaster(source_mailbox); - BeginSharedImageAccessDirectCHROMIUM( + GLuint shared_texture_id = + gl_->CreateAndTexStorage2DSharedImageCHROMIUM(source_mailbox.name); + gl_->BeginSharedImageAccessDirectCHROMIUM( shared_texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM); base::OnceCallback<void()> on_release_mailbox = base::BindOnce(&RasterImplementationGLES::OnReleaseMailbox, @@ -432,8 +435,8 @@ DCHECK(shared_texture_id); DCHECK(!release_mailbox.is_null()); - EndSharedImageAccessDirectCHROMIUM(shared_texture_id); - DeleteGpuRasterTexture(shared_texture_id); + gl_->EndSharedImageAccessDirectCHROMIUM(shared_texture_id); + gl_->DeleteTextures(1u, &shared_texture_id); std::move(release_mailbox).Run(); } @@ -463,50 +466,6 @@ base::FeatureList::IsEnabled(kDisableErrorHandlingForReadbackGLES); } -GLuint RasterImplementationGLES::CreateAndConsumeForGpuRaster( - const gpu::Mailbox& mailbox) { - return gl_->CreateAndTexStorage2DSharedImageCHROMIUM(mailbox.name); -} - -GLuint RasterImplementationGLES::CreateAndConsumeForGpuRaster( - const scoped_refptr<gpu::ClientSharedImage>& shared_image) { - CHECK(shared_image); - return CreateAndConsumeForGpuRaster(shared_image->mailbox()); -} - -void RasterImplementationGLES::DeleteGpuRasterTexture(GLuint texture) { - gl_->DeleteTextures(1u, &texture); -} - -void RasterImplementationGLES::BeginGpuRaster() { - // Using push/pop functions directly incurs cost to evaluate function - // arguments even when tracing is disabled. - gl_->TraceBeginCHROMIUM("BeginGpuRaster", "GpuRasterization"); -} - -void RasterImplementationGLES::EndGpuRaster() { - // Restore default GL unpack alignment. TextureUploader expects this. - gl_->PixelStorei(GL_UNPACK_ALIGNMENT, 4); - - // Using push/pop functions directly incurs cost to evaluate function - // arguments even when tracing is disabled. - gl_->TraceEndCHROMIUM(); - - // Reset cached raster state. - gl_->ActiveTexture(GL_TEXTURE0); -} - -void RasterImplementationGLES::BeginSharedImageAccessDirectCHROMIUM( - GLuint texture, - GLenum mode) { - gl_->BeginSharedImageAccessDirectCHROMIUM(texture, mode); -} - -void RasterImplementationGLES::EndSharedImageAccessDirectCHROMIUM( - GLuint texture) { - gl_->EndSharedImageAccessDirectCHROMIUM(texture); -} - void RasterImplementationGLES::TraceBeginCHROMIUM(const char* category_name, const char* trace_name) { gl_->TraceBeginCHROMIUM(category_name, trace_name);
diff --git a/gpu/command_buffer/client/raster_implementation_gles.h b/gpu/command_buffer/client/raster_implementation_gles.h index a1dbfc9..c2125bf 100644 --- a/gpu/command_buffer/client/raster_implementation_gles.h +++ b/gpu/command_buffer/client/raster_implementation_gles.h
@@ -143,17 +143,6 @@ int plane_index, void* dst_pixels) override; - // Raster via GrContext. - GLuint CreateAndConsumeForGpuRaster(const gpu::Mailbox& mailbox) override; - GLuint CreateAndConsumeForGpuRaster( - const scoped_refptr<gpu::ClientSharedImage>& shared_image) override; - void DeleteGpuRasterTexture(GLuint texture) override; - void BeginGpuRaster() override; - void EndGpuRaster() override; - void BeginSharedImageAccessDirectCHROMIUM(GLuint texture, - GLenum mode) override; - void EndSharedImageAccessDirectCHROMIUM(GLuint texture) override; - void TraceBeginCHROMIUM(const char* category_name, const char* trace_name) override; void TraceEndCHROMIUM() override;
diff --git a/gpu/command_buffer/client/raster_implementation_gles_unittest.cc b/gpu/command_buffer/client/raster_implementation_gles_unittest.cc index f24521f..bde50ad 100644 --- a/gpu/command_buffer/client/raster_implementation_gles_unittest.cc +++ b/gpu/command_buffer/client/raster_implementation_gles_unittest.cc
@@ -354,49 +354,5 @@ ri_->GetQueryObjectui64vEXT(kQueryId, kQueryParam, &result); } -TEST_F(RasterImplementationGLESTest, CreateAndConsumeForGpuRaster) { - const GLuint kTextureId = 23; - const auto mailbox = gpu::Mailbox::Generate(); - EXPECT_CALL(*gl_, CreateAndTexStorage2DSharedImageCHROMIUM(mailbox.name)) - .WillOnce(Return(kTextureId)); - GLuint texture_id = ri_->CreateAndConsumeForGpuRaster(mailbox); - EXPECT_EQ(kTextureId, texture_id); -} - -TEST_F(RasterImplementationGLESTest, DeleteGpuRasterTexture) { - const GLuint kTextureId = 23; - EXPECT_CALL(*gl_, DeleteTextures(1, Pointee(Eq(kTextureId)))).Times(1); - ri_->DeleteGpuRasterTexture(kTextureId); -} - -TEST_F(RasterImplementationGLESTest, BeginSharedImageAccess) { - const GLuint kTextureId = 23; - EXPECT_CALL(*gl_, - BeginSharedImageAccessDirectCHROMIUM( - kTextureId, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM)) - .Times(1); - ri_->BeginSharedImageAccessDirectCHROMIUM( - kTextureId, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM); -} - -TEST_F(RasterImplementationGLESTest, EndSharedImageAccess) { - const GLuint kTextureId = 23; - EXPECT_CALL(*gl_, EndSharedImageAccessDirectCHROMIUM(kTextureId)).Times(1); - ri_->EndSharedImageAccessDirectCHROMIUM(kTextureId); -} - -TEST_F(RasterImplementationGLESTest, BeginGpuRaster) { - EXPECT_CALL(*gl_, TraceBeginCHROMIUM(StrEq("BeginGpuRaster"), - StrEq("GpuRasterization"))) - .Times(1); - ri_->BeginGpuRaster(); -} - -TEST_F(RasterImplementationGLESTest, EndGpuRaster) { - EXPECT_CALL(*gl_, PixelStorei(GL_UNPACK_ALIGNMENT, 4)).Times(1); - EXPECT_CALL(*gl_, TraceEndCHROMIUM()).Times(1); - ri_->EndGpuRaster(); -} - } // namespace raster } // namespace gpu
diff --git a/gpu/command_buffer/client/raster_interface.h b/gpu/command_buffer/client/raster_interface.h index 4fa3dad..f638399 100644 --- a/gpu/command_buffer/client/raster_interface.h +++ b/gpu/command_buffer/client/raster_interface.h
@@ -42,7 +42,6 @@ namespace gpu { -class ClientSharedImage; struct Mailbox; namespace raster { @@ -190,18 +189,6 @@ int plane_index, void* dst_pixels) = 0; - // Raster via GrContext. - virtual GLuint CreateAndConsumeForGpuRaster(const gpu::Mailbox& mailbox) = 0; - virtual GLuint CreateAndConsumeForGpuRaster( - const scoped_refptr<gpu::ClientSharedImage>& shared_image) = 0; - - virtual void DeleteGpuRasterTexture(GLuint texture) = 0; - virtual void BeginGpuRaster() = 0; - virtual void EndGpuRaster() = 0; - virtual void BeginSharedImageAccessDirectCHROMIUM(GLuint texture, - GLenum mode) = 0; - virtual void EndSharedImageAccessDirectCHROMIUM(GLuint texture) = 0; - // Include the auto-generated part of this class. We split this because // it means we can easily edit the non-auto generated parts right here in // this file instead of having to edit some template or the code generator.
diff --git a/gpu/command_buffer/service/shared_image/gpu_memory_buffer_factory_io_surface.cc b/gpu/command_buffer/service/shared_image/gpu_memory_buffer_factory_io_surface.cc index 02a51b1..63cd43b 100644 --- a/gpu/command_buffer/service/shared_image/gpu_memory_buffer_factory_io_surface.cc +++ b/gpu/command_buffer/service/shared_image/gpu_memory_buffer_factory_io_surface.cc
@@ -13,6 +13,7 @@ #include "base/numerics/safe_conversions.h" #include "base/unguessable_token.h" #include "components/viz/common/resources/shared_image_format_utils.h" +#include "gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.h" #include "gpu/ipc/common/gpu_client_ids.h" #include "ui/gfx/buffer_format_util.h" #include "ui/gfx/mac/io_surface.h" @@ -27,15 +28,8 @@ const gfx::Size& size, viz::SharedImageFormat format, gfx::BufferUsage usage) { - bool should_clear = true; - base::apple::ScopedCFTypeRef<IOSurfaceRef> io_surface = - gfx::CreateIOSurface(size, format, should_clear); - if (!io_surface) { - LOG(ERROR) << "Failed to allocate IOSurface."; - return {}; - } - - return gfx::GpuMemoryBufferHandle(std::move(io_surface)); + return IOSurfaceImageBackingFactory::CreateGpuMemoryBufferHandle(size, + format); } } // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.h b/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.h index 73e9e414..46e92c0 100644 --- a/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.h +++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.h
@@ -43,6 +43,10 @@ uint32_t texture_target); ~IOSurfaceImageBackingFactory() override; + static gfx::GpuMemoryBufferHandle CreateGpuMemoryBufferHandle( + const gfx::Size& size, + viz::SharedImageFormat format); + // SharedImageBackingFactory implementation. std::unique_ptr<SharedImageBacking> CreateSharedImage( const Mailbox& mailbox,
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.mm b/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.mm index d88b1af5..a3e12b8f 100644 --- a/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.mm +++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing_factory.mm
@@ -174,6 +174,21 @@ IOSurfaceImageBackingFactory::~IOSurfaceImageBackingFactory() = default; +// static +gfx::GpuMemoryBufferHandle +IOSurfaceImageBackingFactory::CreateGpuMemoryBufferHandle( + const gfx::Size& size, + viz::SharedImageFormat format) { + base::apple::ScopedCFTypeRef<IOSurfaceRef> io_surface = + gfx::CreateIOSurface(size, format, /*should_clear=*/true); + if (!io_surface) { + LOG(ERROR) << "Failed to allocate IOSurface."; + return {}; + } + + return gfx::GpuMemoryBufferHandle(std::move(io_surface)); +} + std::unique_ptr<SharedImageBacking> IOSurfaceImageBackingFactory::CreateSharedImage( const Mailbox& mailbox,
diff --git a/gpu/ipc/service/gpu_channel_manager.cc b/gpu/ipc/service/gpu_channel_manager.cc index 1171abc..be13a9b0 100644 --- a/gpu/ipc/service/gpu_channel_manager.cc +++ b/gpu/ipc/service/gpu_channel_manager.cc
@@ -915,15 +915,6 @@ context = gl::init::CreateGLContext(share_group.get(), surface.get(), attribs); - - if (!context && !features::UseGles2ForOopR()) { - LOG(ERROR) << "Failed to create GLES3 context, fallback to GLES2."; - attribs.client_major_es_version = 2; - attribs.client_minor_es_version = 0; - context = - gl::init::CreateGLContext(share_group.get(), surface.get(), attribs); - } - if (!context) { // TODO(piman): This might not be fatal, we could recurse into // CreateGLContext to get more info, tho it should be exceedingly
diff --git a/infra/config/generated/builders/ci/Linux ASan LSan Builder/targets/chromium.memory.json b/infra/config/generated/builders/ci/Linux ASan LSan Builder/targets/chromium.memory.json index 2e774ecc..feea8bc 100644 --- a/infra/config/generated/builders/ci/Linux ASan LSan Builder/targets/chromium.memory.json +++ b/infra/config/generated/builders/ci/Linux ASan LSan Builder/targets/chromium.memory.json
@@ -1430,7 +1430,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 10 + "shards": 11 }, "test": "sync_integration_tests", "test_id_prefix": "ninja://chrome/test:sync_integration_tests/"
diff --git "a/infra/config/generated/builders/ci/Linux ASan LSan Tests \0501\051/targets/chromium.memory.json" "b/infra/config/generated/builders/ci/Linux ASan LSan Tests \0501\051/targets/chromium.memory.json" index 2e774ecc..feea8bc 100644 --- "a/infra/config/generated/builders/ci/Linux ASan LSan Tests \0501\051/targets/chromium.memory.json" +++ "b/infra/config/generated/builders/ci/Linux ASan LSan Tests \0501\051/targets/chromium.memory.json"
@@ -1430,7 +1430,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 10 + "shards": 11 }, "test": "sync_integration_tests", "test_id_prefix": "ninja://chrome/test:sync_integration_tests/"
diff --git a/infra/config/generated/builders/ci/Linux Builder/targets/chromium.linux.json b/infra/config/generated/builders/ci/Linux Builder/targets/chromium.linux.json index 8bf3c7b..424ddc2 100644 --- a/infra/config/generated/builders/ci/Linux Builder/targets/chromium.linux.json +++ b/infra/config/generated/builders/ci/Linux Builder/targets/chromium.linux.json
@@ -1602,7 +1602,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 7 + "shards": 8 }, "test": "blink_web_tests", "test_id_prefix": "ninja://:blink_web_tests/"
diff --git a/infra/config/generated/builders/ci/Linux TSan Builder/targets/chromium.memory.json b/infra/config/generated/builders/ci/Linux TSan Builder/targets/chromium.memory.json index 6c585a8..3ee93153 100644 --- a/infra/config/generated/builders/ci/Linux TSan Builder/targets/chromium.memory.json +++ b/infra/config/generated/builders/ci/Linux TSan Builder/targets/chromium.memory.json
@@ -388,7 +388,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 5 }, "test": "components_unittests", "test_id_prefix": "ninja://components:components_unittests/"
diff --git a/infra/config/generated/builders/ci/Linux TSan Tests/targets/chromium.memory.json b/infra/config/generated/builders/ci/Linux TSan Tests/targets/chromium.memory.json index 6c585a8..3ee93153 100644 --- a/infra/config/generated/builders/ci/Linux TSan Tests/targets/chromium.memory.json +++ b/infra/config/generated/builders/ci/Linux TSan Tests/targets/chromium.memory.json
@@ -388,7 +388,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 5 }, "test": "components_unittests", "test_id_prefix": "ninja://components:components_unittests/"
diff --git a/infra/config/generated/builders/ci/Linux Tests/targets/chromium.linux.json b/infra/config/generated/builders/ci/Linux Tests/targets/chromium.linux.json index 59e655e..4cc80e0 100644 --- a/infra/config/generated/builders/ci/Linux Tests/targets/chromium.linux.json +++ b/infra/config/generated/builders/ci/Linux Tests/targets/chromium.linux.json
@@ -1559,7 +1559,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 7 + "shards": 8 }, "test": "blink_web_tests", "test_id_prefix": "ninja://:blink_web_tests/"
diff --git a/infra/config/generated/builders/ci/android-10-x86-rel/targets/chromium.android.json b/infra/config/generated/builders/ci/android-10-x86-rel/targets/chromium.android.json index 2a23aaa5..2fa19bf8a 100644 --- a/infra/config/generated/builders/ci/android-10-x86-rel/targets/chromium.android.json +++ b/infra/config/generated/builders/ci/android-10-x86-rel/targets/chromium.android.json
@@ -848,7 +848,7 @@ } }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 75 + "shards": 103 }, "test": "chrome_public_test_apk", "test_id_prefix": "ninja://chrome/android:chrome_public_test_apk/"
diff --git a/infra/config/generated/builders/ci/linux-chromeos-rel/targets/chromium.chromiumos.json b/infra/config/generated/builders/ci/linux-chromeos-rel/targets/chromium.chromiumos.json index ac001db9..c55fca9 100644 --- a/infra/config/generated/builders/ci/linux-chromeos-rel/targets/chromium.chromiumos.json +++ b/infra/config/generated/builders/ci/linux-chromeos-rel/targets/chromium.chromiumos.json
@@ -1464,7 +1464,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 3 }, "test": "sync_integration_tests", "test_id_prefix": "ninja://chrome/test:sync_integration_tests/"
diff --git a/infra/config/generated/builders/try/android-10-x86-rel/targets/chromium.android.json b/infra/config/generated/builders/try/android-10-x86-rel/targets/chromium.android.json index 2a23aaa5..2fa19bf8a 100644 --- a/infra/config/generated/builders/try/android-10-x86-rel/targets/chromium.android.json +++ b/infra/config/generated/builders/try/android-10-x86-rel/targets/chromium.android.json
@@ -848,7 +848,7 @@ } }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 75 + "shards": 103 }, "test": "chrome_public_test_apk", "test_id_prefix": "ninja://chrome/android:chrome_public_test_apk/"
diff --git a/infra/config/generated/builders/try/android-x86-rel/targets/chromium.android.json b/infra/config/generated/builders/try/android-x86-rel/targets/chromium.android.json index 2a23aaa5..2fa19bf8a 100644 --- a/infra/config/generated/builders/try/android-x86-rel/targets/chromium.android.json +++ b/infra/config/generated/builders/try/android-x86-rel/targets/chromium.android.json
@@ -848,7 +848,7 @@ } }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 75 + "shards": 103 }, "test": "chrome_public_test_apk", "test_id_prefix": "ninja://chrome/android:chrome_public_test_apk/"
diff --git a/infra/config/generated/builders/try/linux-chromeos-rel/targets/chromium.chromiumos.json b/infra/config/generated/builders/try/linux-chromeos-rel/targets/chromium.chromiumos.json index ac001db9..c55fca9 100644 --- a/infra/config/generated/builders/try/linux-chromeos-rel/targets/chromium.chromiumos.json +++ b/infra/config/generated/builders/try/linux-chromeos-rel/targets/chromium.chromiumos.json
@@ -1464,7 +1464,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 2 + "shards": 3 }, "test": "sync_integration_tests", "test_id_prefix": "ninja://chrome/test:sync_integration_tests/"
diff --git a/infra/config/generated/builders/try/linux-dcheck-off-rel/targets/chromium.linux.json b/infra/config/generated/builders/try/linux-dcheck-off-rel/targets/chromium.linux.json index e081b7c..5a764f9 100644 --- a/infra/config/generated/builders/try/linux-dcheck-off-rel/targets/chromium.linux.json +++ b/infra/config/generated/builders/try/linux-dcheck-off-rel/targets/chromium.linux.json
@@ -1602,7 +1602,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 7 + "shards": 8 }, "test": "blink_web_tests", "test_id_prefix": "ninja://:blink_web_tests/"
diff --git a/infra/config/generated/builders/try/linux-full-remote-rel/targets/chromium.linux.json b/infra/config/generated/builders/try/linux-full-remote-rel/targets/chromium.linux.json index e081b7c..5a764f9 100644 --- a/infra/config/generated/builders/try/linux-full-remote-rel/targets/chromium.linux.json +++ b/infra/config/generated/builders/try/linux-full-remote-rel/targets/chromium.linux.json
@@ -1602,7 +1602,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 7 + "shards": 8 }, "test": "blink_web_tests", "test_id_prefix": "ninja://:blink_web_tests/"
diff --git a/infra/config/generated/builders/try/linux-rel-test-selection/targets/chromium.linux.json b/infra/config/generated/builders/try/linux-rel-test-selection/targets/chromium.linux.json index e081b7c..5a764f9 100644 --- a/infra/config/generated/builders/try/linux-rel-test-selection/targets/chromium.linux.json +++ b/infra/config/generated/builders/try/linux-rel-test-selection/targets/chromium.linux.json
@@ -1602,7 +1602,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 7 + "shards": 8 }, "test": "blink_web_tests", "test_id_prefix": "ninja://:blink_web_tests/"
diff --git a/infra/config/generated/builders/try/linux-rel/targets/chromium.linux.json b/infra/config/generated/builders/try/linux-rel/targets/chromium.linux.json index e081b7c..5a764f9 100644 --- a/infra/config/generated/builders/try/linux-rel/targets/chromium.linux.json +++ b/infra/config/generated/builders/try/linux-rel/targets/chromium.linux.json
@@ -1602,7 +1602,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 7 + "shards": 8 }, "test": "blink_web_tests", "test_id_prefix": "ninja://:blink_web_tests/"
diff --git a/infra/config/generated/builders/try/linux_chromium_asan_rel_ng/targets/chromium.memory.json b/infra/config/generated/builders/try/linux_chromium_asan_rel_ng/targets/chromium.memory.json index 2e774ecc..feea8bc 100644 --- a/infra/config/generated/builders/try/linux_chromium_asan_rel_ng/targets/chromium.memory.json +++ b/infra/config/generated/builders/try/linux_chromium_asan_rel_ng/targets/chromium.memory.json
@@ -1430,7 +1430,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 10 + "shards": 11 }, "test": "sync_integration_tests", "test_id_prefix": "ninja://chrome/test:sync_integration_tests/"
diff --git a/infra/config/generated/builders/try/linux_chromium_compile_rel_ng/targets/chromium.linux.json b/infra/config/generated/builders/try/linux_chromium_compile_rel_ng/targets/chromium.linux.json index 8bf3c7b..424ddc2 100644 --- a/infra/config/generated/builders/try/linux_chromium_compile_rel_ng/targets/chromium.linux.json +++ b/infra/config/generated/builders/try/linux_chromium_compile_rel_ng/targets/chromium.linux.json
@@ -1602,7 +1602,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 7 + "shards": 8 }, "test": "blink_web_tests", "test_id_prefix": "ninja://:blink_web_tests/"
diff --git a/infra/config/generated/builders/try/linux_chromium_tsan_rel_ng/targets/chromium.memory.json b/infra/config/generated/builders/try/linux_chromium_tsan_rel_ng/targets/chromium.memory.json index 6c585a8..3ee93153 100644 --- a/infra/config/generated/builders/try/linux_chromium_tsan_rel_ng/targets/chromium.memory.json +++ b/infra/config/generated/builders/try/linux_chromium_tsan_rel_ng/targets/chromium.memory.json
@@ -388,7 +388,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 5 }, "test": "components_unittests", "test_id_prefix": "ninja://components:components_unittests/"
diff --git a/infra/config/targets/autoshard_exceptions.json b/infra/config/targets/autoshard_exceptions.json index d849c01..3a44a06 100644 --- a/infra/config/targets/autoshard_exceptions.json +++ b/infra/config/targets/autoshard_exceptions.json
@@ -1,6 +1,10 @@ { "chromium.android": { "android-10-x86-rel": { + "chrome_public_test_apk": { + "shards": 103, + "try_builder": "android-x86-rel" + }, "webview_trichrome_cts_tests full_mode": { "shards": 3, "try_builder": "android-x86-rel" @@ -93,6 +97,10 @@ "shards": 9, "try_builder": "linux-chromeos-rel" }, + "sync_integration_tests": { + "shards": 3, + "try_builder": "linux-chromeos-rel" + }, "unit_tests": { "shards": 3, "try_builder": "linux-chromeos-rel" @@ -130,7 +138,7 @@ "chromium.linux": { "Linux Tests": { "blink_web_tests": { - "shards": 7, + "shards": 8, "try_builder": "linux-rel" }, "blink_wpt_tests": { @@ -178,7 +186,7 @@ "try_builder": "linux_chromium_asan_rel_ng" }, "sync_integration_tests": { - "shards": 10, + "shards": 11, "try_builder": "linux_chromium_asan_rel_ng" }, "unit_tests": { @@ -196,7 +204,7 @@ "try_builder": "linux_chromium_tsan_rel_ng" }, "components_unittests": { - "shards": 4, + "shards": 5, "try_builder": "linux_chromium_tsan_rel_ng" }, "content_browsertests": { @@ -261,4 +269,4 @@ } } } -} +} \ No newline at end of file
diff --git a/internal b/internal index 86a4a8a..1f6db40 160000 --- a/internal +++ b/internal
@@ -1 +1 @@ -Subproject commit 86a4a8afd51091e4227435859e44c9be53d99e77 +Subproject commit 1f6db40eb209591b24ffd779aea31c890eab5392
diff --git a/ios/chrome/app/application_delegate/BUILD.gn b/ios/chrome/app/application_delegate/BUILD.gn index e775faf..ec008cdf 100644 --- a/ios/chrome/app/application_delegate/BUILD.gn +++ b/ios/chrome/app/application_delegate/BUILD.gn
@@ -195,8 +195,10 @@ "//ios/chrome/browser/policy/model:policy_util", "//ios/chrome/browser/shared/coordinator/scene:scene_state_header", "//ios/chrome/browser/shared/model/url", + "//ios/chrome/browser/shared/model/url:constants", "//ios/chrome/browser/shared/public/features", "//ios/chrome/browser/url_loading/model:url_loading_params_header", + "//ios/components/webui:url_constants", "//url", ] }
diff --git a/ios/chrome/app/application_delegate/url_opener.mm b/ios/chrome/app/application_delegate/url_opener.mm index ce8025d..8aa156ae 100644 --- a/ios/chrome/app/application_delegate/url_opener.mm +++ b/ios/chrome/app/application_delegate/url_opener.mm
@@ -14,9 +14,11 @@ #import "ios/chrome/app/startup/chrome_app_startup_parameters.h" #import "ios/chrome/browser/policy/model/policy_util.h" #import "ios/chrome/browser/shared/coordinator/scene/connection_information.h" +#import "ios/chrome/browser/shared/model/url/chrome_url_constants.h" #import "ios/chrome/browser/shared/model/url/url_util.h" #import "ios/chrome/browser/shared/public/features/features.h" #import "ios/chrome/browser/url_loading/model/url_loading_params.h" +#import "ios/components/webui/web_ui_url_constants.h" #import "url/gurl.h" namespace { @@ -114,6 +116,12 @@ gurl = [params externalURL]; } UrlLoadParams urlLoadParams = UrlLoadParams::InNewTab(gurl, virtualURL); + if (gurl.scheme() == kChromeUIScheme && + gurl.host() == kChromeUIDinoHost) { + urlLoadParams.web_params.transition_type = + ui::PAGE_TRANSITION_AUTO_BOOKMARK; + } + BOOL dismissOmnibox = [params postOpeningAction] != FOCUS_OMNIBOX; if (base::FeatureList::IsEnabled(kChromeStartupParametersAsync)) {
diff --git a/ios/chrome/app/profile/identity_confirmation_profile_agent.mm b/ios/chrome/app/profile/identity_confirmation_profile_agent.mm index f082215..ccba481 100644 --- a/ios/chrome/app/profile/identity_confirmation_profile_agent.mm +++ b/ios/chrome/app/profile/identity_confirmation_profile_agent.mm
@@ -128,10 +128,9 @@ - (IdentityConfirmationSnackbarDecision) shouldShowIdentityConfirmationSnackbarWithBrowser:(Browser*)browser { ProfileIOS* profile = browser->GetProfile(); - AuthenticationService* authenticationService = - AuthenticationServiceFactory::GetForProfile(profile); - if (!authenticationService->HasPrimaryIdentity( - signin::ConsentLevel::kSignin)) { + signin::IdentityManager* identityManager = + IdentityManagerFactory::GetForProfile(profile); + if (!identityManager->HasPrimaryAccount(signin::ConsentLevel::kSignin)) { return IdentityConfirmationSnackbarDecision::kDontShowNoAccount; } @@ -141,6 +140,8 @@ return IdentityConfirmationSnackbarDecision::kDontShowSingleAccount; } + AuthenticationService* authenticationService = + AuthenticationServiceFactory::GetForProfile(profile); // For non-managed accounts, show the snackbar only on top of Bling Start. if (!authenticationService->HasPrimaryIdentityManaged( signin::ConsentLevel::kSignin) &&
diff --git a/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.mm b/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.mm index 4659ca4..dd041b0 100644 --- a/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.mm +++ b/ios/chrome/browser/browser_view/ui_bundled/browser_coordinator.mm
@@ -180,6 +180,7 @@ #import "ios/chrome/browser/reader_mode/model/reader_mode_browser_agent.h" #import "ios/chrome/browser/reader_mode/model/reader_mode_browser_agent_delegate.h" #import "ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.h" +#import "ios/chrome/browser/reader_mode/model/reader_mode_web_state_utils.h" #import "ios/chrome/browser/reading_list/model/reading_list_browser_agent.h" #import "ios/chrome/browser/reading_list/ui_bundled/reading_list_coordinator.h" #import "ios/chrome/browser/reading_list/ui_bundled/reading_list_coordinator_delegate.h" @@ -1921,8 +1922,10 @@ #pragma mark - ActivityServiceCommands - (void)stopAndStartSharingCoordinator { - SharingParams* params = - [[SharingParams alloc] initWithScenario:SharingScenario::TabShareButton]; + SharingScenario scenario = IsReaderModeActiveInWebState(self.activeWebState) + ? SharingScenario::ShareInReaderMode + : SharingScenario::TabShareButton; + SharingParams* params = [[SharingParams alloc] initWithScenario:scenario]; // Exit fullscreen if needed to make sure that share button is visible. _fullscreenController->ExitFullscreen(FullscreenExitReason::kForcedByCode);
diff --git a/ios/chrome/browser/context_menu/ui_bundled/context_menu_configuration_provider.mm b/ios/chrome/browser/context_menu/ui_bundled/context_menu_configuration_provider.mm index f049e09..3464fd9e 100644 --- a/ios/chrome/browser/context_menu/ui_bundled/context_menu_configuration_provider.mm +++ b/ios/chrome/browser/context_menu/ui_bundled/context_menu_configuration_provider.mm
@@ -30,6 +30,7 @@ #import "ios/chrome/browser/photos/model/photos_availability.h" #import "ios/chrome/browser/photos/model/photos_metrics.h" #import "ios/chrome/browser/policy/model/policy_util.h" +#import "ios/chrome/browser/reader_mode/model/reader_mode_content_tab_helper.h" #import "ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.h" #import "ios/chrome/browser/reading_list/model/reading_list_browser_agent.h" #import "ios/chrome/browser/search_engines/model/search_engines_util.h" @@ -249,9 +250,9 @@ NSMutableArray<UIMenuElement*>* menuElements = [[NSMutableArray alloc] init]; // TODO(crbug.com/40823789) add scenario for not a link and not an image. MenuScenarioHistogram menuScenario = - isImage && isLink ? kMenuScenarioHistogramContextMenuImageLink - : isImage ? kMenuScenarioHistogramContextMenuImage - : kMenuScenarioHistogramContextMenuLink; + [self getMenuScenarioHistogramWithWebState:webState + isImage:isImage + isLink:isLink]; NSString* menuTitle = nil; UIAction* showFullURL = nil; @@ -928,4 +929,32 @@ didOpenNewTabInBackgroundWithURL:URL]; } +- (MenuScenarioHistogram)getMenuScenarioHistogramWithWebState: + (web::WebState*)webState + isImage:(BOOL)isImage + isLink:(BOOL)isLink { + // Check that the Reader Mode web state implicitly checking that the content + // tab helper is attached. + ReaderModeContentTabHelper* readerModeContentTabHelper = + ReaderModeContentTabHelper::FromWebState(webState); + BOOL isReaderModeActive = readerModeContentTabHelper; + if (isReaderModeActive) { + if (isImage && isLink) { + return kMenuScenarioHistogramReaderModeContextMenuImageLink; + } else if (isImage) { + return kMenuScenarioHistogramReaderModeContextMenuImage; + } else { + return kMenuScenarioHistogramReaderModeContextMenuLink; + } + } else { + if (isImage && isLink) { + return kMenuScenarioHistogramContextMenuImageLink; + } else if (isImage) { + return kMenuScenarioHistogramContextMenuImage; + } else { + return kMenuScenarioHistogramContextMenuLink; + } + } +} + @end
diff --git a/ios/chrome/browser/context_menu/ui_bundled/context_menu_egtest.mm b/ios/chrome/browser/context_menu/ui_bundled/context_menu_egtest.mm index a366cde..ee4faa1f 100644 --- a/ios/chrome/browser/context_menu/ui_bundled/context_menu_egtest.mm +++ b/ios/chrome/browser/context_menu/ui_bundled/context_menu_egtest.mm
@@ -989,6 +989,8 @@ FLAKY_testOpenContextMenuFromReadingMode #endif - (void)testOpenContextMenuFromReadingMode { + [self setUpHistogramTester]; + const GURL initialURL = self.testServer->GetURL("/article.html"); [ChromeEarlGrey loadURL:initialURL]; [ChromeEarlGrey waitForPageToFinishLoading]; @@ -1005,19 +1007,9 @@ [ChromeEarlGrey waitForWebStateContainingElement:ElementSelectorToLongPressLink()]; + // Open the context menu and tap on an action. [ChromeEarlGreyUI longPressElementOnWebView:ElementSelectorToLongPressLink()]; - - // Make sure the context menu appeared. - [[EarlGrey selectElementWithMatcher:OpenLinkInNewTabButton()] - assertWithMatcher:grey_notNil()]; - - if ([ChromeEarlGrey isIPadIdiom]) { - // Tap the tools menu to dismiss the popover. - [[EarlGrey selectElementWithMatcher:chrome_test_util::ToolsMenuButton()] - performAction:grey_tap()]; - } - // Tap the drop shadow to dismiss the popover. - chrome_test_util::TapAtOffsetOf(nil, 0, CGVectorMake(0.5, 0.95)); + TapOnContextMenuButton(OpenLinkInNewTabButton()); // Make sure the context menu disappeared. ConditionBlock condition = ^{ @@ -1031,6 +1023,22 @@ GREYAssert(base::test::ios::WaitUntilConditionOrTimeout( base::test::ios::kWaitForUIElementTimeout, condition), @"Waiting for the context menu to disappear"); + + // Ensure that UMA was logged correctly. + NSError* error = [MetricsAppInterface + expectCount:1 + forBucket:36 // Number refering to MenuScenarioHistogram enum. + forHistogram:@"Mobile.ContextMenu.EntryPoints"]; + if (error) { + GREYFail([error description]); + } + error = [MetricsAppInterface + expectCount:1 + forBucket:0 // Number refering to MenuActionType enum. + forHistogram:@"Mobile.ContextMenu.ReaderModeLink.Actions"]; + if (error) { + GREYFail([error description]); + } } // Tests that the context menu is displayed for an image url in Reading mode. @@ -1044,6 +1052,8 @@ FLAKY_testContextMenuDisplayedOnImageForReadingMode #endif - (void)testContextMenuDisplayedOnImageForReadingMode { + [self setUpHistogramTester]; + const GURL pageURL = self.testServer->GetURL("/article.html"); [ChromeEarlGrey loadURL:pageURL]; [ChromeEarlGrey waitForPageToFinishLoading]; @@ -1069,6 +1079,22 @@ const GURL imageURL = self.testServer->GetURL(kLogoPageImageSourcePath); [[EarlGrey selectElementWithMatcher:OmniboxText(imageURL.GetContent())] assertWithMatcher:grey_notNil()]; + + // Ensure that UMA was logged correctly. + NSError* error = [MetricsAppInterface + expectCount:1 + forBucket:34 // Number refering to MenuScenarioHistogram enum. + forHistogram:@"Mobile.ContextMenu.EntryPoints"]; + if (error) { + GREYFail([error description]); + } + error = [MetricsAppInterface + expectCount:1 + forBucket:20 // Number refering to MenuActionType enum. + forHistogram:@"Mobile.ContextMenu.ReaderModeImage.Actions"]; + if (error) { + GREYFail([error description]); + } } @end
diff --git a/ios/chrome/browser/crash_report/model/crash_report_helper.mm b/ios/chrome/browser/crash_report/model/crash_report_helper.mm index 84f3e15b..8ca0c16 100644 --- a/ios/chrome/browser/crash_report/model/crash_report_helper.mm +++ b/ios/chrome/browser/crash_report/model/crash_report_helper.mm
@@ -6,6 +6,7 @@ #import <Foundation/Foundation.h> +#import "base/apple/foundation_util.h" #import "base/auto_reset.h" #import "base/debug/crash_logging.h" #import "base/files/file_path.h" @@ -27,6 +28,7 @@ #import "ios/web/public/navigation/navigation_context.h" #import "ios/web/public/thread/web_thread.h" #import "ios/web/public/web_state.h" +#import "ios/web/public/web_state_id.h" #import "ios/web/public/web_state_observer_bridge.h" #import "net/base/apple/url_conversions.h" @@ -34,9 +36,9 @@ @interface CrashReporterTabStateObserver : NSObject <CRWWebStateObserver, WebStateListObserving> { @private - // Map associating the tab id to an object describing the current state of the - // tab. - NSMutableDictionary* _tabCurrentStateByTabId; + // Map associating the tab WebStateID to an object describing the current + // state of the tab. + std::map<web::WebStateID, NSMutableDictionary*> _tabCurrentStateByTabId; // The WebStateObserverBridge used to register self as a WebStateObserver std::unique_ptr<web::WebStateObserverBridge> _webStateObserver; // Bridges C++ WebStateListObserver methods to this @@ -48,19 +50,21 @@ _allWebStateObservationForwarders; } + (CrashReporterTabStateObserver*)uniqueInstance; -// Removes the stats for the tab tabId -- (void)removeTabId:(NSString*)tabId; +// Removes the stats for the tab. +- (void)removeTab:(web::WebState*)tab; +// Removes the stats for the tab identified by tabId. +- (void)removeTabId:(web::WebStateID)tabId; // Removes document related information from tabCurrentStateByTabId_. -- (void)closingDocumentInTab:(NSString*)tabId; +- (void)closingDocumentInTab:(web::WebStateID)tabId; // Sets a tab `tabId` specific information with key `key` and value `value` in // tabCurrentStateByTabId_. - (void)setTabInfo:(NSString*)key - withValue:(const NSString*)value - forTab:(NSString*)tabId; + withValue:(NSString*)value + forTabId:(web::WebStateID)tabId; // Retrieves the `key` information for tab `tabID`. -- (id)tabInfo:(NSString*)key forTab:(NSString*)tabID; +- (id)tabInfo:(NSString*)key forTabId:(web::WebStateID)tabID; // Removes the `key` information for tab `tabId` -- (void)removeTabInfo:(NSString*)key forTab:(NSString*)tabId; +- (void)removeTabInfo:(NSString*)key forTabId:(web::WebStateID)tabId; // Observes `webState` by this instance of the CrashReporterTabStateObserver. - (void)observeWebState:(web::WebState*)webState; // Stop Observing `webState` by this instance of the @@ -76,7 +80,7 @@ namespace { // Mime type used for PDF documents. -const NSString* kDocumentMimeType = @"application/pdf"; +NSString* const kDocumentMimeType = @"application/pdf"; } // namespace @implementation CrashReporterTabStateObserver @@ -89,47 +93,62 @@ - (id)init { if ((self = [super init])) { - _tabCurrentStateByTabId = [[NSMutableDictionary alloc] init]; _webStateObserver = std::make_unique<web::WebStateObserverBridge>(self); _webStateListObserver = std::make_unique<WebStateListObserverBridge>(self); } return self; } -- (void)closingDocumentInTab:(NSString*)tabId { - NSString* mime = (NSString*)[self tabInfo:@"mime" forTab:tabId]; +- (void)closingDocumentInTab:(web::WebStateID)tabId { + NSString* mime = base::apple::ObjCCast<NSString>([self tabInfo:@"mime" + forTabId:tabId]); if ([kDocumentMimeType isEqualToString:mime]) { crash_keys::SetCurrentTabIsPDF(false); } - [self removeTabInfo:@"mime" forTab:tabId]; + [self removeTabInfo:@"mime" forTabId:tabId]; } - (void)setTabInfo:(NSString*)key - withValue:(const NSString*)value - forTab:(NSString*)tabId { - NSMutableDictionary* tabCurrentState = - [_tabCurrentStateByTabId objectForKey:tabId]; - if (tabCurrentState == nil) { - NSMutableDictionary* currentStateOfNewTab = - [[NSMutableDictionary alloc] init]; - [_tabCurrentStateByTabId setObject:currentStateOfNewTab forKey:tabId]; - tabCurrentState = [_tabCurrentStateByTabId objectForKey:tabId]; + withValue:(NSString*)value + forTabId:(web::WebStateID)tabId { + auto iter = _tabCurrentStateByTabId.find(tabId); + if (iter == _tabCurrentStateByTabId.end()) { + iter = + _tabCurrentStateByTabId + .insert(std::make_pair(tabId, [[NSMutableDictionary alloc] init])) + .first; } - [tabCurrentState setObject:value forKey:key]; + NSMutableDictionary* tabValues = iter->second; + [tabValues setObject:value forKey:key]; } -- (id)tabInfo:(NSString*)key forTab:(NSString*)tabID { - NSMutableDictionary* tabValues = [_tabCurrentStateByTabId objectForKey:tabID]; +- (id)tabInfo:(NSString*)key forTabId:(web::WebStateID)tabId { + auto iter = _tabCurrentStateByTabId.find(tabId); + if (iter == _tabCurrentStateByTabId.end()) { + return nil; + } + + NSMutableDictionary* tabValues = iter->second; return [tabValues objectForKey:key]; } -- (void)removeTabInfo:(NSString*)key forTab:(NSString*)tabId { - [[_tabCurrentStateByTabId objectForKey:tabId] removeObjectForKey:key]; +- (void)removeTabInfo:(NSString*)key forTabId:(web::WebStateID)tabId { + auto iter = _tabCurrentStateByTabId.find(tabId); + if (iter == _tabCurrentStateByTabId.end()) { + return; + } + + NSMutableDictionary* tabValues = iter->second; + [tabValues removeObjectForKey:key]; } -- (void)removeTabId:(NSString*)tabId { +- (void)removeTab:(web::WebState*)tab { + [self removeTabId:tab->GetUniqueIdentifier()]; +} + +- (void)removeTabId:(web::WebStateID)tabId { [self closingDocumentInTab:tabId]; - [_tabCurrentStateByTabId removeObjectForKey:tabId]; + _tabCurrentStateByTabId.erase(tabId); } - (void)observeWebState:(web::WebState*)webState { @@ -152,6 +171,8 @@ - (void)stopObservingWebStateList:(WebStateList*)webStateList { _allWebStateObservationForwarders[webStateList] = nullptr; + _allWebStateObservationForwarders.erase(webStateList); + webStateList->RemoveObserver(_webStateListObserver.get()); } @@ -167,8 +188,7 @@ case WebStateListChange::Type::kDetach: { const WebStateListChangeDetach& detachChange = change.As<WebStateListChangeDetach>(); - [self - removeTabId:detachChange.detached_web_state()->GetStableIdentifier()]; + [self removeTab:detachChange.detached_web_state()]; break; } case WebStateListChange::Type::kMove: @@ -177,8 +197,7 @@ case WebStateListChange::Type::kReplace: { const WebStateListChangeReplace& replaceChange = change.As<WebStateListChangeReplace>(); - [self removeTabId:replaceChange.replaced_web_state() - ->GetStableIdentifier()]; + [self removeTab:replaceChange.replaced_web_state()]; break; } case WebStateListChange::Type::kInsert: @@ -203,7 +222,7 @@ - (void)webState:(web::WebState*)webState didStartNavigation:(web::NavigationContext*)navigation { - [self closingDocumentInTab:webState->GetStableIdentifier()]; + [self closingDocumentInTab:webState->GetUniqueIdentifier()]; } - (void)webState:(web::WebState*)webState @@ -211,13 +230,14 @@ if (!loadSuccess || webState->GetContentsMimeType() != "application/pdf") { return; } - NSString* tabID = webState->GetStableIdentifier(); - NSString* oldMime = (NSString*)[self tabInfo:@"mime" forTab:tabID]; + web::WebStateID tabID = webState->GetUniqueIdentifier(); + NSString* oldMime = base::apple::ObjCCast<NSString>([self tabInfo:@"mime" + forTabId:tabID]); if ([kDocumentMimeType isEqualToString:oldMime]) { return; } - [self setTabInfo:@"mime" withValue:kDocumentMimeType forTab:tabID]; + [self setTabInfo:@"mime" withValue:kDocumentMimeType forTabId:tabID]; crash_keys::SetCurrentTabIsPDF(true); }
diff --git a/ios/chrome/browser/cross_platform_promos/model/cross_platform_promos_service_unittest.mm b/ios/chrome/browser/cross_platform_promos/model/cross_platform_promos_service_unittest.mm index 6023408..3423cdd7 100644 --- a/ios/chrome/browser/cross_platform_promos/model/cross_platform_promos_service_unittest.mm +++ b/ios/chrome/browser/cross_platform_promos/model/cross_platform_promos_service_unittest.mm
@@ -53,7 +53,9 @@ } // Tests that multiple app foregrounds doesn't add duplicate days. -TEST_F(CrossPlatformPromosServiceTest, RecordActiveDay_AddDuplicateDay) { +// TODO(crbug.com/444748798): Re-enable this test. +TEST_F(CrossPlatformPromosServiceTest, + DISABLED_RecordActiveDay_AddDuplicateDay) { base::Time now = task_environment_.GetMockClock()->Now(); base::Time tomorrow = (now + base::Days(1)).LocalMidnight(); task_environment_.FastForwardBy(tomorrow - now);
diff --git a/ios/chrome/browser/location_bar/ui_bundled/BUILD.gn b/ios/chrome/browser/location_bar/ui_bundled/BUILD.gn index 10b4e1fb..5669a78a 100644 --- a/ios/chrome/browser/location_bar/ui_bundled/BUILD.gn +++ b/ios/chrome/browser/location_bar/ui_bundled/BUILD.gn
@@ -86,6 +86,7 @@ "//ios/chrome/browser/overlays/model", "//ios/chrome/browser/overlays/model/public/web_content_area", "//ios/chrome/browser/reader_mode/coordinator:chip", + "//ios/chrome/browser/reader_mode/model", "//ios/chrome/browser/reader_mode/model:features", "//ios/chrome/browser/reader_mode/ui:chip", "//ios/chrome/browser/search_engines/model",
diff --git a/ios/chrome/browser/location_bar/ui_bundled/DEPS b/ios/chrome/browser/location_bar/ui_bundled/DEPS index 2957129..6b0c313c 100644 --- a/ios/chrome/browser/location_bar/ui_bundled/DEPS +++ b/ios/chrome/browser/location_bar/ui_bundled/DEPS
@@ -19,6 +19,7 @@ "+ios/chrome/browser/ntp/ui_bundled/new_tab_page_util.h", "+ios/chrome/browser/orchestrator/ui_bundled", "+ios/chrome/browser/overlays/model/public", + "+ios/chrome/browser/reader_mode/model/reader_mode_web_state_utils.h", "+ios/chrome/browser/reader_mode/ui/reader_mode_chip_visibility_delegate.h", "+ios/chrome/browser/reading_list/model/offline_page_tab_helper.h", "+ios/chrome/browser/search_engines/model",
diff --git a/ios/chrome/browser/location_bar/ui_bundled/location_bar_coordinator.mm b/ios/chrome/browser/location_bar/ui_bundled/location_bar_coordinator.mm index c59eeb4..e2bbe62da 100644 --- a/ios/chrome/browser/location_bar/ui_bundled/location_bar_coordinator.mm +++ b/ios/chrome/browser/location_bar/ui_bundled/location_bar_coordinator.mm
@@ -67,6 +67,7 @@ #import "ios/chrome/browser/overlays/model/public/overlay_presenter.h" #import "ios/chrome/browser/reader_mode/coordinator/reader_mode_chip_coordinator.h" #import "ios/chrome/browser/reader_mode/model/features.h" +#import "ios/chrome/browser/reader_mode/model/reader_mode_web_state_utils.h" #import "ios/chrome/browser/search_engines/model/template_url_service_factory.h" #import "ios/chrome/browser/shared/coordinator/layout_guide/layout_guide_util.h" #import "ios/chrome/browser/shared/model/browser/browser.h" @@ -649,10 +650,12 @@ const GURL visibleURL = self.webState->GetVisibleURL(); NSString* title = base::SysUTF16ToNSString(self.webState->GetTitle()); - SharingParams* params = - [[SharingParams alloc] initWithURL:visibleURL - title:title - scenario:SharingScenario::TabShareButton]; + SharingScenario scenario = IsReaderModeActiveInWebState(self.webState) + ? SharingScenario::ShareInReaderMode + : SharingScenario::TabShareButton; + SharingParams* params = [[SharingParams alloc] initWithURL:visibleURL + title:title + scenario:scenario]; _sharingCoordinator = [[SharingCoordinator alloc] initWithBaseViewController:self.viewController browser:self.browser
diff --git a/ios/chrome/browser/menu/ui_bundled/menu_histograms.h b/ios/chrome/browser/menu/ui_bundled/menu_histograms.h index 386a36b4..4ed246a4 100644 --- a/ios/chrome/browser/menu/ui_bundled/menu_histograms.h +++ b/ios/chrome/browser/menu/ui_bundled/menu_histograms.h
@@ -44,6 +44,9 @@ kMenuScenarioHistogramAutofillManualFallbackPlusAddressEntry = 31, kMenuScenarioHistogramTabGroupIndicatorNTPEntry = 32, kMenuScenarioHistogramLastVisitedHistoryEntry = 33, + kMenuScenarioHistogramReaderModeContextMenuImage = 34, + kMenuScenarioHistogramReaderModeContextMenuImageLink = 35, + kMenuScenarioHistogramReaderModeContextMenuLink = 36, kMenuScenarioHistogramCount, }; // LINT.ThenChange(/tools/metrics/histograms/metadata/mobile/enums.xml)
diff --git a/ios/chrome/browser/menu/ui_bundled/menu_histograms.mm b/ios/chrome/browser/menu/ui_bundled/menu_histograms.mm index d6637b2..2717b5d 100644 --- a/ios/chrome/browser/menu/ui_bundled/menu_histograms.mm +++ b/ios/chrome/browser/menu/ui_bundled/menu_histograms.mm
@@ -76,6 +76,12 @@ "Mobile.ContextMenu.TabGroupIndicatorNTPEntry.Actions"; const char kLastVisitedHistoryEntryActionsHistogram[] = "Mobile.ContextMenu.LastVisitedHistoryEntry.Actions"; +const char kContextMenuReaderModeImageActionsHistogram[] = + "Mobile.ContextMenu.ReaderModeImage.Actions"; +const char kContextMenuReaderModeImageLinkActionsHistogram[] = + "Mobile.ContextMenu.ReaderModeImageLink.Actions"; +const char kContextMenuReaderModeLinkActionsHistogram[] = + "Mobile.ContextMenu.ReaderModeLink.Actions"; // LINT.ThenChange(/tools/metrics/histograms/metadata/mobile/histograms.xml) } // namespace @@ -152,6 +158,12 @@ return kTabGroupIndicatorNTPEntryActionsHistogram; case kMenuScenarioHistogramLastVisitedHistoryEntry: return kLastVisitedHistoryEntryActionsHistogram; + case kMenuScenarioHistogramReaderModeContextMenuImage: + return kContextMenuReaderModeImageActionsHistogram; + case kMenuScenarioHistogramReaderModeContextMenuImageLink: + return kContextMenuReaderModeImageLinkActionsHistogram; + case kMenuScenarioHistogramReaderModeContextMenuLink: + return kContextMenuReaderModeLinkActionsHistogram; case kMenuScenarioHistogramCount: NOTREACHED(); }
diff --git a/ios/chrome/browser/reader_mode/model/BUILD.gn b/ios/chrome/browser/reader_mode/model/BUILD.gn index 185eef2..3a86da2 100644 --- a/ios/chrome/browser/reader_mode/model/BUILD.gn +++ b/ios/chrome/browser/reader_mode/model/BUILD.gn
@@ -35,6 +35,8 @@ "reader_mode_tab_helper.mm", "reader_mode_web_state_delegate.h", "reader_mode_web_state_delegate.mm", + "reader_mode_web_state_utils.h", + "reader_mode_web_state_utils.mm", ] deps = [ ":constants",
diff --git a/ios/chrome/browser/reader_mode/model/reader_mode_web_state_utils.h b/ios/chrome/browser/reader_mode/model/reader_mode_web_state_utils.h new file mode 100644 index 0000000..e6e8afa --- /dev/null +++ b/ios/chrome/browser/reader_mode/model/reader_mode_web_state_utils.h
@@ -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. + +#ifndef IOS_CHROME_BROWSER_READER_MODE_MODEL_READER_MODE_WEB_STATE_UTILS_H_ +#define IOS_CHROME_BROWSER_READER_MODE_MODEL_READER_MODE_WEB_STATE_UTILS_H_ + +namespace web { +class WebState; +} + +// Returns whether there is an active Reader mode attached to the given +// `web_state`. +bool IsReaderModeActiveInWebState(web::WebState* web_state); + +#endif // IOS_CHROME_BROWSER_READER_MODE_MODEL_READER_MODE_WEB_STATE_UTILS_H_
diff --git a/ios/chrome/browser/reader_mode/model/reader_mode_web_state_utils.mm b/ios/chrome/browser/reader_mode/model/reader_mode_web_state_utils.mm new file mode 100644 index 0000000..7f4788ed --- /dev/null +++ b/ios/chrome/browser/reader_mode/model/reader_mode_web_state_utils.mm
@@ -0,0 +1,22 @@ +// 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. + +#import "ios/chrome/browser/reader_mode/model/reader_mode_web_state_utils.h" + +#import "ios/chrome/browser/reader_mode/model/features.h" +#import "ios/chrome/browser/reader_mode/model/reader_mode_tab_helper.h" +#import "ios/web/public/web_state.h" + +bool IsReaderModeActiveInWebState(web::WebState* web_state) { + if (!IsReaderModeAvailable() || !web_state) { + return false; + } + ReaderModeTabHelper* tab_helper = + ReaderModeTabHelper::FromWebState(web_state); + if (tab_helper) { + return tab_helper->IsActive(); + } + + return false; +}
diff --git a/ios/chrome/browser/reader_mode/ui/BUILD.gn b/ios/chrome/browser/reader_mode/ui/BUILD.gn index a5cc51d..b6da8de5f 100644 --- a/ios/chrome/browser/reader_mode/ui/BUILD.gn +++ b/ios/chrome/browser/reader_mode/ui/BUILD.gn
@@ -85,6 +85,7 @@ "//ios/chrome/browser/badges/ui_bundled:public", "//ios/chrome/browser/intelligence/features", "//ios/chrome/browser/intelligence/page_action_menu/utils", + "//ios/chrome/browser/metrics/model:eg_test_support+eg2", "//ios/chrome/browser/popup_menu/ui_bundled:constants", "//ios/chrome/browser/reader_mode/model:constants", "//ios/chrome/browser/reader_mode/model:features",
diff --git a/ios/chrome/browser/reader_mode/ui/reader_mode_egtest.mm b/ios/chrome/browser/reader_mode/ui/reader_mode_egtest.mm index aedf7ac4..a974e7a 100644 --- a/ios/chrome/browser/reader_mode/ui/reader_mode_egtest.mm +++ b/ios/chrome/browser/reader_mode/ui/reader_mode_egtest.mm
@@ -14,6 +14,7 @@ #import "ios/chrome/browser/badges/ui_bundled/badge_constants.h" #import "ios/chrome/browser/intelligence/features/features.h" #import "ios/chrome/browser/intelligence/page_action_menu/utils/ai_hub_constants.h" +#import "ios/chrome/browser/metrics/model/metrics_app_interface.h" #import "ios/chrome/browser/popup_menu/ui_bundled/popup_menu_constants.h" #import "ios/chrome/browser/reader_mode/model/constants.h" #import "ios/chrome/browser/reader_mode/model/features.h" @@ -112,6 +113,9 @@ net::test_server::RegisterDefaultHandlers(self.testServer); GREYAssertTrue(self.testServer->Start(), @"Server did not start."); + chrome_test_util::GREYAssertErrorNil( + [MetricsAppInterface setupHistogramTester]); + self.fakeIdentity = [FakeSystemIdentity fakeIdentity1]; [SigninEarlGrey addFakeIdentity:self.fakeIdentity withCapabilities:@{ @@ -121,6 +125,8 @@ } - (void)tearDownHelper { + chrome_test_util::GREYAssertErrorNil( + [MetricsAppInterface releaseHistogramTester]); [ChromeEarlGrey clearUserPrefWithName:translate::prefs::kOfferTranslateEnabled]; [ChromeEarlGrey clearUserPrefWithName:prefs::kIOSBwgConsent]; @@ -1258,4 +1264,47 @@ grey_not(grey_accessibilityTrait(UIAccessibilityTraitNotEnabled))]; } +// Tests that the share menu is accessible via Reader Mode and records the +// expected metrics. +- (void)testShareMenuInReaderMode { +#if !TARGET_OS_SIMULATOR + EARL_GREY_TEST_DISABLED(@"Test disabled on device."); +#endif + [ChromeEarlGrey loadURL:self.testServer->GetURL("/article.html")]; + [ChromeEarlGrey waitForPageToFinishLoading]; + + // Open Reader Mode UI. + GREYAssertTrue( + [ChromeEarlGrey showReaderModeAndWaitUntilReaderModeWebStateIsReady], + @"Reader mode content could not be loaded"); + [ChromeEarlGrey + waitForSufficientlyVisibleElementWithMatcher: + grey_accessibilityID(kReaderModeChipViewAccessibilityIdentifier)]; + + [ChromeEarlGreyUI openShareMenu]; + + // Verify that the share menu is up and select the Copy action. + [ChromeEarlGrey verifyActivitySheetVisible]; + [ChromeEarlGrey tapButtonInActivitySheetWithID:@"Copy"]; + [ChromeEarlGrey verifyActivitySheetNotVisible]; + + // Ensure that UMA was logged correctly. + NSError* error = + [MetricsAppInterface expectCount:1 + forBucket:14 // Number refering to + // SharingScenario::ShareInReaderMode + forHistogram:@"Mobile.Share.EntryPoints"]; + if (error) { + GREYFail([error description]); + } + + error = [MetricsAppInterface + expectCount:1 + forBucket:3 // Number refering to ShareActionType::Copy + forHistogram:@"Mobile.Share.ShareInReaderMode.Actions"]; + if (error) { + GREYFail([error description]); + } +} + @end
diff --git a/ios/chrome/browser/sharing/ui_bundled/activity_services/activity_service_histograms.mm b/ios/chrome/browser/sharing/ui_bundled/activity_services/activity_service_histograms.mm index b4ff41da..70a1b54 100644 --- a/ios/chrome/browser/sharing/ui_bundled/activity_services/activity_service_histograms.mm +++ b/ios/chrome/browser/sharing/ui_bundled/activity_services/activity_service_histograms.mm
@@ -40,6 +40,7 @@ "Mobile.Share.TabStripItem.Actions"; const char kShareInWebContextMenu[] = "Mobile.Share.ShareInWebContextMenu.Actions"; +const char kShareInReaderMode[] = "Mobile.Share.ShareInReaderMode.Actions"; // Enum representing an aggregation of the `ActivityType` enum values in a way // that is relevant for metric collection. Current values should not @@ -196,6 +197,9 @@ case SharingScenario::ShareInWebContextMenu: histogramName = kShareInWebContextMenu; break; + case SharingScenario::ShareInReaderMode: + histogramName = kShareInReaderMode; + break; } base::UmaHistogramEnumeration(histogramName, actionType); }
diff --git a/ios/chrome/browser/sharing/ui_bundled/sharing_scenario.h b/ios/chrome/browser/sharing/ui_bundled/sharing_scenario.h index b2c6e3d..54b9611 100644 --- a/ios/chrome/browser/sharing/ui_bundled/sharing_scenario.h +++ b/ios/chrome/browser/sharing/ui_bundled/sharing_scenario.h
@@ -24,8 +24,9 @@ OmniboxMostVisitedEntry = 11, TabStripItem = 12, ShareInWebContextMenu = 13, + ShareInReaderMode = 14, // Highest enumerator. Recommended by Histogram metrics best practices. - kMaxValue = ShareInWebContextMenu + kMaxValue = ShareInReaderMode }; // LINT.ThenChange(/tools/metrics/histograms/metadata/mobile/enums.xml)
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 88ec51f..3e3b64f 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 @@ -e0b8803552bbd29889e2dc94d3196d8bf80c5d7f \ No newline at end of file +88625b440897998a98a4c7c25f3bd7e187d315a9 \ 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 470dd4c..bcea6a8b 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 @@ -f70c1a24776a0c574d2e48daadad9f0020ad2941 \ No newline at end of file +4335d068ebb9f3173dcf49bc3cc6634c03686f29 \ 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 916d07a..c598049b 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 @@ -4a7ebf090872f97c72c0917190d74399928f8d66 \ No newline at end of file +f76fa4fbb3d7a9f2152f0a8c9f6b0249e6b04f80 \ 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 a4e2b7e..bde096d 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 @@ -4f60970cba703890d5b4e2031d018ff34ec64226 \ No newline at end of file +83c4db3812800c68842ce92731403df99fccb33b \ 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 8a1ac15e..59692a9 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 @@ -df63794d9a8cbcd076f734b3457f73c4f8fdcfad \ No newline at end of file +c11f08c327c0e9a856f7d842ee8f06874743fe61 \ 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 b1811db9..4eb9d7e 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 @@ -ac964b254a3597048d23d2a2e568c34c02777601 \ No newline at end of file +f158db165755a0b21c2891d5a4f32ded1dd96441 \ 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 0403f45..7a39625 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 @@ -771d0b033ed86db9c9910db43780f0df2502bb0d \ No newline at end of file +a62a50f3be4ad0677078f148f2994bc9f380d5f5 \ 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 5ca79bd..de093ed 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 @@ -d050fa7af6af6955a6a9a89d468646d7258dc353 \ No newline at end of file +c6b1945009779b7bbc15ab8ca177ec84f9ed7fc9 \ 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 0e64ff1..8b1b34c 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 @@ -6fd3d505249c62cea6e34e4c468318da8bfbde09 \ No newline at end of file +edb9b204fe47b89e900d3b9e9c9f7c0c9a41860d \ 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 174096c1..03d1facb 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 @@ -e14c82d2dd602a439f63ee93b9b0a61c4f87553d \ No newline at end of file +26801e11a91b5f24b95c41ed8439f2a4e9939f67 \ 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 3617cbc3..63c2d3987 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 @@ -506bb564e4af6b0134e2fd34f6463dd3e472a79a \ No newline at end of file +67fd3026553beb925c02749517acf1144c239e46 \ 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 17ae93c..0e204d00 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 @@ -dd84fb9abcba82dc6751812cce3874d07fa8de25 \ No newline at end of file +4736a66d86512c0fb3f7db2c6090193020aeca68 \ 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 ee8b0a7..d190fb9 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 @@ -860482b84734848a1a35f141099018651aaa2c55 \ No newline at end of file +bdfcdd9e11bc9d44c70b5070756c2131bf208986 \ 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 fc4f949..bbc2838 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 @@ -74394082af3b0ebcd4db66044352809340a4258a \ No newline at end of file +8a6b38cc0614cc4ad0cabc249f126e505449708d \ 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 3f04784a..6a28d3d 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 @@ -85440747bcd8f9e3ac6cd25e8ee253c7305b2e14 \ No newline at end of file +2fbb511f9943f3f486021b77746eb7b0fb047272 \ 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 18d5b93..c7b06e6 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 @@ -f9a645315929f1e91fbb6e391ec81a78086f412a \ No newline at end of file +a1f7fb7b2cbd471c059d6bfad0cda83a85fe36c4 \ 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 2ff31702..e7d3508 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 @@ -d718ddca2d3f856c1e9a49b395cf60a73578df84 \ No newline at end of file +1c762d61e5139131ef0c7cc08fcc29f04963250b \ 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 ea599c0..96e5c8a0 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 @@ -646675bee7d458696b02edb0c7b285566a8dd6d5 \ No newline at end of file +f582141ed718e63830374f87d231580f954b904b \ 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 162e7a9c..017d44d 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 @@ -67c7bd211ed4ae796a0e15b898d5aa097b1d5abc \ No newline at end of file +a74d5e1584c3a0ec97a27cd19d45e3acee0cb340 \ 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 8109c607..c5e7e450 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 @@ -c13ad0e09f141b141d5f95ab5c933ace25cf3440 \ No newline at end of file +da53b6a05ce7e473e06055f599dba878d1f81f94 \ 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 f26c101..b2db31d 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 @@ -1e85650e9268726f203d9b437f7cae22db664aad \ No newline at end of file +0622511f1ef29132f69bb6f489293ba16eb2561e \ 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 ce17afa5..5b8e8cad 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 @@ -a6424edd69888b01b4f8debf4d17083afcc5a002 \ No newline at end of file +f917854f3f14d9016c83e9d8f403adddca5623b6 \ 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 f9be70312..b422e4b9 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 @@ -7e86871b48d68205c41bc692aa783151c8e6aaa4 \ No newline at end of file +4d90ec8ea474639d559ca59c990edd9686c945a5 \ 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 3542ccc2..8ee93ee8 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 @@ -c9036428eec5dd8004f06c4169b427c0f34fca03 \ No newline at end of file +62632bb101f3a5dc205159ac739444f80b8374d1 \ 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 74fa3fbd..09843a7b 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 @@ -c0fdce7aecce877c2c42254ed04faf1ff21b6610 \ No newline at end of file +d5e1ff842af108fcbbc06c5d2574f16f7fadecab \ 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 27e3200..8476f57 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 @@ -ea0d1a3ccc2daf09541216b39949f9c7b507b06f \ No newline at end of file +00001b23249564cff3e91688c84e497b60c1179d \ 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 49d1bf3..5a5899a 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 @@ -524ef23df8e92e6731729d3a323da92538c2c543 \ No newline at end of file +586139f875c47da490fcfcebde6f5f873a715f50 \ 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 8503819..50ff9ca 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 @@ -e80a1b5ab15b5bb3ca2c649bed3ae041bf9c39d4 \ No newline at end of file +18c315f04bdb4c91b1b0435be652d1f36f87aa37 \ No newline at end of file
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn index 28d182c..dc0fdefd 100644 --- a/ios/web_view/BUILD.gn +++ b/ios/web_view/BUILD.gn
@@ -36,30 +36,6 @@ deps = [ "//ios/web_view/test:ios_web_view_unittests" ] } -# Target used to avoid breaking internal builders. Will be removed when all -# references to the old target label has been fixed. -group("web_view") { - public_deps = [ "//ios/web_view/framework:web_view" ] -} - -# Target used to avoid breaking internal builders. Will be removed when all -# references to the old target label has been fixed. -group("web_view+link") { - public_deps = [ "//ios/web_view/framework:web_view+link" ] -} - -# Target used to avoid breaking internal builders. Will be removed when all -# references to the old target label has been fixed. -group("web_view+bundle") { - public_deps = [ "//ios/web_view/framework:web_view+bundle" ] -} - -# Target used to avoid breaking internal builders. Will be removed when all -# references to the old target label has been fixed. -group("web_view_sources") { - public_deps = [ "//ios/web_view/framework:web_view_sources" ] -} - _package_dir = "$root_out_dir/ios_web_view" action("ios_web_view_generate_license") {
diff --git a/ios/web_view/shell/BUILD.gn b/ios/web_view/shell/BUILD.gn index afc1ad0..67336a6 100644 --- a/ios/web_view/shell/BUILD.gn +++ b/ios/web_view/shell/BUILD.gn
@@ -41,7 +41,7 @@ deps = [ ":shell" ] bundle_deps = [ - "//ios/web_view:web_view+bundle", + "//ios/web_view/framework:web_view+bundle", "//ios/web_view/shell/resources", "//ios/web_view/shell/resources:launchscreen", ] @@ -52,7 +52,7 @@ source_set("shell_auth_service_interface") { sources = [ "shell_auth_service.h" ] - deps = [ "//ios/web_view:web_view+link" ] + deps = [ "//ios/web_view/framework:web_view+link" ] } source_set("shell_auth_service_fake_impl") { @@ -60,14 +60,14 @@ deps = [ ":shell_auth_service_interface", - "//ios/web_view:web_view+link", + "//ios/web_view/framework:web_view+link", ] } source_set("shell_risk_data_loader_interface") { sources = [ "shell_risk_data_loader.h" ] - deps = [ "//ios/web_view:web_view+link" ] + deps = [ "//ios/web_view/framework:web_view+link" ] } source_set("shell_risk_data_loader_fake_impl") { @@ -75,7 +75,7 @@ deps = [ ":shell_risk_data_loader_interface", - "//ios/web_view:web_view+link", + "//ios/web_view/framework:web_view+link", ] } @@ -84,7 +84,7 @@ deps = [ ":shell_auth_service_interface", - "//ios/web_view:web_view+link", + "//ios/web_view/framework:web_view+link", ] } @@ -93,7 +93,7 @@ deps = [ ":shell_trusted_vault_provider_interface", - "//ios/web_view:web_view+link", + "//ios/web_view/framework:web_view+link", ] } @@ -116,7 +116,7 @@ ":shell_trusted_vault_provider_interface", "//base", "//ios/third_party/webkit", - "//ios/web_view:web_view+link", + "//ios/web_view/framework:web_view+link", ios_web_view_shell_auth_service, ios_web_view_shell_risk_data_loader, ios_web_view_shell_trusted_vault_provider,
diff --git a/ios/web_view/test/BUILD.gn b/ios/web_view/test/BUILD.gn index 38944fa..263fbde 100644 --- a/ios/web_view/test/BUILD.gn +++ b/ios/web_view/test/BUILD.gn
@@ -38,7 +38,7 @@ "//components/variations:test_support", "//ios/third_party/webkit", "//ios/web/common:uikit", - "//ios/web_view:web_view+link", + "//ios/web_view/framework:web_view+link", "//net", "//net:test_support", "//testing/gtest", @@ -155,7 +155,7 @@ "//ios/web/public/security", "//ios/web/public/test", "//ios/web/public/test:test_fixture", - "//ios/web_view:web_view_sources", + "//ios/web_view/framework:web_view_sources", "//net:test_support", "//testing/gtest", "//third_party/ocmock", @@ -169,7 +169,7 @@ deps = [ ":inttests" ] - bundle_deps = [ "//ios/web_view:web_view+bundle" ] + bundle_deps = [ "//ios/web_view/framework:web_view+bundle" ] assert_no_deps = ios_assert_no_deps }
diff --git a/ios_internal b/ios_internal index 9a03b3e..81bfcfd 160000 --- a/ios_internal +++ b/ios_internal
@@ -1 +1 @@ -Subproject commit 9a03b3ecb0093146ef15ae88856b4a5663c9d119 +Subproject commit 81bfcfd0e372697e9f8107b3a59db56caef28472
diff --git a/media/audio/mac/audio_manager_mac.cc b/media/audio/mac/audio_manager_mac.cc index 83c41567..4063229 100644 --- a/media/audio/mac/audio_manager_mac.cc +++ b/media/audio/mac/audio_manager_mac.cc
@@ -474,6 +474,9 @@ return true; } +// TODO(crbug.com/447640763): Remove after M145 if nothing explodes. +BASE_FEATURE(kAudioPowerMonitoring, base::FEATURE_DISABLED_BY_DEFAULT); + class AudioManagerMac::AudioPowerObserver : public base::PowerSuspendObserver { public: AudioPowerObserver() @@ -509,6 +512,10 @@ bool ShouldDeferStreamStart() const { DCHECK(thread_checker_.CalledOnValidThread()); + if (!base::FeatureList::IsEnabled(kAudioPowerMonitoring)) { + return false; + } + // Start() should be deferred if the system is in the middle of a suspend or // has recently started the process of resuming. return is_suspending_ || base::TimeTicks::Now() < earliest_start_time_;
diff --git a/net/base/features.cc b/net/base/features.cc index 5bb545d37..1f032ee 100644 --- a/net/base/features.cc +++ b/net/base/features.cc
@@ -731,12 +731,12 @@ "SocketPoolSizePerTopLevelSiteTrialWebSocketProfileLimit", 256); -BASE_FEATURE(kNetTaskScheduler, base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kNetTaskScheduler, base::FEATURE_ENABLED_BY_DEFAULT); BASE_FEATURE_PARAM(bool, kNetTaskSchedulerHttpProxyConnectJob, &kNetTaskScheduler, "http_proxy_connect_job", - false); + true); BASE_FEATURE_PARAM(bool, kNetTaskSchedulerHttpCache, &kNetTaskScheduler, @@ -751,32 +751,32 @@ kNetTaskSchedulerHttpStreamFactoryJob, &kNetTaskScheduler, "http_stream_factory_job", - false); + true); BASE_FEATURE_PARAM(bool, kNetTaskSchedulerHttpStreamFactoryJobController, &kNetTaskScheduler, "http_stream_factory_job_controller", - false); + true); BASE_FEATURE_PARAM(bool, kNetTaskSchedulerURLRequestErrorJob, &kNetTaskScheduler, "url_request_error_job", - false); + true); BASE_FEATURE_PARAM(bool, kNetTaskSchedulerURLRequestHttpJob, &kNetTaskScheduler, "url_request_http_job", - false); + true); BASE_FEATURE_PARAM(bool, kNetTaskSchedulerURLRequestJob, &kNetTaskScheduler, "url_request_job", - false); + true); BASE_FEATURE_PARAM(bool, kNetTaskSchedulerURLRequestRedirectJob, &kNetTaskScheduler, "url_request_redirect_job", - false); + true); BASE_FEATURE(kAdditionalDelayMainJob, base::FEATURE_DISABLED_BY_DEFAULT); BASE_FEATURE_PARAM(base::TimeDelta,
diff --git a/net/http/http_stream_pool.h b/net/http/http_stream_pool.h index 7ad9c96..ac2868b 100644 --- a/net/http/http_stream_pool.h +++ b/net/http/http_stream_pool.h
@@ -101,13 +101,17 @@ static constexpr base::TimeDelta kDefaultConnectionAttemptDelay = base::Milliseconds(250); + // Sets of protocols for use in allowed ALPN fields of several classes. + // kProtoUnknown is not used, as it's an alias for all protocols, so causes + // issues when excluding one or more protocols. + static inline constexpr NextProtoSet kAllProtocols = { + NextProto::kProtoHTTP11, NextProto::kProtoHTTP2, NextProto::kProtoQUIC}; static inline constexpr NextProtoSet kTcpBasedProtocols = { - NextProto::kProtoUnknown, NextProto::kProtoHTTP11, - NextProto::kProtoHTTP2}; + NextProto::kProtoHTTP11, NextProto::kProtoHTTP2}; static inline constexpr NextProtoSet kHttp11Protocols = { - NextProto::kProtoUnknown, NextProto::kProtoHTTP11}; + NextProto::kProtoHTTP11}; static inline constexpr NextProtoSet kQuicBasedProtocols = { - NextProto::kProtoUnknown, NextProto::kProtoQUIC}; + NextProto::kProtoQUIC}; // Reasons for closing streams. static constexpr std::string_view kIpAddressChanged = "IP address changed";
diff --git a/net/http/http_stream_pool_attempt_manager.cc b/net/http/http_stream_pool_attempt_manager.cc index 71f8aa4..6519d0e5 100644 --- a/net/http/http_stream_pool_attempt_manager.cc +++ b/net/http/http_stream_pool_attempt_manager.cc
@@ -80,10 +80,17 @@ return dict; } -NextProtoSet AllNextProtosButQuic() { - NextProtoSet out = NextProtoSet::All(); - out.RemoveAll(HttpStreamPool::kQuicBasedProtocols); - return out; +// Converts a NextProtoSet containing allowed ALPNs to a value usable in NetLog +// events - currently a std::string, though could make it a Value::List instead. +std::string AllowedAlpnsToValue(const NextProtoSet& allowed_alpns) { + std::string list; + for (const auto proto : allowed_alpns) { + if (!list.empty()) { + list.append(","); + } + list.append(NextProtoToString(proto)); + } + return list; } } // namespace @@ -157,11 +164,13 @@ // This must be before the GetTcpBasedAttemptDelay() call, since it needs // to know that QUIC is not allowed, or it will try to create an invalid // QUIC destination and trigger a CHECK. - allowed_alpns_(UsingTls() ? NextProtoSet::All() : AllNextProtosButQuic()), + allowed_alpns_(UsingTls() ? kAllProtocols : kTcpBasedProtocols), request_jobs_(NUM_PRIORITIES), tcp_based_attempt_delay_(GetTcpBasedAttemptDelay()), should_block_tcp_based_attempt_(!tcp_based_attempt_delay_.is_zero()) { CHECK(group_); + // Since this is only one of two fixed values, seems not worth CHECKing. + DCHECK(!allowed_alpns_.Has(NextProto::kProtoUnknown)); TRACE_EVENT_BEGIN("net.stream", "AttemptManager::AttemptManager", track_, "destination", stream_key().destination().Serialize()); @@ -235,8 +244,7 @@ dict.Set("allowed_bad_certs", std::move(allowed_bad_certs_list)); dict.Set("enable_ip_based_pooling_for_h2", job->enable_ip_based_pooling_for_h2()); - dict.Set("enable_alternative_services", - job->enable_alternative_services()); + dict.Set("allowed_alpns", AllowedAlpnsToValue(job->allowed_alpns())); dict.Set("quic_version", quic::ParsedQuicVersionToString(job->quic_version())); job->net_log().source().AddToEventParameters(dict); @@ -529,7 +537,6 @@ preconnect_jobs_.erase(job); limit_ignoring_jobs_.erase(job); ip_based_pooling_disabling_jobs_.erase(job); - alternative_service_disabling_jobs_.erase(job); auto notified_it = notified_jobs_.find(job); if (notified_it != notified_jobs_.end()) { @@ -965,7 +972,7 @@ dict.Set("num_slow_attempts", static_cast<int>(slow_tcp_based_attempt_count_)); dict.Set("enable_ip_based_pooling_for_h2", IsIpBasedPoolingEnabledForH2()); - dict.Set("enable_alternative_services", IsAlternativeServiceEnabled()); + dict.Set("allowed_alpns", AllowedAlpnsToValue(allowed_alpns_)); dict.Set("quic_attempt_alive", !!quic_attempt_); if (quic_attempt_result_.has_value()) { dict.Set("quic_attempt_result", *quic_attempt_result_); @@ -1013,10 +1020,6 @@ ip_based_pooling_disabling_jobs_.emplace(job); } - if (!job->enable_alternative_services()) { - alternative_service_disabling_jobs_.emplace(job); - } - quic_version_ = job->quic_version(); RestrictAllowedProtocols(job->allowed_alpns()); @@ -1072,6 +1075,8 @@ void HttpStreamPool::AttemptManager::RestrictAllowedProtocols( NextProtoSet allowed_alpns) { + CHECK(!allowed_alpns.Has(NextProto::kProtoUnknown)); + allowed_alpns_ = base::Intersection(allowed_alpns_, allowed_alpns); CHECK(!allowed_alpns_.empty()); @@ -1437,10 +1442,6 @@ return ip_based_pooling_disabling_jobs_.empty(); } -bool HttpStreamPool::AttemptManager::IsAlternativeServiceEnabled() const { - return alternative_service_disabling_jobs_.empty(); -} - bool HttpStreamPool::AttemptManager::SupportsSpdy() const { return http_network_session()->http_server_properties()->GetSupportsSpdy( stream_key().destination(), stream_key().network_anonymization_key()); @@ -2092,7 +2093,6 @@ CHECK(limit_ignoring_jobs_.empty()); CHECK(ip_based_pooling_disabling_jobs_.empty()); - CHECK(alternative_service_disabling_jobs_.empty()); if (on_complete_callback_for_testing_) { base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
diff --git a/net/http/http_stream_pool_attempt_manager.h b/net/http/http_stream_pool_attempt_manager.h index 121ce7b..befa945 100644 --- a/net/http/http_stream_pool_attempt_manager.h +++ b/net/http/http_stream_pool_attempt_manager.h
@@ -145,8 +145,6 @@ return dns_resolution_end_time_; } - NextProtoSet allowed_alpns() const { return allowed_alpns_; } - const NetLogWithSource& net_log(); // Starts `job` for a stream request. Will call one of Job::Delegate methods @@ -371,9 +369,6 @@ // HTTP/2. Note that this does nothing with QUIC. bool IsIpBasedPoolingEnabledForH2() const; - // Returns true only when there are no jobs that disable alternative services. - bool IsAlternativeServiceEnabled() const; - // Returns true when the destination is known to support HTTP/2. Note that // this could return false while initializing HttpServerProperties. bool SupportsSpdy() const; @@ -517,6 +512,9 @@ // attempt for the first time. std::optional<InitialAttemptState> initial_attempt_state_; + // List of allowed protocols. Excludes protocols when, e.g., one protocol or + // another is marked as broken or is disabled for one or more jobs. Never + // includes NextProto::kProtoUnknown, since that's an alias for any protocol. NextProtoSet allowed_alpns_; // Holds request jobs that are waiting for notifications. @@ -531,8 +529,6 @@ base::flat_set<raw_ptr<Job>> ip_based_pooling_disabling_jobs_; - base::flat_set<raw_ptr<Job>> alternative_service_disabling_jobs_; - std::unique_ptr<HostResolver::ServiceEndpointRequest> service_endpoint_request_; bool service_endpoint_request_finished_ = false;
diff --git a/net/http/http_stream_pool_job.cc b/net/http/http_stream_pool_job.cc index 2b9ae5fa..605207f 100644 --- a/net/http/http_stream_pool_job.cc +++ b/net/http/http_stream_pool_job.cc
@@ -44,7 +44,7 @@ } NextProtoSet allowed_alpns = expected_protocol == NextProto::kProtoUnknown - ? NextProtoSet::All() + ? HttpStreamPool::kAllProtocols : NextProtoSet({expected_protocol}); allowed_alpns = Intersection(allowed_alpns, delegate->allowed_alpns()); @@ -207,13 +207,14 @@ CHECK(!negotiated_protocol_); CHECK(attempt_manager_); - // The NextProto::kProtoUnknown check is needed because when establishing a - // connection, it means allow any protocol, so needs to be removed if specific - // protocols aren't allowed, while once a connection is negotiated, it's an - // alias for HTTP/1.x. - if (!allowed_alpns_.Has(negotiated_protocol) && - !(negotiated_protocol == NextProto::kProtoUnknown && - allowed_alpns_.Has(NextProto::kProtoHTTP11))) { + // `allowed_alpns_` never includes kProtoUnknown, which when making a request, + // can mean "any protocol", but when receiving a response means "not H2 and + // not H3", thus implying H1 (or some other protocol), so when comparing the + // protocol of the received stream, replace kProtoUnknown with kProtoHTTP11. + NextProto logical_protocol = (negotiated_protocol != NextProto::kProtoUnknown + ? negotiated_protocol + : NextProto::kProtoHTTP11); + if (!allowed_alpns_.Has(logical_protocol)) { OnStreamFailed(ERR_ALPN_NEGOTIATION_FAILED, NetErrorDetails(), ResolveErrorInfo()); return;
diff --git a/net/http/http_stream_pool_job.h b/net/http/http_stream_pool_job.h index 30fdc8f..7fa073f 100644 --- a/net/http/http_stream_pool_job.h +++ b/net/http/http_stream_pool_job.h
@@ -146,10 +146,6 @@ return delegate_->enable_ip_based_pooling_for_h2(); } - bool enable_alternative_services() const { - return delegate_->enable_alternative_services(); - } - const ProxyInfo& proxy_info() const { return delegate_->proxy_info(); } const std::vector<SSLConfig::CertAndStatus>& allowed_bad_certs() const {
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h index e7cfdb16..6a57c967 100644 --- a/net/log/net_log_event_type_list.h +++ b/net/log/net_log_event_type_list.h
@@ -1527,8 +1527,9 @@ // { // "priority": <The priority of the erquest>, // "allowed_bad_certs": <The list of allowed bad certs>, -// "enable_ip_based_pooling": <True when the request enables IP based -// pooling>, +// "enable_ip_based_pooling_for_h2": <True when the request enables IP based +// pooling for H2>, +// "allowed_alpns": <The list of allowed protocols>, // "quic_version": <The QUIC version to attempt>, // "source_dependency": <The source identifier of the request> // } @@ -1573,6 +1574,10 @@ // Some HTTP_STREAM_POOL_ATTEMPT_MANAGER_* events have the following common // event parameters. // { +// "num_active_sockets": <The number of active sockets>, +// "num_idle_sockets": <The number of idle sockets>, +// "num_handed_out_sockets": <The number of handed out sockets>, +// "num_total_sockets": <The number of total sockets>, // "num_jobs": <The number of active jobs>, // "num_notified_jobs": <The number of jobs that are notified results but // are still not destroyed yet>, @@ -1580,6 +1585,11 @@ // "num_inflight_attempts": <The number of in-flight TCP/TLS attempts>, // "num_slow_attempts": <The number of in-flight TCP/TLS attempts that are // treated as slow>, +// "num_tcp_based_attempt_slots": <The total number of slots for TCP-based +// connection attempts. +// "enable_ip_based_pooling_for_h2": <True when the request enables IP based +// pooling for H2>, +// "allowed_alpns": <List of allowed ALPNs>, // "quic_attempt_alive": <True when a QuicAttempt is alive>, // "quic_attempt_result": <The result of a QuicAttempt, if it is already // finished>
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc index 96ca53dbd..4152ecf 100644 --- a/services/network/public/cpp/features.cc +++ b/services/network/public/cpp/features.cc
@@ -575,16 +575,16 @@ /*name=*/"max_size", 1'000'000); -BASE_FEATURE(kNetworkServiceTaskScheduler, base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kNetworkServiceTaskScheduler, base::FEATURE_ENABLED_BY_DEFAULT); BASE_FEATURE_PARAM(bool, kNetworkServiceTaskSchedulerResourceScheduler, &kNetworkServiceTaskScheduler, "resource_scheduler", - false); + true); BASE_FEATURE_PARAM(bool, kNetworkServiceTaskSchedulerURLLoader, &kNetworkServiceTaskScheduler, "url_loader", - false); + true); } // namespace network::features
diff --git a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc index 27f299a6..eb934bf 100644 --- a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc +++ b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
@@ -44,7 +44,6 @@ #include "gpu/ipc/client/client_shared_image_interface.h" #include "gpu/ipc/client/command_buffer_proxy_impl.h" #include "gpu/ipc/client/gpu_channel_host.h" -#include "gpu/skia_bindings/grcontext_for_gles2_interface.h" #include "services/viz/public/cpp/gpu/command_buffer_metrics.h" #include "skia/buildflags.h" #include "third_party/skia/include/core/SkTraceMemoryDump.h" @@ -535,8 +534,6 @@ for (auto& observer : observers_) observer.OnContextLost(); - if (gr_context_) - gr_context_->OnLostContext(); gpu::CommandBuffer::State state = GetCommandBufferProxy()->GetLastState(); command_buffer_metrics::UmaRecordContextLost(context_type_, state.error, @@ -578,15 +575,6 @@ impl_->OnMemoryDump(args, pmd); helper_->OnMemoryDump(args, pmd); - if (gr_context_) { - if (args.level_of_detail == - base::trace_event::MemoryDumpLevelOfDetail::kBackground) { - gpu::raster::DumpBackgroundGrMemoryStatistics(gr_context_->get(), pmd); - } else { - gpu::raster::DumpGrMemoryStatistics(gr_context_->get(), pmd, - gles2_impl_->ShareGroupTracingGUID()); - } - } return true; }
diff --git a/services/viz/public/cpp/gpu/context_provider_command_buffer.h b/services/viz/public/cpp/gpu/context_provider_command_buffer.h index 6000197..41c575a 100644 --- a/services/viz/public/cpp/gpu/context_provider_command_buffer.h +++ b/services/viz/public/cpp/gpu/context_provider_command_buffer.h
@@ -56,10 +56,6 @@ } // namespace webgpu } // namespace gpu -namespace skia_bindings { -class GrContextForGLES2Interface; -} - namespace viz { enum class WebGLContextType { kWebGL1, kWebGL2 }; @@ -231,8 +227,6 @@ // END IMPORTANT NOTE // ////////////////////////////////////////////////////////////////////////////// - std::unique_ptr<skia_bindings::GrContextForGLES2Interface> gr_context_; - std::unique_ptr<ContextCacheController> cache_controller_; base::ObserverList<ContextLostObserver>::Unchecked observers_;
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 4c17c89..255b952 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -16118,24 +16118,6 @@ ], "experiments": [ { - "name": "Enabled", - "params": { - "http_proxy_connect_job": "true", - "http_stream_factory_job": "true", - "http_stream_factory_job_controller": "true", - "resource_scheduler": "true", - "url_loader": "true", - "url_request_error_job": "true", - "url_request_http_job": "true", - "url_request_job": "true", - "url_request_redirect_job": "true" - }, - "enable_features": [ - "NetTaskScheduler", - "NetworkServiceTaskScheduler" - ] - }, - { "name": "Enabled2", "params": { "http_cache": "true", @@ -21368,28 +21350,6 @@ ] } ], - "SafetyHub": [ - { - "platforms": [ - "chromeos", - "fuchsia", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "params": { - "background-password-check-interval": "30d" - }, - "enable_features": [ - "SafetyHub" - ] - } - ] - } - ], "SafetyHubDisruptiveNotificationRevocation": [ { "platforms": [ @@ -21441,6 +21401,27 @@ ] } ], + "SafetyHubIncreasePasswordCheckFrequency": [ + { + "platforms": [ + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "background-password-check-interval": "10d" + }, + "enable_features": [ + "SafetyHub" + ] + } + ] + } + ], "SafetyHubOneOffHats": [ { "platforms": [ @@ -28016,21 +27997,6 @@ ] } ], - "WebViewUseBackgroundThreadForGms": [ - { - "platforms": [ - "android_webview" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "WebViewUseBackgroundThreadForGms" - ] - } - ] - } - ], "WebViewUseMetricsUploadServiceOnlySdkRuntime": [ { "platforms": [
diff --git a/third_party/androidx/build.gradle b/third_party/androidx/build.gradle index 7429cec..50c189c 100644 --- a/third_party/androidx/build.gradle +++ b/third_party/androidx/build.gradle
@@ -314,7 +314,7 @@ google() maven { // This URL is generated by the fetch_all_androidx.py script. - url 'https://androidx.dev/snapshots/builds/14180086/artifacts/repository' + url 'https://androidx.dev/snapshots/builds/14181415/artifacts/repository' } mavenCentral() }
diff --git a/third_party/androidx/committed/libs/androidx_activity_activity/README.chromium b/third_party/androidx/committed/libs/androidx_activity_activity/README.chromium index 1f1b484..f9bc1f54 100644 --- a/third_party/androidx/committed/libs/androidx_activity_activity/README.chromium +++ b/third_party/androidx/committed/libs/androidx_activity_activity/README.chromium
@@ -1,6 +1,6 @@ Name: Activity Short Name: activity -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/activity/activity/1.12.0-SNAPSHOT/activity-1.12.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/activity/activity/1.12.0-SNAPSHOT/activity-1.12.0-20250929.054628-1.aar Version: 1.12.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_activity_activity_compose/README.chromium b/third_party/androidx/committed/libs/androidx_activity_activity_compose/README.chromium index 050b05c..fd545b6 100644 --- a/third_party/androidx/committed/libs/androidx_activity_activity_compose/README.chromium +++ b/third_party/androidx/committed/libs/androidx_activity_activity_compose/README.chromium
@@ -1,6 +1,6 @@ Name: Activity Compose Short Name: activity-compose -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/activity/activity-compose/1.12.0-SNAPSHOT/activity-compose-1.12.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/activity/activity-compose/1.12.0-SNAPSHOT/activity-compose-1.12.0-20250929.054628-1.aar Version: 1.12.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_activity_activity_ktx/README.chromium b/third_party/androidx/committed/libs/androidx_activity_activity_ktx/README.chromium index cb98d53..fca5ff0 100644 --- a/third_party/androidx/committed/libs/androidx_activity_activity_ktx/README.chromium +++ b/third_party/androidx/committed/libs/androidx_activity_activity_ktx/README.chromium
@@ -1,6 +1,6 @@ Name: Activity Kotlin Extensions Short Name: activity-ktx -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/activity/activity-ktx/1.12.0-SNAPSHOT/activity-ktx-1.12.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/activity/activity-ktx/1.12.0-SNAPSHOT/activity-ktx-1.12.0-20250929.054628-1.aar Version: 1.12.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_annotation_annotation_experimental/README.chromium b/third_party/androidx/committed/libs/androidx_annotation_annotation_experimental/README.chromium index 422c42d9..ee987a42 100644 --- a/third_party/androidx/committed/libs/androidx_annotation_annotation_experimental/README.chromium +++ b/third_party/androidx/committed/libs/androidx_annotation_annotation_experimental/README.chromium
@@ -1,6 +1,6 @@ Name: Experimental annotation Short Name: annotation-experimental -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/annotation/annotation-experimental/1.6.0-SNAPSHOT/annotation-experimental-1.6.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/annotation/annotation-experimental/1.6.0-SNAPSHOT/annotation-experimental-1.6.0-20250929.054628-1.aar Version: 1.6.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_annotation_annotation_jvm/README.chromium b/third_party/androidx/committed/libs/androidx_annotation_annotation_jvm/README.chromium index e7b5ed6..fa85e15 100644 --- a/third_party/androidx/committed/libs/androidx_annotation_annotation_jvm/README.chromium +++ b/third_party/androidx/committed/libs/androidx_annotation_annotation_jvm/README.chromium
@@ -1,6 +1,6 @@ Name: Annotation Short Name: annotation-jvm -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/annotation/annotation-jvm/1.10.0-SNAPSHOT/annotation-jvm-1.10.0-20250928.100029-1.jar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/annotation/annotation-jvm/1.10.0-SNAPSHOT/annotation-jvm-1.10.0-20250929.054628-1.jar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_appcompat_appcompat/README.chromium b/third_party/androidx/committed/libs/androidx_appcompat_appcompat/README.chromium index 13cc77b0..b57d076 100644 --- a/third_party/androidx/committed/libs/androidx_appcompat_appcompat/README.chromium +++ b/third_party/androidx/committed/libs/androidx_appcompat_appcompat/README.chromium
@@ -1,6 +1,6 @@ Name: AppCompat Short Name: appcompat -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/appcompat/appcompat/1.8.0-SNAPSHOT/appcompat-1.8.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/appcompat/appcompat/1.8.0-SNAPSHOT/appcompat-1.8.0-20250929.054628-1.aar Version: 1.8.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_appcompat_appcompat_resources/README.chromium b/third_party/androidx/committed/libs/androidx_appcompat_appcompat_resources/README.chromium index 9b4cb0b0..8a26e3e 100644 --- a/third_party/androidx/committed/libs/androidx_appcompat_appcompat_resources/README.chromium +++ b/third_party/androidx/committed/libs/androidx_appcompat_appcompat_resources/README.chromium
@@ -1,6 +1,6 @@ Name: AppCompat Resources Short Name: appcompat-resources -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/appcompat/appcompat-resources/1.8.0-SNAPSHOT/appcompat-resources-1.8.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/appcompat/appcompat-resources/1.8.0-SNAPSHOT/appcompat-resources-1.8.0-20250929.054628-1.aar Version: 1.8.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_appsearch_appsearch/README.chromium b/third_party/androidx/committed/libs/androidx_appsearch_appsearch/README.chromium index 694af31..81d007d 100644 --- a/third_party/androidx/committed/libs/androidx_appsearch_appsearch/README.chromium +++ b/third_party/androidx/committed/libs/androidx_appsearch_appsearch/README.chromium
@@ -1,6 +1,6 @@ Name: AppSearch Short Name: appsearch -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/appsearch/appsearch/1.2.0-SNAPSHOT/appsearch-1.2.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/appsearch/appsearch/1.2.0-SNAPSHOT/appsearch-1.2.0-20250929.054628-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_appsearch_appsearch_builtin_types/README.chromium b/third_party/androidx/committed/libs/androidx_appsearch_appsearch_builtin_types/README.chromium index 895dd4a5..3ca8109 100644 --- a/third_party/androidx/committed/libs/androidx_appsearch_appsearch_builtin_types/README.chromium +++ b/third_party/androidx/committed/libs/androidx_appsearch_appsearch_builtin_types/README.chromium
@@ -1,6 +1,6 @@ Name: AppSearch Builtin Types Short Name: appsearch-builtin-types -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/appsearch/appsearch-builtin-types/1.2.0-SNAPSHOT/appsearch-builtin-types-1.2.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/appsearch/appsearch-builtin-types/1.2.0-SNAPSHOT/appsearch-builtin-types-1.2.0-20250929.054628-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_appsearch_appsearch_platform_storage/README.chromium b/third_party/androidx/committed/libs/androidx_appsearch_appsearch_platform_storage/README.chromium index 579b427..5d24e5ce 100644 --- a/third_party/androidx/committed/libs/androidx_appsearch_appsearch_platform_storage/README.chromium +++ b/third_party/androidx/committed/libs/androidx_appsearch_appsearch_platform_storage/README.chromium
@@ -1,6 +1,6 @@ Name: AppSearch Platform Storage Short Name: appsearch-platform-storage -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/appsearch/appsearch-platform-storage/1.2.0-SNAPSHOT/appsearch-platform-storage-1.2.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/appsearch/appsearch-platform-storage/1.2.0-SNAPSHOT/appsearch-platform-storage-1.2.0-20250929.054628-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_arch_core_core_common/README.chromium b/third_party/androidx/committed/libs/androidx_arch_core_core_common/README.chromium index ece4bd32..6fcd896 100644 --- a/third_party/androidx/committed/libs/androidx_arch_core_core_common/README.chromium +++ b/third_party/androidx/committed/libs/androidx_arch_core_core_common/README.chromium
@@ -1,6 +1,6 @@ Name: Arch-Common Short Name: core-common -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/arch/core/core-common/2.3.0-SNAPSHOT/core-common-2.3.0-20250928.100029-1.jar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/arch/core/core-common/2.3.0-SNAPSHOT/core-common-2.3.0-20250929.054628-1.jar Version: 2.3.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_arch_core_core_runtime/README.chromium b/third_party/androidx/committed/libs/androidx_arch_core_core_runtime/README.chromium index d4eb720c1..78cc60f 100644 --- a/third_party/androidx/committed/libs/androidx_arch_core_core_runtime/README.chromium +++ b/third_party/androidx/committed/libs/androidx_arch_core_core_runtime/README.chromium
@@ -1,6 +1,6 @@ Name: Arch-Runtime Short Name: core-runtime -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/arch/core/core-runtime/2.3.0-SNAPSHOT/core-runtime-2.3.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/arch/core/core-runtime/2.3.0-SNAPSHOT/core-runtime-2.3.0-20250929.054628-1.aar Version: 2.3.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_autofill_autofill/README.chromium b/third_party/androidx/committed/libs/androidx_autofill_autofill/README.chromium index 9b0017bd..9c0c4a7f 100644 --- a/third_party/androidx/committed/libs/androidx_autofill_autofill/README.chromium +++ b/third_party/androidx/committed/libs/androidx_autofill_autofill/README.chromium
@@ -1,6 +1,6 @@ Name: Autofill Short Name: autofill -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/autofill/autofill/1.4.0-SNAPSHOT/autofill-1.4.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/autofill/autofill/1.4.0-SNAPSHOT/autofill-1.4.0-20250929.054628-1.aar Version: 1.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_common/README.chromium b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_common/README.chromium index 2765ced9..35d89313 100644 --- a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_common/README.chromium +++ b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_common/README.chromium
@@ -1,6 +1,6 @@ Name: Benchmark - Common Short Name: benchmark-common -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/benchmark/benchmark-common/1.5.0-SNAPSHOT/benchmark-common-1.5.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/benchmark/benchmark-common/1.5.0-SNAPSHOT/benchmark-common-1.5.0-20250929.054628-1.aar Version: 1.5.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_junit4/README.chromium b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_junit4/README.chromium index 09fef6f..77a94232e9 100644 --- a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_junit4/README.chromium +++ b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_junit4/README.chromium
@@ -1,6 +1,6 @@ Name: Benchmark - JUnit4 Short Name: benchmark-junit4 -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/benchmark/benchmark-junit4/1.5.0-SNAPSHOT/benchmark-junit4-1.5.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/benchmark/benchmark-junit4/1.5.0-SNAPSHOT/benchmark-junit4-1.5.0-20250929.054628-1.aar Version: 1.5.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_macro/README.chromium b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_macro/README.chromium index ae00d25..6efb96587 100644 --- a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_macro/README.chromium +++ b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_macro/README.chromium
@@ -1,6 +1,6 @@ Name: Benchmark - Macrobenchmark Short Name: benchmark-macro -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/benchmark/benchmark-macro/1.5.0-SNAPSHOT/benchmark-macro-1.5.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/benchmark/benchmark-macro/1.5.0-SNAPSHOT/benchmark-macro-1.5.0-20250929.054628-1.aar Version: 1.5.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_macro_junit4/README.chromium b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_macro_junit4/README.chromium index 795911b..1c53f0e 100644 --- a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_macro_junit4/README.chromium +++ b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_macro_junit4/README.chromium
@@ -1,6 +1,6 @@ Name: Benchmark - Macrobenchmark JUnit4 Short Name: benchmark-macro-junit4 -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/benchmark/benchmark-macro-junit4/1.5.0-SNAPSHOT/benchmark-macro-junit4-1.5.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/benchmark/benchmark-macro-junit4/1.5.0-SNAPSHOT/benchmark-macro-junit4-1.5.0-20250929.054628-1.aar Version: 1.5.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_traceprocessor_android/README.chromium b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_traceprocessor_android/README.chromium index 4d71beaf..8cddecb 100644 --- a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_traceprocessor_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_traceprocessor_android/README.chromium
@@ -1,6 +1,6 @@ Name: Benchmark TraceProcessor Short Name: benchmark-traceprocessor-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/benchmark/benchmark-traceprocessor-android/1.5.0-SNAPSHOT/benchmark-traceprocessor-android-1.5.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/benchmark/benchmark-traceprocessor-android/1.5.0-SNAPSHOT/benchmark-traceprocessor-android-1.5.0-20250929.054628-1.aar Version: 1.5.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_biometric_biometric/README.chromium b/third_party/androidx/committed/libs/androidx_biometric_biometric/README.chromium index bddae9d..3c8e871 100644 --- a/third_party/androidx/committed/libs/androidx_biometric_biometric/README.chromium +++ b/third_party/androidx/committed/libs/androidx_biometric_biometric/README.chromium
@@ -1,6 +1,6 @@ Name: Biometric Short Name: biometric -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/biometric/biometric/1.4.0-SNAPSHOT/biometric-1.4.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/biometric/biometric/1.4.0-SNAPSHOT/biometric-1.4.0-20250929.054628-1.aar Version: 1.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_browser_browser/README.chromium b/third_party/androidx/committed/libs/androidx_browser_browser/README.chromium index 109c9d4..0d096d1 100644 --- a/third_party/androidx/committed/libs/androidx_browser_browser/README.chromium +++ b/third_party/androidx/committed/libs/androidx_browser_browser/README.chromium
@@ -1,6 +1,6 @@ Name: Browser Short Name: browser -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/browser/browser/1.10.0-SNAPSHOT/browser-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/browser/browser/1.10.0-SNAPSHOT/browser-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_cardview_cardview/README.chromium b/third_party/androidx/committed/libs/androidx_cardview_cardview/README.chromium index 94ef2a0..aa85157 100644 --- a/third_party/androidx/committed/libs/androidx_cardview_cardview/README.chromium +++ b/third_party/androidx/committed/libs/androidx_cardview_cardview/README.chromium
@@ -1,6 +1,6 @@ Name: CardView Short Name: cardview -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/cardview/cardview/1.1.0-SNAPSHOT/cardview-1.1.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/cardview/cardview/1.1.0-SNAPSHOT/cardview-1.1.0-20250929.054628-1.aar Version: 1.1.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_collection_collection_jvm/README.chromium b/third_party/androidx/committed/libs/androidx_collection_collection_jvm/README.chromium index 4860ddb..33fa9ca 100644 --- a/third_party/androidx/committed/libs/androidx_collection_collection_jvm/README.chromium +++ b/third_party/androidx/committed/libs/androidx_collection_collection_jvm/README.chromium
@@ -1,6 +1,6 @@ Name: collections Short Name: collection-jvm -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/collection/collection-jvm/1.6.0-SNAPSHOT/collection-jvm-1.6.0-20250928.100029-1.jar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/collection/collection-jvm/1.6.0-SNAPSHOT/collection-jvm-1.6.0-20250929.054628-1.jar Version: 1.6.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_collection_collection_ktx/README.chromium b/third_party/androidx/committed/libs/androidx_collection_collection_ktx/README.chromium index 1ef62a8f..302e4ed 100644 --- a/third_party/androidx/committed/libs/androidx_collection_collection_ktx/README.chromium +++ b/third_party/androidx/committed/libs/androidx_collection_collection_ktx/README.chromium
@@ -1,6 +1,6 @@ Name: Collections Kotlin Extensions Short Name: collection-ktx -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/collection/collection-ktx/1.6.0-SNAPSHOT/collection-ktx-1.6.0-20250928.100029-1.jar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/collection/collection-ktx/1.6.0-SNAPSHOT/collection-ktx-1.6.0-20250929.054628-1.jar Version: 1.6.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_animation_animation_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_animation_animation_android/README.chromium index 94f97ef69..95c99fe 100644 --- a/third_party/androidx/committed/libs/androidx_compose_animation_animation_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_animation_animation_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Animation Short Name: animation-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/animation/animation-android/1.10.0-SNAPSHOT/animation-android-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/animation/animation-android/1.10.0-SNAPSHOT/animation-android-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_animation_animation_core_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_animation_animation_core_android/README.chromium index d483b36..b408861 100644 --- a/third_party/androidx/committed/libs/androidx_compose_animation_animation_core_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_animation_animation_core_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Animation Core Short Name: animation-core-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/animation/animation-core-android/1.10.0-SNAPSHOT/animation-core-android-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/animation/animation-core-android/1.10.0-SNAPSHOT/animation-core-android-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_foundation_foundation_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_foundation_foundation_android/README.chromium index 8de3491..9ac0b59 100644 --- a/third_party/androidx/committed/libs/androidx_compose_foundation_foundation_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_foundation_foundation_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Foundation Short Name: foundation-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/foundation/foundation-android/1.10.0-SNAPSHOT/foundation-android-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/foundation/foundation-android/1.10.0-SNAPSHOT/foundation-android-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_foundation_foundation_layout_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_foundation_foundation_layout_android/README.chromium index 55621cf..fb24c3c 100644 --- a/third_party/androidx/committed/libs/androidx_compose_foundation_foundation_layout_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_foundation_foundation_layout_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Layouts Short Name: foundation-layout-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/foundation/foundation-layout-android/1.10.0-SNAPSHOT/foundation-layout-android-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/foundation/foundation-layout-android/1.10.0-SNAPSHOT/foundation-layout-android-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_material3_material3_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_material3_material3_android/README.chromium index 3516d430..d810b6e 100644 --- a/third_party/androidx/committed/libs/androidx_compose_material3_material3_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_material3_material3_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Material3 Components Short Name: material3-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/material3/material3-android/1.5.0-SNAPSHOT/material3-android-1.5.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/material3/material3-android/1.5.0-SNAPSHOT/material3-android-1.5.0-20250929.054628-1.aar Version: 1.5.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_material_material_ripple_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_material_material_ripple_android/README.chromium index d0b696b8..d069241b 100644 --- a/third_party/androidx/committed/libs/androidx_compose_material_material_ripple_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_material_material_ripple_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Material Ripple Short Name: material-ripple-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/material/material-ripple-android/1.10.0-SNAPSHOT/material-ripple-android-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/material/material-ripple-android/1.10.0-SNAPSHOT/material-ripple-android-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_android/README.chromium index 5214cd4..67159e6 100644 --- a/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Runtime Short Name: runtime-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/runtime/runtime-android/1.10.0-SNAPSHOT/runtime-android-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/runtime/runtime-android/1.10.0-SNAPSHOT/runtime-android-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_annotation_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_annotation_android/README.chromium index 3a764c7..19aa6a3f 100644 --- a/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_annotation_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_annotation_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Runtime Annotation Short Name: runtime-annotation-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/runtime/runtime-annotation-android/1.10.0-SNAPSHOT/runtime-annotation-android-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/runtime/runtime-annotation-android/1.10.0-SNAPSHOT/runtime-annotation-android-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_retain_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_retain_android/README.chromium index 0eea58e..6562c56 100644 --- a/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_retain_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_retain_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Runtime Retain Short Name: runtime-retain-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/runtime/runtime-retain-android/1.10.0-SNAPSHOT/runtime-retain-android-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/runtime/runtime-retain-android/1.10.0-SNAPSHOT/runtime-retain-android-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_saveable_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_saveable_android/README.chromium index 25b7e1e5..f74ee18 100644 --- a/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_saveable_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_saveable_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Saveable Short Name: runtime-saveable-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/runtime/runtime-saveable-android/1.10.0-SNAPSHOT/runtime-saveable-android-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/runtime/runtime-saveable-android/1.10.0-SNAPSHOT/runtime-saveable-android-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_android/README.chromium index 4cfc0e5..609c82f 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose UI Short Name: ui-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/ui/ui-android/1.10.0-SNAPSHOT/ui-android-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/ui/ui-android/1.10.0-SNAPSHOT/ui-android-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_geometry_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_geometry_android/README.chromium index edb01be..4795248 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_geometry_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_geometry_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Geometry Short Name: ui-geometry-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/ui/ui-geometry-android/1.10.0-SNAPSHOT/ui-geometry-android-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/ui/ui-geometry-android/1.10.0-SNAPSHOT/ui-geometry-android-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_graphics_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_graphics_android/README.chromium index 2246574..c5e01156 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_graphics_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_graphics_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Graphics Short Name: ui-graphics-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/ui/ui-graphics-android/1.10.0-SNAPSHOT/ui-graphics-android-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/ui/ui-graphics-android/1.10.0-SNAPSHOT/ui-graphics-android-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_android/README.chromium index 9a4f631d..73480c6d 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Testing Short Name: ui-test-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/ui/ui-test-android/1.10.0-SNAPSHOT/ui-test-android-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/ui/ui-test-android/1.10.0-SNAPSHOT/ui-test-android-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_junit4_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_junit4_android/README.chromium index d2829c7..9248a8ef 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_junit4_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_junit4_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Testing for JUnit4 Short Name: ui-test-junit4-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/ui/ui-test-junit4-android/1.10.0-SNAPSHOT/ui-test-junit4-android-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/ui/ui-test-junit4-android/1.10.0-SNAPSHOT/ui-test-junit4-android-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_manifest/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_manifest/README.chromium index 0ce956d..52f92f2 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_manifest/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_manifest/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Testing manifest dependency Short Name: ui-test-manifest -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/ui/ui-test-manifest/1.10.0-SNAPSHOT/ui-test-manifest-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/ui/ui-test-manifest/1.10.0-SNAPSHOT/ui-test-manifest-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_text_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_text_android/README.chromium index 67cf897..0a1e5da 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_text_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_text_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose UI Text Short Name: ui-text-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/ui/ui-text-android/1.10.0-SNAPSHOT/ui-text-android-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/ui/ui-text-android/1.10.0-SNAPSHOT/ui-text-android-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_text_google_fonts/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_text_google_fonts/README.chromium index 8bfedc65..315b744 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_text_google_fonts/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_text_google_fonts/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Google Fonts integration Short Name: ui-text-google-fonts -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/ui/ui-text-google-fonts/1.10.0-SNAPSHOT/ui-text-google-fonts-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/ui/ui-text-google-fonts/1.10.0-SNAPSHOT/ui-text-google-fonts-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_unit_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_unit_android/README.chromium index 4bb1e07f..23c81de2 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_unit_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_unit_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Unit Short Name: ui-unit-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/ui/ui-unit-android/1.10.0-SNAPSHOT/ui-unit-android-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/ui/ui-unit-android/1.10.0-SNAPSHOT/ui-unit-android-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_util_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_util_android/README.chromium index 6b672816..07eece24 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_util_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_util_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Util Short Name: ui-util-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/compose/ui/ui-util-android/1.10.0-SNAPSHOT/ui-util-android-1.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/compose/ui/ui-util-android/1.10.0-SNAPSHOT/ui-util-android-1.10.0-20250929.054628-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_constraintlayout_constraintlayout/README.chromium b/third_party/androidx/committed/libs/androidx_constraintlayout_constraintlayout/README.chromium index c1e6a143..65cb917 100644 --- a/third_party/androidx/committed/libs/androidx_constraintlayout_constraintlayout/README.chromium +++ b/third_party/androidx/committed/libs/androidx_constraintlayout_constraintlayout/README.chromium
@@ -1,6 +1,6 @@ Name: ConstraintLayout Short Name: constraintlayout -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/constraintlayout/constraintlayout/2.3.0-SNAPSHOT/constraintlayout-2.3.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/constraintlayout/constraintlayout/2.3.0-SNAPSHOT/constraintlayout-2.3.0-20250929.054628-1.aar Version: 2.3.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_constraintlayout_constraintlayout_core/README.chromium b/third_party/androidx/committed/libs/androidx_constraintlayout_constraintlayout_core/README.chromium index 98d8075..0717fd6 100644 --- a/third_party/androidx/committed/libs/androidx_constraintlayout_constraintlayout_core/README.chromium +++ b/third_party/androidx/committed/libs/androidx_constraintlayout_constraintlayout_core/README.chromium
@@ -1,6 +1,6 @@ Name: ConstraintLayout Core Short Name: constraintlayout-core -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/constraintlayout/constraintlayout-core/1.2.0-SNAPSHOT/constraintlayout-core-1.2.0-20250928.100029-1.jar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/constraintlayout/constraintlayout-core/1.2.0-SNAPSHOT/constraintlayout-core-1.2.0-20250929.054628-1.jar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_core_core/README.chromium b/third_party/androidx/committed/libs/androidx_core_core/README.chromium index 6905b15e..84fffdc 100644 --- a/third_party/androidx/committed/libs/androidx_core_core/README.chromium +++ b/third_party/androidx/committed/libs/androidx_core_core/README.chromium
@@ -1,6 +1,6 @@ Name: Core Short Name: core -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/core/core/1.18.0-SNAPSHOT/core-1.18.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/core/core/1.18.0-SNAPSHOT/core-1.18.0-20250929.054628-1.aar Version: 1.18.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_core_core_ktx/README.chromium b/third_party/androidx/committed/libs/androidx_core_core_ktx/README.chromium index ab152e1..0eb7288 100644 --- a/third_party/androidx/committed/libs/androidx_core_core_ktx/README.chromium +++ b/third_party/androidx/committed/libs/androidx_core_core_ktx/README.chromium
@@ -1,6 +1,6 @@ Name: Core Kotlin Extensions Short Name: core-ktx -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/core/core-ktx/1.18.0-SNAPSHOT/core-ktx-1.18.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/core/core-ktx/1.18.0-SNAPSHOT/core-ktx-1.18.0-20250929.054628-1.aar Version: 1.18.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_core_core_viewtree/README.chromium b/third_party/androidx/committed/libs/androidx_core_core_viewtree/README.chromium index 985588ec..46e53e2 100644 --- a/third_party/androidx/committed/libs/androidx_core_core_viewtree/README.chromium +++ b/third_party/androidx/committed/libs/androidx_core_core_viewtree/README.chromium
@@ -1,6 +1,6 @@ Name: androidx.core:core-viewtree Short Name: core-viewtree -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/core/core-viewtree/1.1.0-SNAPSHOT/core-viewtree-1.1.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/core/core-viewtree/1.1.0-SNAPSHOT/core-viewtree-1.1.0-20250929.054628-1.aar Version: 1.1.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_credentials_credentials/README.chromium b/third_party/androidx/committed/libs/androidx_credentials_credentials/README.chromium index 8dd4543..e395f83 100644 --- a/third_party/androidx/committed/libs/androidx_credentials_credentials/README.chromium +++ b/third_party/androidx/committed/libs/androidx_credentials_credentials/README.chromium
@@ -1,6 +1,6 @@ Name: Credentials Short Name: credentials -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/credentials/credentials/1.6.0-SNAPSHOT/credentials-1.6.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/credentials/credentials/1.6.0-SNAPSHOT/credentials-1.6.0-20250929.054628-1.aar Version: 1.6.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_credentials_credentials_play_services_auth/README.chromium b/third_party/androidx/committed/libs/androidx_credentials_credentials_play_services_auth/README.chromium index 96e6dd7a..a15f598 100644 --- a/third_party/androidx/committed/libs/androidx_credentials_credentials_play_services_auth/README.chromium +++ b/third_party/androidx/committed/libs/androidx_credentials_credentials_play_services_auth/README.chromium
@@ -1,6 +1,6 @@ Name: Credentials Play Services Auth Short Name: credentials-play-services-auth -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/credentials/credentials-play-services-auth/1.6.0-SNAPSHOT/credentials-play-services-auth-1.6.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/credentials/credentials-play-services-auth/1.6.0-SNAPSHOT/credentials-play-services-auth-1.6.0-20250929.054628-1.aar Version: 1.6.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_credentials_registry_registry_provider/README.chromium b/third_party/androidx/committed/libs/androidx_credentials_registry_registry_provider/README.chromium index c779f88..c9da7d4a 100644 --- a/third_party/androidx/committed/libs/androidx_credentials_registry_registry_provider/README.chromium +++ b/third_party/androidx/committed/libs/androidx_credentials_registry_registry_provider/README.chromium
@@ -1,6 +1,6 @@ Name: androidx.credentials.registry:registry-provider Short Name: registry-provider -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/credentials/registry/registry-provider/1.0.0-SNAPSHOT/registry-provider-1.0.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/credentials/registry/registry-provider/1.0.0-SNAPSHOT/registry-provider-1.0.0-20250929.054628-1.aar Version: 1.0.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_credentials_registry_registry_provider_play_services/README.chromium b/third_party/androidx/committed/libs/androidx_credentials_registry_registry_provider_play_services/README.chromium index fc2fea2..dd05ed3e 100644 --- a/third_party/androidx/committed/libs/androidx_credentials_registry_registry_provider_play_services/README.chromium +++ b/third_party/androidx/committed/libs/androidx_credentials_registry_registry_provider_play_services/README.chromium
@@ -1,6 +1,6 @@ Name: androidx.credentials.registry:registry-provider-play-services Short Name: registry-provider-play-services -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/credentials/registry/registry-provider-play-services/1.0.0-SNAPSHOT/registry-provider-play-services-1.0.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/credentials/registry/registry-provider-play-services/1.0.0-SNAPSHOT/registry-provider-play-services-1.0.0-20250929.054628-1.aar Version: 1.0.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_cursoradapter_cursoradapter/README.chromium b/third_party/androidx/committed/libs/androidx_cursoradapter_cursoradapter/README.chromium index 13ab978..63181603 100644 --- a/third_party/androidx/committed/libs/androidx_cursoradapter_cursoradapter/README.chromium +++ b/third_party/androidx/committed/libs/androidx_cursoradapter_cursoradapter/README.chromium
@@ -1,6 +1,6 @@ Name: Cursor Adapter Short Name: cursoradapter -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/cursoradapter/cursoradapter/1.1.0-SNAPSHOT/cursoradapter-1.1.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/cursoradapter/cursoradapter/1.1.0-SNAPSHOT/cursoradapter-1.1.0-20250929.054628-1.aar Version: 1.1.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_datastore_datastore_android/README.chromium b/third_party/androidx/committed/libs/androidx_datastore_datastore_android/README.chromium index 2ff8d511e..98dc735 100644 --- a/third_party/androidx/committed/libs/androidx_datastore_datastore_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_datastore_datastore_android/README.chromium
@@ -1,6 +1,6 @@ Name: DataStore Short Name: datastore-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/datastore/datastore-android/1.2.0-SNAPSHOT/datastore-android-1.2.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/datastore/datastore-android/1.2.0-SNAPSHOT/datastore-android-1.2.0-20250929.054628-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_datastore_datastore_core_android/README.chromium b/third_party/androidx/committed/libs/androidx_datastore_datastore_core_android/README.chromium index e9bae44f..e3e751d 100644 --- a/third_party/androidx/committed/libs/androidx_datastore_datastore_core_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_datastore_datastore_core_android/README.chromium
@@ -1,6 +1,6 @@ Name: DataStore Core Short Name: datastore-core-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/datastore/datastore-core-android/1.2.0-SNAPSHOT/datastore-core-android-1.2.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/datastore/datastore-core-android/1.2.0-SNAPSHOT/datastore-core-android-1.2.0-20250929.054628-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_datastore_datastore_core_okio_jvm/README.chromium b/third_party/androidx/committed/libs/androidx_datastore_datastore_core_okio_jvm/README.chromium index e324d5e..efae72b 100644 --- a/third_party/androidx/committed/libs/androidx_datastore_datastore_core_okio_jvm/README.chromium +++ b/third_party/androidx/committed/libs/androidx_datastore_datastore_core_okio_jvm/README.chromium
@@ -1,6 +1,6 @@ Name: DataStore Core Okio Short Name: datastore-core-okio-jvm -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/datastore/datastore-core-okio-jvm/1.2.0-SNAPSHOT/datastore-core-okio-jvm-1.2.0-20250928.100029-1.jar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/datastore/datastore-core-okio-jvm/1.2.0-SNAPSHOT/datastore-core-okio-jvm-1.2.0-20250929.054628-1.jar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_android/README.chromium b/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_android/README.chromium index 8631168..d74602a8c 100644 --- a/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_android/README.chromium
@@ -1,6 +1,6 @@ Name: Preferences DataStore Short Name: datastore-preferences-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/datastore/datastore-preferences-android/1.2.0-SNAPSHOT/datastore-preferences-android-1.2.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/datastore/datastore-preferences-android/1.2.0-SNAPSHOT/datastore-preferences-android-1.2.0-20250929.054628-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_core_android/README.chromium b/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_core_android/README.chromium index 3350513..830114d 100644 --- a/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_core_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_core_android/README.chromium
@@ -1,6 +1,6 @@ Name: Preferences DataStore Core Short Name: datastore-preferences-core-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/datastore/datastore-preferences-core-android/1.2.0-SNAPSHOT/datastore-preferences-core-android-1.2.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/datastore/datastore-preferences-core-android/1.2.0-SNAPSHOT/datastore-preferences-core-android-1.2.0-20250929.054628-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_external_protobuf/README.chromium b/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_external_protobuf/README.chromium index 0bb9cd8..fdc91708 100644 --- a/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_external_protobuf/README.chromium +++ b/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_external_protobuf/README.chromium
@@ -1,6 +1,6 @@ Name: Preferences External Protobuf Short Name: datastore-preferences-external-protobuf -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/datastore/datastore-preferences-external-protobuf/1.2.0-SNAPSHOT/datastore-preferences-external-protobuf-1.2.0-20250928.100029-1.jar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/datastore/datastore-preferences-external-protobuf/1.2.0-SNAPSHOT/datastore-preferences-external-protobuf-1.2.0-20250929.054628-1.jar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: BSD-3-Clause
diff --git a/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_proto/README.chromium b/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_proto/README.chromium index 1bdba30ae..f835986ef 100644 --- a/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_proto/README.chromium +++ b/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_proto/README.chromium
@@ -1,6 +1,6 @@ Name: Preferences DataStore Proto Short Name: datastore-preferences-proto -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/datastore/datastore-preferences-proto/1.2.0-SNAPSHOT/datastore-preferences-proto-1.2.0-20250928.100029-1.jar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/datastore/datastore-preferences-proto/1.2.0-SNAPSHOT/datastore-preferences-proto-1.2.0-20250929.054628-1.jar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_drawerlayout_drawerlayout/README.chromium b/third_party/androidx/committed/libs/androidx_drawerlayout_drawerlayout/README.chromium index 713ff9e..da22d37 100644 --- a/third_party/androidx/committed/libs/androidx_drawerlayout_drawerlayout/README.chromium +++ b/third_party/androidx/committed/libs/androidx_drawerlayout_drawerlayout/README.chromium
@@ -1,6 +1,6 @@ Name: Drawer Layout Short Name: drawerlayout -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/drawerlayout/drawerlayout/1.3.0-SNAPSHOT/drawerlayout-1.3.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/drawerlayout/drawerlayout/1.3.0-SNAPSHOT/drawerlayout-1.3.0-20250929.054628-1.aar Version: 1.3.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_emoji_emoji/README.chromium b/third_party/androidx/committed/libs/androidx_emoji_emoji/README.chromium index d3ffd88..03e1007 100644 --- a/third_party/androidx/committed/libs/androidx_emoji_emoji/README.chromium +++ b/third_party/androidx/committed/libs/androidx_emoji_emoji/README.chromium
@@ -1,6 +1,6 @@ Name: Emoji Short Name: emoji -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/emoji/emoji/1.2.0-SNAPSHOT/emoji-1.2.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/emoji/emoji/1.2.0-SNAPSHOT/emoji-1.2.0-20250929.054628-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0, SIL Open Font License, Version 1.1, Unicode, Inc. License
diff --git a/third_party/androidx/committed/libs/androidx_fragment_fragment/README.chromium b/third_party/androidx/committed/libs/androidx_fragment_fragment/README.chromium index 2a99f151..9265905d 100644 --- a/third_party/androidx/committed/libs/androidx_fragment_fragment/README.chromium +++ b/third_party/androidx/committed/libs/androidx_fragment_fragment/README.chromium
@@ -1,6 +1,6 @@ Name: fragment Short Name: fragment -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/fragment/fragment/1.9.0-SNAPSHOT/fragment-1.9.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/fragment/fragment/1.9.0-SNAPSHOT/fragment-1.9.0-20250929.054628-1.aar Version: 1.9.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_fragment_fragment_compose/README.chromium b/third_party/androidx/committed/libs/androidx_fragment_fragment_compose/README.chromium index 37ca22e..fe02ad9 100644 --- a/third_party/androidx/committed/libs/androidx_fragment_fragment_compose/README.chromium +++ b/third_party/androidx/committed/libs/androidx_fragment_fragment_compose/README.chromium
@@ -1,6 +1,6 @@ Name: Fragment Compose Short Name: fragment-compose -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/fragment/fragment-compose/1.9.0-SNAPSHOT/fragment-compose-1.9.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/fragment/fragment-compose/1.9.0-SNAPSHOT/fragment-compose-1.9.0-20250929.054628-1.aar Version: 1.9.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_fragment_fragment_ktx/README.chromium b/third_party/androidx/committed/libs/androidx_fragment_fragment_ktx/README.chromium index 814b6db..b13499a 100644 --- a/third_party/androidx/committed/libs/androidx_fragment_fragment_ktx/README.chromium +++ b/third_party/androidx/committed/libs/androidx_fragment_fragment_ktx/README.chromium
@@ -1,6 +1,6 @@ Name: Fragment Kotlin Extensions Short Name: fragment-ktx -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/fragment/fragment-ktx/1.9.0-SNAPSHOT/fragment-ktx-1.9.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/fragment/fragment-ktx/1.9.0-SNAPSHOT/fragment-ktx-1.9.0-20250929.054628-1.aar Version: 1.9.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_fragment_fragment_testing/README.chromium b/third_party/androidx/committed/libs/androidx_fragment_fragment_testing/README.chromium index 272d41b..a8438c0 100644 --- a/third_party/androidx/committed/libs/androidx_fragment_fragment_testing/README.chromium +++ b/third_party/androidx/committed/libs/androidx_fragment_fragment_testing/README.chromium
@@ -1,6 +1,6 @@ Name: Fragment Testing Extensions Short Name: fragment-testing -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/fragment/fragment-testing/1.9.0-SNAPSHOT/fragment-testing-1.9.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/fragment/fragment-testing/1.9.0-SNAPSHOT/fragment-testing-1.9.0-20250929.054628-1.aar Version: 1.9.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_fragment_fragment_testing_manifest/README.chromium b/third_party/androidx/committed/libs/androidx_fragment_fragment_testing_manifest/README.chromium index 139e87c9..ad3b9fa1 100644 --- a/third_party/androidx/committed/libs/androidx_fragment_fragment_testing_manifest/README.chromium +++ b/third_party/androidx/committed/libs/androidx_fragment_fragment_testing_manifest/README.chromium
@@ -1,6 +1,6 @@ Name: Fragment Testing Manifest dependency Short Name: fragment-testing-manifest -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/fragment/fragment-testing-manifest/1.9.0-SNAPSHOT/fragment-testing-manifest-1.9.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/fragment/fragment-testing-manifest/1.9.0-SNAPSHOT/fragment-testing-manifest-1.9.0-20250929.054628-1.aar Version: 1.9.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_graphics_graphics_path/README.chromium b/third_party/androidx/committed/libs/androidx_graphics_graphics_path/README.chromium index da908a39..4b0f353 100644 --- a/third_party/androidx/committed/libs/androidx_graphics_graphics_path/README.chromium +++ b/third_party/androidx/committed/libs/androidx_graphics_graphics_path/README.chromium
@@ -1,6 +1,6 @@ Name: Android Graphics Path Short Name: graphics-path -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/graphics/graphics-path/1.1.0-SNAPSHOT/graphics-path-1.1.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/graphics/graphics-path/1.1.0-SNAPSHOT/graphics-path-1.1.0-20250929.054628-1.aar Version: 1.1.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_graphics_graphics_shapes_android/README.chromium b/third_party/androidx/committed/libs/androidx_graphics_graphics_shapes_android/README.chromium index 9640309..f8863a5e 100644 --- a/third_party/androidx/committed/libs/androidx_graphics_graphics_shapes_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_graphics_graphics_shapes_android/README.chromium
@@ -1,6 +1,6 @@ Name: Graphics Shapes Short Name: graphics-shapes-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/graphics/graphics-shapes-android/1.1.0-SNAPSHOT/graphics-shapes-android-1.1.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/graphics/graphics-shapes-android/1.1.0-SNAPSHOT/graphics-shapes-android-1.1.0-20250929.054628-1.aar Version: 1.1.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_interpolator_interpolator/README.chromium b/third_party/androidx/committed/libs/androidx_interpolator_interpolator/README.chromium index cfd3cf8..5762960 100644 --- a/third_party/androidx/committed/libs/androidx_interpolator_interpolator/README.chromium +++ b/third_party/androidx/committed/libs/androidx_interpolator_interpolator/README.chromium
@@ -1,6 +1,6 @@ Name: Interpolators Short Name: interpolator -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/interpolator/interpolator/1.1.0-SNAPSHOT/interpolator-1.1.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/interpolator/interpolator/1.1.0-SNAPSHOT/interpolator-1.1.0-20250929.054628-1.aar Version: 1.1.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_common_java8/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_common_java8/README.chromium index 11ef493..d702e90 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_common_java8/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_common_java8/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle-Common for Java 8 Short Name: lifecycle-common-java8 -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/lifecycle/lifecycle-common-java8/2.10.0-SNAPSHOT/lifecycle-common-java8-2.10.0-20250928.100029-1.jar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/lifecycle/lifecycle-common-java8/2.10.0-SNAPSHOT/lifecycle-common-java8-2.10.0-20250929.054628-1.jar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_common_jvm/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_common_jvm/README.chromium index d09b4381..3f635aa1 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_common_jvm/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_common_jvm/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle-Common Short Name: lifecycle-common-jvm -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/lifecycle/lifecycle-common-jvm/2.10.0-SNAPSHOT/lifecycle-common-jvm-2.10.0-20250928.100029-1.jar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/lifecycle/lifecycle-common-jvm/2.10.0-SNAPSHOT/lifecycle-common-jvm-2.10.0-20250929.054628-1.jar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata/README.chromium index 7c1e3eb..dcf99f51 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle LiveData Short Name: lifecycle-livedata -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/lifecycle/lifecycle-livedata/2.10.0-SNAPSHOT/lifecycle-livedata-2.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/lifecycle/lifecycle-livedata/2.10.0-SNAPSHOT/lifecycle-livedata-2.10.0-20250929.054628-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_core/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_core/README.chromium index 280af83..8044797 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_core/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_core/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle LiveData Core Short Name: lifecycle-livedata-core -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/lifecycle/lifecycle-livedata-core/2.10.0-SNAPSHOT/lifecycle-livedata-core-2.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/lifecycle/lifecycle-livedata-core/2.10.0-SNAPSHOT/lifecycle-livedata-core-2.10.0-20250929.054628-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_core_ktx/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_core_ktx/README.chromium index c685790..aa842a1c 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_core_ktx/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_core_ktx/README.chromium
@@ -1,6 +1,6 @@ Name: LiveData Core Kotlin Extensions Short Name: lifecycle-livedata-core-ktx -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/lifecycle/lifecycle-livedata-core-ktx/2.10.0-SNAPSHOT/lifecycle-livedata-core-ktx-2.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/lifecycle/lifecycle-livedata-core-ktx/2.10.0-SNAPSHOT/lifecycle-livedata-core-ktx-2.10.0-20250929.054628-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_ktx/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_ktx/README.chromium index 3ec12db1..13c362c9 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_ktx/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_ktx/README.chromium
@@ -1,6 +1,6 @@ Name: LiveData Kotlin Extensions Short Name: lifecycle-livedata-ktx -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/lifecycle/lifecycle-livedata-ktx/2.10.0-SNAPSHOT/lifecycle-livedata-ktx-2.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/lifecycle/lifecycle-livedata-ktx/2.10.0-SNAPSHOT/lifecycle-livedata-ktx-2.10.0-20250929.054628-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_process/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_process/README.chromium index 647c5860..6d1f766 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_process/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_process/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle Process Short Name: lifecycle-process -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/lifecycle/lifecycle-process/2.10.0-SNAPSHOT/lifecycle-process-2.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/lifecycle/lifecycle-process/2.10.0-SNAPSHOT/lifecycle-process-2.10.0-20250929.054628-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_android/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_android/README.chromium index 71bb2ca..25911c6 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_android/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle Runtime Short Name: lifecycle-runtime-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/lifecycle/lifecycle-runtime-android/2.10.0-SNAPSHOT/lifecycle-runtime-android-2.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/lifecycle/lifecycle-runtime-android/2.10.0-SNAPSHOT/lifecycle-runtime-android-2.10.0-20250929.054628-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_compose_android/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_compose_android/README.chromium index 24bb2fe..45e68bfb 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_compose_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_compose_android/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle Runtime Compose Short Name: lifecycle-runtime-compose-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/lifecycle/lifecycle-runtime-compose-android/2.10.0-SNAPSHOT/lifecycle-runtime-compose-android-2.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/lifecycle/lifecycle-runtime-compose-android/2.10.0-SNAPSHOT/lifecycle-runtime-compose-android-2.10.0-20250929.054628-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_ktx_android/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_ktx_android/README.chromium index 348a3e7..097642d 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_ktx_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_ktx_android/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle Kotlin Extensions Short Name: lifecycle-runtime-ktx-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/lifecycle/lifecycle-runtime-ktx-android/2.10.0-SNAPSHOT/lifecycle-runtime-ktx-android-2.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/lifecycle/lifecycle-runtime-ktx-android/2.10.0-SNAPSHOT/lifecycle-runtime-ktx-android-2.10.0-20250929.054628-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_service/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_service/README.chromium index 6a7746d1..68685cc 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_service/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_service/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle Service Short Name: lifecycle-service -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/lifecycle/lifecycle-service/2.10.0-SNAPSHOT/lifecycle-service-2.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/lifecycle/lifecycle-service/2.10.0-SNAPSHOT/lifecycle-service-2.10.0-20250929.054628-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_android/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_android/README.chromium index 89c1a2d5..c5439e3 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_android/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle ViewModel Short Name: lifecycle-viewmodel-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/lifecycle/lifecycle-viewmodel-android/2.10.0-SNAPSHOT/lifecycle-viewmodel-android-2.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/lifecycle/lifecycle-viewmodel-android/2.10.0-SNAPSHOT/lifecycle-viewmodel-android-2.10.0-20250929.054628-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_compose_android/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_compose_android/README.chromium index 536bfe3..3b703b3 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_compose_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_compose_android/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle ViewModel Compose Short Name: lifecycle-viewmodel-compose-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/lifecycle/lifecycle-viewmodel-compose-android/2.10.0-SNAPSHOT/lifecycle-viewmodel-compose-android-2.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/lifecycle/lifecycle-viewmodel-compose-android/2.10.0-SNAPSHOT/lifecycle-viewmodel-compose-android-2.10.0-20250929.054628-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_ktx/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_ktx/README.chromium index 5f05a084..de0e47fc 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_ktx/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_ktx/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle ViewModel Kotlin Extensions Short Name: lifecycle-viewmodel-ktx -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/lifecycle/lifecycle-viewmodel-ktx/2.10.0-SNAPSHOT/lifecycle-viewmodel-ktx-2.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/lifecycle/lifecycle-viewmodel-ktx/2.10.0-SNAPSHOT/lifecycle-viewmodel-ktx-2.10.0-20250929.054628-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_savedstate_android/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_savedstate_android/README.chromium index a708a7f..ff01669 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_savedstate_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_savedstate_android/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle ViewModel with SavedState Short Name: lifecycle-viewmodel-savedstate-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/lifecycle/lifecycle-viewmodel-savedstate-android/2.10.0-SNAPSHOT/lifecycle-viewmodel-savedstate-android-2.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/lifecycle/lifecycle-viewmodel-savedstate-android/2.10.0-SNAPSHOT/lifecycle-viewmodel-savedstate-android-2.10.0-20250929.054628-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_loader_loader/README.chromium b/third_party/androidx/committed/libs/androidx_loader_loader/README.chromium index 8f11085..7e51d5c 100644 --- a/third_party/androidx/committed/libs/androidx_loader_loader/README.chromium +++ b/third_party/androidx/committed/libs/androidx_loader_loader/README.chromium
@@ -1,6 +1,6 @@ Name: loader Short Name: loader -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/loader/loader/1.2.0-SNAPSHOT/loader-1.2.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/loader/loader/1.2.0-SNAPSHOT/loader-1.2.0-20250929.054628-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_media_media/README.chromium b/third_party/androidx/committed/libs/androidx_media_media/README.chromium index b050b52..36e9177 100644 --- a/third_party/androidx/committed/libs/androidx_media_media/README.chromium +++ b/third_party/androidx/committed/libs/androidx_media_media/README.chromium
@@ -1,6 +1,6 @@ Name: Media Short Name: media -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/media/media/1.8.0-SNAPSHOT/media-1.8.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/media/media/1.8.0-SNAPSHOT/media-1.8.0-20250929.054628-1.aar Version: 1.8.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_navigation_navigation_common_android/README.chromium b/third_party/androidx/committed/libs/androidx_navigation_navigation_common_android/README.chromium index adc1d1e0..8520c89 100644 --- a/third_party/androidx/committed/libs/androidx_navigation_navigation_common_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_navigation_navigation_common_android/README.chromium
@@ -1,6 +1,6 @@ Name: Navigation Common Short Name: navigation-common-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/navigation/navigation-common-android/2.10.0-SNAPSHOT/navigation-common-android-2.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/navigation/navigation-common-android/2.10.0-SNAPSHOT/navigation-common-android-2.10.0-20250929.054628-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_navigation_navigation_compose_android/README.chromium b/third_party/androidx/committed/libs/androidx_navigation_navigation_compose_android/README.chromium index 3758dc1..276f763 100644 --- a/third_party/androidx/committed/libs/androidx_navigation_navigation_compose_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_navigation_navigation_compose_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Navigation Short Name: navigation-compose-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/navigation/navigation-compose-android/2.10.0-SNAPSHOT/navigation-compose-android-2.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/navigation/navigation-compose-android/2.10.0-SNAPSHOT/navigation-compose-android-2.10.0-20250929.054628-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_navigation_navigation_runtime_android/README.chromium b/third_party/androidx/committed/libs/androidx_navigation_navigation_runtime_android/README.chromium index dcfdb69..9f59b7c6 100644 --- a/third_party/androidx/committed/libs/androidx_navigation_navigation_runtime_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_navigation_navigation_runtime_android/README.chromium
@@ -1,6 +1,6 @@ Name: Navigation Runtime Short Name: navigation-runtime-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/navigation/navigation-runtime-android/2.10.0-SNAPSHOT/navigation-runtime-android-2.10.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/navigation/navigation-runtime-android/2.10.0-SNAPSHOT/navigation-runtime-android-2.10.0-20250929.054628-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_navigationevent_navigationevent_android/README.chromium b/third_party/androidx/committed/libs/androidx_navigationevent_navigationevent_android/README.chromium index 18c9970..446353a 100644 --- a/third_party/androidx/committed/libs/androidx_navigationevent_navigationevent_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_navigationevent_navigationevent_android/README.chromium
@@ -1,6 +1,6 @@ Name: Navigation Event Short Name: navigationevent-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/navigationevent/navigationevent-android/1.0.0-SNAPSHOT/navigationevent-android-1.0.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/navigationevent/navigationevent-android/1.0.0-SNAPSHOT/navigationevent-android-1.0.0-20250929.054628-1.aar Version: 1.0.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_navigationevent_navigationevent_compose_android/README.chromium b/third_party/androidx/committed/libs/androidx_navigationevent_navigationevent_compose_android/README.chromium index 1ddfd8d..450104b5 100644 --- a/third_party/androidx/committed/libs/androidx_navigationevent_navigationevent_compose_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_navigationevent_navigationevent_compose_android/README.chromium
@@ -1,6 +1,6 @@ Name: NavigationEvent Compose Short Name: navigationevent-compose-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/navigationevent/navigationevent-compose-android/1.0.0-SNAPSHOT/navigationevent-compose-android-1.0.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/navigationevent/navigationevent-compose-android/1.0.0-SNAPSHOT/navigationevent-compose-android-1.0.0-20250929.054628-1.aar Version: 1.0.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_paging_paging_common_android/README.chromium b/third_party/androidx/committed/libs/androidx_paging_paging_common_android/README.chromium index 265afdfa..f7da9a4 100644 --- a/third_party/androidx/committed/libs/androidx_paging_paging_common_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_paging_paging_common_android/README.chromium
@@ -1,6 +1,6 @@ Name: Paging-Common Short Name: paging-common-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/paging/paging-common-android/3.4.0-SNAPSHOT/paging-common-android-3.4.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/paging/paging-common-android/3.4.0-SNAPSHOT/paging-common-android-3.4.0-20250929.054628-1.aar Version: 3.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_paging_paging_common_ktx/README.chromium b/third_party/androidx/committed/libs/androidx_paging_paging_common_ktx/README.chromium index 3b8b23f8c..7571323 100644 --- a/third_party/androidx/committed/libs/androidx_paging_paging_common_ktx/README.chromium +++ b/third_party/androidx/committed/libs/androidx_paging_paging_common_ktx/README.chromium
@@ -1,6 +1,6 @@ Name: Paging-Common Kotlin Extensions Short Name: paging-common-ktx -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/paging/paging-common-ktx/3.4.0-SNAPSHOT/paging-common-ktx-3.4.0-20250928.100029-1.jar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/paging/paging-common-ktx/3.4.0-SNAPSHOT/paging-common-ktx-3.4.0-20250929.054628-1.jar Version: 3.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_paging_paging_compose_android/README.chromium b/third_party/androidx/committed/libs/androidx_paging_paging_compose_android/README.chromium index 791f811e..00a17ab 100644 --- a/third_party/androidx/committed/libs/androidx_paging_paging_compose_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_paging_paging_compose_android/README.chromium
@@ -1,6 +1,6 @@ Name: Paging-Compose Short Name: paging-compose-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/paging/paging-compose-android/3.4.0-SNAPSHOT/paging-compose-android-3.4.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/paging/paging-compose-android/3.4.0-SNAPSHOT/paging-compose-android-3.4.0-20250929.054628-1.aar Version: 3.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_paging_paging_runtime/README.chromium b/third_party/androidx/committed/libs/androidx_paging_paging_runtime/README.chromium index 83be0b9..4390a51a 100644 --- a/third_party/androidx/committed/libs/androidx_paging_paging_runtime/README.chromium +++ b/third_party/androidx/committed/libs/androidx_paging_paging_runtime/README.chromium
@@ -1,6 +1,6 @@ Name: Paging-Runtime Short Name: paging-runtime -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/paging/paging-runtime/3.4.0-SNAPSHOT/paging-runtime-3.4.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/paging/paging-runtime/3.4.0-SNAPSHOT/paging-runtime-3.4.0-20250929.054628-1.aar Version: 3.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_palette_palette/README.chromium b/third_party/androidx/committed/libs/androidx_palette_palette/README.chromium index a2dfc31d..5a3485e 100644 --- a/third_party/androidx/committed/libs/androidx_palette_palette/README.chromium +++ b/third_party/androidx/committed/libs/androidx_palette_palette/README.chromium
@@ -1,6 +1,6 @@ Name: Palette Short Name: palette -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/palette/palette/1.1.0-SNAPSHOT/palette-1.1.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/palette/palette/1.1.0-SNAPSHOT/palette-1.1.0-20250929.054628-1.aar Version: 1.1.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_preference_preference/README.chromium b/third_party/androidx/committed/libs/androidx_preference_preference/README.chromium index 8cd6b1c..ca47406 100644 --- a/third_party/androidx/committed/libs/androidx_preference_preference/README.chromium +++ b/third_party/androidx/committed/libs/androidx_preference_preference/README.chromium
@@ -1,6 +1,6 @@ Name: Preference Short Name: preference -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/preference/preference/1.3.0-SNAPSHOT/preference-1.3.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/preference/preference/1.3.0-SNAPSHOT/preference-1.3.0-20250929.054628-1.aar Version: 1.3.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_profileinstaller_profileinstaller/README.chromium b/third_party/androidx/committed/libs/androidx_profileinstaller_profileinstaller/README.chromium index e07117d3..05fb5e1 100644 --- a/third_party/androidx/committed/libs/androidx_profileinstaller_profileinstaller/README.chromium +++ b/third_party/androidx/committed/libs/androidx_profileinstaller_profileinstaller/README.chromium
@@ -1,6 +1,6 @@ Name: Profile Installer Short Name: profileinstaller -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/profileinstaller/profileinstaller/1.5.0-SNAPSHOT/profileinstaller-1.5.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/profileinstaller/profileinstaller/1.5.0-SNAPSHOT/profileinstaller-1.5.0-20250929.054628-1.aar Version: 1.5.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_recyclerview_recyclerview/README.chromium b/third_party/androidx/committed/libs/androidx_recyclerview_recyclerview/README.chromium index f9fa76e3..a493e4b 100644 --- a/third_party/androidx/committed/libs/androidx_recyclerview_recyclerview/README.chromium +++ b/third_party/androidx/committed/libs/androidx_recyclerview_recyclerview/README.chromium
@@ -1,6 +1,6 @@ Name: RecyclerView Short Name: recyclerview -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/recyclerview/recyclerview/1.5.0-SNAPSHOT/recyclerview-1.5.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/recyclerview/recyclerview/1.5.0-SNAPSHOT/recyclerview-1.5.0-20250929.054628-1.aar Version: 1.5.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_resourceinspection_resourceinspection_annotation/README.chromium b/third_party/androidx/committed/libs/androidx_resourceinspection_resourceinspection_annotation/README.chromium index 1834d54..ea5fc8d 100644 --- a/third_party/androidx/committed/libs/androidx_resourceinspection_resourceinspection_annotation/README.chromium +++ b/third_party/androidx/committed/libs/androidx_resourceinspection_resourceinspection_annotation/README.chromium
@@ -1,6 +1,6 @@ Name: Resource Inspection - Annotations Short Name: resourceinspection-annotation -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/resourceinspection/resourceinspection-annotation/1.1.0-SNAPSHOT/resourceinspection-annotation-1.1.0-20250928.100029-1.jar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/resourceinspection/resourceinspection-annotation/1.1.0-SNAPSHOT/resourceinspection-annotation-1.1.0-20250929.054628-1.jar Version: 1.1.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_savedstate_savedstate_android/README.chromium b/third_party/androidx/committed/libs/androidx_savedstate_savedstate_android/README.chromium index fcb9120..74f22031 100644 --- a/third_party/androidx/committed/libs/androidx_savedstate_savedstate_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_savedstate_savedstate_android/README.chromium
@@ -1,6 +1,6 @@ Name: Saved State Short Name: savedstate-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/savedstate/savedstate-android/1.4.0-SNAPSHOT/savedstate-android-1.4.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/savedstate/savedstate-android/1.4.0-SNAPSHOT/savedstate-android-1.4.0-20250929.054628-1.aar Version: 1.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_savedstate_savedstate_compose_android/README.chromium b/third_party/androidx/committed/libs/androidx_savedstate_savedstate_compose_android/README.chromium index 3d5e493..957cf3f 100644 --- a/third_party/androidx/committed/libs/androidx_savedstate_savedstate_compose_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_savedstate_savedstate_compose_android/README.chromium
@@ -1,6 +1,6 @@ Name: Saved State Compose Short Name: savedstate-compose-android -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/savedstate/savedstate-compose-android/1.4.0-SNAPSHOT/savedstate-compose-android-1.4.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/savedstate/savedstate-compose-android/1.4.0-SNAPSHOT/savedstate-compose-android-1.4.0-20250929.054628-1.aar Version: 1.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_savedstate_savedstate_ktx/README.chromium b/third_party/androidx/committed/libs/androidx_savedstate_savedstate_ktx/README.chromium index 57f4ecb3..f8c8976 100644 --- a/third_party/androidx/committed/libs/androidx_savedstate_savedstate_ktx/README.chromium +++ b/third_party/androidx/committed/libs/androidx_savedstate_savedstate_ktx/README.chromium
@@ -1,6 +1,6 @@ Name: SavedState Kotlin Extensions Short Name: savedstate-ktx -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/savedstate/savedstate-ktx/1.4.0-SNAPSHOT/savedstate-ktx-1.4.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/savedstate/savedstate-ktx/1.4.0-SNAPSHOT/savedstate-ktx-1.4.0-20250929.054628-1.aar Version: 1.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_slidingpanelayout_slidingpanelayout/README.chromium b/third_party/androidx/committed/libs/androidx_slidingpanelayout_slidingpanelayout/README.chromium index 999a3c85..c70e573 100644 --- a/third_party/androidx/committed/libs/androidx_slidingpanelayout_slidingpanelayout/README.chromium +++ b/third_party/androidx/committed/libs/androidx_slidingpanelayout_slidingpanelayout/README.chromium
@@ -1,6 +1,6 @@ Name: Sliding Pane Layout Short Name: slidingpanelayout -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/slidingpanelayout/slidingpanelayout/1.3.0-SNAPSHOT/slidingpanelayout-1.3.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/slidingpanelayout/slidingpanelayout/1.3.0-SNAPSHOT/slidingpanelayout-1.3.0-20250929.054628-1.aar Version: 1.3.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_swiperefreshlayout_swiperefreshlayout/README.chromium b/third_party/androidx/committed/libs/androidx_swiperefreshlayout_swiperefreshlayout/README.chromium index 1d3e10a..ff066852 100644 --- a/third_party/androidx/committed/libs/androidx_swiperefreshlayout_swiperefreshlayout/README.chromium +++ b/third_party/androidx/committed/libs/androidx_swiperefreshlayout_swiperefreshlayout/README.chromium
@@ -1,6 +1,6 @@ Name: Swipe Refresh Layout Short Name: swiperefreshlayout -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/swiperefreshlayout/swiperefreshlayout/1.2.0-SNAPSHOT/swiperefreshlayout-1.2.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/swiperefreshlayout/swiperefreshlayout/1.2.0-SNAPSHOT/swiperefreshlayout-1.2.0-20250929.054628-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_test_uiautomator_uiautomator/README.chromium b/third_party/androidx/committed/libs/androidx_test_uiautomator_uiautomator/README.chromium index 9d623d30..b50d6c35 100644 --- a/third_party/androidx/committed/libs/androidx_test_uiautomator_uiautomator/README.chromium +++ b/third_party/androidx/committed/libs/androidx_test_uiautomator_uiautomator/README.chromium
@@ -1,6 +1,6 @@ Name: UIAutomator Short Name: uiautomator -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/test/uiautomator/uiautomator/2.4.0-SNAPSHOT/uiautomator-2.4.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/test/uiautomator/uiautomator/2.4.0-SNAPSHOT/uiautomator-2.4.0-20250929.054628-1.aar Version: 2.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_transition_transition/README.chromium b/third_party/androidx/committed/libs/androidx_transition_transition/README.chromium index a9ba8f4a..3327fce 100644 --- a/third_party/androidx/committed/libs/androidx_transition_transition/README.chromium +++ b/third_party/androidx/committed/libs/androidx_transition_transition/README.chromium
@@ -1,6 +1,6 @@ Name: Transition Short Name: transition -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/transition/transition/1.7.0-SNAPSHOT/transition-1.7.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/transition/transition/1.7.0-SNAPSHOT/transition-1.7.0-20250929.054628-1.aar Version: 1.7.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_viewpager2_viewpager2/README.chromium b/third_party/androidx/committed/libs/androidx_viewpager2_viewpager2/README.chromium index c82f78a5..dca06627 100644 --- a/third_party/androidx/committed/libs/androidx_viewpager2_viewpager2/README.chromium +++ b/third_party/androidx/committed/libs/androidx_viewpager2_viewpager2/README.chromium
@@ -1,6 +1,6 @@ Name: ViewPager2 Short Name: viewpager2 -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/viewpager2/viewpager2/1.2.0-SNAPSHOT/viewpager2-1.2.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/viewpager2/viewpager2/1.2.0-SNAPSHOT/viewpager2-1.2.0-20250929.054628-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_webkit_webkit/README.chromium b/third_party/androidx/committed/libs/androidx_webkit_webkit/README.chromium index cc0d43a..51aa28d 100644 --- a/third_party/androidx/committed/libs/androidx_webkit_webkit/README.chromium +++ b/third_party/androidx/committed/libs/androidx_webkit_webkit/README.chromium
@@ -1,6 +1,6 @@ Name: WebKit Short Name: webkit -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/webkit/webkit/1.15.0-SNAPSHOT/webkit-1.15.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/webkit/webkit/1.15.0-SNAPSHOT/webkit-1.15.0-20250929.054628-1.aar Version: 1.15.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_window_sidecar_sidecar/README.chromium b/third_party/androidx/committed/libs/androidx_window_sidecar_sidecar/README.chromium index 65c89a9..73029b3 100644 --- a/third_party/androidx/committed/libs/androidx_window_sidecar_sidecar/README.chromium +++ b/third_party/androidx/committed/libs/androidx_window_sidecar_sidecar/README.chromium
@@ -1,6 +1,6 @@ Name: WindowManager Sidecar Short Name: sidecar -URL: https://androidx.dev/snapshots/builds/14180086/artifacts/repository/androidx/window/sidecar/sidecar/1.0.0-SNAPSHOT/sidecar-1.0.0-20250928.100029-1.aar +URL: https://androidx.dev/snapshots/builds/14181415/artifacts/repository/androidx/window/sidecar/sidecar/1.0.0-SNAPSHOT/sidecar-1.0.0-20250929.054628-1.aar Version: 1.0.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/angle b/third_party/angle index 7a7681c..6286120 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit 7a7681cc8f888e72663530ca2cc997d9febd08e0 +Subproject commit 62861200bff6e265d6518ef1faa0f2eb90439dbc
diff --git a/third_party/blink/public/mojom/use_counter/metrics/webdx_feature.mojom b/third_party/blink/public/mojom/use_counter/metrics/webdx_feature.mojom index 6eea96b..4f552103 100644 --- a/third_party/blink/public/mojom/use_counter/metrics/webdx_feature.mojom +++ b/third_party/blink/public/mojom/use_counter/metrics/webdx_feature.mojom
@@ -470,6 +470,7 @@ kWebxrHitTest = 408, kWebxrLightingEstimation = 409, kReporting = 410, + kFontLanguageOverride = 411, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py b/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py index 97a87c6..3ca4254 100644 --- a/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py +++ b/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py
@@ -643,23 +643,7 @@ ]) return func_def - def make_api_set_enum_string(member): - type_info = blink_type_info(member.idl_type.unwrap()) - func_def = CxxFuncDefNode(name=member.api_set, - arg_decls=["const String& value"], - return_type="void") - func_def.set_base_template_vars(cg_context.template_bindings()) - func_def.body.append( - F("{} = {}::Create(value).value();", member.value_var, - type_info.value_t)) - if member.does_use_presence_var: - func_def.body.append(F("{} = true;", member.presence_var)) - return func_def - for member in cg_context.dictionary_own_members: - if member.idl_type.unwrap().is_enumeration: - decls.append(make_api_set_enum_string(member)) - if (not member.idl_type.unwrap(nullable=False).is_nullable or member.type_info.has_null_value): continue
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h index 149af8f..fe2dd68 100644 --- a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h +++ b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h
@@ -198,7 +198,6 @@ NOTREACHED(); } virtual bool IsPaintable() const = 0; - virtual bool IsHibernating() const { return false; } void DidDraw(CanvasPerformanceMonitor::DrawType draw_type) { const CanvasRenderingContextHost* const host = Host(); return DidDraw(host ? SkIRect::MakeWH(host->width(), host->height())
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc index 5a808631..849bedf2 100644 --- a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc +++ b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc
@@ -181,9 +181,7 @@ if (RenderingContext()) { // This method is supported only on 2D contexts. CHECK(IsRenderingContext2D()); - return RenderingContext()->IsHibernating() - ? false - : RenderingContext()->Is2DCanvasAccelerated(); + return RenderingContext()->Is2DCanvasAccelerated(); } // Whether or not to accelerate is not yet resolved, the canvas cannot be
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc index 58df65ce..7831167 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
@@ -785,6 +785,10 @@ } bool BaseRenderingContext2D::Is2DCanvasAccelerated() const { + if (IsHibernating()) { + return false; + } + auto* resource_provider = GetResourceProvider(); return resource_provider ? resource_provider->IsAccelerated() : Host()->ShouldTryToUseGpuRaster();
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h index 0f36b22f..7d7bd7e 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h +++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.h
@@ -303,6 +303,7 @@ bool context_restorable_{true}; private: + virtual bool IsHibernating() const { return false; } virtual CanvasResourceProvider* GetResourceProvider() const { NOTREACHED(); } virtual void EnableAccelerationIfPossible() {} void DrawTextInternal(const String& text,
diff --git a/third_party/blink/renderer/modules/media_capabilities/media_capabilities_fuzzer.cc b/third_party/blink/renderer/modules/media_capabilities/media_capabilities_fuzzer.cc index 259ba1bc..42bbd4b7 100644 --- a/third_party/blink/renderer/modules/media_capabilities/media_capabilities_fuzzer.cc +++ b/third_party/blink/renderer/modules/media_capabilities/media_capabilities_fuzzer.cc
@@ -28,21 +28,21 @@ namespace blink { -String MediaKeysRequirementToString( +V8MediaKeysRequirement::Enum MediaKeysRequirementToIdlEnum( mc_fuzzer::MediaConfigProto_KeySystemConfig_MediaKeysRequirement proto_requirement) { switch (proto_requirement) { case mc_fuzzer:: MediaConfigProto_KeySystemConfig_MediaKeysRequirement_REQUIRED: - return "required"; + return V8MediaKeysRequirement::Enum::kRequired; case mc_fuzzer:: MediaConfigProto_KeySystemConfig_MediaKeysRequirement_NOT_REQUIRED: - return "optional"; + return V8MediaKeysRequirement::Enum::kOptional; case mc_fuzzer:: MediaConfigProto_KeySystemConfig_MediaKeysRequirement_NOT_ALLOWED: - return "not-allowed"; + return V8MediaKeysRequirement::Enum::kNotAllowed; } - return ""; + NOTREACHED(); } Vector<String> MediaSessionTypeToVector( @@ -65,9 +65,8 @@ return result; } -template <class T> -T* MakeConfiguration(const mc_fuzzer::MediaConfigProto& proto) { - Persistent<T> config = T::Create(); +void AddMediaConfiguration(const mc_fuzzer::MediaConfigProto& proto, + MediaConfiguration* config) { if (proto.has_video()) { config->setVideo(VideoConfiguration::Create()); config->video()->setContentType(proto.video().content_type().c_str()); @@ -87,24 +86,24 @@ config->audio()->setBitrate(proto.audio().bitrate()); config->audio()->setSamplerate(proto.audio().samplerate()); } - - switch (proto.type()) { - case mc_fuzzer::MediaConfigProto_MediaType_DECODING_FILE: - config->setType("file"); - break; - case mc_fuzzer::MediaConfigProto_MediaType_DECODING_MEDIA_SOURCE: - config->setType("media-source"); - break; - case mc_fuzzer::MediaConfigProto_MediaType_DECODING_WEBRTC: - case mc_fuzzer::MediaConfigProto_MediaType_ENCODING_WEBRTC: - config->setType("webrtc"); - break; - } - return config; } void AddDecodingSpecificConfiguration(const mc_fuzzer::MediaConfigProto& proto, MediaDecodingConfiguration* config) { + switch (proto.type()) { + case mc_fuzzer::MediaConfigProto_MediaType_DECODING_FILE: + config->setType(V8MediaDecodingType::Enum::kFile); + break; + case mc_fuzzer::MediaConfigProto_MediaType_DECODING_MEDIA_SOURCE: + config->setType(V8MediaDecodingType::Enum::kMediaSource); + break; + case mc_fuzzer::MediaConfigProto_MediaType_DECODING_WEBRTC: + config->setType(V8MediaDecodingType::Enum::kWebrtc); + break; + case mc_fuzzer::MediaConfigProto_MediaType_ENCODING_WEBRTC: + NOTREACHED(); + } + if (proto.has_key_system_config()) { config->setKeySystemConfiguration( MediaCapabilitiesKeySystemConfiguration::Create()); @@ -113,10 +112,10 @@ config->keySystemConfiguration()->setInitDataType( String::FromUTF8(proto.key_system_config().init_data_type().c_str())); config->keySystemConfiguration()->setDistinctiveIdentifier( - MediaKeysRequirementToString( + MediaKeysRequirementToIdlEnum( proto.key_system_config().distinctive_identifier())); config->keySystemConfiguration()->setPersistentState( - MediaKeysRequirementToString( + MediaKeysRequirementToIdlEnum( proto.key_system_config().persistent_state())); config->keySystemConfiguration()->setSessionTypes( MediaSessionTypeToVector(proto.key_system_config().session_types())); @@ -142,6 +141,19 @@ } } +void AddEncodingSpecificConfiguration(const mc_fuzzer::MediaConfigProto& proto, + MediaEncodingConfiguration* config) { + switch (proto.type()) { + case mc_fuzzer::MediaConfigProto_MediaType_ENCODING_WEBRTC: + config->setType(V8MediaEncodingType::Enum::kWebrtc); + break; + case mc_fuzzer::MediaConfigProto_MediaType_DECODING_FILE: + case mc_fuzzer::MediaConfigProto_MediaType_DECODING_MEDIA_SOURCE: + case mc_fuzzer::MediaConfigProto_MediaType_DECODING_WEBRTC: + NOTREACHED(); + } +} + DEFINE_TEXT_PROTO_FUZZER(const mc_fuzzer::MediaConfigProto& proto) { static BlinkFuzzerTestSupport test_support = BlinkFuzzerTestSupport(); test::TaskEnvironment task_environment; @@ -159,13 +171,16 @@ case mc_fuzzer::MediaConfigProto_MediaType_DECODING_FILE: case mc_fuzzer::MediaConfigProto_MediaType_DECODING_MEDIA_SOURCE: case mc_fuzzer::MediaConfigProto_MediaType_DECODING_WEBRTC: { - auto* config = MakeConfiguration<MediaDecodingConfiguration>(proto); + auto* config = MediaDecodingConfiguration::Create(); + AddMediaConfiguration(proto, config); AddDecodingSpecificConfiguration(proto, config); media_capabilities->decodingInfo(script_state, config, IGNORE_EXCEPTION_FOR_TESTING); } break; case mc_fuzzer::MediaConfigProto_MediaType_ENCODING_WEBRTC: { - auto* config = MakeConfiguration<MediaEncodingConfiguration>(proto); + auto* config = MediaEncodingConfiguration::Create(); + AddMediaConfiguration(proto, config); + AddEncodingSpecificConfiguration(proto, config); media_capabilities->encodingInfo(script_state, config, IGNORE_EXCEPTION_FOR_TESTING); } break;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.cc b/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.cc index 490215f..ba1a621 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.cc
@@ -70,8 +70,10 @@ if (should_fire_callback && success_callback_) { RTCSessionDescriptionInit* description = RTCSessionDescriptionInit::Create(); - if (description_platform->GetType()) - description->setType(description_platform->GetType()); + if (description_platform->GetType()) { + description->setType( + V8RTCSdpType::Create(description_platform->GetType()).value()); + } description->setSdp(description_platform->Sdp()); requester_->NoteSdpCreated(*description);
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.cc b/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.cc index 1c03ba6..f7dc58b 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.cc
@@ -38,7 +38,8 @@ RTCSessionDescriptionPlatform* platform_session_description) { if (requester_ && requester_->ShouldFireDefaultCallbacks()) { auto* description = RTCSessionDescriptionInit::Create(); - description->setType(platform_session_description->GetType()); + description->setType( + V8RTCSdpType::Create(platform_session_description->GetType()).value()); description->setSdp(platform_session_description->Sdp()); requester_->NoteSdpCreated(*description); resolver_->Resolve(description);
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc b/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc index 9306b11..542861e 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc
@@ -64,6 +64,12 @@ v8_setter(StatsConversionHelper(*webrtc_stat)); \ } +#define SET_STAT_ENUM(webrtc_stat, v8_setter, V8EnumType) \ + if (webrtc_stat.has_value()) { \ + v8_setter( \ + V8EnumType::Create(StatsConversionHelper(*webrtc_stat)).value()); \ + } + template <typename T> v8::Local<v8::Value> HashMapToValue(ScriptState* script_state, HashMap<String, T>&& map) { @@ -291,8 +297,9 @@ SET_STAT(webrtc_stat.total_encode_time, v8_stat->setTotalEncodeTime); SET_STAT(webrtc_stat.total_packet_send_delay, v8_stat->setTotalPacketSendDelay); - SET_STAT(webrtc_stat.quality_limitation_reason, - v8_stat->setQualityLimitationReason); + SET_STAT_ENUM(webrtc_stat.quality_limitation_reason, + v8_stat->setQualityLimitationReason, + V8RTCQualityLimitationReason); if (webrtc_stat.quality_limitation_durations.has_value()) { Vector<std::pair<String, double>> quality_durations; for (const auto& [key, value] : *webrtc_stat.quality_limitation_durations) { @@ -426,7 +433,7 @@ SET_STAT(webrtc_stat.protocol, v8_stat->setProtocol); SET_STAT(webrtc_stat.data_channel_identifier, v8_stat->setDataChannelIdentifier); - SET_STAT(webrtc_stat.state, v8_stat->setState); + SET_STAT_ENUM(webrtc_stat.state, v8_stat->setState, V8RTCDataChannelState); SET_STAT(webrtc_stat.messages_sent, v8_stat->setMessagesSent); SET_STAT(webrtc_stat.bytes_sent, v8_stat->setBytesSent); SET_STAT(webrtc_stat.messages_received, v8_stat->setMessagesReceived); @@ -444,18 +451,20 @@ SET_STAT(webrtc_stat.packets_received, v8_stat->setPacketsReceived); SET_STAT(webrtc_stat.bytes_sent, v8_stat->setBytesSent); SET_STAT(webrtc_stat.bytes_received, v8_stat->setBytesReceived); - SET_STAT(webrtc_stat.ice_role, v8_stat->setIceRole); + SET_STAT_ENUM(webrtc_stat.ice_role, v8_stat->setIceRole, V8RTCIceRole); SET_STAT(webrtc_stat.ice_local_username_fragment, v8_stat->setIceLocalUsernameFragment); - SET_STAT(webrtc_stat.dtls_state, v8_stat->setDtlsState); - SET_STAT(webrtc_stat.ice_state, v8_stat->setIceState); + SET_STAT_ENUM(webrtc_stat.dtls_state, v8_stat->setDtlsState, + V8RTCDtlsTransportState); + SET_STAT_ENUM(webrtc_stat.ice_state, v8_stat->setIceState, + V8RTCIceTransportState); SET_STAT(webrtc_stat.selected_candidate_pair_id, v8_stat->setSelectedCandidatePairId); SET_STAT(webrtc_stat.local_certificate_id, v8_stat->setLocalCertificateId); SET_STAT(webrtc_stat.remote_certificate_id, v8_stat->setRemoteCertificateId); SET_STAT(webrtc_stat.tls_version, v8_stat->setTlsVersion); SET_STAT(webrtc_stat.dtls_cipher, v8_stat->setDtlsCipher); - SET_STAT(webrtc_stat.dtls_role, v8_stat->setDtlsRole); + SET_STAT_ENUM(webrtc_stat.dtls_role, v8_stat->setDtlsRole, V8RTCDtlsRole); SET_STAT(webrtc_stat.srtp_cipher, v8_stat->setSrtpCipher); SET_STAT(webrtc_stat.selected_candidate_pair_changes, v8_stat->setSelectedCandidatePairChanges); @@ -477,18 +486,22 @@ SET_STAT(webrtc_stat.address, v8_stat->setAddress); SET_STAT(webrtc_stat.port, v8_stat->setPort); SET_STAT(webrtc_stat.protocol, v8_stat->setProtocol); - SET_STAT(webrtc_stat.candidate_type, v8_stat->setCandidateType); + SET_STAT_ENUM(webrtc_stat.candidate_type, v8_stat->setCandidateType, + V8RTCIceCandidateType); SET_STAT(webrtc_stat.priority, v8_stat->setPriority); SET_STAT(webrtc_stat.url, v8_stat->setUrl); - SET_STAT(webrtc_stat.relay_protocol, v8_stat->setRelayProtocol); + SET_STAT_ENUM(webrtc_stat.relay_protocol, v8_stat->setRelayProtocol, + V8RTCIceServerTransportProtocol); SET_STAT(webrtc_stat.foundation, v8_stat->setFoundation); SET_STAT(webrtc_stat.related_address, v8_stat->setRelatedAddress); SET_STAT(webrtc_stat.related_port, v8_stat->setRelatedPort); SET_STAT(webrtc_stat.username_fragment, v8_stat->setUsernameFragment); - SET_STAT(webrtc_stat.tcp_type, v8_stat->setTcpType); + SET_STAT_ENUM(webrtc_stat.tcp_type, v8_stat->setTcpType, + V8RTCIceTcpCandidateType); // https://w3c.github.io/webrtc-provisional-stats/#dom-rtcicecandidatestats-networktype // Note: additional work needed to reach consensus on the privacy model. - SET_STAT(webrtc_stat.network_type, v8_stat->setNetworkType); + SET_STAT_ENUM(webrtc_stat.network_type, v8_stat->setNetworkType, + V8RTCNetworkType); // Non-standard and obsolete stats. SET_STAT(webrtc_stat.is_remote, v8_stat->setIsRemote); SET_STAT(webrtc_stat.ip, v8_stat->setIp); @@ -505,7 +518,8 @@ SET_STAT(webrtc_stat.transport_id, v8_stat->setTransportId); SET_STAT(webrtc_stat.local_candidate_id, v8_stat->setLocalCandidateId); SET_STAT(webrtc_stat.remote_candidate_id, v8_stat->setRemoteCandidateId); - SET_STAT(webrtc_stat.state, v8_stat->setState); + SET_STAT_ENUM(webrtc_stat.state, v8_stat->setState, + V8RTCStatsIceCandidatePairState); SET_STAT(webrtc_stat.nominated, v8_stat->setNominated); SET_STAT(webrtc_stat.packets_sent, v8_stat->setPacketsSent); SET_STAT(webrtc_stat.packets_received, v8_stat->setPacketsReceived);
diff --git a/third_party/blink/renderer/modules/smart_card/OWNERS b/third_party/blink/renderer/modules/smart_card/OWNERS index 17811e8..1f114915 100644 --- a/third_party/blink/renderer/modules/smart_card/OWNERS +++ b/third_party/blink/renderer/modules/smart_card/OWNERS
@@ -2,6 +2,7 @@ # For backup greengrape@google.com +simonha@google.com # Changes to Mojo interfaces require a security review to avoid # introducing new sandbox escapes.
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc index da74122..9204915 100644 --- a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc +++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.cc
@@ -193,27 +193,27 @@ return config; } -String ToAccelerationType( +V8HardwarePreference::Enum ToAccelerationType( wc_fuzzer::ConfigureVideoEncoder_EncoderAccelerationPreference type) { switch (type) { case wc_fuzzer::ConfigureVideoEncoder_EncoderAccelerationPreference_ALLOW: - return "no-preference"; + return V8HardwarePreference::Enum::kNoPreference; case wc_fuzzer::ConfigureVideoEncoder_EncoderAccelerationPreference_DENY: - return "prefer-software"; + return V8HardwarePreference::Enum::kPreferSoftware; case wc_fuzzer::ConfigureVideoEncoder_EncoderAccelerationPreference_REQUIRE: - return "prefer-hardware"; + return V8HardwarePreference::Enum::kPreferHardware; } } -String ToBitrateMode( +V8VideoEncoderBitrateMode::Enum ToBitrateMode( wc_fuzzer::ConfigureVideoEncoder_VideoEncoderBitrateMode mode) { switch (mode) { case wc_fuzzer::ConfigureVideoEncoder_VideoEncoderBitrateMode_CONSTANT: - return "constant"; + return V8VideoEncoderBitrateMode::Enum::kConstant; case wc_fuzzer::ConfigureVideoEncoder_VideoEncoderBitrateMode_VARIABLE: - return "variable"; + return V8VideoEncoderBitrateMode::Enum::kVariable; case wc_fuzzer::ConfigureVideoEncoder_VideoEncoderBitrateMode_QUANTIZER: - return "quantizer"; + return V8VideoEncoderBitrateMode::Enum::kQuantizer; } } @@ -229,12 +229,13 @@ } } -String ToLatencyMode(wc_fuzzer::ConfigureVideoEncoder_LatencyMode mode) { +V8LatencyMode::Enum ToLatencyMode( + wc_fuzzer::ConfigureVideoEncoder_LatencyMode mode) { switch (mode) { case wc_fuzzer::ConfigureVideoEncoder_LatencyMode_QUALITY: - return "quality"; + return V8LatencyMode::Enum::kQuality; case wc_fuzzer::ConfigureVideoEncoder_LatencyMode_REALTIME: - return "realtime"; + return V8LatencyMode::Enum::kRealtime; } } @@ -251,82 +252,96 @@ } } -String ToAlphaOption(wc_fuzzer::ConfigureVideoEncoder_AlphaOption option) { +V8AlphaOption::Enum ToAlphaOption( + wc_fuzzer::ConfigureVideoEncoder_AlphaOption option) { switch (option) { case wc_fuzzer::ConfigureVideoEncoder_AlphaOption_KEEP: - return "keep"; + return V8AlphaOption::Enum::kKeep; case wc_fuzzer::ConfigureVideoEncoder_AlphaOption_DISCARD: - return "discard"; + return V8AlphaOption::Enum::kDiscard; } } -String ToAacFormat(wc_fuzzer::AacFormat format) { +V8AacBitstreamFormat::Enum ToAacFormat(wc_fuzzer::AacFormat format) { switch (format) { case wc_fuzzer::AAC: - return "aac"; + return V8AacBitstreamFormat::Enum::kAac; case wc_fuzzer::ADTS: - return "adts"; + return V8AacBitstreamFormat::Enum::kAdts; } } -String ToBitrateMode(wc_fuzzer::BitrateMode bitrate_mode) { +V8BitrateMode::Enum ToBitrateMode(wc_fuzzer::BitrateMode bitrate_mode) { switch (bitrate_mode) { case wc_fuzzer::VARIABLE: - return "variable"; + return V8BitrateMode::Enum::kVariable; case wc_fuzzer::CONSTANT: - return "constant"; + return V8BitrateMode::Enum::kConstant; } } -String ToOpusSignal(wc_fuzzer::OpusSignal opus_signal) { +V8OpusSignal::Enum ToOpusSignal(wc_fuzzer::OpusSignal opus_signal) { switch (opus_signal) { case wc_fuzzer::AUTO: - return "auto"; + return V8OpusSignal::Enum::kAuto; case wc_fuzzer::MUSIC: - return "music"; + return V8OpusSignal::Enum::kMusic; case wc_fuzzer::VOICE: - return "voice"; + return V8OpusSignal::Enum::kVoice; } } -String ToOpusApplication(wc_fuzzer::OpusApplication opus_application) { +V8OpusApplication::Enum ToOpusApplication( + wc_fuzzer::OpusApplication opus_application) { switch (opus_application) { case wc_fuzzer::VOIP: - return "voip"; + return V8OpusApplication::Enum::kVoip; case wc_fuzzer::AUDIO: - return "audio"; + return V8OpusApplication::Enum::kAudio; case wc_fuzzer::LOWDELAY: - return "lowdelay"; + return V8OpusApplication::Enum::kLowdelay; } } -String ToChunkType(wc_fuzzer::EncodedChunkType type) { +V8EncodedAudioChunkType::Enum ToAudioChunkType( + wc_fuzzer::EncodedChunkType type) { switch (type) { case wc_fuzzer::EncodedChunkType::KEY: - return "key"; + return V8EncodedAudioChunkType::Enum::kKey; case wc_fuzzer::EncodedChunkType::DELTA: - return "delta"; + return V8EncodedAudioChunkType::Enum::kDelta; } } -String ToAudioSampleFormat(wc_fuzzer::AudioSampleFormat format) { +V8EncodedVideoChunkType::Enum ToVideoChunkType( + wc_fuzzer::EncodedChunkType type) { + switch (type) { + case wc_fuzzer::EncodedChunkType::KEY: + return V8EncodedVideoChunkType::Enum::kKey; + case wc_fuzzer::EncodedChunkType::DELTA: + return V8EncodedVideoChunkType::Enum::kDelta; + } +} + +V8AudioSampleFormat::Enum ToAudioSampleFormat( + wc_fuzzer::AudioSampleFormat format) { switch (format) { case wc_fuzzer::AudioSampleFormat::U8: - return "u8"; + return V8AudioSampleFormat::Enum::kU8; case wc_fuzzer::AudioSampleFormat::S16: - return "s16"; + return V8AudioSampleFormat::Enum::kS16; case wc_fuzzer::AudioSampleFormat::S32: - return "s32"; + return V8AudioSampleFormat::Enum::kS32; case wc_fuzzer::AudioSampleFormat::F32: - return "f32"; + return V8AudioSampleFormat::Enum::kF32; case wc_fuzzer::AudioSampleFormat::U8_PLANAR: - return "u8-planar"; + return V8AudioSampleFormat::Enum::kU8Planar; case wc_fuzzer::AudioSampleFormat::S16_PLANAR: - return "s16-planar"; + return V8AudioSampleFormat::Enum::kS16Planar; case wc_fuzzer::AudioSampleFormat::S32_PLANAR: - return "s32-planar"; + return V8AudioSampleFormat::Enum::kS32Planar; case wc_fuzzer::AudioSampleFormat::F32_PLANAR: - return "f32-planar"; + return V8AudioSampleFormat::Enum::kF32Planar; } } @@ -358,7 +373,7 @@ auto* init = EncodedVideoChunkInit::Create(); init->setTimestamp(proto.timestamp()); - init->setType(ToChunkType(proto.type())); + init->setType(ToVideoChunkType(proto.type())); init->setData(data); if (proto.has_duration()) @@ -376,7 +391,7 @@ auto* init = EncodedAudioChunkInit::Create(); init->setTimestamp(proto.timestamp()); - init->setType(ToChunkType(proto.type())); + init->setType(ToAudioChunkType(proto.type())); init->setData(data); if (proto.has_duration()) @@ -480,19 +495,19 @@ if (proto.has_primaries()) { switch (proto.primaries()) { case wc_fuzzer::VideoColorSpaceInit_VideoColorPrimaries_VCP_BT709: - init->setPrimaries("bt709"); + init->setPrimaries(V8VideoColorPrimaries::Enum::kBt709); break; case wc_fuzzer::VideoColorSpaceInit_VideoColorPrimaries_VCP_BT470BG: - init->setPrimaries("bt470bg"); + init->setPrimaries(V8VideoColorPrimaries::Enum::kBt470Bg); break; case wc_fuzzer::VideoColorSpaceInit_VideoColorPrimaries_VCP_SMPTE170M: - init->setPrimaries("smpte170m"); + init->setPrimaries(V8VideoColorPrimaries::Enum::kSmpte170M); break; case wc_fuzzer::VideoColorSpaceInit_VideoColorPrimaries_VCP_BT2020: - init->setPrimaries("bt2020"); + init->setPrimaries(V8VideoColorPrimaries::Enum::kBt2020); break; case wc_fuzzer::VideoColorSpaceInit_VideoColorPrimaries_VCP_SMPTE432: - init->setPrimaries("smpte432"); + init->setPrimaries(V8VideoColorPrimaries::Enum::kSmpte432); break; } } @@ -501,25 +516,25 @@ switch (proto.transfer()) { case wc_fuzzer:: VideoColorSpaceInit_VideoTransferCharacteristics_VTC_BT709: - init->setTransfer("bt709"); + init->setTransfer(V8VideoTransferCharacteristics::Enum::kBt709); break; case wc_fuzzer:: VideoColorSpaceInit_VideoTransferCharacteristics_VTC_SMPTE170M: - init->setTransfer("smpte170m"); + init->setTransfer(V8VideoTransferCharacteristics::Enum::kSmpte170M); break; case wc_fuzzer:: VideoColorSpaceInit_VideoTransferCharacteristics_VTC_IEC61966_2_1: - init->setTransfer("iec61966-2-1"); + init->setTransfer(V8VideoTransferCharacteristics::Enum::kIec6196621); break; case wc_fuzzer:: VideoColorSpaceInit_VideoTransferCharacteristics_VTC_LINEAR: - init->setTransfer("linear"); + init->setTransfer(V8VideoTransferCharacteristics::Enum::kLinear); break; case wc_fuzzer::VideoColorSpaceInit_VideoTransferCharacteristics_VTC_PQ: - init->setTransfer("pq"); + init->setTransfer(V8VideoTransferCharacteristics::Enum::kPq); break; case wc_fuzzer::VideoColorSpaceInit_VideoTransferCharacteristics_VTC_HLG: - init->setTransfer("hlg"); + init->setTransfer(V8VideoTransferCharacteristics::Enum::kHlg); break; } } @@ -527,20 +542,20 @@ if (proto.has_matrix()) { switch (proto.matrix()) { case wc_fuzzer::VideoColorSpaceInit_VideoMatrixCoefficients_VMC_RGB: - init->setMatrix("rgb"); + init->setMatrix(V8VideoMatrixCoefficients::Enum::kRgb); break; case wc_fuzzer::VideoColorSpaceInit_VideoMatrixCoefficients_VMC_BT709: - init->setMatrix("bt709"); + init->setMatrix(V8VideoMatrixCoefficients::Enum::kBt709); break; case wc_fuzzer::VideoColorSpaceInit_VideoMatrixCoefficients_VMC_BT470BG: - init->setMatrix("bt470bg"); + init->setMatrix(V8VideoMatrixCoefficients::Enum::kBt470Bg); break; case wc_fuzzer::VideoColorSpaceInit_VideoMatrixCoefficients_VMC_SMPTE170M: - init->setMatrix("smpte170m"); + init->setMatrix(V8VideoMatrixCoefficients::Enum::kSmpte170M); break; case wc_fuzzer:: VideoColorSpaceInit_VideoMatrixCoefficients_VMC_BT2020_NCL: - init->setMatrix("bt2020-ncl"); + init->setMatrix(V8VideoMatrixCoefficients::Enum::kBt2020Ncl); break; } } @@ -560,28 +575,28 @@ switch (proto.init().format()) { case wc_fuzzer::VideoFrameBufferInit_VideoPixelFormat_I420: - init->setFormat("I420"); + init->setFormat(V8VideoPixelFormat::Enum::kI420); break; case wc_fuzzer::VideoFrameBufferInit_VideoPixelFormat_I420A: - init->setFormat("I420A"); + init->setFormat(V8VideoPixelFormat::Enum::kI420A); break; case wc_fuzzer::VideoFrameBufferInit_VideoPixelFormat_I444: - init->setFormat("I444"); + init->setFormat(V8VideoPixelFormat::Enum::kI444); break; case wc_fuzzer::VideoFrameBufferInit_VideoPixelFormat_NV12: - init->setFormat("NV12"); + init->setFormat(V8VideoPixelFormat::Enum::kNV12); break; case wc_fuzzer::VideoFrameBufferInit_VideoPixelFormat_RGBA: - init->setFormat("RGBA"); + init->setFormat(V8VideoPixelFormat::Enum::kRGBA); break; case wc_fuzzer::VideoFrameBufferInit_VideoPixelFormat_RGBX: - init->setFormat("RGBX"); + init->setFormat(V8VideoPixelFormat::Enum::kRGBX); break; case wc_fuzzer::VideoFrameBufferInit_VideoPixelFormat_BGRA: - init->setFormat("BGRA"); + init->setFormat(V8VideoPixelFormat::Enum::kBGRA); break; case wc_fuzzer::VideoFrameBufferInit_VideoPixelFormat_BGRX: - init->setFormat("BGRX"); + init->setFormat(V8VideoPixelFormat::Enum::kBGRX); break; } @@ -666,8 +681,7 @@ return nullptr; } - V8AudioSampleFormat format = - V8AudioSampleFormat::Create(ToAudioSampleFormat(proto.format())).value(); + V8AudioSampleFormat format(ToAudioSampleFormat(proto.format())); int size_per_sample = SampleFormatToSampleSize(format); int number_of_samples = proto.channels().size() * proto.length();
diff --git a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h index 7bb34e6..1f357a4 100644 --- a/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h +++ b/third_party/blink/renderer/modules/webcodecs/fuzzer_utils.h
@@ -5,10 +5,17 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_FUZZER_UTILS_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBCODECS_FUZZER_UTILS_H_ +#include <string> + #include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_aac_bitstream_format.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_audio_decoder_config.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_audio_encoder_config.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_audio_chunk_type.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_chunk_type.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_opus_application.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_opus_signal.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_video_decoder_config.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_video_decoder_init.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_video_encoder_config.h" @@ -23,8 +30,6 @@ #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "v8/include/v8-forward.h" -#include <string> - namespace base { class ScopedClosureRunner; } @@ -97,29 +102,36 @@ VideoEncoderEncodeOptions* MakeEncodeOptions( const wc_fuzzer::EncodeVideo_EncodeOptions& proto); -String ToBitrateMode( +V8VideoEncoderBitrateMode::Enum ToBitrateMode( wc_fuzzer::ConfigureVideoEncoder_VideoEncoderBitrateMode mode); String ToScalabilityMode(wc_fuzzer::ConfigureVideoEncoder_ScalabilityMode mode); -String ToLatencyMode(wc_fuzzer::ConfigureVideoEncoder_LatencyMode mode); +V8LatencyMode::Enum ToLatencyMode( + wc_fuzzer::ConfigureVideoEncoder_LatencyMode mode); String ToContentHint(wc_fuzzer::ConfigureVideoEncoder_ContentHint hint); -String ToAlphaOption(wc_fuzzer::ConfigureVideoEncoder_AlphaOption option); +V8AlphaOption::Enum ToAlphaOption( + wc_fuzzer::ConfigureVideoEncoder_AlphaOption option); -String ToAacFormat(wc_fuzzer::AacFormat format); +V8BitrateMode::Enum ToBitrateMode(wc_fuzzer::BitrateMode bitrate_mode); -String ToBitrateMode(wc_fuzzer::BitrateMode bitrate_mode); +V8OpusSignal::Enum ToOpusSignal(wc_fuzzer::OpusSignal opus_signal); -String ToOpusSignal(wc_fuzzer::OpusSignal opus_signal); +V8OpusApplication::Enum ToOpusApplication( + wc_fuzzer::OpusApplication opus_application); -String ToOpusApplication(wc_fuzzer::OpusApplication opus_application); +V8AacBitstreamFormat::Enum ToAacFormat(wc_fuzzer::AacFormat format); -String ToAccelerationType( +V8HardwarePreference::Enum ToAccelerationType( wc_fuzzer::ConfigureVideoEncoder_EncoderAccelerationPreference type); -String ToChunkType(wc_fuzzer::EncodedChunkType type); +V8EncodedAudioChunkType::Enum ToAudioChunkType( + wc_fuzzer::EncodedChunkType type); + +V8EncodedVideoChunkType::Enum ToVideoChunkType( + wc_fuzzer::EncodedChunkType type); } // namespace blink
diff --git a/third_party/blink/renderer/modules/webcodecs/image_decoder_fuzzer.cc b/third_party/blink/renderer/modules/webcodecs/image_decoder_fuzzer.cc index 14f5c49..f25e47b 100644 --- a/third_party/blink/renderer/modules/webcodecs/image_decoder_fuzzer.cc +++ b/third_party/blink/renderer/modules/webcodecs/image_decoder_fuzzer.cc
@@ -36,13 +36,13 @@ namespace { -String ToColorSpaceConversion( +V8ColorSpaceConversion::Enum ToColorSpaceConversion( wc_fuzzer::ImageBitmapOptions_ColorSpaceConversion type) { switch (type) { case wc_fuzzer::ImageBitmapOptions_ColorSpaceConversion_CS_NONE: - return "none"; + return V8ColorSpaceConversion::Enum::kNone; case wc_fuzzer::ImageBitmapOptions_ColorSpaceConversion_CS_DEFAULT: - return "default"; + return V8ColorSpaceConversion::Enum::kDefault; } }
diff --git a/third_party/blink/renderer/platform/wtf/text/atomic_string.cc b/third_party/blink/renderer/platform/wtf/text/atomic_string.cc index bbec259..ad640cb 100644 --- a/third_party/blink/renderer/platform/wtf/text/atomic_string.cc +++ b/third_party/blink/renderer/platform/wtf/text/atomic_string.cc
@@ -36,22 +36,17 @@ ASSERT_SIZE(AtomicString, String); AtomicString::AtomicString(base::span<const LChar> chars) - : string_(AtomicStringTable::Instance().Add( - chars.data(), - base::checked_cast<wtf_size_t>(chars.size()))) {} + : string_(AtomicStringTable::Instance().Add(chars)) {} AtomicString::AtomicString(base::span<const UChar> chars, AtomicStringUCharEncoding encoding) - : string_(AtomicStringTable::Instance().Add( - chars.data(), - base::checked_cast<wtf_size_t>(chars.size()), - encoding)) {} + : string_(AtomicStringTable::Instance().Add(chars, encoding)) {} AtomicString::AtomicString(const UChar* chars) : string_(AtomicStringTable::Instance().Add( - chars, // SAFETY: safe when `chars` points to a null-terminated cstring. - chars ? UNSAFE_BUFFERS(LengthOfNullTerminatedString(chars)) : 0, + UNSAFE_BUFFERS( + {chars, chars ? LengthOfNullTerminatedString(chars) : 0}), AtomicStringUCharEncoding::kUnknown)) {} AtomicString::AtomicString(const StringView& string_view)
diff --git a/third_party/blink/renderer/platform/wtf/text/atomic_string_table.cc b/third_party/blink/renderer/platform/wtf/text/atomic_string_table.cc index 44b5a45..89e944f 100644 --- a/third_party/blink/renderer/platform/wtf/text/atomic_string_table.cc +++ b/third_party/blink/renderer/platform/wtf/text/atomic_string_table.cc
@@ -27,54 +27,45 @@ class UCharBuffer { public: ALWAYS_INLINE static unsigned ComputeHashAndMaskTop8Bits( - const UChar* chars, - unsigned len, + base::span<const UChar> chars, AtomicStringUCharEncoding encoding) { if (encoding == AtomicStringUCharEncoding::kIs8Bit || (encoding == AtomicStringUCharEncoding::kUnknown && - IsOnly8Bit(UNSAFE_TODO({chars, len})))) { + IsOnly8Bit(chars))) { // This is a very common case from HTML parsing, so we take // the size penalty from inlining. return StringHasher::ComputeHashAndMaskTop8BitsInline< - ConvertTo8BitHashReader>( - UNSAFE_TODO({reinterpret_cast<const uint8_t*>(chars), len})); + ConvertTo8BitHashReader>(UNSAFE_TODO( + {reinterpret_cast<const uint8_t*>(chars.data()), chars.size()})); } else { return StringHasher::ComputeHashAndMaskTop8Bits( - reinterpret_cast<const char*>(chars), len * 2); + reinterpret_cast<const char*>(chars.data()), chars.size() * 2); } } ALWAYS_INLINE UCharBuffer(base::span<const UChar> chars, AtomicStringUCharEncoding encoding) - : characters_(chars.data()), - length_(chars.size()), - hash_(ComputeHashAndMaskTop8Bits(chars.data(), length_, encoding)), + : characters_(chars), + hash_(ComputeHashAndMaskTop8Bits(chars, encoding)), encoding_(encoding) {} - base::span<const UChar> characters() const { - return UNSAFE_TODO({characters_, length_}); - } - unsigned length() const { return length_; } + base::span<const UChar> characters() const { return characters_; } unsigned hash() const { return hash_; } AtomicStringUCharEncoding encoding() const { return encoding_; } scoped_refptr<StringImpl> CreateStringImpl() const { switch (encoding_) { case AtomicStringUCharEncoding::kUnknown: - return StringImpl::Create8BitIfPossible( - UNSAFE_TODO({characters_, length_})); + return StringImpl::Create8BitIfPossible(characters_); case AtomicStringUCharEncoding::kIs8Bit: - return String::Make8BitFrom16BitSource( - UNSAFE_TODO({characters_, length_})) - .ReleaseImpl(); + return String::Make8BitFrom16BitSource(characters_).ReleaseImpl(); case AtomicStringUCharEncoding::kIs16Bit: - return StringImpl::Create(UNSAFE_TODO({characters_, length_})); + return StringImpl::Create(characters_); } } private: - const UChar* characters_; - const unsigned length_; + const base::span<const UChar> characters_; const unsigned hash_; const AtomicStringUCharEncoding encoding_; }; @@ -336,35 +327,32 @@ } scoped_refptr<StringImpl> AtomicStringTable::Add( - const UChar* s, - unsigned length, + base::span<const UChar> chars, AtomicStringUCharEncoding encoding) { - if (!s) + if (!chars.data()) { return nullptr; + } - if (!length) + if (chars.empty()) { return StringImpl::empty_; + } - UCharBuffer buffer(UNSAFE_TODO({s, length}), encoding); + UCharBuffer buffer(chars, encoding); return AddToStringTable<UCharBuffer, UCharBufferTranslator>(buffer); } class LCharBuffer { public: ALWAYS_INLINE explicit LCharBuffer(base::span<const LChar> chars) - : characters_(chars.data()), - length_(chars.size()), + : characters_(chars), // This is a common path from V8 strings, so inlining is worth it. hash_(StringHasher::ComputeHashAndMaskTop8BitsInline(chars)) {} - base::span<const LChar> characters() const { - return UNSAFE_TODO({characters_, length_}); - } + base::span<const LChar> characters() const { return characters_; } unsigned hash() const { return hash_; } private: - const LChar* characters_; - const unsigned length_; + const base::span<const LChar> characters_; const unsigned hash_; }; @@ -403,15 +391,17 @@ return AddToStringTable<UCharBuffer, UCharBufferTranslator>(buffer); } -scoped_refptr<StringImpl> AtomicStringTable::Add(const LChar* s, - unsigned length) { - if (!s) +scoped_refptr<StringImpl> AtomicStringTable::Add( + base::span<const LChar> chars) { + if (!chars.data()) { return nullptr; + } - if (!length) + if (chars.empty()) { return StringImpl::empty_; + } - LCharBuffer buffer(UNSAFE_TODO({s, length})); + LCharBuffer buffer(chars); return AddToStringTable<LCharBuffer, LCharBufferTranslator>(buffer); } @@ -458,7 +448,7 @@ unsigned utf16_length = blink::unicode::CalculateStringLengthFromUtf8( characters_span, seen_non_ascii, seen_non_latin1); if (!seen_non_ascii) { - return Add(characters_span.data(), utf16_length); + return Add(characters_span); } auto utf16_buf = base::HeapArray<UChar>::Uninit(utf16_length);
diff --git a/third_party/blink/renderer/platform/wtf/text/atomic_string_table.h b/third_party/blink/renderer/platform/wtf/text/atomic_string_table.h index 4a32b711..7947a09 100644 --- a/third_party/blink/renderer/platform/wtf/text/atomic_string_table.h +++ b/third_party/blink/renderer/platform/wtf/text/atomic_string_table.h
@@ -42,9 +42,8 @@ // convert the string to save memory if possible. scoped_refptr<StringImpl> Add(StringImpl*); scoped_refptr<StringImpl> Add(scoped_refptr<StringImpl>&&); - scoped_refptr<StringImpl> Add(const LChar* chars, unsigned length); - scoped_refptr<StringImpl> Add(const UChar* chars, - unsigned length, + scoped_refptr<StringImpl> Add(base::span<const LChar> chars); + scoped_refptr<StringImpl> Add(base::span<const UChar> chars, AtomicStringUCharEncoding encoding); scoped_refptr<StringImpl> Add(const StringView& string_view);
diff --git a/third_party/blink/renderer/platform/wtf/text/string_view.h b/third_party/blink/renderer/platform/wtf/text/string_view.h index 302da50..3a11170 100644 --- a/third_party/blink/renderer/platform/wtf/text/string_view.h +++ b/third_party/blink/renderer/platform/wtf/text/string_view.h
@@ -198,12 +198,6 @@ }) } - // Use Span16() instead. - UNSAFE_BUFFER_USAGE const UChar* Characters16() const { - DCHECK(!Is8Bit()); - return static_cast<const UChar*>(bytes_); - } - base::span<const LChar> Span8() const { DCHECK(Is8Bit()); // SAFETY: bytes_ have length_ elements.
diff --git a/third_party/blink/renderer/platform/wtf/text/string_view_test.cc b/third_party/blink/renderer/platform/wtf/text/string_view_test.cc index 4f7f44c..2f5d83a1 100644 --- a/third_party/blink/renderer/platform/wtf/text/string_view_test.cc +++ b/third_party/blink/renderer/platform/wtf/text/string_view_test.cc
@@ -24,6 +24,22 @@ return offset ? view.Span8().subspan(offset).data() : view.Span8().data(); } +const UChar* Address16(const StringImpl& impl, size_t offset = 0) { + return offset ? impl.Span16().subspan(offset).data() : impl.Span16().data(); +} + +const UChar* Address16(const String& str, size_t offset = 0) { + return offset ? str.Span16().subspan(offset).data() : str.Span16().data(); +} + +const UChar* Address16(const AtomicString& str, size_t offset = 0) { + return offset ? str.Span16().subspan(offset).data() : str.Span16().data(); +} + +const UChar* Address16(StringView view, size_t offset = 0) { + return offset ? view.Span16().subspan(offset).data() : view.Span16().data(); +} + const char kChars[] = "12345"; const char16_t kCharsU[] = u"12345"; const LChar* const kChars8 = reinterpret_cast<const LChar*>(kChars); @@ -65,16 +81,15 @@ // StringView(StringImpl*); ASSERT_FALSE(StringView(impl16_bit.get()).Is8Bit()); EXPECT_FALSE(StringView(impl16_bit.get()).IsNull()); - UNSAFE_TODO(EXPECT_EQ(impl16_bit->Characters16(), - StringView(impl16_bit.get()).Characters16())); + EXPECT_EQ(Address16(*impl16_bit), Address16(StringView(impl16_bit.get()))); EXPECT_EQ(impl16_bit->length(), StringView(impl16_bit.get()).length()); EXPECT_EQ(kChars, StringView(impl16_bit.get())); // StringView(StringImpl*, unsigned offset); ASSERT_FALSE(StringView(impl16_bit.get(), 2).Is8Bit()); EXPECT_FALSE(StringView(impl16_bit.get(), 2).IsNull()); - UNSAFE_TODO(EXPECT_EQ(impl16_bit->Characters16() + 2, - StringView(impl16_bit.get(), 2).Characters16())); + EXPECT_EQ(Address16(*impl16_bit, 2u), + Address16(StringView(impl16_bit.get(), 2))); EXPECT_EQ(3u, StringView(impl16_bit.get(), 2).length()); EXPECT_EQ(StringView("345"), StringView(impl16_bit.get(), 2)); EXPECT_EQ("345", StringView(impl16_bit.get(), 2)); @@ -82,8 +97,8 @@ // StringView(StringImpl*, unsigned offset, unsigned length); ASSERT_FALSE(StringView(impl16_bit.get(), 2, 1).Is8Bit()); EXPECT_FALSE(StringView(impl16_bit.get(), 2, 1).IsNull()); - UNSAFE_TODO(EXPECT_EQ(impl16_bit->Characters16() + 2, - StringView(impl16_bit.get(), 2, 1).Characters16())); + EXPECT_EQ(Address16(*impl16_bit, 2u), + Address16(StringView(impl16_bit.get(), 2, 1))); EXPECT_EQ(1u, StringView(impl16_bit.get(), 2, 1).length()); EXPECT_EQ(StringView("3"), StringView(impl16_bit.get(), 2, 1)); EXPECT_EQ("3", StringView(impl16_bit.get(), 2, 1)); @@ -124,16 +139,14 @@ // StringView(StringImpl&); ASSERT_FALSE(StringView(*impl16_bit).Is8Bit()); EXPECT_FALSE(StringView(*impl16_bit).IsNull()); - UNSAFE_TODO(EXPECT_EQ(impl16_bit->Characters16(), - StringView(*impl16_bit).Characters16())); + EXPECT_EQ(Address16(*impl16_bit), Address16(StringView(*impl16_bit))); EXPECT_EQ(impl16_bit->length(), StringView(*impl16_bit).length()); EXPECT_EQ(kChars, StringView(*impl16_bit)); // StringView(StringImpl&, unsigned offset); ASSERT_FALSE(StringView(*impl16_bit, 2).Is8Bit()); EXPECT_FALSE(StringView(*impl16_bit, 2).IsNull()); - UNSAFE_TODO(EXPECT_EQ(impl16_bit->Characters16() + 2, - StringView(*impl16_bit, 2).Characters16())); + EXPECT_EQ(Address16(*impl16_bit, 2u), Address16(StringView(*impl16_bit, 2))); EXPECT_EQ(3u, StringView(*impl16_bit, 2).length()); EXPECT_EQ(StringView("345"), StringView(*impl16_bit, 2)); EXPECT_EQ("345", StringView(*impl16_bit, 2)); @@ -141,8 +154,8 @@ // StringView(StringImpl&, unsigned offset, unsigned length); ASSERT_FALSE(StringView(*impl16_bit, 2, 1).Is8Bit()); EXPECT_FALSE(StringView(*impl16_bit, 2, 1).IsNull()); - UNSAFE_TODO(EXPECT_EQ(impl16_bit->Characters16() + 2, - StringView(*impl16_bit, 2, 1).Characters16())); + EXPECT_EQ(Address16(*impl16_bit, 2u), + Address16(StringView(*impl16_bit, 2, 1))); EXPECT_EQ(1u, StringView(*impl16_bit, 2, 1).length()); EXPECT_EQ(StringView("3"), StringView(*impl16_bit, 2, 1)); EXPECT_EQ("3", StringView(*impl16_bit, 2, 1)); @@ -181,16 +194,15 @@ // StringView(const String&); ASSERT_FALSE(StringView(string16_bit).Is8Bit()); EXPECT_FALSE(StringView(string16_bit).IsNull()); - UNSAFE_TODO(EXPECT_EQ(string16_bit.Characters16(), - StringView(string16_bit).Characters16())); + EXPECT_EQ(Address16(string16_bit), Address16(StringView(string16_bit))); EXPECT_EQ(string16_bit.length(), StringView(string16_bit).length()); EXPECT_EQ(kChars, StringView(string16_bit)); // StringView(const String&, unsigned offset); ASSERT_FALSE(StringView(string16_bit, 2).Is8Bit()); EXPECT_FALSE(StringView(string16_bit, 2).IsNull()); - UNSAFE_TODO(EXPECT_EQ(string16_bit.Characters16() + 2, - StringView(string16_bit, 2).Characters16())); + EXPECT_EQ(Address16(string16_bit, 2u), + Address16(StringView(string16_bit, 2))); EXPECT_EQ(3u, StringView(string16_bit, 2).length()); EXPECT_EQ(StringView("345"), StringView(string16_bit, 2)); EXPECT_EQ("345", StringView(string16_bit, 2)); @@ -198,8 +210,8 @@ // StringView(const String&, unsigned offset, unsigned length); ASSERT_FALSE(StringView(string16_bit, 2, 1).Is8Bit()); EXPECT_FALSE(StringView(string16_bit, 2, 1).IsNull()); - UNSAFE_TODO(EXPECT_EQ(string16_bit.Characters16() + 2, - StringView(string16_bit, 2, 1).Characters16())); + EXPECT_EQ(Address16(string16_bit, 2u), + Address16(StringView(string16_bit, 2, 1))); EXPECT_EQ(1u, StringView(string16_bit, 2, 1).length()); EXPECT_EQ(StringView("3"), StringView(string16_bit, 2, 1)); EXPECT_EQ("3", StringView(string16_bit, 2, 1)); @@ -242,16 +254,14 @@ // StringView(const AtomicString&); ASSERT_FALSE(StringView(atom16_bit).Is8Bit()); EXPECT_FALSE(StringView(atom16_bit).IsNull()); - UNSAFE_TODO(EXPECT_EQ(atom16_bit.Characters16(), - StringView(atom16_bit).Characters16())); + EXPECT_EQ(Address16(atom16_bit), Address16(StringView(atom16_bit))); EXPECT_EQ(atom16_bit.length(), StringView(atom16_bit).length()); EXPECT_EQ(kChars, StringView(atom16_bit)); // StringView(const AtomicString&, unsigned offset); ASSERT_FALSE(StringView(atom16_bit, 2).Is8Bit()); EXPECT_FALSE(StringView(atom16_bit, 2).IsNull()); - UNSAFE_TODO(EXPECT_EQ(atom16_bit.Characters16() + 2, - StringView(atom16_bit, 2).Characters16())); + EXPECT_EQ(Address16(atom16_bit, 2u), Address16(StringView(atom16_bit, 2))); EXPECT_EQ(3u, StringView(atom16_bit, 2).length()); EXPECT_EQ(StringView("345"), StringView(atom16_bit, 2)); EXPECT_EQ("345", StringView(atom16_bit, 2)); @@ -259,8 +269,7 @@ // StringView(const AtomicString&, unsigned offset, unsigned length); ASSERT_FALSE(StringView(atom16_bit, 2, 1).Is8Bit()); EXPECT_FALSE(StringView(atom16_bit, 2, 1).IsNull()); - UNSAFE_TODO(EXPECT_EQ(atom16_bit.Characters16() + 2, - StringView(atom16_bit, 2, 1).Characters16())); + EXPECT_EQ(Address16(atom16_bit, 2u), Address16(StringView(atom16_bit, 2, 1))); EXPECT_EQ(1u, StringView(atom16_bit, 2, 1).length()); EXPECT_EQ(StringView("3"), StringView(atom16_bit, 2, 1)); EXPECT_EQ("3", StringView(atom16_bit, 2, 1)); @@ -299,16 +308,14 @@ // StringView(StringView&); ASSERT_FALSE(StringView(view16_bit).Is8Bit()); EXPECT_FALSE(StringView(view16_bit).IsNull()); - UNSAFE_TODO(EXPECT_EQ(view16_bit.Characters16(), - StringView(view16_bit).Characters16())); + EXPECT_EQ(Address16(view16_bit), Address16(StringView(view16_bit))); EXPECT_EQ(view16_bit.length(), StringView(view16_bit).length()); EXPECT_EQ(kChars, StringView(view16_bit)); // StringView(const StringView&, unsigned offset); ASSERT_FALSE(StringView(view16_bit, 2).Is8Bit()); EXPECT_FALSE(StringView(view16_bit, 2).IsNull()); - UNSAFE_TODO(EXPECT_EQ(view16_bit.Characters16() + 2, - StringView(view16_bit, 2).Characters16())); + EXPECT_EQ(Address16(view16_bit, 2u), Address16(StringView(view16_bit, 2))); EXPECT_EQ(3u, StringView(view16_bit, 2).length()); EXPECT_EQ(StringView("345"), StringView(view16_bit, 2)); EXPECT_EQ("345", StringView(view16_bit, 2)); @@ -316,8 +323,7 @@ // StringView(const StringView&, unsigned offset, unsigned length); ASSERT_FALSE(StringView(view16_bit, 2, 1).Is8Bit()); EXPECT_FALSE(StringView(view16_bit, 2, 1).IsNull()); - UNSAFE_TODO(EXPECT_EQ(view16_bit.Characters16() + 2, - StringView(view16_bit, 2, 1).Characters16())); + EXPECT_EQ(Address16(view16_bit, 2u), Address16(StringView(view16_bit, 2, 1))); EXPECT_EQ(1u, StringView(view16_bit, 2, 1).length()); EXPECT_EQ(StringView("3"), StringView(view16_bit, 2, 1)); EXPECT_EQ("3", StringView(view16_bit, 2, 1)); @@ -361,7 +367,7 @@ // StringView(const UChar* chars); ASSERT_FALSE(StringView(kChars16).Is8Bit()); EXPECT_FALSE(StringView(kChars16).IsNull()); - UNSAFE_TODO(EXPECT_EQ(kChars16, StringView(kChars16).Characters16())); + EXPECT_EQ(kChars16, Address16(StringView(kChars16))); EXPECT_EQ(5u, StringView(kChars16).length()); EXPECT_EQ(String(kChars16), StringView(kChars16)); @@ -369,7 +375,7 @@ StringView uchar2(base::span_from_cstring(kCharsU).first(2u)); ASSERT_FALSE(uchar2.Is8Bit()); EXPECT_FALSE(uchar2.IsNull()); - UNSAFE_TODO(EXPECT_EQ(kChars16, uchar2.Characters16())); + EXPECT_EQ(kChars16, Address16(uchar2)); EXPECT_EQ(StringView("12"), uchar2); EXPECT_EQ(StringView(reinterpret_cast<const UChar*>(u"12")), uchar2); EXPECT_EQ(2u, uchar2.length()); @@ -391,7 +397,7 @@ const auto kCharsSpan16 = base::span_from_cstring(kCharsU); ASSERT_FALSE(StringView(kCharsSpan16).Is8Bit()); EXPECT_FALSE(StringView(kCharsSpan16).IsNull()); - UNSAFE_TODO(EXPECT_EQ(kChars16, StringView(kCharsSpan16).Characters16())); + EXPECT_EQ(kChars16, Address16(StringView(kCharsSpan16))); EXPECT_EQ(5u, StringView(kCharsSpan16).length()); EXPECT_EQ(String(kChars16), StringView(kCharsSpan16)); }
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index c60101f..794c4faf 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -9703,3 +9703,6 @@ # Gardener 2025-09-25 crbug.com/444048840 [ Linux ] inspector-protocol/sessions/page-set-document-content.js [ Pass Timeout ] + +# Gardener 2025-09-29 +crbug.com/447759677 [ Mac ] external/wpt/css/css-conditional/container-queries/scroll-state/scroll-direction-scrollbar-track-clicks.html [ Failure Pass ] \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/WEB_FEATURES.yml b/third_party/blink/web_tests/external/wpt/css/css-fonts/WEB_FEATURES.yml index 5b89ca9..e94cfca 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-fonts/WEB_FEATURES.yml +++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/WEB_FEATURES.yml
@@ -39,3 +39,6 @@ - ascent-descent-override.html - line-gap-override.html - metrics-override-normal-keyword.html +- name: font-language-override + files: + - font-language-override-*
diff --git a/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.isPointInFill-01.svg b/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.isPointInFill-01.svg index 3714c2a..2f5ea193 100644 --- a/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.isPointInFill-01.svg +++ b/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.isPointInFill-01.svg
@@ -54,6 +54,15 @@ test(function() { let circleAtOrigin = document.getElementById("circle-at-origin"); + assert_true(circleAtOrigin.isPointInFill(null)); + assert_true(circleAtOrigin.isPointInFill(undefined)); + let ellipse = document.getElementById("ellipse"); + assert_false(ellipse.isPointInFill(null)); + assert_false(ellipse.isPointInFill(undefined)); + }, document.title + ", null/undefined."); + + test(function() { + let circleAtOrigin = document.getElementById("circle-at-origin"); assert_false(circleAtOrigin.isPointInFill({ x: NaN, y: 0 }), "x is NaN"); assert_false(circleAtOrigin.isPointInFill({ x: Infinity, y: 0 }), "x is Infinity"); assert_false(circleAtOrigin.isPointInFill({ x: -Infinity, y: 0 }), "x is -Infinity");
diff --git a/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.isPointInStroke-01.svg b/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.isPointInStroke-01.svg index 78ba96d..40f66615 100644 --- a/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.isPointInStroke-01.svg +++ b/third_party/blink/web_tests/external/wpt/svg/types/scripted/SVGGeometryElement.isPointInStroke-01.svg
@@ -69,6 +69,15 @@ test(function() { let strokeAtOrigin = document.getElementById("circle-with-stroke-intersecting-origin"); + assert_true(strokeAtOrigin.isPointInStroke(null)); + assert_true(strokeAtOrigin.isPointInStroke(undefined)); + let ellipse = document.getElementById("ellipse"); + assert_false(ellipse.isPointInStroke(null)); + assert_false(ellipse.isPointInStroke(undefined)); + }, document.title + ", null/undefined."); + + test(function() { + let strokeAtOrigin = document.getElementById("circle-with-stroke-intersecting-origin"); assert_false(strokeAtOrigin.isPointInStroke({ x: NaN, y: 0 })), "x is NaN"; assert_false(strokeAtOrigin.isPointInStroke({ x: Infinity, y: 0 }), "x is Infinity"); assert_false(strokeAtOrigin.isPointInStroke({ x: -Infinity, y: 0 }), "x is -Infinity");
diff --git a/third_party/crossbench b/third_party/crossbench index 36df0d4..02fdfd1 160000 --- a/third_party/crossbench +++ b/third_party/crossbench
@@ -1 +1 @@ -Subproject commit 36df0d4649cfdcce5557ce85f43dc6e9d4712dd4 +Subproject commit 02fdfd11a339e4eff97c2ef1b83c0e46b7e4476d
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src index 5784d5e..3e5b3d8 160000 --- a/third_party/devtools-frontend/src +++ b/third_party/devtools-frontend/src
@@ -1 +1 @@ -Subproject commit 5784d5e1f6e3739f966d781b31a4677345300d8b +Subproject commit 3e5b3d89cc270b6f1acb093fbafb0f7e421ce505
diff --git a/third_party/libc++/src b/third_party/libc++/src index 4b4a57f..b77132b 160000 --- a/third_party/libc++/src +++ b/third_party/libc++/src
@@ -1 +1 @@ -Subproject commit 4b4a57f5cf627639c041368120af9d69ed40032c +Subproject commit b77132b512d5411f8393fd3decb3abaeaf1d3ec8
diff --git a/third_party/skia b/third_party/skia index b1e89bd..bb3b6bd 160000 --- a/third_party/skia +++ b/third_party/skia
@@ -1 +1 @@ -Subproject commit b1e89bda2bdee3ed53f7db5aca2bea2e9b4e3801 +Subproject commit bb3b6bd4be0dd757165a5723e1794f7ad2211d49
diff --git a/third_party/vulkan-deps b/third_party/vulkan-deps index 5557290..80a8334 160000 --- a/third_party/vulkan-deps +++ b/third_party/vulkan-deps
@@ -1 +1 @@ -Subproject commit 5557290e35deb7e7e21a6f4d36d487034ef75171 +Subproject commit 80a8334f002c4116b87738d477880e3d38dd445c
diff --git a/third_party/webrtc b/third_party/webrtc index f6a1ab5..dfcd6e3 160000 --- a/third_party/webrtc +++ b/third_party/webrtc
@@ -1 +1 @@ -Subproject commit f6a1ab593b6a0fa6c7e41d65cb84c8e80b5a5890 +Subproject commit dfcd6e3b19ad85c5a43e30927e9a250a92e3a927
diff --git a/tools/metrics/histograms/metadata/autofill/enums.xml b/tools/metrics/histograms/metadata/autofill/enums.xml index 8acec50..f7c62e4 100644 --- a/tools/metrics/histograms/metadata/autofill/enums.xml +++ b/tools/metrics/histograms/metadata/autofill/enums.xml
@@ -347,7 +347,7 @@ <int value="4" label="Profiles from different categories available."/> <int value="5" label="Only a kAccountHome profile available"/> <int value="6" label="Only a kAccountWork profile available"/> - <int value="7" label="Only a kAccountNameEmail profile was used"/> + <int value="7" label="Only a kAccountNameEmail profile available"/> </enum> <enum name="AutofillCreditCardAuthenticationEvents">
diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml index d269502f..a6a6332 100644 --- a/tools/metrics/histograms/metadata/autofill/histograms.xml +++ b/tools/metrics/histograms/metadata/autofill/histograms.xml
@@ -4524,6 +4524,8 @@ <variant name="AccountChrome" summary="Only kAccount profiles originating from Chrome were used"/> <variant name="AccountHome" summary="Only a kAccountHome profile was used"/> + <variant name="AccountNameEmail" + summary="Only a kAccountNameEmail profile was used"/> <variant name="AccountNonChrome" summary="Only kAccount profiles originating from outside Chrome were used"/>
diff --git a/tools/metrics/histograms/metadata/blink/enums.xml b/tools/metrics/histograms/metadata/blink/enums.xml index 9b196a0..ba8dcaa 100644 --- a/tools/metrics/histograms/metadata/blink/enums.xml +++ b/tools/metrics/histograms/metadata/blink/enums.xml
@@ -8598,6 +8598,7 @@ <int value="408" label="WebxrHitTest"/> <int value="409" label="WebxrLightingEstimation"/> <int value="410" label="Reporting"/> + <int value="411" label="FontLanguageOverride"/> </enum> <!-- LINT.ThenChange(//third_party/blink/public/mojom/use_counter/metrics/webdx_feature.mojom:WebDXFeature) -->
diff --git a/tools/metrics/histograms/metadata/mobile/enums.xml b/tools/metrics/histograms/metadata/mobile/enums.xml index 8b17585..3c295cc 100644 --- a/tools/metrics/histograms/metadata/mobile/enums.xml +++ b/tools/metrics/histograms/metadata/mobile/enums.xml
@@ -147,6 +147,7 @@ <int value="11" label="Omnibox Most Visited Tile"/> <int value="12" label="Tab Strip Item"/> <int value="13" label="Share in Web Context Menu"/> + <int value="14" label="Tab Share in Reader Mode"/> </enum> <enum name="IOSLensSupportStatus"> @@ -271,6 +272,9 @@ <int value="31" label="Autofill Manual Fallback Plus Address Entry"/> <int value="32" label="Tab Group Indicator on NTP Entry"/> <int value="33" label="Last Visited History Entry"/> + <int value="34" label="Image on a Reader Mode page"/> + <int value="35" label="Image-Link on a Reader Mode page"/> + <int value="36" label="Link on a Reader Mode page"/> </enum> <enum name="IOSShareAction">
diff --git a/tools/metrics/histograms/metadata/mobile/histograms.xml b/tools/metrics/histograms/metadata/mobile/histograms.xml index f21c7ed..46b432e 100644 --- a/tools/metrics/histograms/metadata/mobile/histograms.xml +++ b/tools/metrics/histograms/metadata/mobile/histograms.xml
@@ -218,6 +218,10 @@ <variant name="OmniboxMostVisitedEntry" summary="Omnibox Most Visited entry"/> <variant name="PinnedTabsEntry" summary="Pinned Tabs entry"/> + <variant name="ReaderModeImage" summary="Image on a Reader Mode page"/> + <variant name="ReaderModeImageLink" + summary="Image-Link on a Reader Mode page"/> + <variant name="ReaderModeLink" summary="Link on a Reader Mode page"/> <variant name="ReadingListEntry" summary="Reading List entry"/> <variant name="RecentTabsEntry" summary="Recent Tabs entry"/> <variant name="RecentTabsHeader" summary="Recent Tabs header/device"/>
diff --git a/tools/metrics/histograms/metadata/storage/enums.xml b/tools/metrics/histograms/metadata/storage/enums.xml index eb2fdbb..9b08a0d 100644 --- a/tools/metrics/histograms/metadata/storage/enums.xml +++ b/tools/metrics/histograms/metadata/storage/enums.xml
@@ -265,6 +265,26 @@ <int value="4" label="Notifications"/> </enum> +<!-- LINT.IfChange(IndexedDbLevelDbCleanupVerificationEvent) --> + +<enum name="IndexedDbLevelDbCleanupVerificationEvent"> + <int value="0" + label="Cleanup was started and a verification snapshot was taken (or at + least attempted)"/> + <int value="1" + label="Error while trying to open the databases before cleanup"/> + <int value="2" + label="Error while trying to create the snapshot before cleanup"/> + <int value="3" + label="Error while trying to open the databases after cleanup"/> + <int value="4" + label="Error while trying to create the snapshot after cleanup"/> + <int value="5" label="Snapshots matched before and after cleanup"/> + <int value="6" label="Snapshots didn't match"/> +</enum> + +<!-- LINT.ThenChange(//content/browser/indexed_db/instance/leveldb/backing_store.h:InSessionCleanupVerificationEvent) --> + <!-- LINT.IfChange(IndexedDbSqliteSpecificEvent) --> <enum name="IndexedDbSqliteSpecificEvent">
diff --git a/tools/metrics/histograms/metadata/storage/histograms.xml b/tools/metrics/histograms/metadata/storage/histograms.xml index b78b6a1..5cd51791 100644 --- a/tools/metrics/histograms/metadata/storage/histograms.xml +++ b/tools/metrics/histograms/metadata/storage/histograms.xml
@@ -22,6 +22,12 @@ <histograms> +<variants name="IndexedDBTransactionCount"> + <variant name="" summary="Always recorded"/> + <variant name="10kTransactions." + summary="Recorded when there are >10k transactions on the connection"/> +</variants> + <variants name="IndexedDBTransactionMode"> <variant name="ReadOnly"/> <variant name="ReadWrite"/> @@ -406,6 +412,34 @@ </summary> </histogram> +<histogram name="IndexedDB.LevelDB.InSessionCleanupSnapshotTime" units="ms" + expires_after="2026-07-01"> + <owner>leimy@chromium.org</owner> + <owner>evanstade@microsoft.com</owner> + <owner>abhishek.shanthkumar@microsoft.com</owner> + <owner>chrome-owp-storage@google.com</owner> + <summary> + Logs the time taken to snapshot/dump an entire backing store for the + purposes of in-session cleanup verification. This is logged for the pre- + cleanup snapshot as well as the post-cleanup snapshot. + </summary> +</histogram> + +<histogram name="IndexedDB.LevelDB.InSessionCleanupVerificationEvent" + enum="IndexedDbLevelDbCleanupVerificationEvent" expires_after="2026-07-01"> + <owner>leimy@chromium.org</owner> + <owner>evanstade@microsoft.com</owner> + <owner>abhishek.shanthkumar@microsoft.com</owner> + <owner>chrome-owp-storage@google.com</owner> + <summary> + Logs results of attempts to verify that in-session cleanup (compaction, + tombstone sweeping) of LevelDB files was successful. This will only be + emitted if in session cleanup is enabled and verification of it is also + enabled, so both kIdbInSessionDbCleanup and kIdbVerifyInSessionDbCleanup + must be enabled. + </summary> +</histogram> + <histogram name="IndexedDB.LevelDBCleanupScheduler.CleanerPostponedCount" units="count" expires_after="2025-11-02"> <owner>leimy@chromium.org</owner> @@ -558,41 +592,45 @@ </token> </histogram> -<histogram name="IndexedDB.TransactionTimeout.CommitPending" enum="Boolean" - expires_after="2026-03-30"> +<histogram name="IndexedDB.TransactionTimeout.{TransactionCount}CommitPending" + enum="Boolean" expires_after="2026-03-30"> <owner>fdoray@chromium.org</owner> <owner>catan-team@chromium.org</owner> <summary> Whether an IndexedDB transaction has a commit pending. Recorded every time the 20 seconds inactivity timeout is hit for a transaction. Will be used to - diagnose crbug.com/381086791. + diagnose crbug.com/381086791. {TransactionCount} </summary> + <token key="TransactionCount" variants="IndexedDBTransactionCount"/> </histogram> -<histogram name="IndexedDB.TransactionTimeout.IsConnected" enum="Boolean" - expires_after="2026-03-30"> +<histogram name="IndexedDB.TransactionTimeout.{TransactionCount}IsConnected" + enum="Boolean" expires_after="2026-03-30"> <owner>fdoray@chromium.org</owner> <owner>catan-team@chromium.org</owner> <summary> Whether the connection to which an IndexedDB transaction is associated is connected. Recorded every time the 20 seconds inactivity timeout is hit for a transaction, if it is associated with an existing connection. Will be used - to diagnose crbug.com/381086791. + to diagnose crbug.com/381086791. {TransactionCount} </summary> + <token key="TransactionCount" variants="IndexedDBTransactionCount"/> </histogram> -<histogram name="IndexedDB.TransactionTimeout.Mode" enum="IDBTransactionMode" - expires_after="2026-03-30"> +<histogram name="IndexedDB.TransactionTimeout.{TransactionCount}Mode" + enum="IDBTransactionMode" expires_after="2026-03-30"> <owner>fdoray@chromium.org</owner> <owner>catan-team@chromium.org</owner> <summary> The mode of an IndexedDB transaction. Recorded every time the 20 seconds inactivity timeout is hit for a transaction. Will be used to diagnose - crbug.com/381086791. + crbug.com/381086791. {TransactionCount} </summary> + <token key="TransactionCount" variants="IndexedDBTransactionCount"/> </histogram> -<histogram name="IndexedDB.TransactionTimeout.NumTransactionsInConnection" +<histogram + name="IndexedDB.TransactionTimeout.{TransactionCount}NumTransactionsInConnection" units="transactions" expires_after="2026-03-30"> <owner>fdoray@chromium.org</owner> <owner>catan-team@chromium.org</owner> @@ -600,11 +638,13 @@ Number of transactions associated with the same connection as an IndexedDB transaction. Recorded every time the 20 seconds inactivity timeout is hit for a transaction. Will be used to diagnose crbug.com/381086791. We suspect - that this can be very high. + that this can be very high. {TransactionCount} </summary> + <token key="TransactionCount" variants="IndexedDBTransactionCount"/> </histogram> -<histogram name="IndexedDB.TransactionTimeout.NumTransactionsInDB" +<histogram + name="IndexedDB.TransactionTimeout.{TransactionCount}NumTransactionsInDB" units="transactions" expires_after="2026-03-30"> <owner>fdoray@chromium.org</owner> <owner>catan-team@chromium.org</owner> @@ -612,8 +652,9 @@ Number of transactions associated with the same database as an IndexedDB transaction. Recorded every time the 20 seconds inactivity timeout is hit for a transaction. Will be used to diagnose crbug.com/381086791. We suspect - that this can be very high. + that this can be very high. {TransactionCount} </summary> + <token key="TransactionCount" variants="IndexedDBTransactionCount"/> </histogram> <histogram name="IndexedDB.ValueDecompressionCount" units="count"
diff --git a/ui/webui/resources/cr_components/history/BUILD.gn b/ui/webui/resources/cr_components/history/BUILD.gn index 25ab7cc4..1b6facd1 100644 --- a/ui/webui/resources/cr_components/history/BUILD.gn +++ b/ui/webui/resources/cr_components/history/BUILD.gn
@@ -9,6 +9,7 @@ mojom("mojo_bindings") { sources = [ "history.mojom" ] + public_deps = [ "//url/mojom:url_mojom_gurl" ] webui_module_path = "" }
diff --git a/ui/webui/resources/cr_components/history/history.mojom b/ui/webui/resources/cr_components/history/history.mojom index 7fe28bf..8ba5d4a01 100644 --- a/ui/webui/resources/cr_components/history/history.mojom +++ b/ui/webui/resources/cr_components/history/history.mojom
@@ -4,6 +4,8 @@ module history.mojom; +import "url/mojom/url.mojom"; + /** * The following enum must be kept in sync with its respective variants in * components/supervised_user/core/browser/supervised_user_utils.h @@ -143,6 +145,15 @@ array<double> timestamps; }; +// TODO(https://crbug.com/447584269): Add user's history sign in state in mojo; +// remove the HistorySignInStateWatcher. +struct AccountInfo { + url.mojom.Url account_image_src; + + string name; + string email; +}; + // Browser-side handler for requests from WebUI page. interface PageHandler { // The BrowserProxy singleton calls this when it's first initialized. @@ -171,6 +182,13 @@ // Notify the backend that the side panel UI is ready to be shown. ShowSidePanelUI(); + + // Requests the signed in user's account info and notifies the browser process + // that the UI is ready to receive account info updates. + RequestAccountInfo() => (AccountInfo account_info); + + // The user turns on the history sync by clicking the "Sync history" button. + TurnOnHistorySync(); }; // WebUI-side handler for requests from browser. @@ -180,4 +198,7 @@ // Alerts the page the other forms of history may or may not be available. OnHasOtherFormsChanged(bool has_other_forms); + + // Sends account info updates to the UI. + SendAccountInfo(AccountInfo account_info); }; \ No newline at end of file
diff --git a/url/url_features.cc b/url/url_features.cc index 6e2162d..55cdc8b 100644 --- a/url/url_features.cc +++ b/url/url_features.cc
@@ -20,4 +20,16 @@ return base::FeatureList::IsEnabled(kDisallowSpaceCharacterInURLHostParsing); } +BASE_FEATURE(kUseIDNAContextJRules, base::FEATURE_DISABLED_BY_DEFAULT); + +bool IsUsingIDNAContextJRules() { + // If the FeatureList isn't available yet, fall back to the feature's default + // state. This may happen during early startup, see crbug.com/1441956. + if (!base::FeatureList::GetInstance()) { + return kUseIDNAContextJRules.default_state == + base::FEATURE_ENABLED_BY_DEFAULT; + } + return base::FeatureList::IsEnabled(kUseIDNAContextJRules); +} + } // namespace url
diff --git a/url/url_features.h b/url/url_features.h index 61a665aa..f53e1777b 100644 --- a/url/url_features.h +++ b/url/url_features.h
@@ -14,7 +14,7 @@ // correspondingly update the EarlyAccess allow list in app shims/ // (chrome/app_shim/app_shim_controller.mm). See https://crbug.com/1520386 for // more details. -// + // Returns true if space characters should be treated as invalid in URL host // parsing. COMPONENT_EXPORT(URL) bool IsDisallowingSpaceCharacterInURLHostParsing(); @@ -23,6 +23,12 @@ COMPONENT_EXPORT(URL) BASE_DECLARE_FEATURE(kDisallowSpaceCharacterInURLHostParsing); +// Returns true if IDNA ContextJ rules are applied in URL host parsing. +COMPONENT_EXPORT(URL) bool IsUsingIDNAContextJRules(); + +// When enabled, apply IDNA ContextJ rules in URL host parsing. +COMPONENT_EXPORT(URL) BASE_DECLARE_FEATURE(kUseIDNAContextJRules); + } // namespace url #endif // URL_URL_FEATURES_H_
diff --git a/url/url_idna_icu.cc b/url/url_idna_icu.cc index 049b58eb..f0ad74c 100644 --- a/url/url_idna_icu.cc +++ b/url/url_idna_icu.cc
@@ -45,9 +45,11 @@ // See http://http://unicode.org/reports/tr46/ and references therein // for more details. UIDNA* CreateIDNA() { - uint32_t options = UIDNA_CHECK_BIDI; - // Use non-transitional processing, see https://url.spec.whatwg.org/#idna. - options |= UIDNA_NONTRANSITIONAL_TO_ASCII | UIDNA_NONTRANSITIONAL_TO_UNICODE; + // Enable options matching https://url.spec.whatwg.org/#idna. + // Note that ContextJ checks are enabled or disabled based on + // IsUsingIDNAContextJRules() in IDNToASCII(). + uint32_t options = UIDNA_CHECK_BIDI | UIDNA_NONTRANSITIONAL_TO_ASCII | + UIDNA_NONTRANSITIONAL_TO_UNICODE | UIDNA_CHECK_CONTEXTJ; UErrorCode err = U_ZERO_ERROR; UIDNA* idna = uidna_openUTS46(options, &err); if (U_FAILURE(err)) { @@ -101,6 +103,7 @@ // Disable the "CheckHyphens" option in UTS #46. See // - https://crbug.com/804688 // - https://github.com/whatwg/url/issues/267 + // - https://github.com/whatwg/url/issues/820 (beStrict is false) info.errors &= ~UIDNA_ERROR_HYPHEN_3_4; info.errors &= ~UIDNA_ERROR_LEADING_HYPHEN; info.errors &= ~UIDNA_ERROR_TRAILING_HYPHEN; @@ -110,6 +113,11 @@ info.errors &= ~UIDNA_ERROR_LABEL_TOO_LONG; info.errors &= ~UIDNA_ERROR_DOMAIN_NAME_TOO_LONG; + // Clear any ContextJ error if the feature isn't enabled. + if (!url::IsUsingIDNAContextJRules()) { + info.errors &= ~UIDNA_ERROR_CONTEXTJ; + } + if (U_SUCCESS(err) && info.errors == 0) { // Per WHATWG URL, it is a failure if the ToASCII output is empty. //