diff --git a/DEPS b/DEPS index 31c2e3cd..cec335bf 100644 --- a/DEPS +++ b/DEPS
@@ -312,7 +312,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'fef9f270935c1b1e8cc881978d510b4a5d13fdc9', + 'skia_revision': '0bdd0daaa3fc8ca569fd9522c0b7cd5ed0edf0a5', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -320,7 +320,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'cc770518b07ce9ef45cd1c283e9f69b3711d304e', + 'angle_revision': '602a6a9a532fac607e3c36824a8998e270d406a4', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -387,7 +387,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling chromium_variations # and whatever else without interference from each other. - 'chromium_variations_revision': 'cf6d4af87f019ef741ad50686e12877d84410a28', + 'chromium_variations_revision': '6a189db270f1b70438eb7db6a73be3d46285defd', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling CrossBench # and whatever else without interference from each other. @@ -403,7 +403,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '6a303cbb86cd070e504f3728d314430f17b4e53d', + 'devtools_frontend_revision': 'caa4a369e29db1c39171a43a5d68412add28069c', # 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. @@ -427,7 +427,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': 'b4d05dec16507b5a6fc832dfb56a9e6489a13302', + 'dawn_revision': '7913b91fdaf8ec73f89407ded62cc7c335ab8da7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -827,12 +827,12 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '4799cd305fe7062e4a6e9b455b2bb2c4db50060d', + '6e6172a7ecc30400437bbe53d6c8c006ab8f3f48', 'condition': 'checkout_android and checkout_src_internal', }, 'src/docs/website': { - 'url': Var('chromium_git') + '/website.git' + '@' + 'c50bcc04d18f45a37e8b7aca67e712d20bf145c2', + 'url': Var('chromium_git') + '/website.git' + '@' + 'e154573dde8bd6bab4bc32b52be8542de4aa858d', }, 'src/ios/third_party/earl_grey2/src': { @@ -982,7 +982,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'uG5mZUXGcnn0JQiovIHkaxoRszRRnVnHNGrQfcredVQC', + 'version': 'UKX5El2J6Sx7Ik-Xhy7SJaDtUuqpkVfG1OIc_XoPrn4C', }, ], 'condition': 'checkout_android', @@ -1192,13 +1192,13 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '1a61eb625d4b062bb2d6f0902b4979b48def4d33', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'b7ed76a09d1953d75968cbc14a53f724c11fb5f9', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), 'src/third_party/devtools-frontend-internal': { - 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '2829e054a8419e6ecf6d60eb321ca8511317d3f2', + 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '75f138cb8f9cafdfef0c8ab615bb99dbb8fc1ad4', 'condition': 'checkout_src_internal', }, @@ -1811,7 +1811,7 @@ 'dep_type': 'cipd', }, - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@707349d2ea9e104986b12655c944c6f758a2443b', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@5b3e26527906aceb0f77f9be20a9f7a11f6b0c70', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + '56300b29fbfcc693ee6609ddad3fdd5b7a449a21', @@ -1848,10 +1848,10 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'bc3c8bad295ae0ba7f0ddb18848df70f92a820c0', 'src/third_party/webgpu-cts/src': - Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'a2897c33ec90d37cbfefed3b3f738f785850c6bf', + Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '40da315f03a896d15fc72911cdf73262c56f7162', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'ff54aee9ab3d5fc5ea6f9d12fb05c582115b736d', + Var('webrtc_git') + '/src.git' + '@' + '299b28569682198aed2b2635f2405c6e7db471ba', # 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. @@ -2018,7 +2018,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/projector_app/app', - 'version': '9ALSFghfWRjqv9UChViV_k5hVWHCcvUg1asF3_eGXmgC', + 'version': 'Xfsbd88OenRBWE4llWiL7oyZeQkJKb_b6IMlsn4jTfoC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -3866,7 +3866,7 @@ 'src/ash/webui/conch': { 'url': Var('chrome_git') + '/ash/webui/conch.git' + '@' + - '63688f1742cefae6fc6aaf7732838f4eb420b4d3', + '6e3f1d19bc845e70d07ed85628e7bcc19a57b2f0', 'condition': 'checkout_src_internal and checkout_chromeos', }, @@ -4125,7 +4125,7 @@ 'src/ios_internal': { 'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' + - '753730eaf49d6dd766d2dc2d1b3b0eaf83a3ec1a', + '6b94e1a9bd73cfc7373ebd18c06e7f543cceec3b', 'condition': 'checkout_ios and checkout_src_internal', },
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwPrerenderTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwPrerenderTest.java index e3b9167..2208faeb2 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwPrerenderTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwPrerenderTest.java
@@ -495,6 +495,68 @@ shouldOverrideUrlLoadingHelper.requestHeaders()); } + // Tests that subframe navigation of prerendered page emits shouldInterceptRequest with + // Sec-Purpose header. + @Test + @LargeTest + @Feature({"AndroidWebView"}) + @Features.EnableFeatures({AwFeatures.WEBVIEW_PRERENDER2}) + @Features.DisableFeatures({BlinkFeatures.PRERENDER2_MEMORY_CONTROLS}) + public void testSubframeOfPrerenderedPageAndShouldInterceptRequest() throws Throwable { + String subframeUrl1 = mTestServer.getURL("/android_webview/test/data/hello_world.html?q=1"); + String subframeUrl2 = mTestServer.getURL("/android_webview/test/data/hello_world.html?q=2"); + String prerenderUrl = + mTestServer.getURL( + "/android_webview/test/data/prerender.html?iframeSrc=" + .concat(subframeUrl1)); + + final TestAwContentsClient.ShouldInterceptRequestHelper helper = + mContentsClient.getShouldInterceptRequestHelper(); + + { + helper.clearUrls(); + int callCount = helper.getCallCount(); + injectSpeculationRulesAndWait(prerenderUrl); + helper.waitForCallback(callCount); + Assert.assertEquals(helper.getUrls(), Arrays.asList(prerenderUrl)); + AwContentsClient.AwWebResourceRequest request = helper.getRequestsForUrl(prerenderUrl); + Assert.assertEquals(request.requestHeaders.get("Sec-Purpose"), "prefetch;prerender"); + } + + { + helper.clearUrls(); + int callCount = helper.getCallCount(); + helper.waitForCallback(callCount); + Assert.assertEquals(helper.getUrls(), Arrays.asList(subframeUrl1)); + AwContentsClient.AwWebResourceRequest request = helper.getRequestsForUrl(subframeUrl1); + // Subframe navigation of prerendered page also has a Sec-Purpose header. + Assert.assertEquals(request.requestHeaders.get("Sec-Purpose"), "prefetch;prerender"); + } + + { + int callCount = helper.getCallCount(); + activatePage(prerenderUrl); + Assert.assertEquals( + "Prerender activation navigation doesn't trigger shouldInterceptRequest", + helper.getCallCount(), + callCount); + } + + { + helper.clearUrls(); + int callCount = helper.getCallCount(); + final String script = String.format("createIframe('%s');", subframeUrl2); + mActivityTestRule.executeJavaScriptAndWaitForResult( + mAwContents, mContentsClient, script); + helper.waitForCallback(callCount); + Assert.assertEquals(helper.getUrls(), Arrays.asList(subframeUrl2)); + AwContentsClient.AwWebResourceRequest request = helper.getRequestsForUrl(subframeUrl2); + // Subframe navigation of the activated page doesn't have a Sec-Purpose header. + Assert.assertNotNull(request.requestHeaders); + Assert.assertNull(request.requestHeaders.get("Sec-Purpose")); + } + } + // Tests postMessage() from JS to Java during prerendering are deferred until activation. // TODO(crbug.com/41490450): Test postMessage() from iframes. @Test
diff --git a/android_webview/test/data/prerender.html b/android_webview/test/data/prerender.html index 21b7c8c..fa648e2 100644 --- a/android_webview/test/data/prerender.html +++ b/android_webview/test/data/prerender.html
@@ -1,7 +1,21 @@ <html> + <body> + </body> <script> // Objects starting with the "aw" prefix are injected by AwPrerenderTest. + function createIframe(url) { + const iframe = document.createElement("iframe"); + iframe.setAttribute("src", url); + document.body.appendChild(iframe); + } + + const params = new URLSearchParams(document.location.search); + const iframeSrc = params.get("iframeSrc"); + if (iframeSrc !== null) { + createIframe(iframeSrc); + } + function wasActivated() { return self.performance?.getEntriesByType?.('navigation')[0]?.activationStart > 0; }
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 3545d6d0..1fad828 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -7153,9 +7153,6 @@ <message name="IDS_PICKER_LOCAL_FILES_CATEGORY_LABEL" translateable="false" desc="Label of the Picker list item which can be clicked to show local file results."> My Files </message> - <message name="IDS_PICKER_EDITOR_CATEGORY_LABEL" translateable="false" desc="Label of the Picker list item which can be clicked to show editor results."> - Editor - </message> <message name="IDS_PICKER_DATES_TIMES_CATEGORY_LABEL" translateable="false" desc="Label of the Picker list item which can be clicked to show date and time results."> Dates & Times </message>
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index c0738f3..ea1866b 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -2180,6 +2180,11 @@ "OrcaUseAccountCapabilities", base::FEATURE_ENABLED_BY_DEFAULT); +// Enables or disables Orca internationalization. +BASE_FEATURE(kOrcaInternationalize, + "OrcaInternationalize", + base::FEATURE_DISABLED_BY_DEFAULT); + // Enables or disables Orca on Workspace. BASE_FEATURE(kOrcaForceFetchContextOnGetEditorPanelContext, "OrcaForceFetchContextOnGetEditorPanelContext",
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index 5d0dbc6..94b544e 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -665,6 +665,8 @@ BASE_DECLARE_FEATURE(kOrcaResizingSupport); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kOrcaUseAccountCapabilities); +COMPONENT_EXPORT(ASH_CONSTANTS) +BASE_DECLARE_FEATURE(kOrcaInternationalize); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsOsFeedbackDialogEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kOsFeedbackDialog);
diff --git a/ash/login/ui/local_authentication_request_widget.cc b/ash/login/ui/local_authentication_request_widget.cc index 163a3f62..d387f19f 100644 --- a/ash/login/ui/local_authentication_request_widget.cc +++ b/ash/login/ui/local_authentication_request_widget.cc
@@ -78,6 +78,9 @@ std::unique_ptr<UserContext> user_context) { CHECK(!g_instance); + const auto& auth_factors = user_context->GetAuthFactorsData(); + CHECK(auth_factors.FindLocalPasswordFactor()); + g_instance = new LocalAuthenticationRequestWidget( std::move(local_authentication_callback), title, description, delegate, std::move(user_context));
diff --git a/ash/picker/model/picker_model.cc b/ash/picker/model/picker_model.cc index 884dd5d..6ff429a7 100644 --- a/ash/picker/model/picker_model.cc +++ b/ash/picker/model/picker_model.cc
@@ -37,7 +37,7 @@ if (HasSelectedText()) { std::vector<PickerCategory> categories; if (editor_status_ == EditorStatus::kEnabled) { - categories.push_back(PickerCategory::kEditor); + categories.push_back(PickerCategory::kEditorRewrite); } categories.insert(categories.end(), { PickerCategory::kUpperCase, @@ -52,7 +52,7 @@ ? PickerCategory::kCapsOff : PickerCategory::kCapsOn}; if (editor_status_ == EditorStatus::kEnabled) { - categories.push_back(PickerCategory::kEditor); + categories.push_back(PickerCategory::kEditorWrite); } categories.insert(categories.end(), { PickerCategory::kLinks,
diff --git a/ash/picker/model/picker_model_unittest.cc b/ash/picker/model/picker_model_unittest.cc index f9af4c2..a2ca1d3d 100644 --- a/ash/picker/model/picker_model_unittest.cc +++ b/ash/picker/model/picker_model_unittest.cc
@@ -24,7 +24,7 @@ PickerModel::EditorStatus::kEnabled); EXPECT_THAT( model.GetAvailableCategories(), - ElementsAre(PickerCategory::kCapsOn, PickerCategory::kEditor, + ElementsAre(PickerCategory::kCapsOn, PickerCategory::kEditorWrite, PickerCategory::kLinks, PickerCategory::kExpressions, PickerCategory::kClipboard, PickerCategory::kDriveFiles, PickerCategory::kLocalFiles, PickerCategory::kDatesTimes, @@ -40,7 +40,7 @@ PickerModel::EditorStatus::kEnabled); EXPECT_THAT( model.GetAvailableCategories(), - ElementsAre(PickerCategory::kCapsOn, PickerCategory::kEditor, + ElementsAre(PickerCategory::kCapsOn, PickerCategory::kEditorWrite, PickerCategory::kLinks, PickerCategory::kExpressions, PickerCategory::kClipboard, PickerCategory::kDriveFiles, PickerCategory::kLocalFiles, PickerCategory::kDatesTimes, @@ -56,7 +56,7 @@ PickerModel::EditorStatus::kEnabled); EXPECT_THAT( model.GetAvailableCategories(), - ElementsAre(PickerCategory::kEditor, PickerCategory::kUpperCase, + ElementsAre(PickerCategory::kEditorRewrite, PickerCategory::kUpperCase, PickerCategory::kLowerCase, PickerCategory::kSentenceCase, PickerCategory::kTitleCase)); } @@ -83,26 +83,46 @@ Contains(PickerCategory::kCapsOn)); } -TEST(PickerModel, AvailableCategoriesEnablesEditorWhenEnabled) { +TEST(PickerModel, AvailableCategoriesContainsEditorWriteWhenEnabled) { input_method::FakeImeKeyboard fake_ime_keyboard; - fake_ime_keyboard.SetCapsLockEnabled(false); ui::FakeTextInputClient client({.type = ui::TEXT_INPUT_TYPE_TEXT}); PickerModel model(&client, &fake_ime_keyboard, PickerModel::EditorStatus::kEnabled); EXPECT_THAT(model.GetAvailableCategories(), - Contains(PickerCategory::kEditor)); + Contains(PickerCategory::kEditorWrite)); } -TEST(PickerModel, AvailableCategoriesDisablesEditorWhenDisabled) { +TEST(PickerModel, AvailableCategoriesOmitsEditorWriteWhenDisabled) { input_method::FakeImeKeyboard fake_ime_keyboard; - fake_ime_keyboard.SetCapsLockEnabled(false); ui::FakeTextInputClient client({.type = ui::TEXT_INPUT_TYPE_TEXT}); PickerModel model(&client, &fake_ime_keyboard, PickerModel::EditorStatus::kDisabled); EXPECT_THAT(model.GetAvailableCategories(), - Not(Contains(PickerCategory::kEditor))); + Not(Contains(PickerCategory::kEditorWrite))); +} + +TEST(PickerModel, AvailableCategoriesContainsEditorRewriteWhenEnabled) { + input_method::FakeImeKeyboard fake_ime_keyboard; + ui::FakeTextInputClient client({.type = ui::TEXT_INPUT_TYPE_TEXT}); + client.SetTextAndSelection(u"a", gfx::Range(0, 1)); + + PickerModel model(&client, &fake_ime_keyboard, + PickerModel::EditorStatus::kEnabled); + EXPECT_THAT(model.GetAvailableCategories(), + Contains(PickerCategory::kEditorRewrite)); +} + +TEST(PickerModel, AvailableCategoriesOmitsEditorRewriteWhenDisabled) { + input_method::FakeImeKeyboard fake_ime_keyboard; + ui::FakeTextInputClient client({.type = ui::TEXT_INPUT_TYPE_TEXT}); + client.SetTextAndSelection(u"a", gfx::Range(0, 1)); + + PickerModel model(&client, &fake_ime_keyboard, + PickerModel::EditorStatus::kDisabled); + EXPECT_THAT(model.GetAvailableCategories(), + Not(Contains(PickerCategory::kEditorRewrite))); } TEST(PickerModel, GetsEmptySelectedText) {
diff --git a/ash/picker/model/picker_search_results_section.h b/ash/picker/model/picker_search_results_section.h index ad93abc8..3614ade8 100644 --- a/ash/picker/model/picker_search_results_section.h +++ b/ash/picker/model/picker_search_results_section.h
@@ -23,7 +23,8 @@ kGifs, kRecentlyUsed, kExamples, - kEditor, + kEditorWrite, + kEditorRewrite, }; // Search results are divided into different sections.
diff --git a/ash/picker/picker_controller.cc b/ash/picker/picker_controller.cc index 15deafc..3434b387 100644 --- a/ash/picker/picker_controller.cc +++ b/ash/picker/picker_controller.cc
@@ -240,7 +240,8 @@ return ToSentenceCase(text); case PickerCategory::kTitleCase: return ToTitleCase(text); - case PickerCategory::kEditor: + case PickerCategory::kEditorWrite: + case PickerCategory::kEditorRewrite: case PickerCategory::kLinks: case PickerCategory::kExpressions: case PickerCategory::kDriveFiles: @@ -345,7 +346,8 @@ // TODO: b/325977099 - Get actual results for each category. std::vector<ash::PickerSearchResult> recent_results; switch (category) { - case PickerCategory::kEditor: + case PickerCategory::kEditorWrite: + case PickerCategory::kEditorRewrite: case PickerCategory::kUpperCase: case PickerCategory::kLowerCase: case PickerCategory::kSentenceCase:
diff --git a/ash/picker/picker_controller_unittest.cc b/ash/picker/picker_controller_unittest.cc index 394c6bc..3b73e70 100644 --- a/ash/picker/picker_controller_unittest.cc +++ b/ash/picker/picker_controller_unittest.cc
@@ -398,7 +398,7 @@ controller.ToggleWidget(); EXPECT_THAT(controller.GetAvailableCategories(), - Contains(PickerCategory::kEditor)); + Contains(PickerCategory::kEditorWrite)); } TEST_F(PickerControllerTest, @@ -411,7 +411,7 @@ controller.ToggleWidget(); EXPECT_THAT(controller.GetAvailableCategories(), - Not(Contains(PickerCategory::kEditor))); + Not(Contains(PickerCategory::kEditorWrite))); } TEST_F(PickerControllerTest, GetUpperCaseSelectedText) {
diff --git a/ash/picker/search/picker_editor_search.cc b/ash/picker/search/picker_editor_search.cc index 00e700b..f7c1b29 100644 --- a/ash/picker/search/picker_editor_search.cc +++ b/ash/picker/search/picker_editor_search.cc
@@ -21,12 +21,13 @@ } std::optional<PickerSearchResult> PickerEditorSearch( + PickerSearchResult::EditorData::Mode mode, std::u16string_view query) { CHECK(!query.empty()); string_matching::TokenizedString tokenized_query{std::u16string(query)}; return tokenized_query.tokens().size() >= kMinWordsNeededForEditorMatch ? std::make_optional( - PickerSearchResult::Editor(base::UTF16ToUTF8(query))) + PickerSearchResult::Editor(mode, base::UTF16ToUTF8(query))) : std::nullopt; }
diff --git a/ash/picker/search/picker_editor_search.h b/ash/picker/search/picker_editor_search.h index 779fee4..0606329 100644 --- a/ash/picker/search/picker_editor_search.h +++ b/ash/picker/search/picker_editor_search.h
@@ -9,15 +9,15 @@ #include <string_view> #include "ash/ash_export.h" +#include "ash/public/cpp/picker/picker_search_result.h" namespace ash { -class PickerSearchResult; - // `query` must not be empty. ASH_EXPORT std::optional<PickerSearchResult> PickerEditorSearch( + PickerSearchResult::EditorData::Mode mode, std::u16string_view query); } // namespace ash -#endif // ASH_PICKER_SEARCH_PICKER_CATEGORY_SEARCH_H_ +#endif // ASH_PICKER_SEARCH_PICKER_EDITOR_SEARCH_H_
diff --git a/ash/picker/search/picker_editor_search_unittest.cc b/ash/picker/search/picker_editor_search_unittest.cc index 1433e52..ea0ed3e 100644 --- a/ash/picker/search/picker_editor_search_unittest.cc +++ b/ash/picker/search/picker_editor_search_unittest.cc
@@ -21,7 +21,8 @@ TEST(PickerEditorSearchTest, MatchesSentence) { EXPECT_THAT( - PickerEditorSearch(u"the quick brown fox"), + PickerEditorSearch(PickerSearchResult::EditorData::Mode::kWrite, + u"the quick brown fox"), Optional(Property( "data", &PickerSearchResult::data, VariantWith<PickerSearchResult::EditorData>(Field( @@ -30,7 +31,9 @@ } TEST(PickerEditorSearchTest, DoesNotMatchShortSentence) { - EXPECT_EQ(PickerEditorSearch(u"the quick brown"), std::nullopt); + EXPECT_EQ(PickerEditorSearch(PickerSearchResult::EditorData::Mode::kWrite, + u"the quick brown"), + std::nullopt); } } // namespace
diff --git a/ash/picker/search/picker_search_aggregator.cc b/ash/picker/search/picker_search_aggregator.cc index a0637c42..063320f 100644 --- a/ash/picker/search/picker_search_aggregator.cc +++ b/ash/picker/search/picker_search_aggregator.cc
@@ -40,8 +40,10 @@ return PickerSectionType::kFiles; case PickerSearchSource::kDrive: return PickerSectionType::kDriveFiles; - case PickerSearchSource::kEditor: - return PickerSectionType::kEditor; + case PickerSearchSource::kEditorWrite: + return PickerSectionType::kEditorWrite; + case PickerSearchSource::kEditorRewrite: + return PickerSectionType::kEditorRewrite; } } @@ -109,7 +111,8 @@ for (PickerSectionType type : { PickerSectionType::kSuggestions, PickerSectionType::kCategories, - PickerSectionType::kEditor, + PickerSectionType::kEditorWrite, + PickerSectionType::kEditorRewrite, PickerSectionType::kExpressions, PickerSectionType::kLinks, PickerSectionType::kFiles,
diff --git a/ash/picker/search/picker_search_aggregator_unittest.cc b/ash/picker/search/picker_search_aggregator_unittest.cc index c3a4e93..7e7957f 100644 --- a/ash/picker/search/picker_search_aggregator_unittest.cc +++ b/ash/picker/search/picker_search_aggregator_unittest.cc
@@ -92,8 +92,12 @@ .section_type = PickerSectionType::kSuggestions, }, TestCase{ - .source = PickerSearchSource::kEditor, - .section_type = PickerSectionType::kEditor, + .source = PickerSearchSource::kEditorWrite, + .section_type = PickerSectionType::kEditorWrite, + }, + TestCase{ + .source = PickerSearchSource::kEditorRewrite, + .section_type = PickerSectionType::kEditorRewrite, })); TEST_P(PickerSearchAggregatorTest, DoesNotPublishResultsDuringBurnIn) { @@ -284,14 +288,23 @@ &PickerSearchResult::TextData::primary_text, u"category")))))), AllOf(Property("type", &PickerSearchResultsSection::type, - PickerSectionType::kEditor), + PickerSectionType::kEditorWrite), Property("results", &PickerSearchResultsSection::results, ElementsAre(Property( "data", &PickerSearchResult::data, VariantWith<PickerSearchResult::TextData>(Field( "primary_text", &PickerSearchResult::TextData::primary_text, - u"editor")))))), + u"write")))))), + AllOf(Property("type", &PickerSearchResultsSection::type, + PickerSectionType::kEditorRewrite), + Property("results", &PickerSearchResultsSection::results, + ElementsAre(Property( + "data", &PickerSearchResult::data, + VariantWith<PickerSearchResult::TextData>(Field( + "primary_text", + &PickerSearchResult::TextData::primary_text, + u"rewrite")))))), AllOf(Property("type", &PickerSearchResultsSection::type, PickerSectionType::kExpressions), Property("results", &PickerSearchResultsSection::results, @@ -368,8 +381,11 @@ aggregator.HandleSearchSourceResults(PickerSearchSource::kMath, {PickerSearchResult::Text(u"math")}, /*has_more_results=*/false); - aggregator.HandleSearchSourceResults(PickerSearchSource::kEditor, - {PickerSearchResult::Text(u"editor")}, + aggregator.HandleSearchSourceResults(PickerSearchSource::kEditorWrite, + {PickerSearchResult::Text(u"write")}, + /*has_more_results=*/false); + aggregator.HandleSearchSourceResults(PickerSearchSource::kEditorRewrite, + {PickerSearchResult::Text(u"rewrite")}, /*has_more_results=*/false); task_environment().FastForwardBy(kBurnInPeriod); } @@ -455,14 +471,26 @@ EXPECT_CALL(search_results_callback, Call(ElementsAre(AllOf( Property("type", &PickerSearchResultsSection::type, - PickerSectionType::kEditor), + PickerSectionType::kEditorWrite), Property("results", &PickerSearchResultsSection::results, ElementsAre(Property( "data", &PickerSearchResult::data, VariantWith<PickerSearchResult::TextData>(Field( "primary_text", &PickerSearchResult::TextData::primary_text, - u"editor"))))))))) + u"write"))))))))) + .Times(1); + EXPECT_CALL(search_results_callback, + Call(ElementsAre(AllOf( + Property("type", &PickerSearchResultsSection::type, + PickerSectionType::kEditorRewrite), + Property("results", &PickerSearchResultsSection::results, + ElementsAre(Property( + "data", &PickerSearchResult::data, + VariantWith<PickerSearchResult::TextData>(Field( + "primary_text", + &PickerSearchResult::TextData::primary_text, + u"rewrite"))))))))) .Times(1); PickerSearchAggregator aggregator( @@ -495,8 +523,11 @@ aggregator.HandleSearchSourceResults(PickerSearchSource::kMath, {PickerSearchResult::Text(u"math")}, /*has_more_results=*/false); - aggregator.HandleSearchSourceResults(PickerSearchSource::kEditor, - {PickerSearchResult::Text(u"editor")}, + aggregator.HandleSearchSourceResults(PickerSearchSource::kEditorWrite, + {PickerSearchResult::Text(u"write")}, + /*has_more_results=*/false); + aggregator.HandleSearchSourceResults(PickerSearchSource::kEditorRewrite, + {PickerSearchResult::Text(u"rewrite")}, /*has_more_results=*/false); }
diff --git a/ash/picker/search/picker_search_controller_unittest.cc b/ash/picker/search/picker_search_controller_unittest.cc index 1ab39764..8f68335 100644 --- a/ash/picker/search/picker_search_controller_unittest.cc +++ b/ash/picker/search/picker_search_controller_unittest.cc
@@ -58,7 +58,8 @@ static_assert(kBurnInPeriod < kAfterBurnIn); constexpr base::span<const PickerCategory> kAllCategories = {(PickerCategory[]){ - PickerCategory::kEditor, + PickerCategory::kEditorWrite, + PickerCategory::kEditorRewrite, PickerCategory::kLinks, PickerCategory::kExpressions, PickerCategory::kClipboard,
diff --git a/ash/picker/search/picker_search_request.cc b/ash/picker/search/picker_search_request.cc index d84c88a..0d5d3ef 100644 --- a/ash/picker/search/picker_search_request.cc +++ b/ash/picker/search/picker_search_request.cc
@@ -115,9 +115,23 @@ HandleCategorySearchResults( PickerCategorySearch(available_categories, query)); - // Editor results are currently synchronous. - editor_search_start_ = base::TimeTicks::Now(); - HandleEditorSearchResults(PickerEditorSearch(query)); + if (base::Contains(available_categories, PickerCategory::kEditorWrite)) { + // Editor results are currently synchronous. + editor_search_start_ = base::TimeTicks::Now(); + HandleEditorSearchResults( + PickerSearchSource::kEditorWrite, + PickerEditorSearch(PickerSearchResult::EditorData::Mode::kWrite, + query)); + } + + if (base::Contains(available_categories, PickerCategory::kEditorRewrite)) { + // Editor results are currently synchronous. + editor_search_start_ = base::TimeTicks::Now(); + HandleEditorSearchResults( + PickerSearchSource::kEditorRewrite, + PickerEditorSearch(PickerSearchResult::EditorData::Mode::kRewrite, + query)); + } } } @@ -320,6 +334,7 @@ } void PickerSearchRequest::HandleEditorSearchResults( + PickerSearchSource source, std::optional<PickerSearchResult> result) { if (editor_search_start_.has_value()) { base::TimeDelta elapsed = base::TimeTicks::Now() - *editor_search_start_; @@ -333,7 +348,7 @@ } // Editor results are never truncated. - HandleSearchSourceResults(PickerSearchSource::kEditor, std::move(results), + HandleSearchSourceResults(source, std::move(results), /*has_more_results=*/false); }
diff --git a/ash/picker/search/picker_search_request.h b/ash/picker/search/picker_search_request.h index d1ea54d..3c8deac 100644 --- a/ash/picker/search/picker_search_request.h +++ b/ash/picker/search/picker_search_request.h
@@ -71,7 +71,8 @@ void HandleDateSearchResults(std::vector<PickerSearchResult> results); void HandleMathSearchResults(std::optional<PickerSearchResult> result); void HandleClipboardSearchResults(std::vector<PickerSearchResult> results); - void HandleEditorSearchResults(std::optional<PickerSearchResult> result); + void HandleEditorSearchResults(PickerSearchSource source, + std::optional<PickerSearchResult> result); void OnDriveSearchTimeout();
diff --git a/ash/picker/search/picker_search_request_unittest.cc b/ash/picker/search/picker_search_request_unittest.cc index 16c4ba1..3ca8e54 100644 --- a/ash/picker/search/picker_search_request_unittest.cc +++ b/ash/picker/search/picker_search_request_unittest.cc
@@ -54,7 +54,8 @@ constexpr base::TimeDelta kMetricMetricTime = base::Milliseconds(300); constexpr base::span<const PickerCategory> kAllCategories = {(PickerCategory[]){ - PickerCategory::kEditor, + PickerCategory::kEditorWrite, + PickerCategory::kEditorRewrite, PickerCategory::kLinks, PickerCategory::kExpressions, PickerCategory::kClipboard, @@ -1190,12 +1191,18 @@ "Ash.Picker.Search.ClipboardProvider.QueryTime", kMetricMetricTime, 1); } -TEST_F(PickerSearchRequestTest, ShowsResultsFromEditorSearch) { +class PickerSearchRequestEditorTest + : public PickerSearchRequestTest, + public testing::WithParamInterface< + std::pair<PickerCategory, PickerSearchSource>> {}; + +TEST_P(PickerSearchRequestEditorTest, ShowsResultsFromEditorSearch) { + const auto& [category, source] = GetParam(); MockSearchResultsCallback search_results_callback; EXPECT_CALL(search_results_callback, Call).Times(AnyNumber()); EXPECT_CALL( search_results_callback, - Call(PickerSearchSource::kEditor, + Call(source, ElementsAre(Property( "data", &PickerSearchResult::data, VariantWith<PickerSearchResult::EditorData>(Field( @@ -1209,10 +1216,25 @@ u"quick brown fox jumped over lazy dog", std::nullopt, base::BindRepeating(&MockSearchResultsCallback::Call, base::Unretained(&search_results_callback)), - &client(), &emoji_search(), kAllCategories); + &client(), &emoji_search(), {{category}}); } -TEST_F(PickerSearchRequestTest, RecordsEditorMetrics) { +TEST_P(PickerSearchRequestEditorTest, + DoNotShowResultsFromEditorSearchIfNotAvailable) { + const auto& [category, source] = GetParam(); + MockSearchResultsCallback search_results_callback; + EXPECT_CALL(search_results_callback, Call).Times(AnyNumber()); + EXPECT_CALL(search_results_callback, Call(source, _, _)).Times(0); + + PickerSearchRequest request( + u"quick brown fox jumped over lazy dog", std::nullopt, + base::BindRepeating(&MockSearchResultsCallback::Call, + base::Unretained(&search_results_callback)), + &client(), &emoji_search(), {}); +} + +TEST_P(PickerSearchRequestEditorTest, RecordsEditorMetrics) { + const auto& [category, source] = GetParam(); base::HistogramTester histogram; NiceMock<MockSearchResultsCallback> search_results_callback; @@ -1220,10 +1242,18 @@ u"quick brown fox jumped over lazy dog", std::nullopt, base::BindRepeating(&MockSearchResultsCallback::Call, base::Unretained(&search_results_callback)), - &client(), &emoji_search(), kAllCategories); + &client(), &emoji_search(), {{category}}); histogram.ExpectTotalCount("Ash.Picker.Search.EditorProvider.QueryTime", 1); } +INSTANTIATE_TEST_SUITE_P( + , + PickerSearchRequestEditorTest, + testing::Values(std::make_pair(PickerCategory::kEditorWrite, + PickerSearchSource::kEditorWrite), + std::make_pair(PickerCategory::kEditorRewrite, + PickerSearchSource::kEditorRewrite))); + } // namespace } // namespace ash
diff --git a/ash/picker/search/picker_search_source.h b/ash/picker/search/picker_search_source.h index 23396598..8668674 100644 --- a/ash/picker/search/picker_search_source.h +++ b/ash/picker/search/picker_search_source.h
@@ -17,7 +17,8 @@ kDrive, kMath, kClipboard, - kEditor, + kEditorWrite, + kEditorRewrite, }; }
diff --git a/ash/picker/views/picker_category_type.cc b/ash/picker/views/picker_category_type.cc index 5d48973..07d2976 100644 --- a/ash/picker/views/picker_category_type.cc +++ b/ash/picker/views/picker_category_type.cc
@@ -10,8 +10,10 @@ ASH_EXPORT PickerCategoryType GetPickerCategoryType(PickerCategory category) { switch (category) { - case PickerCategory::kEditor: - return PickerCategoryType::kEditors; + case PickerCategory::kEditorWrite: + return PickerCategoryType::kEditorWrite; + case PickerCategory::kEditorRewrite: + return PickerCategoryType::kEditorRewrite; case PickerCategory::kLinks: case PickerCategory::kExpressions: case PickerCategory::kClipboard:
diff --git a/ash/picker/views/picker_category_type.h b/ash/picker/views/picker_category_type.h index 1b447416..147d50d 100644 --- a/ash/picker/views/picker_category_type.h +++ b/ash/picker/views/picker_category_type.h
@@ -12,7 +12,8 @@ // Used to group related categories together. enum class ASH_EXPORT PickerCategoryType { - kEditors, + kEditorWrite, + kEditorRewrite, kGeneral, kCalculations, kCaseTransformations,
diff --git a/ash/picker/views/picker_icons.cc b/ash/picker/views/picker_icons.cc index ccc428e..074aa036 100644 --- a/ash/picker/views/picker_icons.cc +++ b/ash/picker/views/picker_icons.cc
@@ -14,7 +14,10 @@ const gfx::VectorIcon& GetVectorIconForPickerCategory(PickerCategory category) { switch (category) { - case PickerCategory::kEditor: + case PickerCategory::kEditorWrite: + // TODO: b/322926823 - Use correct icons. + return kPencilIcon; + case PickerCategory::kEditorRewrite: // TODO: b/322926823 - Use correct icons. return kPencilIcon; case PickerCategory::kExpressions:
diff --git a/ash/picker/views/picker_search_results_view.cc b/ash/picker/views/picker_search_results_view.cc index 24e04e6..9ef3d70 100644 --- a/ash/picker/views/picker_search_results_view.cc +++ b/ash/picker/views/picker_search_results_view.cc
@@ -46,9 +46,21 @@ namespace ash { namespace { + // Some of the icons we use do not have a default size, so we need to manually // set it. constexpr int kIconSize = 20; + +PickerCategory GetCategoryForEditorData( + const PickerSearchResult::EditorData& data) { + switch (data.mode) { + case PickerSearchResult::EditorData::Mode::kWrite: + return PickerCategory::kEditorWrite; + case PickerSearchResult::EditorData::Mode::kRewrite: + return PickerCategory::kEditorRewrite; + } +} + } // namespace PickerSearchResultsView::PickerSearchResultsView( @@ -340,10 +352,9 @@ [&](const PickerSearchResult::EditorData& data) { auto item_view = std::make_unique<PickerListItemView>( std::move(select_result_callback)); - item_view->SetPrimaryText( - GetLabelForPickerCategory(PickerCategory::kEditor)); - item_view->SetLeadingIcon( - GetIconForPickerCategory(PickerCategory::kEditor)); + const PickerCategory category = GetCategoryForEditorData(data); + item_view->SetPrimaryText(GetLabelForPickerCategory(category)); + item_view->SetLeadingIcon(GetIconForPickerCategory(category)); section_view->AddListItem(std::move(item_view)); }, },
diff --git a/ash/picker/views/picker_strings.cc b/ash/picker/views/picker_strings.cc index 19ea877..d8097ae 100644 --- a/ash/picker/views/picker_strings.cc +++ b/ash/picker/views/picker_strings.cc
@@ -11,14 +11,30 @@ #include "ash/public/cpp/picker/picker_category.h" #include "ash/strings/grit/ash_strings.h" #include "base/notreached.h" +#include "build/branding_buildflags.h" +#include "chromeos/strings/grit/chromeos_strings.h" #include "ui/base/l10n/l10n_util.h" +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) +#include "chromeos/ash/resources/internal/strings/grit/ash_internal_strings.h" +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) + namespace ash { std::u16string GetLabelForPickerCategory(PickerCategory category) { switch (category) { - case PickerCategory::kEditor: - return l10n_util::GetStringUTF16(IDS_PICKER_EDITOR_CATEGORY_LABEL); + case PickerCategory::kEditorWrite: +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + return l10n_util::GetStringUTF16(IDS_EDITOR_MENU_WRITE_CARD_TITLE); +#else + return u""; +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) + case PickerCategory::kEditorRewrite: +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + return l10n_util::GetStringUTF16(IDS_EDITOR_MENU_REWRITE_CARD_TITLE); +#else + return u""; +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) case PickerCategory::kLinks: return l10n_util::GetStringUTF16(IDS_PICKER_LINKS_CATEGORY_LABEL); case PickerCategory::kExpressions: @@ -69,7 +85,8 @@ case PickerCategory::kUnitsMaths: return l10n_util::GetStringUTF16( IDS_PICKER_UNITS_MATHS_CATEGORY_SEARCH_FIELD_PLACEHOLDER_TEXT); - case PickerCategory::kEditor: + case PickerCategory::kEditorWrite: + case PickerCategory::kEditorRewrite: case PickerCategory::kExpressions: case PickerCategory::kUpperCase: case PickerCategory::kLowerCase: @@ -84,9 +101,20 @@ std::u16string GetSectionTitleForPickerCategoryType( PickerCategoryType category_type) { switch (category_type) { - case PickerCategoryType::kEditors: + case PickerCategoryType::kEditorWrite: +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) return l10n_util::GetStringUTF16( - IDS_PICKER_EDITOR_CATEGORY_TYPE_SECTION_TITLE); + IDS_PICKER_EDITOR_WRITE_CATEGORY_TYPE_SECTION_TITLE); +#else + return u""; +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) + case PickerCategoryType::kEditorRewrite: +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + return l10n_util::GetStringUTF16( + IDS_PICKER_EDITOR_REWRITE_CATEGORY_TYPE_SECTION_TITLE); +#else + return u""; +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) case PickerCategoryType::kGeneral: return l10n_util::GetStringUTF16( IDS_PICKER_GENERAL_CATEGORY_TYPE_SECTION_TITLE); @@ -124,8 +152,20 @@ return u"Recently used"; case PickerSectionType::kExamples: return u"Examples"; - case PickerSectionType::kEditor: - return u"Editor"; + case PickerSectionType::kEditorWrite: +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + return l10n_util::GetStringUTF16( + IDS_PICKER_EDITOR_WRITE_CATEGORY_TYPE_SECTION_TITLE); +#else + return u""; +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) + case PickerSectionType::kEditorRewrite: +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + return l10n_util::GetStringUTF16( + IDS_PICKER_EDITOR_REWRITE_CATEGORY_TYPE_SECTION_TITLE); +#else + return u""; +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) } }
diff --git a/ash/picker/views/picker_view.cc b/ash/picker/views/picker_view.cc index 33993c00..9a6b699 100644 --- a/ash/picker/views/picker_view.cc +++ b/ash/picker/views/picker_view.cc
@@ -129,7 +129,8 @@ case PickerSectionType::kSuggestions: case PickerSectionType::kRecentlyUsed: case PickerSectionType::kExamples: - case PickerSectionType::kEditor: + case PickerSectionType::kEditorWrite: + case PickerSectionType::kEditorRewrite: NOTREACHED_NORETURN(); case PickerSectionType::kExpressions: return PickerCategory::kExpressions; @@ -295,7 +296,8 @@ return; } - if (category == PickerCategory::kEditor) { + if (category == PickerCategory::kEditorWrite || + category == PickerCategory::kEditorRewrite) { if (auto* widget = GetWidget()) { // TODO: b/330267329 - Correctly handle opening of Editor. Probably // best to wait for the IME on focus event, or save some coordinates and
diff --git a/ash/picker/views/picker_view_unittest.cc b/ash/picker/views/picker_view_unittest.cc index 1c04a03..eb53fd1 100644 --- a/ash/picker/views/picker_view_unittest.cc +++ b/ash/picker/views/picker_view_unittest.cc
@@ -729,7 +729,7 @@ TEST_F(PickerViewTest, ShowsEditorWhenClickingOnEditor) { FakePickerViewDelegate delegate({ - .available_categories = {PickerCategory::kEditor}, + .available_categories = {PickerCategory::kEditorWrite}, }); auto widget = PickerWidget::Create(&delegate, kDefaultAnchorBounds); widget->Show();
diff --git a/ash/picker/views/picker_zero_state_view_unittest.cc b/ash/picker/views/picker_zero_state_view_unittest.cc index 5b86013b..5924b96 100644 --- a/ash/picker/views/picker_zero_state_view_unittest.cc +++ b/ash/picker/views/picker_zero_state_view_unittest.cc
@@ -45,7 +45,8 @@ constexpr int kPickerWidth = 320; constexpr base::span<const PickerCategory> kAllCategories = {(PickerCategory[]){ - PickerCategory::kEditor, + PickerCategory::kEditorWrite, + PickerCategory::kEditorRewrite, PickerCategory::kLinks, PickerCategory::kExpressions, PickerCategory::kClipboard, @@ -74,7 +75,8 @@ PickerZeroStateView view(&mock_delegate, kAllCategories, true, kPickerWidth); EXPECT_THAT(view.section_views_for_testing(), - ElementsAre(Key(PickerCategoryType::kEditors), + ElementsAre(Key(PickerCategoryType::kEditorWrite), + Key(PickerCategoryType::kEditorRewrite), Key(PickerCategoryType::kGeneral), Key(PickerCategoryType::kCalculations))); EXPECT_THAT(view.SuggestedSectionForTesting(), IsNull());
diff --git a/ash/public/cpp/picker/picker_category.h b/ash/public/cpp/picker/picker_category.h index a385461..de9f3ff 100644 --- a/ash/public/cpp/picker/picker_category.h +++ b/ash/public/cpp/picker/picker_category.h
@@ -12,7 +12,8 @@ // A category specifies a type of data that can be searched for. enum class ASH_PUBLIC_EXPORT PickerCategory { // Editor categories: - kEditor, + kEditorWrite, + kEditorRewrite, // General categories: kLinks, kExpressions,
diff --git a/ash/public/cpp/picker/picker_search_result.cc b/ash/public/cpp/picker/picker_search_result.cc index 0ada6fb..612bfac 100644 --- a/ash/public/cpp/picker/picker_search_result.cc +++ b/ash/public/cpp/picker/picker_search_result.cc
@@ -87,8 +87,9 @@ default; PickerSearchResult::EditorData::EditorData( + PickerSearchResult::EditorData::Mode mode, std::optional<std::string> freeform_text) - : freeform_text(std::move(freeform_text)) {} + : mode(mode), freeform_text(std::move(freeform_text)) {} PickerSearchResult::EditorData::EditorData( const PickerSearchResult::EditorData&) = default; @@ -191,8 +192,9 @@ } PickerSearchResult PickerSearchResult::Editor( + PickerSearchResult::EditorData::Mode mode, std::optional<std::string> freeform_text) { - return PickerSearchResult(EditorData(std::move(freeform_text))); + return PickerSearchResult(EditorData(mode, std::move(freeform_text))); } bool PickerSearchResult::operator==(const PickerSearchResult&) const = default;
diff --git a/ash/public/cpp/picker/picker_search_result.h b/ash/public/cpp/picker/picker_search_result.h index f8e8ac6..ec874d8 100644 --- a/ash/public/cpp/picker/picker_search_result.h +++ b/ash/public/cpp/picker/picker_search_result.h
@@ -144,9 +144,12 @@ }; struct EditorData { + enum class Mode { kWrite, kRewrite }; + + Mode mode; std::optional<std::string> freeform_text; - EditorData(std::optional<std::string> freeform_text); + EditorData(Mode mode, std::optional<std::string> freeform_text); EditorData(const EditorData&); EditorData& operator=(const EditorData&); ~EditorData(); @@ -200,7 +203,8 @@ base::FilePath file_path); static PickerSearchResult DriveFile(std::u16string title, const GURL& url); static PickerSearchResult Category(PickerCategory category); - static PickerSearchResult Editor(std::optional<std::string> freeform_text); + static PickerSearchResult Editor(PickerSearchResult::EditorData::Mode mode, + std::optional<std::string> freeform_text); const Data& data() const;
diff --git a/ash/style/icon_button.cc b/ash/style/icon_button.cc index 88006c0..9748dc2 100644 --- a/ash/style/icon_button.cc +++ b/ash/style/icon_button.cc
@@ -33,6 +33,7 @@ constexpr int kSmallButtonSize = 24; constexpr int kMediumButtonSize = 32; constexpr int kLargeButtonSize = 36; +constexpr int kXLargeButtonSize = 48; // Icon size of the small, medium and large size buttons. constexpr int kIconSize = 20; @@ -70,6 +71,11 @@ case IconButton::Type::kLargeFloating: case IconButton::Type::kLargeProminentFloating: return kLargeButtonSize; + case IconButton::Type::kXLarge: + case IconButton::Type::kXLargeProminent: + case IconButton::Type::kXLargeFloating: + case IconButton::Type::kXLargeProminentFloating: + return kXLargeButtonSize; } } @@ -79,11 +85,13 @@ case IconButton::Type::kSmall: case IconButton::Type::kMedium: case IconButton::Type::kLarge: + case IconButton::Type::kXLarge: return cros_tokens::kCrosSysSystemOnBase; case IconButton::Type::kXSmallProminent: case IconButton::Type::kSmallProminent: case IconButton::Type::kMediumProminent: case IconButton::Type::kLargeProminent: + case IconButton::Type::kXLargeProminent: return cros_tokens::kCrosSysSystemPrimaryContainer; default: NOTREACHED() << "Floating type button does not have a background"; @@ -101,16 +109,20 @@ case IconButton::Type::kMediumFloating: case IconButton::Type::kLarge: case IconButton::Type::kLargeFloating: + case IconButton::Type::kXLarge: + case IconButton::Type::kXLargeFloating: return cros_tokens::kCrosSysOnSurface; case IconButton::Type::kXSmallProminent: case IconButton::Type::kSmallProminent: case IconButton::Type::kMediumProminent: case IconButton::Type::kLargeProminent: + case IconButton::Type::kXLargeProminent: return cros_tokens::kCrosSysSystemOnPrimaryContainer; case IconButton::Type::kXSmallProminentFloating: case IconButton::Type::kSmallProminentFloating: case IconButton::Type::kMediumProminentFloating: case IconButton::Type::kLargeProminentFloating: + case IconButton::Type::kXLargeProminentFloating: return focused ? cros_tokens::kCrosSysPrimary : cros_tokens::kCrosSysSecondary; } @@ -136,6 +148,8 @@ case IconButton::Type::kMediumProminentFloating: case IconButton::Type::kLargeFloating: case IconButton::Type::kLargeProminentFloating: + case IconButton::Type::kXLargeFloating: + case IconButton::Type::kXLargeProminentFloating: return true; default: break; @@ -150,6 +164,7 @@ case IconButton::Type::kSmallProminentFloating: case IconButton::Type::kMediumProminentFloating: case IconButton::Type::kLargeProminentFloating: + case IconButton::Type::kXLargeProminentFloating: return true; default: break;
diff --git a/ash/style/icon_button.h b/ash/style/icon_button.h index 008a98e..20756b3 100644 --- a/ash/style/icon_button.h +++ b/ash/style/icon_button.h
@@ -47,18 +47,22 @@ kSmall, kMedium, kLarge, + kXLarge, kXSmallProminent, kSmallProminent, kMediumProminent, kLargeProminent, + kXLargeProminent, kXSmallFloating, kSmallFloating, kMediumFloating, kLargeFloating, + kXLargeFloating, kXSmallProminentFloating, kSmallProminentFloating, kMediumProminentFloating, kLargeProminentFloating, + kXLargeProminentFloating, }; // Used to determine how the button will behave when disabled.
diff --git a/ash/style/style_viewer/icon_button_instances_grid_view_factory.cc b/ash/style/style_viewer/icon_button_instances_grid_view_factory.cc index d2f23612..f75c0880 100644 --- a/ash/style/style_viewer/icon_button_instances_grid_view_factory.cc +++ b/ash/style/style_viewer/icon_button_instances_grid_view_factory.cc
@@ -51,6 +51,7 @@ {u"Default Small", IconButton::Type::kSmall, false, true, nullptr}, {u"Default Meduim", IconButton::Type::kMedium, false, true, nullptr}, {u"Default Large", IconButton::Type::kLarge, false, true, nullptr}, + {u"Default XLarge", IconButton::Type::kXLarge, false, true, nullptr}, {u"Floating XSmall", IconButton::Type::kXSmallFloating, false, true, nullptr}, @@ -60,11 +61,14 @@ nullptr}, {u"Floating Large", IconButton::Type::kLargeFloating, false, true, nullptr}, + {u"Floating XLarge", IconButton::Type::kXLargeFloating, false, true, + nullptr}, {u"Toggled XSmall", IconButton::Type::kXSmall, true, true, nullptr}, {u"Toggled Small", IconButton::Type::kSmall, true, true, nullptr}, {u"Toggled Meduim", IconButton::Type::kMedium, true, true, nullptr}, {u"Toggled Large", IconButton::Type::kLarge, true, true, nullptr}, + {u"Toggled XLarge", IconButton::Type::kLarge, true, true, nullptr}, {u"Prominent Floating XSmall", IconButton::Type::kXSmallProminentFloating, false, true, nullptr}, @@ -73,7 +77,9 @@ {u"Prominent Floating Medium", IconButton::Type::kMediumProminentFloating, false, true, nullptr}, {u"Prominent Floating Large", IconButton::Type::kLargeProminentFloating, - false, true, nullptr}}, + false, true, nullptr}, + {u"Prominent Floating XLarge", + IconButton::Type::kXLargeProminentFloating, false, true, nullptr}}, {{u"Default XSmall With Background Image", IconButton::Type::kXSmall, false, true, image}, @@ -83,11 +89,14 @@ false, true, image}, {u"Default Large With Background Image", IconButton::Type::kLarge, false, true, image}, + {u"Default XLarge With Background Image", IconButton::Type::kXLarge, + false, true, image}, {u"Disabled XSmall", IconButton::Type::kXSmall, false, false, nullptr}, {u"Disabled Small", IconButton::Type::kSmall, false, false, nullptr}, {u"Disabled Meduim", IconButton::Type::kMedium, false, false, nullptr}, - {u"Disabled Large", IconButton::Type::kLarge, false, false, nullptr}}}; + {u"Disabled Large", IconButton::Type::kLarge, false, false, nullptr}, + {u"Disabled XLarge", IconButton::Type::kXLarge, false, false, nullptr}}}; // Insert the instance in grid view with column-primary order. for (auto types : type_groups) {
diff --git a/ash/webui/conch b/ash/webui/conch index 63688f1..6e3f1d1 160000 --- a/ash/webui/conch +++ b/ash/webui/conch
@@ -1 +1 @@ -Subproject commit 63688f1742cefae6fc6aaf7732838f4eb420b4d3 +Subproject commit 6e3f1d19bc845e70d07ed85628e7bcc19a57b2f0
diff --git a/base/BUILD.gn b/base/BUILD.gn index 22b45f82..ad421b6 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -4486,7 +4486,6 @@ ] sources = [ - "android/java/src/org/chromium/base/ActivityLifecycleCallbacksAdapter.java", "android/java/src/org/chromium/base/ActivityState.java", "android/java/src/org/chromium/base/ApiCompatibilityUtils.java", "android/java/src/org/chromium/base/ApkAssets.java", @@ -4815,7 +4814,6 @@ sources = [ "test/android/java/src/org/chromium/base/multidex/ChromiumMultiDexInstaller.java", - "test/android/javatests/src/org/chromium/base/test/ActivityFinisher.java", "test/android/javatests/src/org/chromium/base/test/BaseActivityTestRule.java", "test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java", "test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java",
diff --git a/base/allocator/partition_allocator/partition_alloc.gni b/base/allocator/partition_allocator/partition_alloc.gni index d7be302..4bc43603 100644 --- a/base/allocator/partition_allocator/partition_alloc.gni +++ b/base/allocator/partition_allocator/partition_alloc.gni
@@ -215,7 +215,7 @@ enable_backup_ref_ptr_instance_tracer = false - backup_ref_ptr_extra_oob_checks = enable_backup_ref_ptr_support + backup_ref_ptr_extra_oob_checks = false } declare_args() {
diff --git a/base/android/java/src/org/chromium/base/ActivityLifecycleCallbacksAdapter.java b/base/android/java/src/org/chromium/base/ActivityLifecycleCallbacksAdapter.java deleted file mode 100644 index 4abcc95..0000000 --- a/base/android/java/src/org/chromium/base/ActivityLifecycleCallbacksAdapter.java +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2024 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.base; - -import android.app.Activity; -import android.app.Application; -import android.os.Bundle; - -/** An ActivityLifecycleCallbacks that routes all methods to a single onStateChanged(). */ -public abstract class ActivityLifecycleCallbacksAdapter - implements Application.ActivityLifecycleCallbacks { - public abstract void onStateChanged(Activity activity, @ActivityState int newState); - - @Override - public void onActivityCreated(Activity activity, Bundle savedInstanceState) { - onStateChanged(activity, ActivityState.CREATED); - } - - @Override - public void onActivityDestroyed(Activity activity) { - onStateChanged(activity, ActivityState.DESTROYED); - } - - @Override - public void onActivityPaused(Activity activity) { - onStateChanged(activity, ActivityState.PAUSED); - } - - @Override - public void onActivityResumed(Activity activity) { - onStateChanged(activity, ActivityState.RESUMED); - } - - @Override - public void onActivityStarted(Activity activity) { - onStateChanged(activity, ActivityState.STARTED); - } - - @Override - public void onActivityStopped(Activity activity) { - onStateChanged(activity, ActivityState.STOPPED); - } - - @Override - public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {} -}
diff --git a/base/android/java/src/org/chromium/base/ApplicationStatus.java b/base/android/java/src/org/chromium/base/ApplicationStatus.java index 612dc59..bb9daebe 100644 --- a/base/android/java/src/org/chromium/base/ApplicationStatus.java +++ b/base/android/java/src/org/chromium/base/ApplicationStatus.java
@@ -7,7 +7,9 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.app.Application; +import android.app.Application.ActivityLifecycleCallbacks; import android.content.SharedPreferences; +import android.os.Bundle; import android.view.Window; import androidx.annotation.AnyThread; @@ -19,6 +21,8 @@ import org.jni_zero.JNINamespace; import org.jni_zero.NativeMethods; +import org.chromium.build.BuildConfig; + import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; @@ -317,17 +321,55 @@ }); application.registerActivityLifecycleCallbacks( - new ActivityLifecycleCallbacksAdapter() { + new ActivityLifecycleCallbacks() { @Override - public void onStateChanged(Activity activity, @ActivityState int newState) { - if (newState == ActivityState.CREATED) { - Window.Callback callback = activity.getWindow().getCallback(); - activity.getWindow() - .setCallback(createWindowCallbackProxy(activity, callback)); - } else { + public void onActivityCreated( + final Activity activity, Bundle savedInstanceState) { + onStateChange(activity, ActivityState.CREATED); + Window.Callback callback = activity.getWindow().getCallback(); + activity.getWindow() + .setCallback(createWindowCallbackProxy(activity, callback)); + } + + @Override + public void onActivityDestroyed(Activity activity) { + onStateChange(activity, ActivityState.DESTROYED); + checkCallback(activity); + } + + @Override + public void onActivityPaused(Activity activity) { + onStateChange(activity, ActivityState.PAUSED); + checkCallback(activity); + } + + @Override + public void onActivityResumed(Activity activity) { + onStateChange(activity, ActivityState.RESUMED); + checkCallback(activity); + } + + @Override + public void onActivitySaveInstanceState(Activity activity, Bundle outState) { + checkCallback(activity); + } + + @Override + public void onActivityStarted(Activity activity) { + onStateChange(activity, ActivityState.STARTED); + checkCallback(activity); + } + + @Override + public void onActivityStopped(Activity activity) { + onStateChange(activity, ActivityState.STOPPED); + checkCallback(activity); + } + + private void checkCallback(Activity activity) { + if (BuildConfig.ENABLE_ASSERTS) { assert reachesWindowCallback(activity.getWindow().getCallback()); } - onStateChange(activity, newState); } }); } @@ -645,10 +687,8 @@ ActivityInfo info = sActivityInfo.get(activity); assert info != null - : String.format( - "Found untracked Activity: %s isDestroyed=%s isFinishing=%s", - activity, activity.isDestroyed(), activity.isFinishing()); - assert info.getStatus() != ActivityState.DESTROYED : activity.toString(); + : "destroyed: " + activity.isDestroyed() + " finishing: " + activity.isFinishing(); + assert info.getStatus() != ActivityState.DESTROYED; info.getListeners().addObserver(listener); }
diff --git a/base/test/android/javatests/src/org/chromium/base/test/ActivityFinisher.java b/base/test/android/javatests/src/org/chromium/base/test/ActivityFinisher.java deleted file mode 100644 index f4f6688..0000000 --- a/base/test/android/javatests/src/org/chromium/base/test/ActivityFinisher.java +++ /dev/null
@@ -1,227 +0,0 @@ -// Copyright 2024 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.base.test; - -import android.app.Activity; -import android.app.ActivityManager; -import android.app.ActivityManager.AppTask; -import android.app.Application.ActivityLifecycleCallbacks; -import android.content.Context; -import android.os.Looper; - -import androidx.annotation.Nullable; -import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry; -import androidx.test.runner.lifecycle.Stage; - -import org.chromium.base.ActivityLifecycleCallbacksAdapter; -import org.chromium.base.ActivityState; -import org.chromium.base.Log; -import org.chromium.base.TimeUtils.UptimeMillisTimer; -import org.chromium.base.supplier.Supplier; -import org.chromium.base.test.util.CallbackHelper; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Helpers for finishing activities and waiting for them to be destroyed. - * - * <p>AndroidX's test runner supports finishing activities, but does not support timeouts and - * leaving activities started in @BeforeClass. - * - * <p>As of March 2024, finishAll() took ~250ms per-Activity, and finishAllExceptFor() took ~300ms - * per-Activity on a P920 running an x86 Android O emulator. - */ -public class ActivityFinisher { - private static final String TAG = "ActivityFinisher"; - - public static List<Activity> snapshotActivities( - @Nullable Collection<Activity> ignoreActivities) { - List<Activity> ret = new ArrayList<>(); - // Cannot use ThreadUtils since WebView may override UI thread. - Runnable r = - () -> { - // AndroidX's ActivityFinisher also collects Activities in this way. - var lifecycleMonitor = ActivityLifecycleMonitorRegistry.getInstance(); - for (Stage s : EnumSet.range(Stage.PRE_ON_CREATE, Stage.RESTARTED)) { - ret.addAll(lifecycleMonitor.getActivitiesInStage(s)); - } - }; - if (Looper.myLooper() == Looper.getMainLooper()) { - r.run(); - } else { - BaseChromiumAndroidJUnitRunner.sInstance.runOnMainSync(r); - } - if (ignoreActivities != null) { - ret.removeAll(ignoreActivities); - } - return ret; - } - - public static List<Activity> snapshotActivities() { - return snapshotActivities(null); - } - - /** Finishes all activities via AppTask.finishAndRemoveTask(). */ - public static void finishAll() { - assert Looper.myLooper() != Looper.getMainLooper(); - UptimeMillisTimer timer = new UptimeMillisTimer(); - - ActivityManager activityManager = - (ActivityManager) - BaseChromiumAndroidJUnitRunner.sApplication.getSystemService( - Context.ACTIVITY_SERVICE); - List<AppTask> allTasks = activityManager.getAppTasks(); - if (allTasks.isEmpty()) { - return; - } - try { - // Use multiple rounds in case new activities are started. - for (int attempts = 0; attempts < 3; ++attempts) { - int numActivities = finishAllTasks(allTasks); - allTasks = activityManager.getAppTasks(); - if (allTasks.isEmpty()) { - Log.i( - TAG, - "Closed all %d leftover activities in %s milliseconds.", - numActivities, - timer.getElapsedMillis()); - return; - } - Log.i( - TAG, - "Closed %d leftover activities, but more %s tasks remain.", - numActivities, - allTasks.size()); - } - } catch (TimeoutException e) { - // The exception is logged in finishHelper(); - } - } - - private static int finishAllTasks(List<AppTask> allTasks) throws TimeoutException { - AtomicInteger numActivitiesHolder = new AtomicInteger(); - boolean succeeded = - finishHelper( - () -> { - List<Activity> ret = snapshotActivities(); - Log.i(TAG, "Finishing leftover Activities: %s", ret); - numActivitiesHolder.set(ret.size()); - for (ActivityManager.AppTask task : allTasks) { - task.finishAndRemoveTask(); - } - return ret; - }); - return succeeded ? numActivitiesHolder.get() : 0; - } - - /** When ignoreActivities is present, finishes activities one by one via Activity.finish(). */ - public static void finishAllExceptFor(@Nullable Collection<Activity> ignoreActivities) { - assert Looper.myLooper() != Looper.getMainLooper(); - // finishAll() is a bit faster. - if (ignoreActivities == null || ignoreActivities.isEmpty()) { - finishAll(); - return; - } - UptimeMillisTimer timer = new UptimeMillisTimer(); - try { - // Use multiple rounds in case new activities are started, and to ensure deterministic - // close order. - for (int i = 0; i < 20; ++i) { - if (!finishOneActivity(ignoreActivities)) { - if (i > 0) { - Log.i( - TAG, - "Closed %s leftover activities in %s milliseconds.", - i, - timer.getElapsedMillis()); - } - return; - } - } - Log.w( - TAG, - "More than 20 activities finished, but some still remain: %s", - snapshotActivities(ignoreActivities)); - } catch (TimeoutException e) { - // The exception is logged in finishHelper(); - } - } - - private static boolean finishOneActivity(Collection<Activity> ignoreActivities) - throws TimeoutException { - return finishHelper( - () -> { - List<Activity> activities = snapshotActivities(ignoreActivities); - if (activities.isEmpty()) { - return Collections.emptyList(); - } - // Finish the activity with the highest state. - Activity targetActivity = activities.get(activities.size() - 1); - if (!targetActivity.isFinishing()) { - targetActivity.finish(); - } - Log.i(TAG, "Finishing leftover activity: %s", targetActivity); - return List.of(targetActivity); - }); - } - - /** Returns whether all activities were destroyed. */ - private static boolean finishHelper(Supplier<List<Activity>> collectAndFinish) - throws TimeoutException { - CallbackHelper doneCallback = new CallbackHelper(); - Set<Activity> remaining = Collections.synchronizedSet(new HashSet<>()); - ActivityLifecycleCallbacks lifecycleCallbacks = - new ActivityLifecycleCallbacksAdapter() { - @Override - public void onStateChanged(Activity activity, @ActivityState int newState) { - if (newState == ActivityState.DESTROYED && remaining.contains(activity)) { - remaining.remove(activity); - if (remaining.isEmpty()) { - doneCallback.notifyCalled(); - } - } - } - }; - - // Cannot use ThreadUtils since WebView may override UI thread. - BaseChromiumAndroidJUnitRunner.sInstance.runOnMainSync( - () -> { - // Collect activities on the UI thread to ensure that the list of - // activities do not - // change before installing the lifecycle listener. - remaining.addAll(collectAndFinish.get()); - if (!remaining.isEmpty()) { - BaseChromiumAndroidJUnitRunner.sApplication - .registerActivityLifecycleCallbacks(lifecycleCallbacks); - } - }); - if (remaining.isEmpty()) { - // There are no activities to destroy. - return false; - } - - try { - doneCallback.waitForFirst(); - // Ensure that all onDestroy() callbacks are dispatched before returning. - BaseChromiumAndroidJUnitRunner.sInstance.runOnMainSync(() -> {}); - return true; - } catch (TimeoutException e) { - Log.w(TAG, "Timed out trying to close leftover activities: %s", remaining); - throw e; - } finally { - // This call is thread-safe. - BaseChromiumAndroidJUnitRunner.sApplication.unregisterActivityLifecycleCallbacks( - lifecycleCallbacks); - } - } -}
diff --git a/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java b/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java index ec0f7b6f..a7ae1a8 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java +++ b/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumAndroidJUnitRunner.java
@@ -5,13 +5,17 @@ package org.chromium.base.test; import android.app.Activity; +import android.app.ActivityManager; import android.app.Application; import android.app.Instrumentation; import android.content.Context; import android.content.ContextWrapper; +import android.os.Build; import android.os.Build.VERSION; import android.os.Bundle; +import android.os.Handler; import android.os.Looper; +import android.os.SystemClock; import android.system.Os; import androidx.core.content.ContextCompat; @@ -27,6 +31,7 @@ import org.junit.runner.Request; import org.junit.runner.RunWith; +import org.chromium.base.ActivityState; import org.chromium.base.ApplicationStatus; import org.chromium.base.CommandLineInitUtil; import org.chromium.base.ContextUtils; @@ -39,6 +44,7 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.InMemorySharedPreferencesContext; import org.chromium.base.test.util.MinAndroidSdkLevel; +import org.chromium.base.test.util.ScalableTimeout; import org.chromium.build.BuildConfig; import org.chromium.testing.TestListInstrumentationRunListener; @@ -64,10 +70,10 @@ * </pre> */ public class BaseChromiumAndroidJUnitRunner extends AndroidJUnitRunner { - private static final String IS_UNIT_TEST_FLAG = "BaseChromiumAndroidJUnitRunner.IsUnitTest"; + private static final String IS_UNIT_TEST_FLAG = + "org.chromium.base.test.BaseChromiumAndroidJUnitRunner.IsUnitTest"; private static final String EXTRA_CLANG_COVERAGE_DEVICE_FILE = - "BaseChromiumAndroidJUnitRunner.ClangCoverageDeviceFile"; - private static final String EXTRA_TRACE_FILE = "BaseChromiumAndroidJUnitRunner.TraceFile"; + "org.chromium.base.test.BaseChromiumAndroidJUnitRunner.ClangCoverageDeviceFile"; private static final String ARGUMENT_LOG_ONLY = "log"; @@ -81,8 +87,9 @@ private static final long WAIT_FOR_IDLE_TIMEOUT_MS = 10000L; - static BaseChromiumAndroidJUnitRunner sInstance; - static Application sApplication; + private static final long FINISH_APP_TASKS_TIMEOUT_MS = 3000L; + private static final long FINISH_APP_TASKS_POLL_INTERVAL_MS = 100; + static InMemorySharedPreferencesContext sInMemorySharedPreferencesContext; private static boolean sTestListMode; @@ -90,10 +97,6 @@ CommandLineInitUtil.setFilenameOverrideForTesting(CommandLineFlags.getTestCmdLineFile()); } - public BaseChromiumAndroidJUnitRunner() { - sInstance = this; - } - @Override public Application newApplication(ClassLoader cl, String className, Context context) throws ClassNotFoundException, IllegalAccessException, InstantiationException { @@ -101,7 +104,6 @@ // attachBaseContext() will hit our InMemorySharedPreferencesContext. sInMemorySharedPreferencesContext = new InMemorySharedPreferencesContext(context); Application ret = super.newApplication(cl, className, sInMemorySharedPreferencesContext); - sApplication = ret; try { // There is framework code that assumes Application.getBaseContext() can be casted to // ContextImpl (on KitKat for broadcast receivers, refer to ActivityThread.java), so @@ -142,13 +144,18 @@ /** * Add TestListInstrumentationRunListener when argument ask the runner to list tests info. * - * <p>The running mechanism when argument has "listAllTests" is equivalent to that of {@link - * androidx.test.runner.AndroidJUnitRunner#onStart()} except it adds only - * TestListInstrumentationRunListener to monitor the tests. + * The running mechanism when argument has "listAllTests" is equivalent to that of + * {@link androidx.test.runner.AndroidJUnitRunner#onStart()} except it adds + * only TestListInstrumentationRunListener to monitor the tests. */ @Override public void onStart() { Bundle arguments = InstrumentationRegistry.getArguments(); + ResettersForTesting.enable(); + if (arguments.getString(IS_UNIT_TEST_FLAG) != null) { + LibraryLoader.setBrowserProcessStartupBlockedForTesting(); + } + if (sTestListMode) { Log.w( TAG, @@ -158,37 +165,27 @@ arguments.toString())); listTests(); // Intentionally not calling super.onStart() to avoid additional work. } else { - initTestRunner(arguments); - super.onStart(); - } - } - - private void initTestRunner(Bundle arguments) { - BaseJUnit4TestRule.clearJobSchedulerJobs(); - clearDataDirectory(sInMemorySharedPreferencesContext); - setInTouchMode(true); - // //third_party/mockito is looking for android.support.test.InstrumentationRegistry. - // Manually set target to override. We can remove this once we roll mockito to support - // androidx.test. - System.setProperty( - "org.mockito.android.target", - sInMemorySharedPreferencesContext.getCacheDir().getPath()); - setClangCoverageEnvIfEnabled(); - if (arguments.getString(IS_UNIT_TEST_FLAG) != null) { - LibraryLoader.setBrowserProcessStartupBlockedForTesting(); - } - ResettersForTesting.enable(); - - String traceOutput = arguments.getString(EXTRA_TRACE_FILE); - if (traceOutput != null) { - File traceOutputFile = new File(traceOutput); - File traceOutputDir = traceOutputFile.getParentFile(); - - if (traceOutputDir != null) { - if (traceOutputDir.exists() || traceOutputDir.mkdirs()) { - TestTraceEvent.enable(traceOutputFile); - } + if (arguments != null && arguments.getString(ARGUMENT_LOG_ONLY) != null) { + Log.e( + TAG, + String.format( + "Runner will log the tests without running tests." + + " If this cause a test run to fail, please report to" + + " crbug.com/754015. Arguments: %s", + arguments.toString())); } + finishAllAppTasks(getTargetContext()); + BaseJUnit4TestRule.clearJobSchedulerJobs(); + clearDataDirectory(sInMemorySharedPreferencesContext); + InstrumentationRegistry.getInstrumentation().setInTouchMode(true); + // //third_party/mockito is looking for android.support.test.InstrumentationRegistry. + // Manually set target to override. We can remove this once we roll mockito to support + // androidx.test. + System.setProperty( + "org.mockito.android.target", + InstrumentationRegistry.getTargetContext().getCacheDir().getPath()); + setClangCoverageEnvIfEnabled(); + super.onStart(); } } @@ -472,7 +469,16 @@ } try { - org.chromium.base.test.ActivityFinisher.finishAll(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + finishAllAppTasks(getTargetContext()); + } + finishAllActivities(); + } catch (Exception e) { + // Ignore any errors finishing Activities so that otherwise passing tests don't fail + // during tear down due to framework issues. See crbug.com/653731. + } + + try { writeClangCoverageProfileIfEnabled(); // There is a bug on L and below that DestroyActivitiesRule does not cause onStop and @@ -496,6 +502,91 @@ super.finish(resultCode, results); } + /** Finishes all tasks Chrome has listed in Android's Overview. */ + private void finishAllAppTasks(final Context context) { + // Close all of the tasks one by one. + ActivityManager activityManager = + (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + for (ActivityManager.AppTask task : activityManager.getAppTasks()) { + task.finishAndRemoveTask(); + } + long endTime = + SystemClock.uptimeMillis() + + ScalableTimeout.scaleTimeout(FINISH_APP_TASKS_TIMEOUT_MS); + while (activityManager.getAppTasks().size() != 0 && SystemClock.uptimeMillis() < endTime) { + try { + Thread.sleep(FINISH_APP_TASKS_POLL_INTERVAL_MS); + } catch (InterruptedException e) { + } + } + } + + private void finishAllActivities() { + // This mirrors the default logic of the test runner for finishing Activities when + // ApplicationStatus isn't initialized. However, we keep Chromium's logic for finishing + // Activities below both because it's worked historically and we don't want to risk breaking + // things, and because the ActivityFinisher does some filtering on which Activities it + // chooses to finish which could potentially cause issues. + if (!ApplicationStatus.isInitialized()) { + runOnMainSync(() -> new ActivityFinisher().run()); + super.waitForActivitiesToComplete(); + return; + } + Handler mainHandler = new Handler(Looper.getMainLooper()); + CallbackHelper allDestroyedCalledback = new CallbackHelper(); + ApplicationStatus.ActivityStateListener activityStateListener = + new ApplicationStatus.ActivityStateListener() { + @Override + public void onActivityStateChange(Activity activity, int newState) { + switch (newState) { + case ActivityState.DESTROYED: + if (ApplicationStatus.isEveryActivityDestroyed()) { + // Allow onDestroy to finish running before we notify. + mainHandler.post( + () -> { + allDestroyedCalledback.notifyCalled(); + }); + ApplicationStatus.unregisterActivityStateListener(this); + } + break; + case ActivityState.CREATED: + if (!activity.isFinishing()) { + // This is required to ensure we finish any activities created + // after doing the bulk finish operation below. + activity.finishAndRemoveTask(); + } + break; + } + } + }; + + mainHandler.post( + () -> { + if (ApplicationStatus.isEveryActivityDestroyed()) { + allDestroyedCalledback.notifyCalled(); + } else { + ApplicationStatus.registerStateListenerForAllActivities( + activityStateListener); + } + for (Activity a : ApplicationStatus.getRunningActivities()) { + if (!a.isFinishing()) a.finishAndRemoveTask(); + } + }); + try { + allDestroyedCalledback.waitForFirst(); + } catch (TimeoutException e) { + // There appears to be a framework bug on K and L where onStop and onDestroy are not + // called for a handful of tests. We ignore these exceptions. + Log.w(TAG, "Activity failed to be destroyed after a test"); + + runOnMainSync( + () -> { + // Make sure subsequent tests don't have these notifications firing. + ApplicationStatus.unregisterActivityStateListener(activityStateListener); + }); + } + } + // This method clears the data directory for the test apk, but device_utils.py clears the data // for the apk under test via `pm clear`. Fake module smoke tests in particular requires some // data to be kept for the apk under test: /sdcard/Android/data/package/files/local_testing
diff --git a/base/test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java b/base/test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java index 1eac6aa..e9de7b3 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java +++ b/base/test/android/javatests/src/org/chromium/base/test/BaseJUnit4ClassRunner.java
@@ -33,6 +33,7 @@ import org.chromium.base.test.util.RestrictionSkipCheck; import org.chromium.base.test.util.SkipCheck; +import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -40,16 +41,19 @@ import java.util.concurrent.TimeUnit; /** - * A custom runner for JUnit4 tests that checks requirements to conditionally ignore tests. + * A custom runner for JUnit4 tests that checks requirements to conditionally ignore tests. * - * <p>This ClassRunner imports from AndroidJUnit4ClassRunner which is a hidden but accessible class. - * The reason is that default JUnit4 runner for Android is a final class, AndroidJUnit4. We need to - * extends an inheritable class to change {@link #runChild} and {@link #isIgnored} to add SkipChecks - * and PreTesthook. + * This ClassRunner imports from AndroidJUnit4ClassRunner which is a hidden but accessible + * class. The reason is that default JUnit4 runner for Android is a final class, + * AndroidJUnit4. We need to extends an inheritable class to change {@link #runChild} + * and {@link #isIgnored} to add SkipChecks and PreTesthook. */ public class BaseJUnit4ClassRunner extends AndroidJUnit4ClassRunner { private static final String TAG = "BaseJUnit4ClassRunnr"; + private static final String EXTRA_TRACE_FILE = + "org.chromium.base.test.BaseJUnit4ClassRunner.TraceFile"; + // Arbirary int that must not overlap with status codes defined by // https://developer.android.com/reference/android/test/InstrumentationTestRunner.html#REPORT_VALUE_ID private static final int STATUS_CODE_TEST_DURATION = 1337; @@ -111,17 +115,30 @@ : "Must use BaseChromiumAndroidJUnitRunner instrumentation with " + "BaseJUnit4ClassRunner, but found: " + InstrumentationRegistry.getInstrumentation().getClass(); + String traceOutput = InstrumentationRegistry.getArguments().getString(EXTRA_TRACE_FILE); + + if (traceOutput != null) { + File traceOutputFile = new File(traceOutput); + File traceOutputDir = traceOutputFile.getParentFile(); + + if (traceOutputDir != null) { + if (traceOutputDir.exists() || traceOutputDir.mkdirs()) { + TestTraceEvent.enable(traceOutputFile); + } + } + } } /** Returns the singleton Application instance. */ public static Application getApplication() { - return BaseChromiumAndroidJUnitRunner.sApplication; + return (Application) + BaseChromiumAndroidJUnitRunner.sInMemorySharedPreferencesContext.getBaseContext(); } /** * Merge two List into a new ArrayList. * - * <p>Used to merge the default SkipChecks/PreTestHooks with the subclasses's + * Used to merge the default SkipChecks/PreTestHooks with the subclasses's * SkipChecks/PreTestHooks. */ private static <T> List<T> mergeList(List<T> listA, List<T> listB) {
diff --git a/build/android/pylib/local/device/local_device_instrumentation_test_run.py b/build/android/pylib/local/device/local_device_instrumentation_test_run.py index 539a9e3..750361c 100644 --- a/build/android/pylib/local/device/local_device_instrumentation_test_run.py +++ b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
@@ -91,7 +91,8 @@ 'StrictMode:D', '%s:I' % _TAG] EXTRA_CLANG_COVERAGE_DEVICE_FILE = ( - 'BaseChromiumAndroidJUnitRunner.ClangCoverageDeviceFile') + 'org.chromium.base.test.BaseChromiumAndroidJUnitRunner.' + 'ClangCoverageDeviceFile') EXTRA_SCREENSHOT_FILE = ( 'org.chromium.base.test.ScreenshotOnFailureStatement.ScreenshotFile') @@ -99,12 +100,13 @@ EXTRA_UI_CAPTURE_DIR = ( 'org.chromium.base.test.util.Screenshooter.ScreenshotDir') -EXTRA_TRACE_FILE = 'BaseChromiumAndroidJUnitRunner.TraceFile' +EXTRA_TRACE_FILE = ('org.chromium.base.test.BaseJUnit4ClassRunner.TraceFile') _EXTRA_RUN_DISABLED_TEST = ( 'org.chromium.base.test.util.DisableIfSkipCheck.RunDisabledTest') -_EXTRA_TEST_IS_UNIT = 'BaseChromiumAndroidJUnitRunner.IsUnitTest' +_EXTRA_TEST_IS_UNIT = ( + 'org.chromium.base.test.BaseChromiumAndroidJUnitRunner.IsUnitTest') _EXTRA_PACKAGE_UNDER_TEST = ('org.chromium.chrome.test.pagecontroller.rules.' 'ChromeUiApplicationTestRule.PackageUnderTest')
diff --git a/build/config/siso/clang_windows.star b/build/config/siso/clang_windows.star index 3ba7f5a..3d755eb8 100644 --- a/build/config/siso/clang_windows.star +++ b/build/config/siso/clang_windows.star
@@ -61,7 +61,10 @@ if k.startswith("label:action"): continue largePlatform[k] = v - largePlatform["label:action_large"] = "1" + + # no "action_large" Windows worker pool + if reproxy_config["platform"]["OSFamily"] != "Windows": + largePlatform["label:action_large"] = "1" step_config["platforms"].update({ "clang-cl": reproxy_config["platform"], "clang-cl_large": largePlatform,
diff --git a/build/util/ide_query b/build/util/ide_query index 80536c1..f35bf8a 100755 --- a/build/util/ide_query +++ b/build/util/ide_query
@@ -51,10 +51,10 @@ def main(): parser = argparse.ArgumentParser() - parser.add_argument('--source', action='append', + parser.add_argument('source', nargs='+', help=('The source file being analyzed.' - 'Multiple --source arguments can be passed in order to batch ' - 'process is desired. ')) + 'Multiple source arguments can be passed in order to batch ' + 'process if desired.')) parser.add_argument('--perform-build', action='store_true', help=('If specified, actually build the target, including any generated ' 'prerequisite files. ' @@ -62,7 +62,7 @@ 'the GeneratedFile results will only be returned if a build has ' 'been previously completed, and may be stale.')) parser.add_argument('--out-dir', - help=('Output directory, containing args.gn, which specifies the build ' + help=('Output directory, containing args.gn, which specifies the build ' 'configuration.')) options = parser.parse_args()
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/AutofillKeyboardAccessoryViewBridge.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/AutofillKeyboardAccessoryViewBridge.java index 68916ac..92dfd07 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/AutofillKeyboardAccessoryViewBridge.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/AutofillKeyboardAccessoryViewBridge.java
@@ -214,21 +214,21 @@ @NativeMethods interface Natives { void viewDismissed( - long nativeAutofillKeyboardAccessoryView, + long nativeAutofillKeyboardAccessoryViewImpl, AutofillKeyboardAccessoryViewBridge caller); void suggestionSelected( - long nativeAutofillKeyboardAccessoryView, + long nativeAutofillKeyboardAccessoryViewImpl, AutofillKeyboardAccessoryViewBridge caller, int listIndex); void deletionRequested( - long nativeAutofillKeyboardAccessoryView, + long nativeAutofillKeyboardAccessoryViewImpl, AutofillKeyboardAccessoryViewBridge caller, int listIndex); void onDeletionDialogClosed( - long nativeAutofillKeyboardAccessoryView, + long nativeAutofillKeyboardAccessoryViewImpl, AutofillKeyboardAccessoryViewBridge caller, boolean confirmed); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/identity_disc/IdentityDiscController.java b/chrome/android/java/src/org/chromium/chrome/browser/identity_disc/IdentityDiscController.java index 9cd3253..547e33c9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/identity_disc/IdentityDiscController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/identity_disc/IdentityDiscController.java
@@ -12,14 +12,12 @@ import androidx.annotation.VisibleForTesting; import androidx.appcompat.content.res.AppCompatResources; -import org.chromium.base.BuildInfo; import org.chromium.base.Callback; import org.chromium.base.ObserverList; import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.chrome.R; import org.chromium.chrome.browser.feature_engagement.TrackerFactory; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.layouts.LayoutType; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.lifecycle.NativeInitObserver; @@ -40,6 +38,7 @@ import org.chromium.chrome.browser.toolbar.ButtonDataProvider; import org.chromium.chrome.browser.toolbar.adaptive.AdaptiveToolbarButtonVariant; import org.chromium.chrome.browser.ui.signin.SigninAndHistoryOptInCoordinator; +import org.chromium.chrome.browser.ui.signin.SigninUtils; import org.chromium.chrome.browser.ui.signin.account_picker.AccountPickerBottomSheetStrings; import org.chromium.chrome.browser.user_education.IPHCommandBuilder; import org.chromium.chrome.browser.util.BrowserUiUtils; @@ -339,7 +338,7 @@ private String getContentDescription(@Nullable String email) { if (email == null) { - if (shouldShowNewSigninFlow()) { + if (SigninUtils.shouldShowNewSigninFlow()) { return mContext.getString( R.string.accessibility_toolbar_btn_signed_out_identity_disc); } else { @@ -377,7 +376,7 @@ .getSigninManager(mProfileSupplier.get().getOriginalProfile()); if (getSignedInAccountInfo() == null && !signinManager.isSigninDisabledByPolicy()) { // TODO(crbug.com/1523958): Implement the new sign-in flow for automotive. - if (shouldShowNewSigninFlow()) { + if (SigninUtils.shouldShowNewSigninFlow()) { AccountPickerBottomSheetStrings bottomSheetStrings = new AccountPickerBottomSheetStrings.Builder(R.string.sign_in_to_chrome) .setSubtitleStringId( @@ -408,11 +407,4 @@ boolean isProfileDataCacheEmpty() { return mProfileDataCache == null; } - - @VisibleForTesting - static boolean shouldShowNewSigninFlow() { - return ChromeFeatureList.isEnabled( - ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS) - && !BuildInfo.getInstance().isAutomotive; - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInActivity.java index 7c52991..f220c33 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInActivity.java
@@ -72,7 +72,7 @@ private final Promise<Void> mNativeInitializationPromise = new Promise<>(); // These two coordinators are mutually exclusive: if one is initialized the other should be // null. - // TODO(b/41493788): Consider making each of these implement a common interface to skip the + // TODO(b/326019991): Consider making each of these implement a common interface to skip the // redundancy. private SigninAndHistoryOptInCoordinator mCoordinator; private UpgradePromoCoordinator mUpgradePromoCoordinator; @@ -274,16 +274,22 @@ /** Implements {@link UpgradePromoCoordinator.Delegate} */ @Override public void addAccount() { + // TODO(crbug.com/41493767): Handle result in onActivityResult rather than using + // IntentCallback to resume the flow when Chrome is killed. final WindowAndroid.IntentCallback onAddAccountCompleted = (int resultCode, Intent data) -> { - if (resultCode != Activity.RESULT_OK) { + final String accountEmail = + data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME); + if (resultCode != Activity.RESULT_OK || accountEmail == null) { + onFlowComplete(); return; } - String accountAddedEmail = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME); - // TODO(crbug.com/41493767): Implement new account selection for when the - // SigninAndHistoryOptIn coordinator is shown rather than the Upgrade promo. - if (mUpgradePromoCoordinator != null && accountAddedEmail != null) { - mUpgradePromoCoordinator.onAccountSelected(accountAddedEmail); + + if (mUpgradePromoCoordinator != null) { + mUpgradePromoCoordinator.onAccountSelected(accountEmail); + } else { + assert mCoordinator != null; + mCoordinator.onAccountAdded(accountEmail); } }; AccountManagerFacadeProvider.getInstance()
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/identity_disc/IdentityDiscControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/identity_disc/IdentityDiscControllerTest.java index ed028d3..3a772eae 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/identity_disc/IdentityDiscControllerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/identity_disc/IdentityDiscControllerTest.java
@@ -58,6 +58,7 @@ import org.chromium.chrome.browser.signin.services.SigninManager; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.toolbar.ButtonDataProvider; +import org.chromium.chrome.browser.ui.signin.SigninUtils; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.R; @@ -435,7 +436,7 @@ } private @StringRes int getSignedOutAvatarDescription() { - return (IdentityDiscController.shouldShowNewSigninFlow()) + return (SigninUtils.shouldShowNewSigninFlow()) ? R.string.accessibility_toolbar_btn_signed_out_identity_disc : R.string.accessibility_toolbar_btn_signed_out_with_sync_identity_disc; }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInIntegrationTest.java index 5794537..c1a10d8e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninAndHistoryOptInIntegrationTest.java
@@ -22,6 +22,7 @@ import static org.chromium.ui.test.util.ViewUtils.onViewWaiting; +import android.app.Activity; import android.content.Intent; import androidx.test.core.app.ApplicationProvider; @@ -53,6 +54,7 @@ import org.chromium.chrome.browser.ui.signin.history_sync.HistorySyncHelper; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.R; +import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule; import org.chromium.chrome.test.util.browser.signin.SigninTestRule; import org.chromium.chrome.test.util.browser.sync.SyncTestUtil; import org.chromium.components.signin.base.CoreAccountInfo; @@ -124,17 +126,8 @@ WithAccountSigninMode.DEFAULT_ACCOUNT_BOTTOM_SHEET, HistoryOptInMode.REQUIRED); - verifyBottomSheetAndSignin(accountInfo); - - // Verify that the history opt-in dialog is shown and accept. - onView(withId(R.id.history_sync_illustration)).check(matches(isDisplayed())); - onView(allOf(withId(R.id.button_primary), isCompletelyDisplayed())).perform(click()); - - // Verify history sync state. - SyncTestUtil.waitForHistorySyncEnabled(); - - // Verify that the flow completion callback, which finishes the activity, is called. - ApplicationTestUtils.waitForActivityState(mActivity, Stage.DESTROYED); + verifyCollapsedBottomSheetAndSignin(accountInfo); + acceptHistorySyncAndVerifyFlowCompletion(); } @Test @@ -149,7 +142,7 @@ WithAccountSigninMode.DEFAULT_ACCOUNT_BOTTOM_SHEET, HistoryOptInMode.REQUIRED); - verifyBottomSheetAndSignin(accountInfo); + verifyCollapsedBottomSheetAndSignin(accountInfo); // Verify that the flow completion callback, which finishes the activity, is called. ApplicationTestUtils.waitForActivityState(mActivity, Stage.DESTROYED); @@ -167,7 +160,7 @@ WithAccountSigninMode.DEFAULT_ACCOUNT_BOTTOM_SHEET, HistoryOptInMode.REQUIRED); - verifyBottomSheetAndSignin(accountInfo); + verifyCollapsedBottomSheetAndSignin(accountInfo); // Verify that the flow completion callback, which finishes the activity, is called. ApplicationTestUtils.waitForActivityState(mActivity, Stage.DESTROYED); @@ -185,7 +178,7 @@ WithAccountSigninMode.DEFAULT_ACCOUNT_BOTTOM_SHEET, HistoryOptInMode.REQUIRED); - verifyBottomSheetAndSignin(accountInfo); + verifyCollapsedBottomSheetAndSignin(accountInfo); // Verify that the flow completion callback, which finishes the activity, is called. ApplicationTestUtils.waitForActivityState(mActivity, Stage.DESTROYED); @@ -228,7 +221,7 @@ WithAccountSigninMode.DEFAULT_ACCOUNT_BOTTOM_SHEET, HistoryOptInMode.REQUIRED); - verifyBottomSheetAndSignin(accountInfo); + verifyCollapsedBottomSheetAndSignin(accountInfo); // Verify that the history opt-in dialog is shown and decline. onView(withId(R.id.history_sync_illustration)).check(matches(isDisplayed())); @@ -252,17 +245,8 @@ WithAccountSigninMode.DEFAULT_ACCOUNT_BOTTOM_SHEET, HistoryOptInMode.OPTIONAL); - verifyBottomSheetAndSignin(accountInfo); - - // Verify that the history opt-in dialog is shown and accept. - onView(withId(R.id.history_sync_illustration)).check(matches(isDisplayed())); - onView(allOf(withId(R.id.button_primary), isCompletelyDisplayed())).perform(click()); - - // Verify history sync state. - SyncTestUtil.waitForHistorySyncEnabled(); - - // Verify that the flow completion callback, which finishes the activity, is called. - ApplicationTestUtils.waitForActivityState(mActivity, Stage.DESTROYED); + verifyCollapsedBottomSheetAndSignin(accountInfo); + acceptHistorySyncAndVerifyFlowCompletion(); } @Test @@ -276,7 +260,7 @@ WithAccountSigninMode.DEFAULT_ACCOUNT_BOTTOM_SHEET, HistoryOptInMode.NONE); - verifyBottomSheetAndSignin(accountInfo); + verifyCollapsedBottomSheetAndSignin(accountInfo); // Verify that the flow completion callback, which finishes the activity, is called. ApplicationTestUtils.waitForActivityState(mActivity, Stage.DESTROYED); @@ -426,6 +410,47 @@ verifySigninCancelled(); } + @Test + @MediumTest + public void testWithNoAccount_bottomSheetSignin_requiredHistorySync() { + launchActivity( + NoAccountSigninMode.BOTTOM_SHEET, + WithAccountSigninMode.DEFAULT_ACCOUNT_BOTTOM_SHEET, + HistoryOptInMode.REQUIRED); + + verifyNoAccountBottomSheetAndSignin(); + acceptHistorySyncAndVerifyFlowCompletion(); + } + + @Test + @MediumTest + public void testWithNoAccount_instantSignin_requiredHistorySync() { + CoreAccountInfo accountInfo = AccountManagerTestRule.TEST_ACCOUNT_1; + mSigninTestRule.setResultForNextAddAccountFlow(Activity.RESULT_OK, accountInfo.getEmail()); + + launchActivity( + NoAccountSigninMode.ADD_ACCOUNT, + WithAccountSigninMode.DEFAULT_ACCOUNT_BOTTOM_SHEET, + HistoryOptInMode.REQUIRED); + + acceptHistorySyncAndVerifyFlowCompletion(); + } + + @Test + @MediumTest + public void testWithNoAccount_instantSignin_requiredHistorySync_cancelAddAccount() { + CoreAccountInfo accountInfo = AccountManagerTestRule.TEST_ACCOUNT_1; + mSigninTestRule.setResultForNextAddAccountFlow( + Activity.RESULT_CANCELED, accountInfo.getEmail()); + + launchActivity( + NoAccountSigninMode.ADD_ACCOUNT, + WithAccountSigninMode.DEFAULT_ACCOUNT_BOTTOM_SHEET, + HistoryOptInMode.REQUIRED); + + verifySigninCancelled(); + } + private void launchActivity( @NoAccountSigninMode int noAccountSigninMode, @WithAccountSigninMode int withAccountSigninMode, @@ -444,7 +469,7 @@ mActivity = mActivityTestRule.getActivity(); } - private void verifyBottomSheetAndSignin(CoreAccountInfo accountInfo) { + private void verifyCollapsedBottomSheetAndSignin(CoreAccountInfo accountInfo) { // Verify that the collapsed sign-in bottom-sheet is shown, and start sign-in. onView( allOf( @@ -457,6 +482,31 @@ mSigninTestRule.waitForSignin(accountInfo); } + private void verifyNoAccountBottomSheetAndSignin() { + CoreAccountInfo accountInfo = AccountManagerTestRule.TEST_ACCOUNT_1; + mSigninTestRule.setResultForNextAddAccountFlow(Activity.RESULT_OK, accountInfo.getEmail()); + onView( + allOf( + withId(R.id.account_picker_continue_as_button), + withParent(withId(R.id.account_picker_state_no_account)), + isCompletelyDisplayed())) + .perform(click()); + + mSigninTestRule.waitForSignin(accountInfo); + } + + private void acceptHistorySyncAndVerifyFlowCompletion() { + // Verify that the history opt-in dialog is shown and accept. + onView(withId(R.id.history_sync_illustration)).check(matches(isDisplayed())); + onView(allOf(withId(R.id.button_primary), isCompletelyDisplayed())).perform(click()); + + // Verify history sync state. + SyncTestUtil.waitForHistorySyncEnabled(); + + // Verify that the flow completion callback, which finishes the activity, is called. + ApplicationTestUtils.waitForActivityState(mActivity, Stage.DESTROYED); + } + // Verifies that the activity finishes, no account is signed in, and history sync is disabled. private void verifySigninCancelled() { ApplicationTestUtils.waitForActivityState(mActivity, Stage.DESTROYED);
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 1d6b3a19a..af6deccc 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-126.0.6423.0_rc-r1-merged.afdo.bz2 +chromeos-chrome-amd64-126.0.6423.0_rc-r2-merged.afdo.bz2
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index d94dc09..e85be77 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -13111,6 +13111,9 @@ <message name="IDS_SYNC_ERROR_USER_MENU_CONFIRM_SYNC_SETTINGS_BUTTON" desc="Button in the header of desktop user menu prompting users to confirm their sync settings."> Open settings </message> + <message name="IDS_SYNC_ERROR_USER_MENU_VERIFY_MESSAGE" translateable="false" desc="This is the text of a card that means the user needs to sign back in to Chrome in order to continue saving and using data (like passwords or payment methods) in their Google Account. This is an error message that appears when the user's sign-in credential has expired; to fix the issue, the user needs to sign back in. The tone should be straightforward and motivating."> + To keep using the passwords and more in your Google Account, verify it's you + </message> <if expr="chromeos_ash"> <message name="IDS_SYNC_PASSPHRASE_ERROR_BUBBLE_VIEW_MESSAGE" desc="Message in the sync error bubble view when the user needs to enter their sync passphrase.">
diff --git a/chrome/app/password_manager_ui_strings.grdp b/chrome/app/password_manager_ui_strings.grdp index 6c0377f..861e4a5 100644 --- a/chrome/app/password_manager_ui_strings.grdp +++ b/chrome/app/password_manager_ui_strings.grdp
@@ -852,7 +852,10 @@ <message name="IDS_PASSWORD_MANAGER_UI_PROMO_CARD_ARIA_LABEL" is_accessibility_with_no_ui="true" desc="The ARIA (accessibility) for the recommendation in password manager settings."> Recommendation </message> - <message name="IDS_PASSWORD_MANAGER_UI_CLOSE_PROMO_CARD_BUTTON_ARIA_LABEL" is_accessibility_with_no_ui="true" desc="The ARIA (accessibility) for the close recommendation button in password manager settings."> + <message name="IDS_PASSWORD_MANAGER_UI_CLOSE_PROMO_CARD_BUTTON_ARIA_LABEL" is_accessibility_with_no_ui="true" desc="The ARIA (accessibility) for the close recommendation button in password manager settings."> Dismiss recommendation </message> + <message name="IDS_PASSWORD_MANAGER_PIN_CHANGED" desc="The text that is shown in the toast when the password manager PIN is successfully changed."> + PIN changed successfully + </message> </grit-part>
diff --git a/chrome/app/password_manager_ui_strings_grdp/IDS_PASSWORD_MANAGER_PIN_CHANGED.png.sha1 b/chrome/app/password_manager_ui_strings_grdp/IDS_PASSWORD_MANAGER_PIN_CHANGED.png.sha1 new file mode 100644 index 0000000..f040e195 --- /dev/null +++ b/chrome/app/password_manager_ui_strings_grdp/IDS_PASSWORD_MANAGER_PIN_CHANGED.png.sha1
@@ -0,0 +1 @@ +8c01a203d6baf3ad6871a6cde0b924c190b67f46 \ No newline at end of file
diff --git a/chrome/browser/android/cookies/cookies_fetcher_restore_util.cc b/chrome/browser/android/cookies/cookies_fetcher_restore_util.cc index 1f87e39..64e14b32 100644 --- a/chrome/browser/android/cookies/cookies_fetcher_restore_util.cc +++ b/chrome/browser/android/cookies/cookies_fetcher_restore_util.cc
@@ -84,21 +84,14 @@ return; } - // Assume HTTPS - since the cookies are being restored from another store, - // they have already gone through the strict secure check. - // - // Similarly, permit samesite cookies to be imported. - net::CookieOptions options; - options.set_include_httponly(); - options.set_same_site_cookie_context( - net::CookieOptions::SameSiteCookieContext::MakeInclusive()); - options.set_do_not_update_access_time(); + // Fetch cookies all-inclusive as we are doing so for the OTR profile. GetCookieServiceClient()->SetCanonicalCookie( *cookie, net::cookie_util::CookieDomainAndPathToURL( domain_str, path_str, static_cast<net::CookieSourceScheme>(source_scheme)), - options, network::mojom::CookieManager::SetCanonicalCookieCallback()); + net::CookieOptions::MakeAllInclusive(), + network::mojom::CookieManager::SetCanonicalCookieCallback()); } } // namespace cookie_fetcher_restore_util
diff --git a/chrome/browser/android/cookies/cookies_fetcher_restore_util_browsertest.cc b/chrome/browser/android/cookies/cookies_fetcher_restore_util_browsertest.cc index 1427f5e..a2b4c00d 100644 --- a/chrome/browser/android/cookies/cookies_fetcher_restore_util_browsertest.cc +++ b/chrome/browser/android/cookies/cookies_fetcher_restore_util_browsertest.cc
@@ -79,6 +79,8 @@ EXPECT_EQ(cookies_for_profile[0].PartitionKey(), *net::CookiePartitionKey::FromStorage( partition_key, /*has_cross_site_ancestor=*/true)); + EXPECT_NE(cookies_for_profile[0].IsPartitioned(), + partition_key.empty()); return true; }
diff --git a/chrome/browser/apps/app_service/app_service_proxy_lacros.cc b/chrome/browser/apps/app_service/app_service_proxy_lacros.cc index 1238a53..bf4654b 100644 --- a/chrome/browser/apps/app_service/app_service_proxy_lacros.cc +++ b/chrome/browser/apps/app_service/app_service_proxy_lacros.cc
@@ -60,7 +60,7 @@ if (service && service->IsAvailable<crosapi::mojom::BrowserAppInstanceRegistry>()) { browser_app_instance_tracker_ = - std::make_unique<apps::BrowserAppInstanceTracker>( + std::make_unique<apps::BrowserAppInstanceTrackerLacros>( profile_, app_registry_cache_); auto& registry = service->GetRemote<crosapi::mojom::BrowserAppInstanceRegistry>();
diff --git a/chrome/browser/apps/app_service/browser_app_instance.cc b/chrome/browser/apps/app_service/browser_app_instance.cc index 6043e103..85db227 100644 --- a/chrome/browser/apps/app_service/browser_app_instance.cc +++ b/chrome/browser/apps/app_service/browser_app_instance.cc
@@ -6,6 +6,8 @@ #include <utility> +#include "ui/wm/core/window_util.h" + #if BUILDFLAG(IS_CHROMEOS_ASH) #include "chrome/browser/ash/crosapi/browser_util.h" #include "components/app_constants/constants.h" @@ -43,7 +45,7 @@ app_id(app_id), window(window), title(title), - is_browser_active(is_browser_active), + is_browser_active_deprecated(is_browser_active), is_web_contents_active(is_web_contents_active), browser_session_id(browser_session_id), restored_browser_session_id(restored_browser_session_id) {} @@ -55,7 +57,7 @@ app_id(update.app_id), window(window), title(update.title), - is_browser_active(update.is_browser_active), + is_browser_active_deprecated(update.is_browser_active), is_web_contents_active(update.is_web_contents_active), browser_session_id(update.browser_session_id), restored_browser_session_id(update.restored_browser_session_id) {} @@ -69,7 +71,7 @@ uint32_t new_browser_session_id, uint32_t new_restored_browser_session_id) { if (window == new_window && title == new_title && - is_browser_active == new_is_browser_active && + is_browser_active_deprecated == new_is_browser_active && is_web_contents_active == new_is_web_contents_active && browser_session_id == new_browser_session_id && restored_browser_session_id == new_restored_browser_session_id) { @@ -77,7 +79,7 @@ } window = new_window; title = std::move(new_title); - is_browser_active = new_is_browser_active; + is_browser_active_deprecated = new_is_browser_active; is_web_contents_active = new_is_web_contents_active; browser_session_id = new_browser_session_id; restored_browser_session_id = new_restored_browser_session_id; @@ -91,13 +93,17 @@ update.app_id = app_id; update.window_id = GetWindowUniqueId(window); update.title = title; - update.is_browser_active = is_browser_active; + update.is_browser_active = is_browser_active_deprecated; update.is_web_contents_active = is_web_contents_active; update.browser_session_id = browser_session_id; update.restored_browser_session_id = restored_browser_session_id; return update; } +bool BrowserAppInstance::is_browser_active() const { + return wm::IsActiveWindow(window); +} + BrowserWindowInstance::BrowserWindowInstance( base::UnguessableToken id, aura::Window* window, @@ -112,7 +118,7 @@ restored_browser_session_id(restored_browser_session_id), is_incognito(is_incognito), lacros_profile_id(lacros_profile_id), - is_active(is_active) {} + is_active_deprecated(is_active) {} BrowserWindowInstance::BrowserWindowInstance(BrowserWindowInstanceUpdate update, aura::Window* window) @@ -122,22 +128,22 @@ restored_browser_session_id(update.restored_browser_session_id), is_incognito(update.is_incognito), lacros_profile_id(update.lacros_profile_id), - is_active(update.is_active) {} + is_active_deprecated(update.is_active) {} BrowserWindowInstance::~BrowserWindowInstance() = default; bool BrowserWindowInstance::MaybeUpdate(bool new_is_active) { - if (is_active == new_is_active) { + if (is_active_deprecated == new_is_active) { return false; } - is_active = new_is_active; + is_active_deprecated = new_is_active; return true; } BrowserWindowInstanceUpdate BrowserWindowInstance::ToUpdate() const { return BrowserWindowInstanceUpdate{id, GetWindowUniqueId(window), - is_active, + is_active_deprecated, browser_session_id, restored_browser_session_id, is_incognito, @@ -152,4 +158,8 @@ } #endif +bool BrowserWindowInstance::is_active() const { + return wm::IsActiveWindow(window); +} + } // namespace apps
diff --git a/chrome/browser/apps/app_service/browser_app_instance.h b/chrome/browser/apps/app_service/browser_app_instance.h index e466768..8fdd135 100644 --- a/chrome/browser/apps/app_service/browser_app_instance.h +++ b/chrome/browser/apps/app_service/browser_app_instance.h
@@ -54,6 +54,10 @@ BrowserAppInstanceUpdate ToUpdate() const; + // TODO(b/332628771): Hide this behind BUILDFLAG(IS_CHROMEOS_ASH) in M127. + // Checks if `window` is the active window. + bool is_browser_active() const; + const base::UnguessableToken id; const Type type; const std::string app_id; @@ -62,7 +66,9 @@ // same for an app window. raw_ptr<aura::Window> window; std::string title; - bool is_browser_active; + // TODO(b/332628771): Remove this in M127. + // Use `is_browser_activated()` instead. + bool is_browser_active_deprecated; // If a tab is active in the browser's tab strip. Only applicable to instances // with type kAppTab. Always set to true for app instances of type kAppWindow. bool is_web_contents_active; @@ -93,6 +99,10 @@ std::string GetAppId() const; #endif + // TODO(b/332628771): Hide this behind BUILDFLAG(IS_CHROMEOS_ASH) in M127. + // Checks if `window` is the active window. + bool is_active() const; + const base::UnguessableToken id; const raw_ptr<aura::Window> window; const uint32_t browser_session_id; @@ -101,7 +111,9 @@ // This value will only be non-zero when refer to a lacros browser instance. const uint64_t lacros_profile_id; - bool is_active; + // TODO(b/332628771): Remove this in M127. + // Do not add code which uses this state but use `is_active()` instead. + bool is_active_deprecated; }; } // namespace apps
diff --git a/chrome/browser/apps/app_service/browser_app_instance_registry.cc b/chrome/browser/apps/app_service/browser_app_instance_registry.cc index 44ed771c..f1efd842 100644 --- a/chrome/browser/apps/app_service/browser_app_instance_registry.cc +++ b/chrome/browser/apps/app_service/browser_app_instance_registry.cc
@@ -59,6 +59,22 @@ }); } +const std::set<const BrowserAppInstance*> +BrowserAppInstanceRegistry::GetBrowserAppInstancesByWindow( + const aura::Window* window) const { + return SelectAppInstances([&window](const BrowserAppInstance& instance) { + return instance.window == window; + }); +} + +const BrowserWindowInstance* +BrowserAppInstanceRegistry::GetBrowserWindowInstanceByWindow( + const aura::Window* window) const { + return FindWindowInstanceIf([&window](const BrowserWindowInstance& instance) { + return instance.window == window; + }); +} + aura::Window* BrowserAppInstanceRegistry::GetWindowByInstanceId( const base::UnguessableToken& id) const { if (const BrowserAppInstance* instance = GetAppInstanceById(id)) { @@ -131,12 +147,12 @@ bool BrowserAppInstanceRegistry::IsInstanceActive( const base::UnguessableToken& id) const { if (const BrowserAppInstance* instance = GetAppInstanceById(id)) { - return instance->is_browser_active && instance->is_web_contents_active; + return instance->is_browser_active() && instance->is_web_contents_active; } if (const BrowserWindowInstance* instance = GetBrowserWindowInstanceById(id)) { - return instance->is_active; + return instance->is_active(); } return false; } @@ -160,6 +176,25 @@ } } +void BrowserAppInstanceRegistry::MaybeStartActivationObservation( + aura::Window* window) { + if (is_activation_observed_) { + return; + } + + is_activation_observed_ = true; + // On Ash Chrome, there is only one `ActivationClient` so as long as `window` + // is attached to the tree, it serves the purpose of getting the + // `ActivationClient`. + // Since `ActivationClient` is destroyed before `BrowserAppInstanceRegistry`, + // `BrowserAppInstanceRegistry` does not need to remove itself upon + // destruction. + wm::ActivationClient* activation_client = + wm::GetActivationClient(window->GetRootWindow()); + CHECK(activation_client); + activation_client->AddObserver(this); +} + void BrowserAppInstanceRegistry::BindReceiver( crosapi::CrosapiId id, mojo::PendingReceiver<crosapi::mojom::BrowserAppInstanceRegistry> @@ -169,6 +204,7 @@ void BrowserAppInstanceRegistry::OnBrowserWindowAdded( const apps::BrowserWindowInstance& instance) { + MaybeStartActivationObservation(instance.window); for (auto& observer : observers_) { observer.OnBrowserWindowAdded(instance); } @@ -190,6 +226,7 @@ void BrowserAppInstanceRegistry::OnBrowserAppAdded( const BrowserAppInstance& instance) { + MaybeStartActivationObservation(instance.window); for (auto& observer : observers_) { observer.OnBrowserAppAdded(instance); } @@ -295,6 +332,18 @@ event_list.events.clear(); } +void BrowserAppInstanceRegistry::OnWindowVisibilityChanged(aura::Window* window, + bool visible) { + if (visible) { + // When `LacrosWindowInstanceAdded()` or + // `LacrosAppInstanceAddedOrUpdated()` is called, the `window` is not + // attached to the tree yet and will not be able to get `ActivationClient` + // from it. For this reason, for Lacros window, we delay the start of + // activation to when it becomes visible. + MaybeStartActivationObservation(window); + } +} + void BrowserAppInstanceRegistry::OnWindowDestroying(aura::Window* window) { lacros_window_observations_.RemoveObservation(window); const std::string* id = exo::GetShellApplicationId(window); @@ -328,6 +377,31 @@ } } +void BrowserAppInstanceRegistry::OnWindowActivated(ActivationReason reason, + aura::Window* gained_active, + aura::Window* lost_active) { + std::set<const BrowserAppInstance*> instances = + GetBrowserAppInstancesByWindow(gained_active); + for (const auto* instance : instances) { + OnBrowserAppUpdated(*instance); + } + + instances = GetBrowserAppInstancesByWindow(lost_active); + for (const auto* instance : instances) { + OnBrowserAppUpdated(*instance); + } + + if (const BrowserWindowInstance* instance = + GetBrowserWindowInstanceByWindow(gained_active)) { + OnBrowserWindowUpdated(*instance); + } + + if (const BrowserWindowInstance* instance = + GetBrowserWindowInstanceByWindow(lost_active)) { + OnBrowserWindowUpdated(*instance); + } +} + // Run the action immediately if the window matching |window_id| is // available, otherwise buffer the event until it is. void BrowserAppInstanceRegistry::RunOrEnqueueEventForWindow(
diff --git a/chrome/browser/apps/app_service/browser_app_instance_registry.h b/chrome/browser/apps/app_service/browser_app_instance_registry.h index 6c0ea7f..94df3c4 100644 --- a/chrome/browser/apps/app_service/browser_app_instance_registry.h +++ b/chrome/browser/apps/app_service/browser_app_instance_registry.h
@@ -31,6 +31,8 @@ #include "ui/aura/env_observer.h" #include "ui/aura/window.h" #include "ui/aura/window_observer.h" +#include "ui/wm/public/activation_change_observer.h" +#include "ui/wm/public/activation_client.h" namespace aura { class Window; @@ -45,7 +47,8 @@ : public BrowserAppInstanceObserver, public crosapi::mojom::BrowserAppInstanceRegistry, public aura::EnvObserver, - public aura::WindowObserver { + public aura::WindowObserver, + public wm::ActivationChangeObserver { public: explicit BrowserAppInstanceRegistry( BrowserAppInstanceTracker& ash_instance_tracker); @@ -58,6 +61,14 @@ const BrowserWindowInstance* GetBrowserWindowInstanceById( base::UnguessableToken id) const; + // Get all instances of apps that are hosted on |window| (Ash or Lacros). + const std::set<const BrowserAppInstance*> GetBrowserAppInstancesByWindow( + const aura::Window* window) const; + + // Get a single instance that corresponds to |window| (Ash or Lacros). + const BrowserWindowInstance* GetBrowserWindowInstanceByWindow( + const aura::Window* window) const; + // Get a single window by instance ID (Ash or Lacros). Returns a nullptr if // instance identified by |id| does not exist. aura::Window* GetWindowByInstanceId(const base::UnguessableToken& id) const; @@ -179,8 +190,14 @@ void OnWindowInitialized(aura::Window* window) override; // aura::WindowObserver overrides: + void OnWindowVisibilityChanged(aura::Window* window, bool visible) override; void OnWindowDestroying(aura::Window* window) override; + // wm::ActivationChangeObserver overrides: + void OnWindowActivated(ActivationReason reason, + aura::Window* gained_active, + aura::Window* lost_active) override; + private: // Buffered Lacros instance events for windows that weren't available yet // when events arrived. @@ -206,6 +223,8 @@ void OnControllerDisconnected(); + void MaybeStartActivationObservation(aura::Window* window); + const raw_ref<BrowserAppInstanceTracker> ash_instance_tracker_; // Lacros app instances. @@ -216,6 +235,8 @@ BrowserAppInstanceMap<base::UnguessableToken, BrowserWindowInstance> lacros_window_instances_; + bool is_activation_observed_ = false; + // Track all Aura windows belonging to Lacros. This is necessary to // synchronise crosapi events and Aura windows matching these events being // available.
diff --git a/chrome/browser/apps/app_service/browser_app_instance_tracker.cc b/chrome/browser/apps/app_service/browser_app_instance_tracker.cc index 03fb3df..2d45d63 100644 --- a/chrome/browser/apps/app_service/browser_app_instance_tracker.cc +++ b/chrome/browser/apps/app_service/browser_app_instance_tracker.cc
@@ -38,6 +38,8 @@ #include "chrome/browser/lacros/lacros_extensions_util.h" #include "chrome/browser/lacros/profile_util.h" #include "ui/views/widget/desktop_aura/desktop_window_tree_host_lacros.h" +#else +#include "ui/wm/core/window_util.h" #endif namespace apps { @@ -69,7 +71,7 @@ return host1 == host2; } } -#endif +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) Browser* GetBrowserWithTabStripModel(TabStripModel* tab_strip_model) { for (Browser* browser : *BrowserList::GetInstance()) { @@ -80,20 +82,20 @@ return nullptr; } +#if BUILDFLAG(IS_CHROMEOS_LACROS) Browser* GetBrowserWithAuraWindow(aura::Window* aura_window) { for (Browser* browser : *BrowserList::GetInstance()) { BrowserWindow* window = browser->window(); if (window && window->GetNativeWindow() == aura_window) { return browser; } -#if BUILDFLAG(IS_CHROMEOS_LACROS) if (HaveSameWindowTreeHostLacros(window->GetNativeWindow(), aura_window)) { return browser; } -#endif } return nullptr; } +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) aura::Window* AuraWindowForBrowser(Browser* browser) { BrowserWindow* window = browser->window(); @@ -103,21 +105,23 @@ return aura_window; } +#if BUILDFLAG(IS_CHROMEOS_LACROS) wm::ActivationClient* ActivationClientForBrowser(Browser* browser) { aura::Window* window = AuraWindowForBrowser(browser)->GetRootWindow(); wm::ActivationClient* client = wm::GetActivationClient(window); DCHECK(client); return client; } +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) bool IsBrowserActive(Browser* browser) { auto* aura_window = AuraWindowForBrowser(browser); - auto* activation_client = ActivationClientForBrowser(browser); #if BUILDFLAG(IS_CHROMEOS_LACROS) + auto* activation_client = ActivationClientForBrowser(browser); return HaveSameWindowTreeHostLacros(aura_window, activation_client->GetActiveWindow()); #else - return activation_client->GetActiveWindow() == aura_window; + return wm::IsActiveWindow(aura_window); #endif } @@ -210,7 +214,6 @@ BrowserAppInstanceTracker::~BrowserAppInstanceTracker() { BrowserList::GetInstance()->RemoveObserver(this); - DCHECK_EQ(activation_client_observations_.GetSourcesCount(), 0u); DCHECK(tracked_browsers_.empty()); DCHECK(observers_.empty()); } @@ -318,17 +321,6 @@ return profile_->IsSameOrParent(browser->profile()); } -void BrowserAppInstanceTracker::OnWindowActivated(ActivationReason reason, - aura::Window* gained_active, - aura::Window* lost_active) { - if (Browser* browser = GetBrowserWithAuraWindow(lost_active)) { - OnBrowserWindowUpdated(browser); - } - if (Browser* browser = GetBrowserWithAuraWindow(gained_active)) { - OnBrowserWindowUpdated(browser); - } -} - void BrowserAppInstanceTracker::OnBrowserAdded(Browser* browser) { DCHECK(!base::Contains(tracked_browsers_, browser)); } @@ -469,14 +461,6 @@ } void BrowserAppInstanceTracker::OnBrowserFirstTabAttached(Browser* browser) { - // Observe the activation client of the root window of the browser's aura - // window if this is the first browser matching it (there is no other tracked - // browser matching it). - wm::ActivationClient* activation_client = ActivationClientForBrowser(browser); - if (!IsActivationClientTracked(activation_client)) { - activation_client_observations_.AddObservation(activation_client); - } - tracked_browsers_.insert(browser); if (IsBrowserWindow(browser)) { CreateBrowserWindowInstance(browser); @@ -494,13 +478,6 @@ RemoveAppWindowInstanceIfExists(browser); } tracked_browsers_.erase(browser); - - // Unobserve the activation client of the root window of the browser's aura - // window if the last browser using it was just removed. - wm::ActivationClient* activation_client = ActivationClientForBrowser(browser); - if (!IsActivationClientTracked(activation_client)) { - activation_client_observations_.RemoveObservation(activation_client); - } } void BrowserAppInstanceTracker::OnTabCreated(Browser* browser, @@ -571,24 +548,6 @@ } } -void BrowserAppInstanceTracker::OnBrowserWindowUpdated(Browser* browser) { - // We only want to send window events for the browsers we track to avoid - // sending window events before a "browser added" event. - if (!IsBrowserTracked(browser)) { - return; - } - BrowserWindowInstance* instance = GetInstance(window_instances_, browser); - if (instance) { - MaybeUpdateBrowserWindowInstance(*instance, browser); - } - - TabStripModel* tab_strip_model = browser->tab_strip_model(); - for (int i = 0; i < tab_strip_model->count(); i++) { - content::WebContents* contents = tab_strip_model->GetWebContentsAt(i); - OnTabUpdated(browser, contents); - } -} - void BrowserAppInstanceTracker::CreateAppTabInstance( std::string app_id, Browser* browser, @@ -685,16 +644,6 @@ } } -void BrowserAppInstanceTracker::MaybeUpdateBrowserWindowInstance( - BrowserWindowInstance& instance, - Browser* browser) { - if (instance.MaybeUpdate(IsBrowserActive(browser))) { - for (auto& observer : observers_) { - observer.OnBrowserWindowUpdated(instance); - } - } -} - void BrowserAppInstanceTracker::RemoveBrowserWindowInstanceIfExists( Browser* browser) { auto instance = PopInstanceIfExists(window_instances_, browser); @@ -713,7 +662,57 @@ return base::Contains(tracked_browsers_, browser); } -bool BrowserAppInstanceTracker::IsActivationClientTracked( +#if BUILDFLAG(IS_CHROMEOS_LACROS) +BrowserAppInstanceTrackerLacros::BrowserAppInstanceTrackerLacros( + Profile* profile, + AppRegistryCache& app_registry_cache) + : BrowserAppInstanceTracker(profile, app_registry_cache) {} + +BrowserAppInstanceTrackerLacros::~BrowserAppInstanceTrackerLacros() { + DCHECK_EQ(activation_client_observations_.GetSourcesCount(), 0u); +} + +void BrowserAppInstanceTrackerLacros::OnWindowActivated( + ActivationReason reason, + aura::Window* gained_active, + aura::Window* lost_active) { + if (Browser* browser = GetBrowserWithAuraWindow(lost_active)) { + OnBrowserWindowUpdated(browser); + } + if (Browser* browser = GetBrowserWithAuraWindow(gained_active)) { + OnBrowserWindowUpdated(browser); + } +} + +void BrowserAppInstanceTrackerLacros::OnBrowserWindowUpdated(Browser* browser) { + // We only want to send window events for the browsers we track to avoid + // sending window events before a "browser added" event. + if (!IsBrowserTracked(browser)) { + return; + } + BrowserWindowInstance* instance = GetInstance(window_instances_, browser); + if (instance) { + MaybeUpdateBrowserWindowInstance(*instance, browser); + } + + TabStripModel* tab_strip_model = browser->tab_strip_model(); + for (int i = 0; i < tab_strip_model->count(); i++) { + content::WebContents* contents = tab_strip_model->GetWebContentsAt(i); + OnTabUpdated(browser, contents); + } +} + +void BrowserAppInstanceTrackerLacros::MaybeUpdateBrowserWindowInstance( + BrowserWindowInstance& instance, + Browser* browser) { + if (instance.MaybeUpdate(IsBrowserActive(browser))) { + for (auto& observer : observers_) { + observer.OnBrowserWindowUpdated(instance); + } + } +} + +bool BrowserAppInstanceTrackerLacros::IsActivationClientTracked( wm::ActivationClient* client) const { // Iterate over the full list of browsers instead of tracked_browsers_ in case // tracked_browsers_ is out of date with global state @@ -728,4 +727,30 @@ return false; } +void BrowserAppInstanceTrackerLacros::OnBrowserFirstTabAttached( + Browser* browser) { + // Observe the activation client of the root window of + // the browser's aura + // window if this is the first browser matching it (there is no other tracked + // browser matching it). + wm::ActivationClient* activation_client = ActivationClientForBrowser(browser); + if (!IsActivationClientTracked(activation_client)) { + activation_client_observations_.AddObservation(activation_client); + } + BrowserAppInstanceTracker::OnBrowserFirstTabAttached(browser); +} + +void BrowserAppInstanceTrackerLacros::OnBrowserLastTabDetached( + Browser* browser) { + BrowserAppInstanceTracker::OnBrowserLastTabDetached(browser); + + // Unobserve the activation client of the root window of the browser's aura + // window if the last browser using it was just removed. + wm::ActivationClient* activation_client = ActivationClientForBrowser(browser); + if (!IsActivationClientTracked(activation_client)) { + activation_client_observations_.RemoveObservation(activation_client); + } +} +#endif // #BUILDFLAG(IS_CHROMEOS_LACROS) + } // namespace apps
diff --git a/chrome/browser/apps/app_service/browser_app_instance_tracker.h b/chrome/browser/apps/app_service/browser_app_instance_tracker.h index 6203ab22..2eca9e3 100644 --- a/chrome/browser/apps/app_service/browser_app_instance_tracker.h +++ b/chrome/browser/apps/app_service/browser_app_instance_tracker.h
@@ -25,8 +25,11 @@ #include "components/app_constants/constants.h" #include "components/services/app_service/public/cpp/app_registry_cache.h" #include "content/public/browser/web_contents.h" + +#if BUILDFLAG(IS_CHROMEOS_LACROS) #include "ui/wm/public/activation_change_observer.h" #include "ui/wm/public/activation_client.h" +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) class Browser; class Profile; @@ -46,7 +49,6 @@ // - browser instances (registered with app ID |app_constants::kChromeAppId|). class BrowserAppInstanceTracker : public TabStripModelObserver, public BrowserTabStripTrackerDelegate, - public wm::ActivationChangeObserver, public AppRegistryCache::Observer, public BrowserListObserver { public: @@ -96,11 +98,6 @@ // BrowserTabStripTrackerDelegate overrides: bool ShouldTrackBrowser(Browser* browser) override; - // wm::ActivationChangeObserver overrides: - void OnWindowActivated(ActivationReason reason, - aura::Window* gained_active, - aura::Window* lost_active) override; - // BrowserListObserver overrides: void OnBrowserAdded(Browser* browser) override; void OnBrowserRemoved(Browser* browser) override; @@ -115,6 +112,7 @@ private: class WebContentsObserver; friend class BrowserAppInstanceRegistry; + friend class BrowserAppInstanceTrackerLacros; // Called by TabStripModelChanged(). void OnTabStripModelChangeInsert(Browser* browser, @@ -130,8 +128,8 @@ const TabStripSelectionChange& selection); // Called by OnTabStripModelChange* functions. - void OnBrowserFirstTabAttached(Browser* browser); - void OnBrowserLastTabDetached(Browser* browser); + virtual void OnBrowserFirstTabAttached(Browser* browser); + virtual void OnBrowserLastTabDetached(Browser* browser); void OnTabCreated(Browser* browser, content::WebContents* contents); void OnTabAttached(Browser* browser, content::WebContents* contents); void OnTabUpdated(Browser* browser, content::WebContents* contents); @@ -140,9 +138,6 @@ // Called by |BrowserAppInstanceTracker::WebContentsObserver|. void OnWebContentsUpdated(content::WebContents* contents); - // Called on browser window changes. Sends update events for all open tabs. - void OnBrowserWindowUpdated(Browser* browser); - // App tab instance lifecycle // Creates an app tab instance for the app running in |contents|. @@ -172,10 +167,6 @@ // Creates an app instance for a Chrome browser window. void CreateBrowserWindowInstance(Browser* browser); - // Updates the browser instance with the new attributes and notifies - // observers, if it was updated. - void MaybeUpdateBrowserWindowInstance(BrowserWindowInstance& instance, - Browser* browser); // Removes the browser instance, if it exists, and notifies observers. void RemoveBrowserWindowInstanceIfExists(Browser* browser); @@ -183,7 +174,6 @@ virtual base::UnguessableToken GenerateId() const; bool IsBrowserTracked(Browser* browser) const; - bool IsActivationClientTracked(wm::ActivationClient* client) const; const raw_ptr<Profile, DanglingUntriaged> profile_; @@ -194,11 +184,6 @@ // Events for all other browsers are filtered out. std::set<raw_ptr<Browser, SetExperimental>> tracked_browsers_; - // A set of observed activation clients for all browser's windows. - base::ScopedMultiSourceObservation<wm::ActivationClient, - wm::ActivationChangeObserver> - activation_client_observations_{this}; - BrowserTabStripTracker browser_tab_strip_tracker_; #if DCHECK_IS_ON() @@ -223,6 +208,55 @@ base::ObserverList<BrowserAppInstanceObserver, true>::Unchecked observers_; }; +#if BUILDFLAG(IS_CHROMEOS_LACROS) +// TODO(b/332628771): Remove this class 2 mile stones from this patch. +// Now that activation is observed by Ash even for Lacros windows, +// |BrowserAppInstanceTracker| no longer needs to observe activation changes. +// However to support older Ash, |BrowserAppInstanceTrackerLacros| adds +// |ActivationChangeObserver| functionality to |BrowserAppInstanceTracker| and +// notifies Ash. +class BrowserAppInstanceTrackerLacros : public BrowserAppInstanceTracker, + public wm::ActivationChangeObserver { + public: + BrowserAppInstanceTrackerLacros(Profile* profile, + AppRegistryCache& app_registry_cache); + ~BrowserAppInstanceTrackerLacros() override; + BrowserAppInstanceTrackerLacros(const BrowserAppInstanceTrackerLacros&) = + delete; + BrowserAppInstanceTrackerLacros& operator=( + const BrowserAppInstanceTrackerLacros&) = delete; + + // wm::ActivationChangeObserver overrides: + void OnWindowActivated(ActivationReason reason, + aura::Window* gained_active, + aura::Window* lost_active) override; + + private: + // Updates the browser instance with the new attributes and notifies + // observers, if it was updated. + void MaybeUpdateBrowserWindowInstance(BrowserWindowInstance& instance, + Browser* browser); + // Called on browser window changes. Sends update events for all open tabs. + void OnBrowserWindowUpdated(Browser* browser); + + bool IsActivationClientTracked(wm::ActivationClient* client) const; + + // In addition to calling + // |BrowserAppInstanceTracker::OnBrowserFirstTabAttached| starts observing + // |ActivationClient| corresponding to |browser|. + void OnBrowserFirstTabAttached(Browser* browser) override; + // In addition to calling + // |BrowserAppInstanceTracker::OnBrowserLastTabDetached| stops observing + // |ActivationClient| corresponding to |browser|. + void OnBrowserLastTabDetached(Browser* browser) override; + + // A set of observed activation clients for all browser's windows. + base::ScopedMultiSourceObservation<wm::ActivationClient, + wm::ActivationChangeObserver> + activation_client_observations_{this}; +}; +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + } // namespace apps #endif // CHROME_BROWSER_APPS_APP_SERVICE_BROWSER_APP_INSTANCE_TRACKER_H_
diff --git a/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc b/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc index 0a79f55..a230076 100644 --- a/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc +++ b/chrome/browser/apps/app_service/browser_app_instance_tracker_browsertest.cc
@@ -76,7 +76,6 @@ instance.app_id, instance.window, instance.title, - instance.is_browser_active, instance.is_web_contents_active, }; } @@ -89,7 +88,6 @@ /* app_id= */ "", instance.window, /* title= */ "", - instance.is_active, /* is_web_contents_active= */ false, }; } @@ -111,22 +109,21 @@ std::string app_id; raw_ptr<aura::Window> window; std::string title; - bool is_browser_active; bool is_web_contents_active; }; bool operator==(const TestInstance& e1, const TestInstance& e2) { return e1.name == e2.name && e1.id == e2.id && e1.type == e2.type && e1.app_id == e2.app_id && e1.window == e2.window && - e1.title == e2.title && e1.is_browser_active == e2.is_browser_active && + e1.title == e2.title && e1.is_web_contents_active == e2.is_web_contents_active; } bool operator<(const TestInstance& e1, const TestInstance& e2) { return std::tie(e1.name, e1.id, e1.type, e1.app_id, e1.window, e1.title, - e1.is_browser_active, e1.is_web_contents_active) < + e1.is_web_contents_active) < std::tie(e2.name, e2.id, e2.type, e2.app_id, e2.window, e2.title, - e2.is_browser_active, e2.is_web_contents_active); + e2.is_web_contents_active); } std::ostream& operator<<(std::ostream& os, const TestInstance& e) { @@ -136,7 +133,6 @@ return os << e.name << "(id=" << e.id << ",type=" << e.type << ",app_id=" << e.app_id << ", title='" << e.title << "'" << ", window=" << e.window - << ", browser=" << (e.is_browser_active ? "active" : "inactive") << ", tab=" << (e.is_web_contents_active ? "active" : "inactive") << ")"; } @@ -368,9 +364,9 @@ EXPECT_EQ(GetId(browser), 1u); EXPECT_EQ(GetId(tab_app1), 2u); recorder.Verify({ - {"added", 1, kChromeWindow, "", window, "", kActive, false}, - {"added", 2, kAppTab, kAppId_A, window, "", kActive, kActive}, - {"updated", 2, kAppTab, kAppId_A, window, kTitle_A, kActive, kActive}, + {"added", 1, kChromeWindow, "", window, "", false}, + {"added", 2, kAppTab, kAppId_A, window, "", kActive}, + {"updated", 2, kAppTab, kAppId_A, window, kTitle_A, kActive}, }); } @@ -382,9 +378,9 @@ tab_app2 = InsertForegroundTab(browser, "https://b.example.org"); EXPECT_EQ(GetId(tab_app2), 3u); recorder.Verify({ - {"updated", 2, kAppTab, kAppId_A, window, kTitle_A, kActive, kInactive}, - {"added", 3, kAppTab, kAppId_B, window, "", kActive, kActive}, - {"updated", 3, kAppTab, kAppId_B, window, kTitle_B, kActive, kActive}, + {"updated", 2, kAppTab, kAppId_A, window, kTitle_A, kInactive}, + {"added", 3, kAppTab, kAppId_B, window, "", kActive}, + {"updated", 3, kAppTab, kAppId_B, window, kTitle_B, kActive}, }); } @@ -395,7 +391,7 @@ InsertForegroundTab(browser, "https://c.example.org"); recorder.Verify({ - {"updated", 3, kAppTab, kAppId_B, window, kTitle_B, kActive, kInactive}, + {"updated", 3, kAppTab, kAppId_B, window, kTitle_B, kInactive}, }); } @@ -418,17 +414,17 @@ recorder.Verify({ // tab 4 opened: no events for tab 3 as it has no app - {"added", 4, kAppTab, kAppId_A, window, "", kActive, kActive}, - {"updated", 4, kAppTab, kAppId_A, window, kTitle_A, kActive, kActive}, + {"added", 4, kAppTab, kAppId_A, window, "", kActive}, + {"updated", 4, kAppTab, kAppId_A, window, kTitle_A, kActive}, // tab 5 opened: tab 4 deactivates - {"updated", 4, kAppTab, kAppId_A, window, kTitle_A, kActive, kInactive}, - {"added", 5, kAppTab, kAppId_B, window, "", kActive, kActive}, - {"updated", 5, kAppTab, kAppId_B, window, kTitle_B, kActive, kActive}, + {"updated", 4, kAppTab, kAppId_A, window, kTitle_A, kInactive}, + {"added", 5, kAppTab, kAppId_B, window, "", kActive}, + {"updated", 5, kAppTab, kAppId_B, window, kTitle_B, kActive}, // tab 5 closed: tab 4 reactivates - {"removed", 5, kAppTab, kAppId_B, window, kTitle_B, kActive, kActive}, - {"updated", 4, kAppTab, kAppId_A, window, kTitle_A, kActive, kActive}, + {"removed", 5, kAppTab, kAppId_B, window, kTitle_B, kActive}, + {"updated", 4, kAppTab, kAppId_A, window, kTitle_A, kActive}, // tab closed: no events for tab 3 as it has no app - {"removed", 4, kAppTab, kAppId_A, window, kTitle_A, kActive, kActive}, + {"removed", 4, kAppTab, kAppId_A, window, kTitle_A, kActive}, }); } @@ -439,9 +435,9 @@ browser->tab_strip_model()->CloseAllTabs(); recorder.Verify({ - {"removed", 3, kAppTab, kAppId_B, window, kTitle_B, kActive, kInactive}, - {"removed", 2, kAppTab, kAppId_A, window, kTitle_A, kActive, kInactive}, - {"removed", 1, kChromeWindow, "", window, "", kActive, false}, + {"removed", 3, kAppTab, kAppId_B, window, kTitle_B, kInactive}, + {"removed", 2, kAppTab, kAppId_A, window, kTitle_A, kInactive}, + {"removed", 1, kChromeWindow, "", window, "", false}, }); } } @@ -459,7 +455,7 @@ InsertForegroundTab(browser, "https://c.example.org"); recorder.Verify({ - {"added", 1, kChromeWindow, "", window, "", kActive, false}, + {"added", 1, kChromeWindow, "", window, "", false}, }); } @@ -470,7 +466,7 @@ browser->tab_strip_model()->CloseAllTabs(); recorder.Verify({ - {"removed", 1, kChromeWindow, "", window, "", kActive, false}, + {"removed", 1, kChromeWindow, "", window, "", false}, }); } @@ -486,9 +482,9 @@ InsertForegroundTab(browser, "https://a.example.org"); recorder.Verify({ - {"added", 2, kChromeWindow, "", window, "", kActive, false}, - {"added", 3, kAppTab, kAppId_A, window, "", kActive, kActive}, - {"updated", 3, kAppTab, kAppId_A, window, kTitle_A, kActive, kActive}, + {"added", 2, kChromeWindow, "", window, "", false}, + {"added", 3, kAppTab, kAppId_A, window, "", kActive}, + {"updated", 3, kAppTab, kAppId_A, window, kTitle_A, kActive}, }); } @@ -499,8 +495,8 @@ browser->tab_strip_model()->CloseAllTabs(); recorder.Verify({ - {"removed", 3, kAppTab, kAppId_A, window, kTitle_A, kActive, kActive}, - {"removed", 2, kChromeWindow, "", window, "", kActive, false}, + {"removed", 3, kAppTab, kAppId_A, window, kTitle_A, kActive}, + {"removed", 2, kChromeWindow, "", window, "", false}, }); } } @@ -541,13 +537,13 @@ recorder.Verify({ // dev tools window opened - {"added", 2, kChromeWindow, "", window2, "", kInactive, false}, - {"updated", 1, kChromeWindow, "", window1, "", kInactive, false}, - {"updated", 2, kChromeWindow, "", window2, "", kActive, false}, + {"added", 2, kChromeWindow, "", window2, "", false}, + {"updated", 1, kChromeWindow, "", window1, "", false}, + {"updated", 2, kChromeWindow, "", window2, "", false}, // dev tools window closed - {"updated", 2, kChromeWindow, "", window2, "", kInactive, false}, - {"updated", 1, kChromeWindow, "", window1, "", kActive, false}, - {"removed", 2, kChromeWindow, "", window2, "", kInactive, false}, + {"updated", 2, kChromeWindow, "", window2, "", false}, + {"updated", 1, kChromeWindow, "", window1, "", false}, + {"removed", 2, kChromeWindow, "", window2, "", false}, }); } } @@ -568,7 +564,7 @@ NavigateActiveTab(browser, "https://a.example.org"); EXPECT_EQ(GetId(tab), 2u); recorder.Verify({ - {"added", 2, kAppTab, kAppId_A, window, kTitle_A, kActive, kActive}, + {"added", 2, kAppTab, kAppId_A, window, kTitle_A, kActive}, }); } @@ -580,8 +576,8 @@ NavigateActiveTab(browser, "https://b.example.org"); EXPECT_EQ(GetId(tab), 3u); recorder.Verify({ - {"removed", 2, kAppTab, kAppId_A, window, kTitle_A, kActive, kActive}, - {"added", 3, kAppTab, kAppId_B, window, kTitle_B, kActive, kActive}, + {"removed", 2, kAppTab, kAppId_A, window, kTitle_A, kActive}, + {"added", 3, kAppTab, kAppId_B, window, kTitle_B, kActive}, }); } @@ -593,7 +589,7 @@ NavigateActiveTab(browser, "https://c.example.org"); EXPECT_EQ(GetId(tab), 0u); recorder.Verify({ - {"removed", 3, kAppTab, kAppId_B, window, kTitle_B, kActive, kActive}, + {"removed", 3, kAppTab, kAppId_B, window, kTitle_B, kActive}, }); } @@ -605,7 +601,7 @@ NavigateActiveTab(browser, "https://b.example.org"); EXPECT_EQ(GetId(tab), 4u); recorder.Verify({ - {"added", 4, kAppTab, kAppId_B, window, kTitle_B, kActive, kActive}, + {"added", 4, kAppTab, kAppId_B, window, kTitle_B, kActive}, }); } @@ -617,7 +613,7 @@ NavigateActiveTab(browser, "https://example.com"); EXPECT_EQ(GetId(tab), 0u); recorder.Verify({ - {"removed", 4, kAppTab, kAppId_B, window, kTitle_B, kActive, kActive}, + {"removed", 4, kAppTab, kAppId_B, window, kTitle_B, kActive}, }); } @@ -629,7 +625,7 @@ NavigateActiveTab(browser, "https://b.example.org"); EXPECT_EQ(GetId(tab), 5u); recorder.Verify({ - {"added", 5, kAppTab, kAppId_B, window, kTitle_B, kActive, kActive}, + {"added", 5, kAppTab, kAppId_B, window, kTitle_B, kActive}, }); } } @@ -652,9 +648,8 @@ EXPECT_EQ(GetId(tab), 1u); window = browser->window()->GetNativeWindow(); recorder.Verify({ - {"added", 1, kAppWindow, app_id, window, "", kActive, kActive}, - {"updated", 1, kAppWindow, app_id, window, "d.example.org", kActive, - kActive}, + {"added", 1, kAppWindow, app_id, window, "", kActive}, + {"updated", 1, kAppWindow, app_id, window, "d.example.org", kActive}, }); } @@ -665,8 +660,7 @@ browser->tab_strip_model()->CloseAllTabs(); recorder.Verify({ - {"removed", 1, kAppWindow, app_id, window, "d.example.org", kActive, - kActive}, + {"removed", 1, kAppWindow, app_id, window, "d.example.org", kActive}, }); } @@ -683,9 +677,8 @@ // When open in a window it's still an app, even if configured to open in a // tab. recorder.Verify({ - {"added", 2, kAppWindow, kAppId_A, window, "", kActive, kActive}, - {"updated", 2, kAppWindow, kAppId_A, window, kTitle_A, kActive, - kActive}, + {"added", 2, kAppWindow, kAppId_A, window, "", kActive}, + {"updated", 2, kAppWindow, kAppId_A, window, kTitle_A, kActive}, }); } @@ -696,8 +689,7 @@ browser->tab_strip_model()->CloseAllTabs(); recorder.Verify({ - {"removed", 2, kAppWindow, kAppId_A, window, kTitle_A, kActive, - kActive}, + {"removed", 2, kAppWindow, kAppId_A, window, kTitle_A, kActive}, }); } } @@ -729,10 +721,9 @@ EXPECT_EQ(GetId(tab), 1u); window = browser->window()->GetNativeWindow(); recorder.Verify({ - {"added", 1, kAppWindow, web_app::kCroshAppId, window, "", kActive, - kActive}, + {"added", 1, kAppWindow, web_app::kCroshAppId, window, "", kActive}, {"updated", 1, kAppWindow, web_app::kCroshAppId, window, "crosh1", - kActive, kActive}, + kActive}, }); } @@ -750,10 +741,9 @@ // Only title of the existing app instance should be updated. EXPECT_EQ(GetId(tab), 1u); recorder.Verify({ - {"updated", 1, kAppWindow, web_app::kCroshAppId, window, "", kActive, - kActive}, + {"updated", 1, kAppWindow, web_app::kCroshAppId, window, "", kActive}, {"updated", 1, kAppWindow, web_app::kCroshAppId, window, "crosh2", - kActive, kActive}, + kActive}, }); } @@ -766,7 +756,7 @@ // The app instance disappars with the window. recorder.Verify({ {"removed", 1, kAppWindow, web_app::kCroshAppId, window, "crosh2", - kActive, kActive}, + kActive}, }); } } @@ -789,7 +779,7 @@ browser->tab_strip_model()->ActivateTabAt(0); recorder.Verify({ - {"updated", 2, kAppTab, kAppId_A, window, kTitle_A, kActive, kActive}, + {"updated", 2, kAppTab, kAppId_A, window, kTitle_A, kActive}, }); } @@ -800,8 +790,8 @@ browser->tab_strip_model()->ActivateTabAt(1); recorder.Verify({ - {"updated", 3, kAppTab, kAppId_B, window, kTitle_B, kActive, kActive}, - {"updated", 2, kAppTab, kAppId_A, window, kTitle_A, kActive, kInactive}, + {"updated", 3, kAppTab, kAppId_B, window, kTitle_B, kActive}, + {"updated", 2, kAppTab, kAppId_A, window, kTitle_A, kInactive}, }); } @@ -812,75 +802,7 @@ browser->tab_strip_model()->ActivateTabAt(2); recorder.Verify({ - {"updated", 3, kAppTab, kAppId_B, window, kTitle_B, kActive, kInactive}, - }); - } -} - -IN_PROC_BROWSER_TEST_F(BrowserAppInstanceTrackerTest, WindowActivation) { - // Setup: two browsers with two tabs each. - auto* browser1 = CreateBrowser(); - auto* window1 = browser1->window()->GetNativeWindow(); - auto* b1_tab1 = InsertForegroundTab(browser1, "https://a.example.org"); - auto* b1_tab2 = InsertForegroundTab(browser1, "https://c.example.org"); - auto* b1_tab3 = InsertForegroundTab(browser1, "https://b.example.org"); - EXPECT_EQ(GetId(browser1), 1u); - EXPECT_EQ(GetId(b1_tab1), 2u); - EXPECT_EQ(GetId(b1_tab2), 0u); - EXPECT_EQ(GetId(b1_tab3), 3u); - - auto* browser2 = CreateBrowser(); - auto* window2 = browser2->window()->GetNativeWindow(); - auto* b2_tab1 = InsertForegroundTab(browser2, "https://a.example.org"); - auto* b2_tab2 = InsertForegroundTab(browser2, "https://c.example.org"); - auto* b2_tab3 = InsertForegroundTab(browser2, "https://b.example.org"); - EXPECT_EQ(GetId(browser2), 4u); - EXPECT_EQ(GetId(b2_tab1), 5u); - EXPECT_EQ(GetId(b2_tab2), 0u); - EXPECT_EQ(GetId(b2_tab3), 6u); - - ASSERT_FALSE(browser1->window()->IsActive()); - ASSERT_TRUE(browser2->window()->IsActive()); - - // Activate window 1. - { - SCOPED_TRACE("activate window 1"); - Recorder recorder(*tracker_); - - browser1->window()->Activate(); - recorder.Verify({ - // deactivated first - {"updated", 4, kChromeWindow, "", window2, "", kInactive, false}, - {"updated", 5, kAppTab, kAppId_A, window2, kTitle_A, kInactive, - kInactive}, - {"updated", 6, kAppTab, kAppId_B, window2, kTitle_B, kInactive, - kActive}, - // then activated - {"updated", 1, kChromeWindow, "", window1, "", kActive, false}, - {"updated", 2, kAppTab, kAppId_A, window1, kTitle_A, kActive, - kInactive}, - {"updated", 3, kAppTab, kAppId_B, window1, kTitle_B, kActive, kActive}, - }); - } - - // Activate window 2. - { - SCOPED_TRACE("activate window 2"); - Recorder recorder(*tracker_); - - browser2->window()->Activate(); - recorder.Verify({ - // deactivated first - {"updated", 1, kChromeWindow, "", window1, "", kInactive, false}, - {"updated", 2, kAppTab, kAppId_A, window1, kTitle_A, kInactive, - kInactive}, - {"updated", 3, kAppTab, kAppId_B, window1, kTitle_B, kInactive, - kActive}, - // then activated - {"updated", 4, kChromeWindow, "", window2, "", kActive, false}, - {"updated", 5, kAppTab, kAppId_A, window2, kTitle_A, kActive, - kInactive}, - {"updated", 6, kAppTab, kAppId_B, window2, kTitle_B, kActive, kActive}, + {"updated", 3, kAppTab, kAppId_B, window, kTitle_B, kInactive}, }); } } @@ -931,21 +853,12 @@ recorder.Verify({ // background tab in the dragged-from browser gets activated when the // active tab is detached - {"updated", 6, kAppTab, kAppId_A, window2, kTitle_A, kActive, kActive}, - // dragged-from browser goes into background - {"updated", 4, kChromeWindow, "", window2, "", kInactive, false}, - {"updated", 5, kAppTab, kAppId_A, window2, kTitle_A, kInactive, - kInactive}, - {"updated", 6, kAppTab, kAppId_A, window2, kTitle_A, kInactive, kActive}, - // dragged-into browser window goes into foreground - {"updated", 1, kChromeWindow, "", window1, "", kActive, false}, - {"updated", 2, kAppTab, kAppId_A, window1, kTitle_A, kActive, kInactive}, - {"updated", 3, kAppTab, kAppId_B, window1, kTitle_B, kActive, kActive}, + {"updated", 6, kAppTab, kAppId_A, window2, kTitle_A, kActive}, // previously foreground tab in the dragged-into browser goes into // background when the dragged tab is attached to the new browser - {"updated", 3, kAppTab, kAppId_B, window1, kTitle_B, kActive, kInactive}, + {"updated", 3, kAppTab, kAppId_B, window1, kTitle_B, kInactive}, // dragged tab gets reparented and becomes active in the new browser - {"updated", 7, kAppTab, kAppId_B, window1, kTitle_B, kActive, kActive}, + {"updated", 7, kAppTab, kAppId_B, window1, kTitle_B, kActive}, }); } @@ -955,7 +868,6 @@ std::string app_id = InstallWebAppOpeningAsWindow("https://d.example.org"); auto* browser1 = CreateBrowser(); - auto* window1 = browser1->window()->GetNativeWindow(); InsertForegroundTab(browser1, "https://c.example.org"); auto* tab = InsertForegroundTab(browser1, "https://d.example.org"); EXPECT_EQ(GetId(browser1), 1u); @@ -983,11 +895,8 @@ browser2->tab_strip_model()->InsertDetachedTabAt( dst_index, std::move(detached_tab), AddTabTypes::ADD_ACTIVE); recorder.Verify({ - // source browser goes into background when app browser is created - {"updated", 1, kChromeWindow, "", window1, "", kInactive, false}, // moved tab gets reparented and becomes an app in the new browser - {"added", 2, kAppWindow, app_id, window2, "d.example.org", kActive, - kActive}, + {"added", 2, kAppWindow, app_id, window2, "d.example.org", kActive}, }); } @@ -1032,24 +941,24 @@ auto* b3_app = tracker_->GetAppInstance(browser3); auto* b3_tab1_app = tracker_->GetAppInstance(b3_tab1); - EXPECT_EQ(TestInstance::Create(b1_app), - (TestInstance{"snapshot", 1, kChromeWindow, "", window1, "", - kInactive, false})); + EXPECT_EQ( + TestInstance::Create(b1_app), + (TestInstance{"snapshot", 1, kChromeWindow, "", window1, "", false})); EXPECT_EQ(TestInstance::Create(b1_tab1_app), (TestInstance{"snapshot", 2, kAppTab, kAppId_A, window1, kTitle_A, - kInactive, kInactive})); + kInactive})); EXPECT_EQ(TestInstance::Create(b1_tab2_app), TestInstance{}); EXPECT_EQ(TestInstance::Create(b1_tab3_app), (TestInstance{"snapshot", 3, kAppTab, kAppId_B, window1, kTitle_B, - kInactive, kActive})); + kActive})); - EXPECT_EQ(TestInstance::Create(b2_app), - (TestInstance{"snapshot", 4, kChromeWindow, "", window2, "", - kInactive, false})); + EXPECT_EQ( + TestInstance::Create(b2_app), + (TestInstance{"snapshot", 4, kChromeWindow, "", window2, "", false})); EXPECT_EQ(TestInstance::Create(b2_tab1_app), TestInstance{}); EXPECT_EQ(TestInstance::Create(b2_tab2_app), (TestInstance{"snapshot", 5, kAppTab, kAppId_B, window2, kTitle_B, - kInactive, kActive})); + kActive})); // browser3 does not map to any browser window instance, but it maps to the // same app instance as the tab. @@ -1058,7 +967,7 @@ EXPECT_EQ(b3_app, b3_tab1_app); EXPECT_EQ(TestInstance::Create(b3_tab1_app), (TestInstance{"snapshot", 6, kAppWindow, kAppId_B, window3, - kTitle_B, kActive, kActive})); + kTitle_B, kActive})); } IN_PROC_BROWSER_TEST_F(BrowserAppInstanceTrackerTest, AppInstall) { @@ -1080,8 +989,8 @@ EXPECT_EQ(GetId(tab1), 2u); EXPECT_EQ(GetId(tab3), 3u); recorder.Verify({ - {"added", 2, kAppTab, app_id, window1, title, kActive, kInactive}, - {"added", 3, kAppTab, app_id, window1, title, kActive, kActive}, + {"added", 2, kAppTab, app_id, window1, title, kInactive}, + {"added", 3, kAppTab, app_id, window1, title, kActive}, }); } @@ -1093,8 +1002,8 @@ EXPECT_EQ(GetId(tab1), 0u); EXPECT_EQ(GetId(tab3), 0u); recorder.Verify({ - {"removed", 2, kAppTab, app_id, window1, title, kActive, kInactive}, - {"removed", 3, kAppTab, app_id, window1, title, kActive, kActive}, + {"removed", 2, kAppTab, app_id, window1, title, kInactive}, + {"removed", 3, kAppTab, app_id, window1, title, kActive}, }); } @@ -1172,10 +1081,8 @@ tracker_->StopInstancesOfApp(kAppId_A); recorder.VerifyIgnoreOrder({ - {"removed", 3, kAppTab, kAppId_A, window1, kTitle_A, kInactive, - kInactive}, - {"removed", 2, kAppTab, kAppId_A, window1, kTitle_A, kInactive, - kInactive}, + {"removed", 3, kAppTab, kAppId_A, window1, kTitle_A, kInactive}, + {"removed", 2, kAppTab, kAppId_A, window1, kTitle_A, kInactive}, }); } @@ -1187,11 +1094,7 @@ tracker_->StopInstancesOfApp(app_d_id); recorder.Verify({ - {"removed", 5, kAppWindow, app_d_id, window2, "d.example.org", kActive, - kActive}, - {"updated", 1, kChromeWindow, {}, window1, {}, kActive, kInactive}, - {"updated", 4, kAppTab, kAppId_B, window1, "b.example.org", kActive, - kInactive}, + {"removed", 5, kAppWindow, app_d_id, window2, "d.example.org", kActive}, }); } @@ -1203,8 +1106,7 @@ tracker_->StopInstancesOfApp(kAppId_B); recorder.Verify({ - {"removed", 4, kAppTab, kAppId_B, window1, kTitle_B, kActive, - kInactive}, + {"removed", 4, kAppTab, kAppId_B, window1, kTitle_B, kInactive}, }); } }
diff --git a/chrome/browser/apps/app_service/instance_registry_updater.cc b/chrome/browser/apps/app_service/instance_registry_updater.cc index 741845a..b41fc6ac 100644 --- a/chrome/browser/apps/app_service/instance_registry_updater.cc +++ b/chrome/browser/apps/app_service/instance_registry_updater.cc
@@ -62,7 +62,7 @@ void InstanceRegistryUpdater::OnBrowserWindowUpdated( const BrowserWindowInstance& instance) { InstanceState state = - GetState(instance.window->IsVisible(), instance.is_active); + GetState(instance.window->IsVisible(), instance.is_active()); OnInstance(instance.id, instance.GetAppId(), instance.window, state); } @@ -81,7 +81,7 @@ const BrowserAppInstance& instance) { InstanceState state = GetState(instance.window->IsVisible(), - instance.is_browser_active && instance.is_web_contents_active); + instance.is_browser_active() && instance.is_web_contents_active); OnInstance(instance.id, instance.app_id, instance.window, state); }
diff --git a/chrome/browser/apps/app_service/lacros_browser_shelf_lacros_browsertest.cc b/chrome/browser/apps/app_service/lacros_browser_shelf_lacros_browsertest.cc new file mode 100644 index 0000000..bc444b5c --- /dev/null +++ b/chrome/browser/apps/app_service/lacros_browser_shelf_lacros_browsertest.cc
@@ -0,0 +1,65 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/test/test_future.h" +#include "chrome/browser/lacros/browser_test_util.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chromeos/crosapi/mojom/test_controller.mojom.h" +#include "chromeos/lacros/lacros_service.h" +#include "components/app_constants/constants.h" +#include "content/public/test/browser_test.h" +#include "ui/base/ui_base_types.h" +#include "ui/views/test/widget_activation_waiter.h" +#include "ui/views/test/widget_show_state_waiter.h" +#include "ui/views/widget/widget.h" + +using crosapi::mojom::ShelfItemState; + +namespace { + +class LacrosBrowserShelfLacrosBrowserTest : public InProcessBrowserTest { + public: + views::Widget* GetWidgetForBrowser(Browser* browser) { + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); + CHECK(browser_view); + views::Widget* widget = browser_view->GetWidget(); + CHECK(widget); + return widget; + } +}; + +// Test that clicking on Lacros icon has the expected effect of toggling between +// minimized state and visible state when there is one browser window. +IN_PROC_BROWSER_TEST_F(LacrosBrowserShelfLacrosBrowserTest, ClickOnShelf) { + crosapi::mojom::TestController* const test_controller = + chromeos::LacrosService::Get() + ->GetRemote<crosapi::mojom::TestController>() + .get(); + views::Widget* widget = GetWidgetForBrowser(browser()); + views::test::WaitForWidgetActive(widget, true); + ASSERT_TRUE(browser_test_util::WaitForShelfItemState( + app_constants::kLacrosAppId, + static_cast<uint32_t>(ShelfItemState::kActive))); + ASSERT_TRUE(browser()->window()->IsVisible()); + ASSERT_FALSE(browser()->window()->IsMinimized()); + + base::test::TestFuture<bool> success_future; + test_controller->SelectItemInShelf(app_constants::kLacrosAppId, + success_future.GetCallback()); + ASSERT_TRUE(success_future.Take()); + views::test::WaitForWidgetShowState(widget, ui::SHOW_STATE_MINIMIZED); + ASSERT_FALSE(browser()->window()->IsVisible()); + ASSERT_TRUE(browser()->window()->IsMinimized()); + + test_controller->SelectItemInShelf(app_constants::kLacrosAppId, + success_future.GetCallback()); + ASSERT_TRUE(success_future.Take()); + views::test::WaitForWidgetActive(widget, true); + ASSERT_TRUE(browser()->window()->IsVisible()); + ASSERT_FALSE(browser()->window()->IsMinimized()); +} + +} // namespace
diff --git a/chrome/browser/ash/input_method/editor_switch.cc b/chrome/browser/ash/input_method/editor_switch.cc index 0feba68a..7d7fd00 100644 --- a/chrome/browser/ash/input_method/editor_switch.cc +++ b/chrome/browser/ash/input_method/editor_switch.cc
@@ -91,6 +91,77 @@ constexpr char kImeAllowlistLabel[] = "ime_allowlist"; +std::vector<std::string> Combine( + const std::vector<std::vector<std::string>>& vecs) { + std::vector<std::string> combined; + for (auto& vec : vecs) { + combined.insert(combined.end(), vec.begin(), vec.end()); + } + return combined; +} + +const std::vector<std::string>& EnglishInputMethods() { + static const base::NoDestructor<std::vector<std::string>> input_methods({ + "xkb:ca:eng:eng", // Canada + "xkb:gb::eng", // UK + "xkb:gb:extd:eng", // UK Extended + "xkb:gb:dvorak:eng", // UK Dvorak + "xkb:in::eng", // India + "xkb:pk::eng", // Pakistan + "xkb:us:altgr-intl:eng", // US Extended + "xkb:us:colemak:eng", // US Colemak + "xkb:us:dvorak:eng", // US Dvorak + "xkb:us:dvp:eng", // US Programmer Dvorak + "xkb:us:intl_pc:eng", // US Intl (PC) + "xkb:us:intl:eng", // US Intl + "xkb:us:workman-intl:eng", // US Workman Intl + "xkb:us:workman:eng", // US Workman + "xkb:us::eng", // US + "xkb:za:gb:eng" // South Africa + }); + return *input_methods; +} + +const std::vector<std::string>& FrenchInputMethods() { + static const base::NoDestructor<std::vector<std::string>> input_methods({ + "xkb:be::fra", // French (Belgium) + "xkb:ca::fra", // French (Canada) + "xkb:ca:multix:fra", // French (Canada) with multilingual keyboard + "xkb:fr::fra", // French (France) + "xkb:fr:bepo:fra", // French (France) with bepo keyboard + "xkb:ch:fr:fra", // French (Switzerland) + }); + return *input_methods; +} + +const std::vector<std::string>& GermanInputMethods() { + static const base::NoDestructor<std::vector<std::string>> input_methods({ + "xkb:be::ger", // German (Belgium) + "xkb:de::ger", // German (Germany) + "xkb:de:neo:ger", // German (Germany) with neo keyboard + "xkb:ch::ger", // German (Switzerland) + }); + return *input_methods; +} + +const std::vector<std::string>& JapaneseInputMethods() { + static const base::NoDestructor<std::vector<std::string>> input_methods({ + "xkb:jp::jpn", // Alphanumeric with Japanese keyboard + "nacl_mozc_us", // Japanese with US keyboard + "nacl_mozc_jp", // Japanese + }); + return *input_methods; +} + +const std::vector<std::string>& AllowedInputMethods() { + static const base::NoDestructor<std::vector<std::string>> input_methods( + base::FeatureList::IsEnabled(features::kOrcaInternationalize) + ? Combine({EnglishInputMethods(), FrenchInputMethods(), + GermanInputMethods(), JapaneseInputMethods()}) + : EnglishInputMethods()); + return *input_methods; +} + manta::FeatureSupportStatus FetchOrcaAccountCapabilityFromMantaService( Profile* profile) { if (manta::MantaService* service = @@ -175,25 +246,7 @@ } std::vector<std::string> GetAllowedInputMethodEngines() { - // Default English IMEs. - std::vector<std::string> allowed_imes = { - "xkb:ca:eng:eng", // Canada - "xkb:gb::eng", // UK - "xkb:gb:extd:eng", // UK Extended - "xkb:gb:dvorak:eng", // UK Dvorak - "xkb:in::eng", // India - "xkb:pk::eng", // Pakistan - "xkb:us:altgr-intl:eng", // US Extended - "xkb:us:colemak:eng", // US Colemak - "xkb:us:dvorak:eng", // US Dvorak - "xkb:us:dvp:eng", // US Programmer Dvorak - "xkb:us:intl_pc:eng", // US Intl (PC) - "xkb:us:intl:eng", // US Intl - "xkb:us:workman-intl:eng", // US Workman Intl - "xkb:us:workman:eng", // US Workman - "xkb:us::eng", // US, - "xkb:za:gb:eng" // South Africa - }; + std::vector<std::string> allowed_imes = AllowedInputMethods(); // Loads allowed imes from field trials if (auto parsed = base::JSONReader::Read(
diff --git a/chrome/browser/ash/input_method/editor_switch_unittest.cc b/chrome/browser/ash/input_method/editor_switch_unittest.cc index 8b218a5..baabb5ea 100644 --- a/chrome/browser/ash/input_method/editor_switch_unittest.cc +++ b/chrome/browser/ash/input_method/editor_switch_unittest.cc
@@ -539,5 +539,171 @@ testing::ElementsAreArray(test_case.expected_blocked_reasons)); } +using InputMethodTestCase = std::pair<std::string, EditorMode>; + +using EditorSwitchEnglishOnlyTest = TestWithParam<InputMethodTestCase>; + +INSTANTIATE_TEST_SUITE_P(EditorSwitchEnglishOnly, + EditorSwitchEnglishOnlyTest, + testing::ValuesIn<InputMethodTestCase>({ + // English + {"xkb:ca:eng:eng", EditorMode::kWrite}, + {"xkb:gb::eng", EditorMode::kWrite}, + {"xkb:gb:extd:eng", EditorMode::kWrite}, + {"xkb:gb:dvorak:eng", EditorMode::kWrite}, + {"xkb:in::eng", EditorMode::kWrite}, + {"xkb:pk::eng", EditorMode::kWrite}, + {"xkb:us:altgr-intl:eng", EditorMode::kWrite}, + {"xkb:us:colemak:eng", EditorMode::kWrite}, + {"xkb:us:dvorak:eng", EditorMode::kWrite}, + {"xkb:us:dvp:eng", EditorMode::kWrite}, + {"xkb:us:intl_pc:eng", EditorMode::kWrite}, + {"xkb:us:intl:eng", EditorMode::kWrite}, + {"xkb:us:workman-intl:eng", EditorMode::kWrite}, + {"xkb:us:workman:eng", EditorMode::kWrite}, + {"xkb:us::eng", EditorMode::kWrite}, + {"xkb:za:gb:eng", EditorMode::kWrite}, + // French + {"xkb:be::fra", EditorMode::kBlocked}, + {"xkb:ca::fra", EditorMode::kBlocked}, + {"xkb:ca:multix:fra", EditorMode::kBlocked}, + {"xkb:fr::fra", EditorMode::kBlocked}, + {"xkb:fr:bepo:fra", EditorMode::kBlocked}, + {"xkb:ch:fr:fra", EditorMode::kBlocked}, + // German + {"xkb:be::ger", EditorMode::kBlocked}, + {"xkb:de::ger", EditorMode::kBlocked}, + {"xkb:de:neo:ger", EditorMode::kBlocked}, + {"xkb:ch::ger", EditorMode::kBlocked}, + // Japanese + {"xkb:jp::jpn", EditorMode::kBlocked}, + {"nacl_mozc_us", EditorMode::kBlocked}, + {"nacl_mozc_jp", EditorMode::kBlocked}, + // Dutch (example case where always disabled) + {"xkb:be::nld", EditorMode::kBlocked}, + {"xkb:us:intl_pc:nld", EditorMode::kBlocked}, + {"xkb:us:intl:nld", EditorMode::kBlocked}, + })); + +TEST_P(EditorSwitchEnglishOnlyTest, EditorIsEnabledForEnglishInputMethodsOnly) { + const InputMethodTestCase& test_case = GetParam(); + const std::string& engine_id = std::get<0>(test_case); + const EditorMode& expected_mode = std::get<1>(test_case); + content::BrowserTaskEnvironment task_environment; + base::test::ScopedFeatureList feature_list; + feature_list.InitWithFeatures( + /*enabled_features=*/{chromeos::features::kOrca, + chromeos::features::kFeatureManagementOrca}, + /*disabled_features=*/{ash::features::kOrcaUseAccountCapabilities}); + ScopedBrowserLocale browser_locale("en"); + + std::unique_ptr<TestingProfile> profile = + CreateTestingProfile("testuser@gmail.com"); + FakeEditorSwitchDelegate delegate; + EditorSwitch editor_switch(/*delegate=*/&delegate, + /*profile=*/profile.get(), + /*country_code=*/kAllowedTestCountry); + + auto mock_notifier = net::test::MockNetworkChangeNotifier::Create(); + profile->GetProfilePolicyConnector()->OverrideIsManagedForTesting(false); + mock_notifier->SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); + + profile->GetPrefs()->SetBoolean(prefs::kOrcaEnabled, true); + profile->GetPrefs()->SetInteger( + prefs::kOrcaConsentStatus, base::to_underlying(ConsentStatus::kApproved)); + editor_switch.OnTabletModeUpdated(false); + editor_switch.OnActivateIme(engine_id); + editor_switch.OnInputContextUpdated( + TextInputMethod::InputContext(ui::TEXT_INPUT_TYPE_TEXT), + CreateFakeTextFieldContextualInfo(AppType::BROWSER, kAllowedTestUrl, "")); + editor_switch.OnTextSelectionLengthChanged(0); + + EXPECT_TRUE(editor_switch.IsAllowedForUse()); + EXPECT_EQ(editor_switch.GetEditorMode(), expected_mode); +} + +using EditorSwitchInternationalizeTest = TestWithParam<InputMethodTestCase>; + +INSTANTIATE_TEST_SUITE_P(EditorSwitchInternationalize, + EditorSwitchInternationalizeTest, + testing::ValuesIn<InputMethodTestCase>({ + // English + {"xkb:ca:eng:eng", EditorMode::kWrite}, + {"xkb:gb::eng", EditorMode::kWrite}, + {"xkb:gb:extd:eng", EditorMode::kWrite}, + {"xkb:gb:dvorak:eng", EditorMode::kWrite}, + {"xkb:in::eng", EditorMode::kWrite}, + {"xkb:pk::eng", EditorMode::kWrite}, + {"xkb:us:altgr-intl:eng", EditorMode::kWrite}, + {"xkb:us:colemak:eng", EditorMode::kWrite}, + {"xkb:us:dvorak:eng", EditorMode::kWrite}, + {"xkb:us:dvp:eng", EditorMode::kWrite}, + {"xkb:us:intl_pc:eng", EditorMode::kWrite}, + {"xkb:us:intl:eng", EditorMode::kWrite}, + {"xkb:us:workman-intl:eng", EditorMode::kWrite}, + {"xkb:us:workman:eng", EditorMode::kWrite}, + {"xkb:us::eng", EditorMode::kWrite}, + {"xkb:za:gb:eng", EditorMode::kWrite}, + // French + {"xkb:be::fra", EditorMode::kWrite}, + {"xkb:ca::fra", EditorMode::kWrite}, + {"xkb:ca:multix:fra", EditorMode::kWrite}, + {"xkb:fr::fra", EditorMode::kWrite}, + {"xkb:fr:bepo:fra", EditorMode::kWrite}, + {"xkb:ch:fr:fra", EditorMode::kWrite}, + // German + {"xkb:be::ger", EditorMode::kWrite}, + {"xkb:de::ger", EditorMode::kWrite}, + {"xkb:de:neo:ger", EditorMode::kWrite}, + {"xkb:ch::ger", EditorMode::kWrite}, + // Japanese + {"xkb:jp::jpn", EditorMode::kWrite}, + {"nacl_mozc_us", EditorMode::kWrite}, + {"nacl_mozc_jp", EditorMode::kWrite}, + // Dutch (example case where always disabled) + {"xkb:be::nld", EditorMode::kBlocked}, + {"xkb:us:intl_pc:nld", EditorMode::kBlocked}, + {"xkb:us:intl:nld", EditorMode::kBlocked}, + })); + +TEST_P(EditorSwitchInternationalizeTest, + EditorIsEnabledForEnglishAndOtherInputMethods) { + const InputMethodTestCase& test_case = GetParam(); + const std::string& engine_id = std::get<0>(test_case); + const EditorMode& expected_mode = std::get<1>(test_case); + content::BrowserTaskEnvironment task_environment; + base::test::ScopedFeatureList feature_list; + feature_list.InitWithFeatures( + /*enabled_features=*/{chromeos::features::kOrca, + chromeos::features::kFeatureManagementOrca, + ash::features::kOrcaInternationalize}, + /*disabled_features=*/{ash::features::kOrcaUseAccountCapabilities}); + ScopedBrowserLocale browser_locale("en"); + + std::unique_ptr<TestingProfile> profile = + CreateTestingProfile("testuser@gmail.com"); + FakeEditorSwitchDelegate delegate; + EditorSwitch editor_switch(/*delegate=*/&delegate, + /*profile=*/profile.get(), + /*country_code=*/kAllowedTestCountry); + + auto mock_notifier = net::test::MockNetworkChangeNotifier::Create(); + profile->GetProfilePolicyConnector()->OverrideIsManagedForTesting(false); + mock_notifier->SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); + + profile->GetPrefs()->SetBoolean(prefs::kOrcaEnabled, true); + profile->GetPrefs()->SetInteger( + prefs::kOrcaConsentStatus, base::to_underlying(ConsentStatus::kApproved)); + editor_switch.OnTabletModeUpdated(false); + editor_switch.OnActivateIme(engine_id); + editor_switch.OnInputContextUpdated( + TextInputMethod::InputContext(ui::TEXT_INPUT_TYPE_TEXT), + CreateFakeTextFieldContextualInfo(AppType::BROWSER, kAllowedTestUrl, "")); + editor_switch.OnTextSelectionLengthChanged(0); + + EXPECT_TRUE(editor_switch.IsAllowedForUse()); + EXPECT_EQ(editor_switch.GetEditorMode(), expected_mode); +} + } // namespace } // namespace ash::input_method
diff --git a/chrome/browser/autofill/form_structure_browsertest.cc b/chrome/browser/autofill/form_structure_browsertest.cc index db1f07b..986bf50 100644 --- a/chrome/browser/autofill/form_structure_browsertest.cc +++ b/chrome/browser/autofill/form_structure_browsertest.cc
@@ -113,8 +113,8 @@ std::string string_form; std::map<std::string, int> section_to_index; for (const auto& field : *form_structure) { - std::string section = field->section.ToString(); - if (field->section.is_from_fieldidentifier()) { + std::string section = field->section().ToString(); + if (field->section().is_from_fieldidentifier()) { // Normalize the section by replacing the unique but platform-dependent // integers in `field->section` with consecutive unique integers. // The section string is of the form "fieldname_id1_id2", where id1, id2
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc index a040440c..4d158beb 100644 --- a/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc +++ b/chrome/browser/extensions/api/passwords_private/passwords_private_api.cc
@@ -653,13 +653,22 @@ // PasswordsPrivateChangePasswordManagerPinFunction ResponseAction PasswordsPrivateChangePasswordManagerPinFunction::Run() { if (auto delegate = GetDelegate(browser_context())) { - delegate->ChangePasswordManagerPin(GetSenderWebContents()); - return RespondNow(NoArguments()); + delegate->ChangePasswordManagerPin( + GetSenderWebContents(), + base::BindOnce(&PasswordsPrivateChangePasswordManagerPinFunction:: + OnPinChangeCompleted, + this)); + return did_respond() ? AlreadyResponded() : RespondLater(); } return RespondNow(Error(kNoDelegateError)); } +void PasswordsPrivateChangePasswordManagerPinFunction::OnPinChangeCompleted( + bool success) { + Respond(WithArguments(success)); +} + ResponseAction PasswordsPrivateIsPasswordManagerPinAvailableFunction::Run() { if (auto delegate = GetDelegate(browser_context())) { return RespondNow(WithArguments(
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_api.h b/chrome/browser/extensions/api/passwords_private/passwords_private_api.h index b6cca75..a64017e 100644 --- a/chrome/browser/extensions/api/passwords_private/passwords_private_api.h +++ b/chrome/browser/extensions/api/passwords_private/passwords_private_api.h
@@ -473,6 +473,9 @@ // ExtensionFunction overrides. ResponseAction Run() override; + + private: + void OnPinChangeCompleted(bool success); }; class PasswordsPrivateIsPasswordManagerPinAvailableFunction
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate.h b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate.h index 026c63d..d749db4 100644 --- a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate.h +++ b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate.h
@@ -256,7 +256,9 @@ std::string file_path) = 0; // Starts the flow for changing the password manager PIN. - virtual void ChangePasswordManagerPin(content::WebContents* web_contents) = 0; + virtual void ChangePasswordManagerPin( + content::WebContents* web_contents, + base::OnceCallback<void(bool)> success_callback) = 0; // Returns true if it's allowed to change the password manager PIN, if it // exists.
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc index e56be6e..f368142 100644 --- a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc +++ b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.cc
@@ -935,11 +935,12 @@ } void PasswordsPrivateDelegateImpl::ChangePasswordManagerPin( - content::WebContents* web_contents) { + content::WebContents* web_contents, + base::OnceCallback<void(bool)> success_callback) { ChangePinController* controller = ChangePinController::ForWebContents(web_contents); if (controller) { - controller->StartChangePin(); + controller->StartChangePin(std::move(success_callback)); } }
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.h b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.h index fad2069..7227770 100644 --- a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.h +++ b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.h
@@ -132,7 +132,9 @@ void ShowAddShortcutDialog(content::WebContents* web_contents) override; void ShowExportedFileInShell(content::WebContents* web_contents, std::string file_path) override; - void ChangePasswordManagerPin(content::WebContents* web_contents) override; + void ChangePasswordManagerPin( + content::WebContents* web_contents, + base::OnceCallback<void(bool)> success_callback) override; bool IsPasswordManagerPinAvailable( content::WebContents* web_contents) override;
diff --git a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc index 8e3cf2c..abbc3c2 100644 --- a/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc +++ b/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl_unittest.cc
@@ -165,7 +165,10 @@ class MockChangePinController : public ChangePinController { public: MOCK_METHOD(bool, IsChangePinFlowAvailable, (), (override)); - MOCK_METHOD(bool, StartChangePin, (), (override)); + MOCK_METHOD(void, + StartChangePin, + (base::OnceCallback<void(bool)>), + (override)); }; class FakePasswordManagerPorter : public PasswordManagerPorterInterface { @@ -1862,7 +1865,7 @@ delegate->SharePassword(/*id=*/100, recipients); } -TEST_F(PasswordsPrivateDelegateImplTest, ChangePin) { +TEST_F(PasswordsPrivateDelegateImplTest, IsChangePinFlowAvailable) { auto delegate = CreateDelegate(); std::unique_ptr<content::WebContents> web_contents = CreateWebContents();
diff --git a/chrome/browser/extensions/api/passwords_private/test_passwords_private_delegate.cc b/chrome/browser/extensions/api/passwords_private/test_passwords_private_delegate.cc index 876bb2f..169f7e50 100644 --- a/chrome/browser/extensions/api/passwords_private/test_passwords_private_delegate.cc +++ b/chrome/browser/extensions/api/passwords_private/test_passwords_private_delegate.cc
@@ -434,8 +434,10 @@ } void TestPasswordsPrivateDelegate::ChangePasswordManagerPin( - content::WebContents* web_contents) { + content::WebContents* web_contents, + base::OnceCallback<void(bool)> success_callback) { change_password_manager_pin_called_ = true; + std::move(success_callback).Run(false); } bool TestPasswordsPrivateDelegate::IsPasswordManagerPinAvailable(
diff --git a/chrome/browser/extensions/api/passwords_private/test_passwords_private_delegate.h b/chrome/browser/extensions/api/passwords_private/test_passwords_private_delegate.h index 02f6b6b..49aefb7 100644 --- a/chrome/browser/extensions/api/passwords_private/test_passwords_private_delegate.h +++ b/chrome/browser/extensions/api/passwords_private/test_passwords_private_delegate.h
@@ -97,7 +97,9 @@ void ShowAddShortcutDialog(content::WebContents* web_contents) override; void ShowExportedFileInShell(content::WebContents* web_contents, std::string file_path) override; - void ChangePasswordManagerPin(content::WebContents* web_contents) override; + void ChangePasswordManagerPin( + content::WebContents* web_contents, + base::OnceCallback<void(bool)> success_callback) override; bool IsPasswordManagerPinAvailable( content::WebContents* web_contents) override; base::WeakPtr<PasswordsPrivateDelegate> AsWeakPtr() override;
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 3835783..2a053a9 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -3653,12 +3653,12 @@ { "name": "enable-save-to-drive", "owners": [ "qpubert@google.com", "djean@google.com", "olivierrobin@google.com", "bling-flags@google.com" ], - "expiry_milestone": 125 + "expiry_milestone": 128 }, { "name": "enable-save-to-photos", "owners": [ "qpubert@google.com", "djean@google.com", "bling-flags@google.com" ], - "expiry_milestone": 125 + "expiry_milestone": 128 }, { "name": "enable-seamless-refresh-rate-switching", @@ -5021,7 +5021,7 @@ { "name": "intents-on-measurements", "owners": [ "djean@google.com", "erahmaoui@google.com", "bling-flags@google.com" ], - "expiry_milestone": 125 + "expiry_milestone": 128 }, { "name": "intents-on-viewport",
diff --git a/chrome/browser/model_execution/android/java/src/org/chromium/chrome/browser/model_execution/ExecutionResult.java b/chrome/browser/model_execution/android/java/src/org/chromium/chrome/browser/model_execution/ExecutionResult.java index 2660031..094547cf 100644 --- a/chrome/browser/model_execution/android/java/src/org/chromium/chrome/browser/model_execution/ExecutionResult.java +++ b/chrome/browser/model_execution/android/java/src/org/chromium/chrome/browser/model_execution/ExecutionResult.java
@@ -42,7 +42,7 @@ * @param errorCode A value from {@code ExecutionError} */ @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) - ExecutionResult(@ExecutionError int errorCode) { + public ExecutionResult(@ExecutionError int errorCode) { mIsCompleteResult = false; mErrorCode = Optional.of(errorCode); mResponse = null;
diff --git a/chrome/browser/predictors/loading_predictor_browsertest.cc b/chrome/browser/predictors/loading_predictor_browsertest.cc index 433929d..39660e7 100644 --- a/chrome/browser/predictors/loading_predictor_browsertest.cc +++ b/chrome/browser/predictors/loading_predictor_browsertest.cc
@@ -680,9 +680,6 @@ } } - void OnPrefetchNetworkBytesChanged( - prerender::NoStatePrefetchHandle* handle) override {} - private: base::OnceClosure on_stop_closure_; };
diff --git a/chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_unittest.cc b/chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_unittest.cc index 234e619f..2282503 100644 --- a/chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_unittest.cc +++ b/chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_unittest.cc
@@ -69,7 +69,7 @@ class TestNetworkBytesChangedObserver : public prerender::NoStatePrefetchHandle::Observer { public: - TestNetworkBytesChangedObserver() : network_bytes_changed_(false) {} + TestNetworkBytesChangedObserver() = default; TestNetworkBytesChangedObserver(const TestNetworkBytesChangedObserver&) = delete; @@ -79,15 +79,6 @@ // prerender::NoStatePrefetchHandle::Observer void OnPrefetchStop( NoStatePrefetchHandle* no_state_prefetch_handle) override {} - void OnPrefetchNetworkBytesChanged( - NoStatePrefetchHandle* no_state_prefetch_handle) override { - network_bytes_changed_ = true; - } - - bool network_bytes_changed() const { return network_bytes_changed_; } - - private: - bool network_bytes_changed_; }; const gfx::Size kDefaultViewSize(640, 480); @@ -1128,33 +1119,6 @@ ASSERT_EQ(no_state_prefetch_contents, entry.get()); } -TEST_F(NoStatePrefetchTest, PrerenderAllowedForForcedCellular) { - EnablePrerender(); - std::unique_ptr<net::NetworkChangeNotifier> mock( - new MockNetworkChangeNotifier4GMetered); - EXPECT_TRUE(net::NetworkChangeNotifier::IsConnectionCellular( - net::NetworkChangeNotifier::GetConnectionType())); - GURL url("http://www.google.com/"); - FakeNoStatePrefetchContents* no_state_prefetch_contents = nullptr; - std::unique_ptr<NoStatePrefetchHandle> no_state_prefetch_handle; - no_state_prefetch_contents = - no_state_prefetch_manager()->CreateNextNoStatePrefetchContents( - url, std::nullopt, ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER, - FINAL_STATUS_USED); - no_state_prefetch_handle = - no_state_prefetch_manager()->AddForcedPrerenderFromExternalRequest( - url, content::Referrer(), nullptr, gfx::Rect(kDefaultViewSize)); - EXPECT_TRUE(no_state_prefetch_handle); - EXPECT_TRUE(no_state_prefetch_handle->IsPrefetching()); - EXPECT_TRUE(no_state_prefetch_contents->prefetching_has_started()); - EXPECT_EQ(no_state_prefetch_contents, no_state_prefetch_handle->contents()); - EXPECT_EQ(ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER, - no_state_prefetch_handle->contents()->origin()); - std::unique_ptr<NoStatePrefetchContents> entry = - no_state_prefetch_manager()->FindAndUseEntry(url); - ASSERT_EQ(no_state_prefetch_contents, entry.get()); -} - TEST_F(NoStatePrefetchTest, LinkManagerCancel) { EXPECT_TRUE(IsEmptyNoStatePrefetchLinkManager()); GURL url("http://www.myexample.com"); @@ -1519,24 +1483,6 @@ EXPECT_FALSE(IsValidHttpMethod("WHATEVER")); } -TEST_F(NoStatePrefetchTest, NoStatePrefetchContentsIncrementsByteCount) { - GURL url("http://www.google.com/"); - FakeNoStatePrefetchContents* no_state_prefetch_contents = - no_state_prefetch_manager()->CreateNextNoStatePrefetchContents( - url, std::nullopt, ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER, - FINAL_STATUS_PROFILE_DESTROYED); - std::unique_ptr<NoStatePrefetchHandle> no_state_prefetch_handle = - no_state_prefetch_manager()->AddForcedPrerenderFromExternalRequest( - url, content::Referrer(), nullptr, gfx::Rect(kDefaultViewSize)); - - TestNetworkBytesChangedObserver observer; - no_state_prefetch_handle->SetObserver(&observer); - - no_state_prefetch_contents->AddNetworkBytes(12); - EXPECT_TRUE(observer.network_bytes_changed()); - EXPECT_EQ(12, no_state_prefetch_contents->network_bytes()); -} - TEST_F(NoStatePrefetchTest, NoPrerenderInSingleProcess) { GURL url("http://www.google.com/"); auto* command_line = base::CommandLine::ForCurrentProcess();
diff --git a/chrome/browser/preloading/prerender/prerender_browsertest.cc b/chrome/browser/preloading/prerender/prerender_browsertest.cc index f48ebd69..4e954ca 100644 --- a/chrome/browser/preloading/prerender/prerender_browsertest.cc +++ b/chrome/browser/preloading/prerender/prerender_browsertest.cc
@@ -785,7 +785,7 @@ } IN_PROC_BROWSER_TEST_P(PrerenderNewTabPageBrowserTest, - PrerenderTriggeredCanceled) { + PrerenderTriggeredCancelAndRetrigger) { base::HistogramTester histogram_tester; // Navigate to an initial page. @@ -807,6 +807,25 @@ histogram_tester.ExpectUniqueSample( "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_NewTabPage", kFinalStatusTriggerDestroyed, 1); + + // Retrigger after cancelation. + EXPECT_TRUE( + prerender_manager->StartPrerenderNewTabPage(prerender_url, GetParam())); + content::test::PrerenderTestHelper::WaitForPrerenderLoadCompletion( + *GetActiveWebContents(), prerender_url); + + // Activate. + content::TestActivationManager activation_manager(GetActiveWebContents(), + prerender_url); + SimulateNewTabNavigation(prerender_url); + activation_manager.WaitForNavigationFinished(); + EXPECT_TRUE(activation_manager.was_activated()); + + histogram_tester.ExpectBucketCount( + "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_NewTabPage", + kFinalStatusActivated, 1); + histogram_tester.ExpectTotalCount( + "NewTabPage.PrerenderNavigationToActivation", 1); } IN_PROC_BROWSER_TEST_P(PrerenderNewTabPageBrowserTest,
diff --git a/chrome/browser/resources/password_manager/password_manager_proxy.ts b/chrome/browser/resources/password_manager/password_manager_proxy.ts index 159afe7..c3c7e2a 100644 --- a/chrome/browser/resources/password_manager/password_manager_proxy.ts +++ b/chrome/browser/resources/password_manager/password_manager_proxy.ts
@@ -382,7 +382,7 @@ dismissSafetyHubPasswordMenuNotification(): void; /** Starts the flow for changing Password Manager PIN. */ - changePasswordManagerPin(): void; + changePasswordManagerPin(): Promise<boolean>; /** Checks whether changing the Password Manager PIN is possible. */ isPasswordManagerPinAvailable(): Promise<boolean>; @@ -616,7 +616,7 @@ } changePasswordManagerPin() { - chrome.passwordsPrivate.changePasswordManagerPin(); + return chrome.passwordsPrivate.changePasswordManagerPin(); } isPasswordManagerPinAvailable() {
diff --git a/chrome/browser/resources/password_manager/settings_section.html b/chrome/browser/resources/password_manager/settings_section.html index ea565ff..90053a76 100644 --- a/chrome/browser/resources/password_manager/settings_section.html +++ b/chrome/browser/resources/password_manager/settings_section.html
@@ -186,3 +186,6 @@ trigger="[[getMovePasswordsDialogTrigger_()]]"> </move-passwords-dialog> </template> +<cr-toast id="toast" duration="5000"> + <span id="toast-message">$i18n{passwordManagerPinChanged}</span> +</cr-toast>
diff --git a/chrome/browser/resources/password_manager/settings_section.ts b/chrome/browser/resources/password_manager/settings_section.ts index c9435d6..ba40f09 100644 --- a/chrome/browser/resources/password_manager/settings_section.ts +++ b/chrome/browser/resources/password_manager/settings_section.ts
@@ -12,6 +12,7 @@ import {PrefsMixin} from '/shared/settings/prefs/prefs_mixin.js'; import {HelpBubbleMixin} from 'chrome://resources/cr_components/help_bubble/help_bubble_mixin.js'; import type {CrLinkRowElement} from 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js'; +import type {CrToastElement} from 'chrome://resources/cr_elements/cr_toast/cr_toast.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {WebUiListenerMixin} from 'chrome://resources/cr_elements/web_ui_listener_mixin.js'; import {assert, assertNotReached} from 'chrome://resources/js/assert.js'; @@ -41,6 +42,7 @@ passwordToggle: PrefToggleButtonElement, trustedVaultBanner: CrLinkRowElement, accountStorageToggle: PrefToggleButtonElement, + toast: CrToastElement, }; } @@ -227,6 +229,7 @@ PasswordManagerImpl.getInstance().removeSavedPasswordListChangedListener( this.setCredentialsChangedListener_); this.setCredentialsChangedListener_ = null; + this.$.toast.hide(); } override currentRouteChanged(route: Route): void { @@ -399,7 +402,15 @@ } private onChangePasswordManagerPinRowClick_() { - PasswordManagerImpl.getInstance().changePasswordManagerPin(); + PasswordManagerImpl.getInstance().changePasswordManagerPin().then( + this.showToastForPasswordChange_.bind(this)); + } + + private showToastForPasswordChange_(success: boolean): void { + if (!success) { + return; + } + this.$.toast.show(); } }
diff --git a/chrome/browser/resources/settings/privacy_page/cookies_page.ts b/chrome/browser/resources/settings/privacy_page/cookies_page.ts index 08ad525..a6bebec 100644 --- a/chrome/browser/resources/settings/privacy_page/cookies_page.ts +++ b/chrome/browser/resources/settings/privacy_page/cookies_page.ts
@@ -39,7 +39,6 @@ import type {Route} from '../router.js'; import {RouteObserverMixin, Router} from '../router.js'; import {ContentSetting, ContentSettingsTypes, CookieControlsMode} from '../site_settings/constants.js'; -import {CookiePrimarySetting} from '../site_settings/site_settings_prefs_browser_proxy.js'; import {getTemplate} from './cookies_page.html.js'; @@ -80,14 +79,6 @@ value: '', }, - /** - * Primary cookie control states for use in bindings. - */ - cookiePrimarySettingEnum_: { - type: Object, - value: CookiePrimarySetting, - }, - /** Cookie control modes for use in bindings. */ cookieControlsModeEnum_: { type: Object,
diff --git a/chrome/browser/resources/settings/site_settings/add_site_dialog.ts b/chrome/browser/resources/settings/site_settings/add_site_dialog.ts index 277c70dd..54d29f3 100644 --- a/chrome/browser/resources/settings/site_settings/add_site_dialog.ts +++ b/chrome/browser/resources/settings/site_settings/add_site_dialog.ts
@@ -23,7 +23,7 @@ import {loadTimeData} from '../i18n_setup.js'; import {getTemplate} from './add_site_dialog.html.js'; -import {ContentSetting, CookiesExceptionType, SITE_EXCEPTION_WILDCARD} from './constants.js'; +import {ContentSetting, ContentSettingsTypes, CookiesExceptionType, SITE_EXCEPTION_WILDCARD} from './constants.js'; import type {SiteSettingsMixinInterface} from './site_settings_mixin.js'; import {SiteSettingsMixin} from './site_settings_mixin.js'; @@ -133,7 +133,8 @@ let primaryPattern = this.site_; let secondaryPattern = SITE_EXCEPTION_WILDCARD; - if (this.cookiesExceptionType === CookiesExceptionType.THIRD_PARTY) { + if (this.cookiesExceptionType === CookiesExceptionType.THIRD_PARTY || + this.category === ContentSettingsTypes.TRACKING_PROTECTION) { primaryPattern = SITE_EXCEPTION_WILDCARD; secondaryPattern = this.site_; }
diff --git a/chrome/browser/resources/settings/site_settings/site_list_entry.ts b/chrome/browser/resources/settings/site_settings/site_list_entry.ts index dff3326c..9baa103 100644 --- a/chrome/browser/resources/settings/site_settings/site_list_entry.ts +++ b/chrome/browser/resources/settings/site_settings/site_list_entry.ts
@@ -185,8 +185,9 @@ */ private computeDisplayName_(): string { if (this.model.embeddingOrigin && - this.model.category === ContentSettingsTypes.COOKIES && - this.model.origin.trim() === SITE_EXCEPTION_WILDCARD) { + ((this.model.category === ContentSettingsTypes.COOKIES && + this.model.origin.trim() === SITE_EXCEPTION_WILDCARD) || + this.model.category === ContentSettingsTypes.TRACKING_PROTECTION)) { return this.model.embeddingOrigin; } return this.model.displayName; @@ -232,7 +233,8 @@ description = loadTimeData.getString( 'siteSettingsCookiesThirdPartyExceptionLabel'); } - } else { + } else if ( + this.model.category !== ContentSettingsTypes.TRACKING_PROTECTION) { description = loadTimeData.getStringF( 'embeddedOnHost', this.sanitizePort(this.model.embeddingOrigin)); }
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/page_info_sheet/PageInfoBottomSheetMediator.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/page_info_sheet/PageInfoBottomSheetMediator.java index c50a62a..71ece57 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/page_info_sheet/PageInfoBottomSheetMediator.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/page_info_sheet/PageInfoBottomSheetMediator.java
@@ -9,6 +9,7 @@ import org.chromium.chrome.browser.share.page_info_sheet.PageInfoBottomSheetCoordinator.PageInfoContents; import org.chromium.chrome.browser.share.page_info_sheet.PageInfoBottomSheetProperties.PageInfoState; +import org.chromium.chrome.browser.share.page_info_sheet.PageSummaryMetrics.PageSummarySheetEvents; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.SheetState; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.StateChangeReason; @@ -96,20 +97,41 @@ case StateChangeReason.BACK_PRESS, StateChangeReason.SWIPE, StateChangeReason.TAP_SCRIM -> { - mPageInfoDelegate.onCancel(); - destroySheet(); + dismissSheet(); } } } private void onAcceptClicked(View view) { mPageInfoDelegate.onAccept(); - destroySheet(); } private void onCancelClicked(View view) { + dismissSheet(); + } + + private void dismissSheet() { + recordStateOnDismiss(); mPageInfoDelegate.onCancel(); - destroySheet(); + } + + private void recordStateOnDismiss() { + @PageInfoState int state = mModel.get(PageInfoBottomSheetProperties.STATE); + @PageSummarySheetEvents + int stateOnDismiss = PageSummarySheetEvents.CLOSE_SHEET_WHILE_INITIALIZING; + switch (state) { + case PageInfoState.ERROR: + stateOnDismiss = PageSummarySheetEvents.CLOSE_SHEET_ON_ERROR; + break; + case PageInfoState.LOADING: + stateOnDismiss = PageSummarySheetEvents.CLOSE_SHEET_WHILE_LOADING; + break; + case PageInfoState.SUCCESS: + stateOnDismiss = PageSummarySheetEvents.CLOSE_SHEET_AFTER_SUCCESS; + break; + } + + PageSummaryMetrics.recordSummarySheetEvent(stateOnDismiss); } @Override
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/page_info_sheet/PageInfoSharingControllerImpl.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/page_info_sheet/PageInfoSharingControllerImpl.java index 6c7faf6b..e8d7714 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/page_info_sheet/PageInfoSharingControllerImpl.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/page_info_sheet/PageInfoSharingControllerImpl.java
@@ -22,6 +22,7 @@ import org.chromium.chrome.browser.model_execution.ModelExecutionSession; import org.chromium.chrome.browser.share.ChromeShareExtras; import org.chromium.chrome.browser.share.page_info_sheet.PageInfoBottomSheetCoordinator.PageInfoContents; +import org.chromium.chrome.browser.share.page_info_sheet.PageSummaryMetrics.PageSummarySheetEvents; import org.chromium.chrome.browser.share.page_info_sheet.PageSummaryMetrics.ShareActionVisibility; import org.chromium.chrome.browser.share.share_sheet.ChromeOptionShareCallback; import org.chromium.chrome.browser.tab.Tab; @@ -109,6 +110,7 @@ ChromeOptionShareCallback chromeOptionShareCallback, HelpAndFeedbackLauncher helpAndFeedbackLauncher, Tab tab) { + PageSummaryMetrics.recordSummarySheetEvent(PageSummarySheetEvents.OPEN_SUMMARY_SHEET); if (!shouldShowInShareSheetInternal(tab, false)) return; if (sErrorMessage == null) { // TODO(salg): Improve the way this resource is fetched. @@ -192,6 +194,7 @@ @Override public void shareWithoutPageInfo(ChromeOptionShareCallback chromeOptionShareCallback, Tab tab) { + PageSummaryMetrics.recordSummarySheetEvent(PageSummarySheetEvents.REMOVE_SUMMARY); ShareParams shareParams = new ShareParams.Builder( tab.getWindowAndroid(), tab.getTitle(), tab.getUrl().getSpec())
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/page_info_sheet/PageSummaryMetrics.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/page_info_sheet/PageSummaryMetrics.java index d413372..0cb7d0f 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/page_info_sheet/PageSummaryMetrics.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/page_info_sheet/PageSummaryMetrics.java
@@ -34,8 +34,48 @@ int COUNT = 7; } + // These values must match the PageSummarySheetEvents enum in enums.xml. + // Only add new values at the end, right before COUNT. + @IntDef({ + PageSummarySheetEvents.OPEN_SUMMARY_SHEET, + PageSummarySheetEvents.CLOSE_SHEET_WHILE_INITIALIZING, + PageSummarySheetEvents.CLOSE_SHEET_WHILE_LOADING, + PageSummarySheetEvents.CLOSE_SHEET_ON_ERROR, + PageSummarySheetEvents.CLOSE_SHEET_AFTER_SUCCESS, + PageSummarySheetEvents.ADD_SUMMARY, + PageSummarySheetEvents.REMOVE_SUMMARY, + PageSummarySheetEvents.CLICK_POSITIVE_FEEDBACK, + PageSummarySheetEvents.CLICK_NEGATIVE_FEEDBACK, + PageSummarySheetEvents.NEGATIVE_FEEDBACK_TYPE_SELECTED, + PageSummarySheetEvents.NEGATIVE_FEEDBACK_SHEET_DISMISSED, + PageSummarySheetEvents.CLICK_LEARN_MORE, + PageSummarySheetEvents.COUNT, + }) + @interface PageSummarySheetEvents { + int OPEN_SUMMARY_SHEET = 0; + int CLOSE_SHEET_WHILE_INITIALIZING = 1; + int CLOSE_SHEET_WHILE_LOADING = 2; + int CLOSE_SHEET_ON_ERROR = 3; + int CLOSE_SHEET_AFTER_SUCCESS = 4; + int ADD_SUMMARY = 5; + int REMOVE_SUMMARY = 6; + int CLICK_POSITIVE_FEEDBACK = 7; + int CLICK_NEGATIVE_FEEDBACK = 8; + int NEGATIVE_FEEDBACK_TYPE_SELECTED = 9; + int NEGATIVE_FEEDBACK_SHEET_DISMISSED = 10; + int CLICK_LEARN_MORE = 11; + int COUNT = 12; + } + static final String SHARE_SHEET_VISIBILITY_HISTOGRAM = "Android.PageSummary.Share.IsVisibleInShareSheet"; + static final String SUMMARY_SHEET_UI_EVENTS = "Sharing.AndroidPageSummary.SheetEvents"; + + /** Records UI events related to the page summary sharing flow. */ + public static void recordSummarySheetEvent(@PageSummarySheetEvents int event) { + RecordHistogram.recordEnumeratedHistogram( + SUMMARY_SHEET_UI_EVENTS, event, PageSummarySheetEvents.COUNT); + } /** * Records whether the page summary option is shown on a share sheet, and if not the reason why.
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/page_info_sheet/PageSummarySharingRequest.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/page_info_sheet/PageSummarySharingRequest.java index c006e11..8696a002 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/page_info_sheet/PageSummarySharingRequest.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/page_info_sheet/PageSummarySharingRequest.java
@@ -26,6 +26,7 @@ import org.chromium.chrome.browser.share.ChromeShareExtras.DetailedContentType; import org.chromium.chrome.browser.share.page_info_sheet.PageInfoBottomSheetCoordinator.Delegate; import org.chromium.chrome.browser.share.page_info_sheet.PageInfoBottomSheetCoordinator.PageInfoContents; +import org.chromium.chrome.browser.share.page_info_sheet.PageSummaryMetrics.PageSummarySheetEvents; import org.chromium.chrome.browser.share.page_info_sheet.feedback.FeedbackSheetCoordinator; import org.chromium.chrome.browser.share.page_info_sheet.feedback.FeedbackSheetCoordinator.FeedbackOption; import org.chromium.chrome.browser.share.share_sheet.ChromeOptionShareCallback; @@ -96,26 +97,38 @@ new Delegate() { @Override public void onAccept() { + PageSummaryMetrics.recordSummarySheetEvent( + PageSummarySheetEvents.ADD_SUMMARY); attachSummaryToShareSheet(); } @Override public void onCancel() { + // Calls to PageSummaryMetrics.recordSummarySheetEvent on + // cancellation/dismiss are handled inside + // PageInfoBottomSheetMediator because they record the sheet's + // internal state. destroy(); } @Override public void onLearnMore() { + PageSummaryMetrics.recordSummarySheetEvent( + PageSummarySheetEvents.CLICK_LEARN_MORE); openLearnMorePage(); } @Override public void onPositiveFeedback() { + PageSummaryMetrics.recordSummarySheetEvent( + PageSummarySheetEvents.CLICK_POSITIVE_FEEDBACK); // TODO(salg): Record a histogram. } @Override public void onNegativeFeedback() { + PageSummaryMetrics.recordSummarySheetEvent( + PageSummarySheetEvents.CLICK_NEGATIVE_FEEDBACK); openFeedbackSheet(); } @@ -142,12 +155,16 @@ new FeedbackSheetCoordinator.Delegate() { @Override public void onAccepted(String selectedType) { + PageSummaryMetrics.recordSummarySheetEvent( + PageSummarySheetEvents.NEGATIVE_FEEDBACK_TYPE_SELECTED); openSystemFeedbackSheet(selectedType); destroy(); } @Override public void onCanceled() { + PageSummaryMetrics.recordSummarySheetEvent( + PageSummarySheetEvents.NEGATIVE_FEEDBACK_SHEET_DISMISSED); destroyFeedbackSheet(); openPageSummarySheet(); }
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/page_info_sheet/PageInfoSharingControllerUnitTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/page_info_sheet/PageInfoSharingControllerUnitTest.java index bc817b8..b42aeb3 100644 --- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/page_info_sheet/PageInfoSharingControllerUnitTest.java +++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/page_info_sheet/PageInfoSharingControllerUnitTest.java
@@ -68,10 +68,12 @@ import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncher; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.model_execution.ExecutionResult; +import org.chromium.chrome.browser.model_execution.ExecutionResult.ExecutionError; import org.chromium.chrome.browser.model_execution.ModelExecutionSession; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.share.ChromeShareExtras; import org.chromium.chrome.browser.share.ChromeShareExtras.DetailedContentType; +import org.chromium.chrome.browser.share.page_info_sheet.PageSummaryMetrics.PageSummarySheetEvents; import org.chromium.chrome.browser.share.page_info_sheet.PageSummaryMetrics.ShareActionVisibility; import org.chromium.chrome.browser.share.share_sheet.ChromeOptionShareCallback; import org.chromium.chrome.browser.tab.Tab; @@ -136,6 +138,18 @@ .setModelExecutionSessionForTesting(mModelExecutionSession); } + private void setInnerTextExtractionResult(String innerText) { + doAnswer( + invocationOnMock -> { + Callback<Optional<String>> innerTextCallback = + invocationOnMock.getArgument(1); + innerTextCallback.onResult(Optional.of(innerText)); + return null; + }) + .when(mInnerTextJniMock) + .getInnerText(any(), any()); + } + /** * Sets up and starts a summarization flow for {@code tab} and invokes the result callbacks that * move the UI into the success state, where the result can be shared and feedback can be @@ -150,15 +164,7 @@ when(mPageInfoSharingBridgeJni.doesProfileSupportPageInfo(mProfile)).thenReturn(true); when(mPageInfoSharingBridgeJni.doesTabSupportPageInfo(tab)).thenReturn(true); when(mModelExecutionSession.isAvailable()).thenReturn(true); - doAnswer( - invocationOnMock -> { - Callback<Optional<String>> innerTextCallback = - invocationOnMock.getArgument(1); - innerTextCallback.onResult(Optional.of("Inner text of web page")); - return null; - }) - .when(mInnerTextJniMock) - .getInnerText(any(), any()); + setInnerTextExtractionResult("Inner text of web page"); PageInfoSharingControllerImpl.getInstance() .sharePageInfo( @@ -317,6 +323,10 @@ Tab tab = createMockTab(JUnitTestGURLs.EXAMPLE_URL); when(mPageInfoSharingBridgeJni.doesProfileSupportPageInfo(mProfile)).thenReturn(true); when(mPageInfoSharingBridgeJni.doesTabSupportPageInfo(tab)).thenReturn(true); + var histogramWatcher = + HistogramWatcher.newSingleRecordWatcher( + PageSummaryMetrics.SUMMARY_SHEET_UI_EVENTS, + PageSummarySheetEvents.OPEN_SUMMARY_SHEET); var activityScenario = mActivityScenarioRule.getScenario(); activityScenario.onActivity( @@ -329,6 +339,199 @@ mMockFeedbackLauncher, tab); verify(mBottomSheetController).requestShowContent(any(), anyBoolean()); + histogramWatcher.assertExpected(); + }); + } + + @Test + public void testDismissDialog_whileInitializing() { + when(mModelExecutionSession.isAvailable()).thenReturn(true); + Tab tab = createMockTab(JUnitTestGURLs.EXAMPLE_URL); + when(mPageInfoSharingBridgeJni.doesProfileSupportPageInfo(mProfile)).thenReturn(true); + when(mPageInfoSharingBridgeJni.doesTabSupportPageInfo(tab)).thenReturn(true); + var histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord( + PageSummaryMetrics.SUMMARY_SHEET_UI_EVENTS, + PageSummarySheetEvents.OPEN_SUMMARY_SHEET) + .expectIntRecord( + PageSummaryMetrics.SUMMARY_SHEET_UI_EVENTS, + PageSummarySheetEvents.CLOSE_SHEET_WHILE_INITIALIZING) + .build(); + + var activityScenario = mActivityScenarioRule.getScenario(); + activityScenario.onActivity( + activity -> { + ArgumentCaptor<BottomSheetContent> bottomSheetContentCaptor = + ArgumentCaptor.forClass(BottomSheetContent.class); + + PageInfoSharingControllerImpl.getInstance() + .sharePageInfo( + activity, + mBottomSheetController, + mChromeOptionShareCallback, + mMockFeedbackLauncher, + tab); + + verify(mBottomSheetController) + .requestShowContent(bottomSheetContentCaptor.capture(), anyBoolean()); + BottomSheetContent sheetContent = bottomSheetContentCaptor.getValue(); + View cancelButton = + sheetContent.getContentView().findViewById(R.id.cancel_button); + + cancelButton.performClick(); + + verify(mBottomSheetController).hideContent(sheetContent, true); + histogramWatcher.assertExpected(); + }); + } + + @Test + public void testDismissDialog_whileLoading() { + when(mModelExecutionSession.isAvailable()).thenReturn(true); + Tab tab = createMockTab(JUnitTestGURLs.EXAMPLE_URL); + when(mPageInfoSharingBridgeJni.doesProfileSupportPageInfo(mProfile)).thenReturn(true); + when(mPageInfoSharingBridgeJni.doesTabSupportPageInfo(tab)).thenReturn(true); + setInnerTextExtractionResult("Inner text of web page"); + var histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord( + PageSummaryMetrics.SUMMARY_SHEET_UI_EVENTS, + PageSummarySheetEvents.OPEN_SUMMARY_SHEET) + .expectIntRecord( + PageSummaryMetrics.SUMMARY_SHEET_UI_EVENTS, + PageSummarySheetEvents.CLOSE_SHEET_WHILE_LOADING) + .build(); + + var activityScenario = mActivityScenarioRule.getScenario(); + activityScenario.onActivity( + activity -> { + ArgumentCaptor<Callback<ExecutionResult>> modelExecutionCallbackCaptor = + ArgumentCaptor.forClass(Callback.class); + ArgumentCaptor<BottomSheetContent> bottomSheetContentCaptor = + ArgumentCaptor.forClass(BottomSheetContent.class); + + PageInfoSharingControllerImpl.getInstance() + .sharePageInfo( + activity, + mBottomSheetController, + mChromeOptionShareCallback, + mMockFeedbackLauncher, + tab); + + verify(mBottomSheetController) + .requestShowContent(bottomSheetContentCaptor.capture(), anyBoolean()); + verify(mModelExecutionSession) + .executeModel(anyString(), modelExecutionCallbackCaptor.capture()); + + Callback<ExecutionResult> executionResultCallback = + modelExecutionCallbackCaptor.getValue(); + + // Call model execution callback with a single partial streaming result. + executionResultCallback.onResult( + new ExecutionResult("Test", /* isCompleteResult= */ false)); + ShadowLooper.runUiThreadTasks(); + + BottomSheetContent sheetContent = bottomSheetContentCaptor.getValue(); + View cancelButton = + sheetContent.getContentView().findViewById(R.id.cancel_button); + + cancelButton.performClick(); + + verify(mBottomSheetController).hideContent(sheetContent, true); + histogramWatcher.assertExpected(); + }); + } + + @Test + public void testDismissDialog_afterError() { + when(mModelExecutionSession.isAvailable()).thenReturn(true); + Tab tab = createMockTab(JUnitTestGURLs.EXAMPLE_URL); + when(mPageInfoSharingBridgeJni.doesProfileSupportPageInfo(mProfile)).thenReturn(true); + when(mPageInfoSharingBridgeJni.doesTabSupportPageInfo(tab)).thenReturn(true); + setInnerTextExtractionResult("Inner text of web page"); + var histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord( + PageSummaryMetrics.SUMMARY_SHEET_UI_EVENTS, + PageSummarySheetEvents.OPEN_SUMMARY_SHEET) + .expectIntRecord( + PageSummaryMetrics.SUMMARY_SHEET_UI_EVENTS, + PageSummarySheetEvents.CLOSE_SHEET_ON_ERROR) + .build(); + + var activityScenario = mActivityScenarioRule.getScenario(); + activityScenario.onActivity( + activity -> { + ArgumentCaptor<Callback<ExecutionResult>> modelExecutionCallbackCaptor = + ArgumentCaptor.forClass(Callback.class); + ArgumentCaptor<BottomSheetContent> bottomSheetContentCaptor = + ArgumentCaptor.forClass(BottomSheetContent.class); + + PageInfoSharingControllerImpl.getInstance() + .sharePageInfo( + activity, + mBottomSheetController, + mChromeOptionShareCallback, + mMockFeedbackLauncher, + tab); + + verify(mBottomSheetController) + .requestShowContent(bottomSheetContentCaptor.capture(), anyBoolean()); + verify(mModelExecutionSession) + .executeModel(anyString(), modelExecutionCallbackCaptor.capture()); + + Callback<ExecutionResult> executionResultCallback = + modelExecutionCallbackCaptor.getValue(); + + // Call model execution callback with an error. + executionResultCallback.onResult( + new ExecutionResult(ExecutionError.NOT_AVAILABLE)); + ShadowLooper.runUiThreadTasks(); + + BottomSheetContent sheetContent = bottomSheetContentCaptor.getValue(); + View cancelButton = + sheetContent.getContentView().findViewById(R.id.cancel_button); + + cancelButton.performClick(); + + verify(mBottomSheetController).hideContent(sheetContent, true); + histogramWatcher.assertExpected(); + }); + } + + @Test + public void testDismissDialog_afterSuccessfulLoading() { + when(mModelExecutionSession.isAvailable()).thenReturn(true); + Tab tab = createMockTab(JUnitTestGURLs.EXAMPLE_URL); + when(mPageInfoSharingBridgeJni.doesProfileSupportPageInfo(mProfile)).thenReturn(true); + when(mPageInfoSharingBridgeJni.doesTabSupportPageInfo(tab)).thenReturn(true); + var histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord( + PageSummaryMetrics.SUMMARY_SHEET_UI_EVENTS, + PageSummarySheetEvents.OPEN_SUMMARY_SHEET) + .expectIntRecord( + PageSummaryMetrics.SUMMARY_SHEET_UI_EVENTS, + PageSummarySheetEvents.CLOSE_SHEET_AFTER_SUCCESS) + .build(); + + var activityScenario = mActivityScenarioRule.getScenario(); + activityScenario.onActivity( + activity -> { + ArgumentCaptor<BottomSheetContent> bottomSheetContentCaptor = + ArgumentCaptor.forClass(BottomSheetContent.class); + simulateSuccessfulSummarization(activity, tab, bottomSheetContentCaptor); + ShadowLooper.runUiThreadTasks(); + + BottomSheetContent sheetContent = bottomSheetContentCaptor.getValue(); + View cancelButton = + sheetContent.getContentView().findViewById(R.id.cancel_button); + + cancelButton.performClick(); + + verify(mBottomSheetController).hideContent(sheetContent, true); + histogramWatcher.assertExpected(); }); } @@ -374,17 +577,8 @@ Tab tab = createMockTab(JUnitTestGURLs.EXAMPLE_URL); when(mPageInfoSharingBridgeJni.doesProfileSupportPageInfo(mProfile)).thenReturn(true); when(mPageInfoSharingBridgeJni.doesTabSupportPageInfo(tab)).thenReturn(true); - RenderFrameHost mainFrame = tab.getWebContents().getMainFrame(); - doAnswer( - invocationOnMock -> { - Callback<Optional<String>> innerTextCallback = - invocationOnMock.getArgument(1); - innerTextCallback.onResult(Optional.of("Inner text of web page")); - return null; - }) - .when(mInnerTextJniMock) - .getInnerText(eq(mainFrame), any()); + setInnerTextExtractionResult("Inner text of web page"); var activityScenario = mActivityScenarioRule.getScenario(); activityScenario.onActivity( @@ -448,17 +642,17 @@ Tab tab = createMockTab(JUnitTestGURLs.EXAMPLE_URL); when(mPageInfoSharingBridgeJni.doesProfileSupportPageInfo(mProfile)).thenReturn(true); when(mPageInfoSharingBridgeJni.doesTabSupportPageInfo(tab)).thenReturn(true); - RenderFrameHost mainFrame = tab.getWebContents().getMainFrame(); + var histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord( + PageSummaryMetrics.SUMMARY_SHEET_UI_EVENTS, + PageSummarySheetEvents.OPEN_SUMMARY_SHEET) + .expectIntRecord( + PageSummaryMetrics.SUMMARY_SHEET_UI_EVENTS, + PageSummarySheetEvents.ADD_SUMMARY) + .build(); - doAnswer( - invocationOnMock -> { - Callback<Optional<String>> innerTextCallback = - invocationOnMock.getArgument(1); - innerTextCallback.onResult(Optional.of("Inner text of web page")); - return null; - }) - .when(mInnerTextJniMock) - .getInnerText(eq(mainFrame), any()); + setInnerTextExtractionResult("Inner text of web page"); var activityScenario = mActivityScenarioRule.getScenario(); activityScenario.onActivity( @@ -530,6 +724,7 @@ assertEquals( DetailedContentType.PAGE_INFO, chromeShareExtrasCaptor.getValue().getDetailedContentType()); + histogramWatcher.assertExpected(); }); } @@ -539,6 +734,18 @@ ArgumentCaptor.forClass(BottomSheetContent.class); Tab tab = createMockTab(JUnitTestGURLs.EXAMPLE_URL); String tabUrl = tab.getUrl().getSpec(); + var histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord( + PageSummaryMetrics.SUMMARY_SHEET_UI_EVENTS, + PageSummarySheetEvents.OPEN_SUMMARY_SHEET) + .expectIntRecord( + PageSummaryMetrics.SUMMARY_SHEET_UI_EVENTS, + PageSummarySheetEvents.CLICK_NEGATIVE_FEEDBACK) + .expectIntRecord( + PageSummaryMetrics.SUMMARY_SHEET_UI_EVENTS, + PageSummarySheetEvents.NEGATIVE_FEEDBACK_TYPE_SELECTED) + .build(); var activityScenario = mActivityScenarioRule.getScenario(); activityScenario.onActivity( @@ -584,6 +791,7 @@ // Feedback launcher should have been invoked. verify(mMockFeedbackLauncher) .showFeedback(eq(activity), eq(tabUrl), anyString(), any()); + histogramWatcher.assertExpected(); }); } @@ -592,6 +800,18 @@ ArgumentCaptor<BottomSheetContent> sheetContentCaptor = ArgumentCaptor.forClass(BottomSheetContent.class); Tab tab = createMockTab(JUnitTestGURLs.EXAMPLE_URL); + var histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord( + PageSummaryMetrics.SUMMARY_SHEET_UI_EVENTS, + PageSummarySheetEvents.OPEN_SUMMARY_SHEET) + .expectIntRecord( + PageSummaryMetrics.SUMMARY_SHEET_UI_EVENTS, + PageSummarySheetEvents.CLICK_NEGATIVE_FEEDBACK) + .expectIntRecord( + PageSummaryMetrics.SUMMARY_SHEET_UI_EVENTS, + PageSummarySheetEvents.NEGATIVE_FEEDBACK_SHEET_DISMISSED) + .build(); var activityScenario = mActivityScenarioRule.getScenario(); activityScenario.onActivity( @@ -635,6 +855,7 @@ // Feedback launcher shouldn't have been invoked. verifyNoInteractions(mMockFeedbackLauncher); + histogramWatcher.assertExpected(); }); } @@ -653,6 +874,15 @@ ArgumentCaptor.forClass(BottomSheetContent.class); Tab tab = createMockTab(JUnitTestGURLs.EXAMPLE_URL); + var histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord( + PageSummaryMetrics.SUMMARY_SHEET_UI_EVENTS, + PageSummarySheetEvents.OPEN_SUMMARY_SHEET) + .expectIntRecord( + PageSummaryMetrics.SUMMARY_SHEET_UI_EVENTS, + PageSummarySheetEvents.CLICK_LEARN_MORE) + .build(); var activityScenario = mActivityScenarioRule.getScenario(); activityScenario.onActivity( @@ -681,6 +911,7 @@ // Summary sheet should be closed. verify(mBottomSheetController).hideContent(summaryBottomSheetContent, true); + histogramWatcher.assertExpected(); }); } }
diff --git a/chrome/browser/touch_to_fill/autofill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillPaymentMethodControllerBridge.java b/chrome/browser/touch_to_fill/autofill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillPaymentMethodControllerBridge.java index 3807a3cb..8eaf2a93e 100644 --- a/chrome/browser/touch_to_fill/autofill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillPaymentMethodControllerBridge.java +++ b/chrome/browser/touch_to_fill/autofill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillPaymentMethodControllerBridge.java
@@ -59,10 +59,10 @@ } @Override - public void suggestionSelected(String uniqueId, boolean isVirtual) { + public void creditCardSuggestionSelected(String uniqueId, boolean isVirtual) { if (mNativeTouchToFillPaymentMethodViewController != 0) { TouchToFillPaymentMethodControllerBridgeJni.get() - .suggestionSelected( + .creditCardSuggestionSelected( mNativeTouchToFillPaymentMethodViewController, uniqueId, isVirtual); } } @@ -76,7 +76,7 @@ void showPaymentMethodSettings(long nativeTouchToFillPaymentMethodViewController); - void suggestionSelected( + void creditCardSuggestionSelected( long nativeTouchToFillPaymentMethodViewController, String uniqueId, boolean isVirtual);
diff --git a/chrome/browser/touch_to_fill/autofill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillPaymentMethodControllerRobolectricTest.java b/chrome/browser/touch_to_fill/autofill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillPaymentMethodControllerRobolectricTest.java index adf442b..0dafbb0 100644 --- a/chrome/browser/touch_to_fill/autofill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillPaymentMethodControllerRobolectricTest.java +++ b/chrome/browser/touch_to_fill/autofill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillPaymentMethodControllerRobolectricTest.java
@@ -25,11 +25,11 @@ import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillPaymentMethodProperties.CreditCardProperties.CARD_NUMBER; import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillPaymentMethodProperties.CreditCardProperties.NETWORK_NAME; import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillPaymentMethodProperties.CreditCardProperties.ON_CREDIT_CARD_CLICK_ACTION; -import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillPaymentMethodProperties.IbanProperties.IBAN_NICKNAME; -import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillPaymentMethodProperties.IbanProperties.IBAN_VALUE; import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillPaymentMethodProperties.DISMISS_HANDLER; import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillPaymentMethodProperties.FooterProperties.SCAN_CREDIT_CARD_CALLBACK; import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillPaymentMethodProperties.FooterProperties.SHOW_PAYMENT_METHOD_SETTINGS_CALLBACK; +import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillPaymentMethodProperties.IbanProperties.IBAN_NICKNAME; +import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillPaymentMethodProperties.IbanProperties.IBAN_VALUE; import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillPaymentMethodProperties.ItemType.CREDIT_CARD; import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillPaymentMethodProperties.ItemType.FILL_BUTTON; import static org.chromium.chrome.browser.touch_to_fill.payments.TouchToFillPaymentMethodProperties.ItemType.FOOTER; @@ -293,12 +293,14 @@ mClock.advanceCurrentTimeMillis( InputProtector.POTENTIALLY_UNINTENDED_INPUT_THRESHOLD - 100); cardModel.get().get(ON_CREDIT_CARD_CLICK_ACTION).run(); - verify(mDelegateMock, times(0)).suggestionSelected(VISA.getGUID(), VISA.getIsVirtual()); + verify(mDelegateMock, times(0)) + .creditCardSuggestionSelected(VISA.getGUID(), VISA.getIsVirtual()); // Clicking after the threshold should work. mClock.advanceCurrentTimeMillis(100); cardModel.get().get(ON_CREDIT_CARD_CLICK_ACTION).run(); - verify(mDelegateMock, times(1)).suggestionSelected(VISA.getGUID(), VISA.getIsVirtual()); + verify(mDelegateMock, times(1)) + .creditCardSuggestionSelected(VISA.getGUID(), VISA.getIsVirtual()); } @Test @@ -311,7 +313,7 @@ assertNotNull(cardModel.get().get(ON_CREDIT_CARD_CLICK_ACTION)); advanceClockAndClick(cardModel.get()); - verify(mDelegateMock).suggestionSelected(VISA.getGUID(), VISA.getIsVirtual()); + verify(mDelegateMock).creditCardSuggestionSelected(VISA.getGUID(), VISA.getIsVirtual()); assertEquals( 1, RecordHistogram.getHistogramValueCountForTesting( @@ -333,7 +335,7 @@ advanceClockAndClick(cardModel.get()); verify(mDelegateMock) - .suggestionSelected(VIRTUAL_CARD.getGUID(), VIRTUAL_CARD.getIsVirtual()); + .creditCardSuggestionSelected(VIRTUAL_CARD.getGUID(), VIRTUAL_CARD.getIsVirtual()); assertEquals( 1, RecordHistogram.getHistogramValueCountForTesting( @@ -406,7 +408,7 @@ mCoordinator.showSheet(new CreditCard[] {VISA}, false); ModelList itemList = mTouchToFillPaymentMethodModel.get(SHEET_ITEMS); advanceClockAndClick(getModelsOfType(itemList, FILL_BUTTON).get(0)); - verify(mDelegateMock).suggestionSelected(VISA.getGUID(), VISA.getIsVirtual()); + verify(mDelegateMock).creditCardSuggestionSelected(VISA.getGUID(), VISA.getIsVirtual()); } @Test
diff --git a/chrome/browser/touch_to_fill/autofill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillPaymentMethodMediator.java b/chrome/browser/touch_to_fill/autofill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillPaymentMethodMediator.java index f7450af..c6527db2 100644 --- a/chrome/browser/touch_to_fill/autofill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillPaymentMethodMediator.java +++ b/chrome/browser/touch_to_fill/autofill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillPaymentMethodMediator.java
@@ -209,7 +209,7 @@ public void onSelectedCreditCard(CreditCard card) { if (!mInputProtector.shouldInputBeProcessed()) return; - mDelegate.suggestionSelected(card.getGUID(), card.getIsVirtual()); + mDelegate.creditCardSuggestionSelected(card.getGUID(), card.getIsVirtual()); recordTouchToFillOutcomeHistogram( card.getIsVirtual() ? TouchToFillCreditCardOutcome.VIRTUAL_CARD
diff --git a/chrome/browser/touch_to_fill/autofill/android/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillPaymentMethodComponent.java b/chrome/browser/touch_to_fill/autofill/android/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillPaymentMethodComponent.java index fe14ca3e..bd20945 100644 --- a/chrome/browser/touch_to_fill/autofill/android/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillPaymentMethodComponent.java +++ b/chrome/browser/touch_to_fill/autofill/android/java/src/org/chromium/chrome/browser/touch_to_fill/payments/TouchToFillPaymentMethodComponent.java
@@ -32,7 +32,7 @@ * @param uniqueId A backend id of the card. * @param isVirtual A boolean to identify if the card is a virtual card. */ - void suggestionSelected(String uniqueId, boolean isVirtual); + void creditCardSuggestionSelected(String uniqueId, boolean isVirtual); } /**
diff --git a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl.cc b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl.cc index 17a4ca81..a78d81f 100644 --- a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl.cc +++ b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl.cc
@@ -269,8 +269,9 @@ manager_->client().ShowAutofillSettings(FillingProduct::kCreditCard); } -void TouchToFillDelegateAndroidImpl::SuggestionSelected(std::string unique_id, - bool is_virtual) { +void TouchToFillDelegateAndroidImpl::CreditCardSuggestionSelected( + std::string unique_id, + bool is_virtual) { HideTouchToFill(); PersonalDataManager* pdm = manager_->client().GetPersonalDataManager(); @@ -324,13 +325,13 @@ bool TouchToFillDelegateAndroidImpl::HasAnyAutofilledFields( const FormStructure& submitted_form) const { return base::ranges::any_of( - submitted_form, [](const auto& field) { return field->is_autofilled; }); + submitted_form, [](const auto& field) { return field->is_autofilled(); }); } bool TouchToFillDelegateAndroidImpl::IsFillingPerfect( const FormStructure& submitted_form) const { return base::ranges::all_of(submitted_form, [](const auto& field) { - return field->value().empty() || field->is_autofilled; + return field->value().empty() || field->is_autofilled(); }); }
diff --git a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl.h b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl.h index 9a14ba8..a098eaf 100644 --- a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl.h +++ b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl.h
@@ -126,7 +126,8 @@ void ScanCreditCard() override; void OnCreditCardScanned(const CreditCard& card) override; void ShowPaymentMethodSettings() override; - void SuggestionSelected(std::string unique_id, bool is_virtual) override; + void CreditCardSuggestionSelected(std::string unique_id, + bool is_virtual) override; void OnDismissed(bool dismissed_by_user) override; void LogMetricsAfterSubmission(const FormStructure& submitted_form) override;
diff --git a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl_unittest.cc b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl_unittest.cc index 3a9c9b9a..2edbeefa 100644 --- a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl_unittest.cc +++ b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_delegate_android_impl_unittest.cc
@@ -763,7 +763,8 @@ TryToShowTouchToFill(/*expected_success=*/true); EXPECT_CALL(autofill_client_, HideTouchToFillCreditCard).Times(1); - touch_to_fill_delegate_->SuggestionSelected(credit_card.guid(), false); + touch_to_fill_delegate_->CreditCardSuggestionSelected(credit_card.guid(), + false); } TEST_F(TouchToFillDelegateAndroidImplCreditCardUnitTest, @@ -777,7 +778,8 @@ TryToShowTouchToFill(/*expected_success=*/true); EXPECT_CALL(*browser_autofill_manager_, AuthenticateThenFillCreditCardForm); - touch_to_fill_delegate_->SuggestionSelected(credit_card.guid(), false); + touch_to_fill_delegate_->CreditCardSuggestionSelected(credit_card.guid(), + false); } TEST_F(TouchToFillDelegateAndroidImplCreditCardUnitTest, @@ -792,7 +794,8 @@ TryToShowTouchToFill(/*expected_success=*/true); EXPECT_CALL(*browser_autofill_manager_, AuthenticateThenFillCreditCardForm); - touch_to_fill_delegate_->SuggestionSelected(credit_card.guid(), true); + touch_to_fill_delegate_->CreditCardSuggestionSelected(credit_card.guid(), + true); } TEST_F(TouchToFillDelegateAndroidImplCreditCardUnitTest, @@ -803,7 +806,7 @@ // Simulate that the form was autofilled by other means FormStructure submitted_form(form_); for (const std::unique_ptr<AutofillField>& field : submitted_form) { - field->is_autofilled = true; + field->set_is_autofilled(true); } touch_to_fill_delegate_->LogMetricsAfterSubmission(submitted_form);
diff --git a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_controller.cc b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_controller.cc index f160055..022cfb9 100644 --- a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_controller.cc +++ b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_controller.cc
@@ -137,12 +137,12 @@ } } -void TouchToFillPaymentMethodController::SuggestionSelected( +void TouchToFillPaymentMethodController::CreditCardSuggestionSelected( JNIEnv* env, base::android::JavaParamRef<jstring> unique_id, bool is_virtual) { if (delegate_) { - delegate_->SuggestionSelected( + delegate_->CreditCardSuggestionSelected( base::android::ConvertJavaStringToUTF8(env, unique_id), is_virtual); } }
diff --git a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_controller.h b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_controller.h index c0680be..0c7a7c89e 100644 --- a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_controller.h +++ b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_controller.h
@@ -63,9 +63,10 @@ void OnDismissed(JNIEnv* env, bool dismissed_by_user) override; void ScanCreditCard(JNIEnv* env) override; void ShowPaymentMethodSettings(JNIEnv* env) override; - void SuggestionSelected(JNIEnv* env, - base::android::JavaParamRef<jstring> unique_id, - bool is_virtual) override; + void CreditCardSuggestionSelected( + JNIEnv* env, + base::android::JavaParamRef<jstring> unique_id, + bool is_virtual) override; TouchToFillKeyboardSuppressor& keyboard_suppressor_for_test() { return keyboard_suppressor_;
diff --git a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_controller_unittest.cc b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_controller_unittest.cc index 5c59dd8..850773f54 100644 --- a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_controller_unittest.cc +++ b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_controller_unittest.cc
@@ -69,7 +69,7 @@ MOCK_METHOD(void, OnCreditCardScanned, (const CreditCard& card), (override)); MOCK_METHOD(void, ShowPaymentMethodSettings, (), (override)); MOCK_METHOD(void, - SuggestionSelected, + CreditCardSuggestionSelected, (std::string unique_id, bool is_virtual), (override)); MOCK_METHOD(void, OnDismissed, (bool dismissed_by_user), (override));
diff --git a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_quality_metrics_unittest.cc b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_quality_metrics_unittest.cc index 7086aaf4..e300a0c2 100644 --- a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_quality_metrics_unittest.cc +++ b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_quality_metrics_unittest.cc
@@ -85,7 +85,7 @@ ASSERT_EQ(form.fields.size(), fields_have_autofilled_values.size()); ASSERT_EQ(form.fields.size(), field_types.size()); for (size_t i = 0; i < fields_have_autofilled_values.size(); i++) { - form.fields[i].is_autofilled = fields_have_autofilled_values[i]; + form.fields[i].set_is_autofilled(fields_have_autofilled_values[i]); CreditCard test_card = test::GetCreditCard(); form.fields[i].set_value(field_types[i] != CREDIT_CARD_VERIFICATION_CODE ? test_card.GetRawInfo(field_types[i]) @@ -126,8 +126,9 @@ base::HistogramTester histogram_tester; // Simulate user selection in the payments bottom sheet. - touch_to_fill_delegate().SuggestionSelected(/*unique_id=*/kTestLocalCardId, - /*is_virtual=*/false); + touch_to_fill_delegate().CreditCardSuggestionSelected( + /*unique_id=*/kTestLocalCardId, + /*is_virtual=*/false); touch_to_fill_delegate().OnDismissed(/*dismissed_by_user=*/false); // Simulate that fields were autofilled. SetFieldsAutofilledValues(form, test_case.fields_have_autofilled_values,
diff --git a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_view_controller.h b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_view_controller.h index 899cad7..b781291 100644 --- a/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_view_controller.h +++ b/chrome/browser/touch_to_fill/autofill/android/touch_to_fill_payment_method_view_controller.h
@@ -23,7 +23,7 @@ virtual void ScanCreditCard(JNIEnv* env) = 0; // Causes the payment methods settings page to be shown virtual void ShowPaymentMethodSettings(JNIEnv* env) = 0; - virtual void SuggestionSelected( + virtual void CreditCardSuggestionSelected( JNIEnv* env, base::android::JavaParamRef<jstring> unique_id, bool is_virtual) = 0;
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 6120157..4c41082a 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -824,8 +824,8 @@ "android/autofill/autofill_cvc_save_message_delegate.h", "android/autofill/autofill_error_dialog_view_android.cc", "android/autofill/autofill_error_dialog_view_android.h", - "android/autofill/autofill_keyboard_accessory_view.cc", - "android/autofill/autofill_keyboard_accessory_view.h", + "android/autofill/autofill_keyboard_accessory_view_impl.cc", + "android/autofill/autofill_keyboard_accessory_view_impl.h", "android/autofill/autofill_logger_android.cc", "android/autofill/autofill_logger_android.h", "android/autofill/autofill_progress_dialog_view_android.cc", @@ -958,6 +958,7 @@ "autofill/autofill_keyboard_accessory_controller.h", "autofill/autofill_keyboard_accessory_controller_impl.cc", "autofill/autofill_keyboard_accessory_controller_impl.h", + "autofill/autofill_keyboard_accessory_view.h", "autofill/payments/autofill_snackbar_controller.h", "autofill/payments/autofill_snackbar_controller_impl.cc", "autofill/payments/autofill_snackbar_controller_impl.h",
diff --git a/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view.cc b/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view_impl.cc similarity index 90% rename from chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view.cc rename to chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view_impl.cc index 95092508..ccc1da6 100644 --- a/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view.cc +++ b/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view_impl.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view.h" +#include "chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view_impl.h" #include <string> #include <utility> @@ -37,7 +37,7 @@ namespace autofill { -AutofillKeyboardAccessoryView::AutofillKeyboardAccessoryView( +AutofillKeyboardAccessoryViewImpl::AutofillKeyboardAccessoryViewImpl( base::WeakPtr<AutofillKeyboardAccessoryController> adapter, base::WeakPtr<AutofillKeyboardAccessoryController> controller) : adapter_(adapter), controller_(controller) { @@ -45,12 +45,12 @@ base::android::AttachCurrentThread())); } -AutofillKeyboardAccessoryView::~AutofillKeyboardAccessoryView() { +AutofillKeyboardAccessoryViewImpl::~AutofillKeyboardAccessoryViewImpl() { Java_AutofillKeyboardAccessoryViewBridge_resetNativeViewPointer( base::android::AttachCurrentThread(), java_object_); } -bool AutofillKeyboardAccessoryView::Initialize() { +bool AutofillKeyboardAccessoryViewImpl::Initialize() { if (!controller_) { return false; } @@ -66,13 +66,13 @@ return true; } -void AutofillKeyboardAccessoryView::Hide() { +void AutofillKeyboardAccessoryViewImpl::Hide() { TRACE_EVENT0("passwords", "AutofillKeyboardAccessoryView::Hide"); Java_AutofillKeyboardAccessoryViewBridge_dismiss( base::android::AttachCurrentThread(), java_object_); } -void AutofillKeyboardAccessoryView::Show() { +void AutofillKeyboardAccessoryViewImpl::Show() { TRACE_EVENT0("passwords", "AutofillKeyboardAccessoryView::Show"); if (!controller_) { return; @@ -122,11 +122,11 @@ Java_AutofillKeyboardAccessoryViewBridge_show(env, java_object_, data_array); } -void AutofillKeyboardAccessoryView::AxAnnounce(const std::u16string& text) { +void AutofillKeyboardAccessoryViewImpl::AxAnnounce(const std::u16string& text) { AnnounceTextForA11y(text); } -void AutofillKeyboardAccessoryView::ConfirmDeletion( +void AutofillKeyboardAccessoryViewImpl::ConfirmDeletion( const std::u16string& confirmation_title, const std::u16string& confirmation_body, base::OnceCallback<void(bool)> deletion_callback) { @@ -136,14 +136,14 @@ env, java_object_, confirmation_title, confirmation_body); } -void AutofillKeyboardAccessoryView::SuggestionSelected( +void AutofillKeyboardAccessoryViewImpl::SuggestionSelected( JNIEnv* env, const JavaParamRef<jobject>& obj, jint list_index) { adapter_->AcceptSuggestion(list_index); } -void AutofillKeyboardAccessoryView::DeletionRequested( +void AutofillKeyboardAccessoryViewImpl::DeletionRequested( JNIEnv* env, const JavaParamRef<jobject>& obj, jint list_index) { @@ -152,7 +152,7 @@ AutofillMetrics::SingleEntryRemovalMethod::kKeyboardAccessory); } -void AutofillKeyboardAccessoryView::OnDeletionDialogClosed( +void AutofillKeyboardAccessoryViewImpl::OnDeletionDialogClosed( JNIEnv* env, const JavaParamRef<jobject>& obj, jboolean confirmed) { @@ -163,7 +163,7 @@ std::move(deletion_callback_).Run(confirmed); } -void AutofillKeyboardAccessoryView::ViewDismissed( +void AutofillKeyboardAccessoryViewImpl::ViewDismissed( JNIEnv* env, const JavaParamRef<jobject>& obj) { adapter_->ViewDestroyed(); @@ -181,7 +181,7 @@ .GetWeakPtrToController(); auto adapter = std::make_unique<AutofillKeyboardAccessoryAdapter>(controller_weak); - auto accessory_view = std::make_unique<AutofillKeyboardAccessoryView>( + auto accessory_view = std::make_unique<AutofillKeyboardAccessoryViewImpl>( adapter->GetWeakPtrToAdapter(), controller_weak); if (!accessory_view->Initialize()) { return nullptr; // Don't create an adapter without initialized view.
diff --git a/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view.h b/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view_impl.h similarity index 84% rename from chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view.h rename to chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view_impl.h index b04a5be..97261e9 100644 --- a/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view.h +++ b/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view_impl.h
@@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_ANDROID_AUTOFILL_AUTOFILL_KEYBOARD_ACCESSORY_VIEW_H_ -#define CHROME_BROWSER_UI_ANDROID_AUTOFILL_AUTOFILL_KEYBOARD_ACCESSORY_VIEW_H_ +#ifndef CHROME_BROWSER_UI_ANDROID_AUTOFILL_AUTOFILL_KEYBOARD_ACCESSORY_VIEW_IMPL_H_ +#define CHROME_BROWSER_UI_ANDROID_AUTOFILL_AUTOFILL_KEYBOARD_ACCESSORY_VIEW_IMPL_H_ #include <jni.h> #include <stddef.h> + #include <vector> #include "base/android/scoped_java_ref.h" @@ -14,7 +15,7 @@ #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.h" -#include "chrome/browser/ui/autofill/autofill_popup_view.h" +#include "chrome/browser/ui/autofill/autofill_keyboard_accessory_view.h" namespace autofill { @@ -23,20 +24,20 @@ // A suggestion view that acts as an alternative to the field-attached popup // window. This view appears above the keyboard and spans the width of the // screen, condensing rather than overlaying the content area. -class AutofillKeyboardAccessoryView - : public AutofillKeyboardAccessoryAdapter::AccessoryView { +class AutofillKeyboardAccessoryViewImpl + : public AutofillKeyboardAccessoryView { public: - AutofillKeyboardAccessoryView( + AutofillKeyboardAccessoryViewImpl( base::WeakPtr<AutofillKeyboardAccessoryController> adapter, base::WeakPtr<AutofillKeyboardAccessoryController> controller); - AutofillKeyboardAccessoryView(const AutofillKeyboardAccessoryView&) = delete; - AutofillKeyboardAccessoryView& operator=( - const AutofillKeyboardAccessoryView&) = delete; + AutofillKeyboardAccessoryViewImpl(const AutofillKeyboardAccessoryViewImpl&) = delete; + AutofillKeyboardAccessoryViewImpl& operator=( + const AutofillKeyboardAccessoryViewImpl&) = delete; - ~AutofillKeyboardAccessoryView() override; + ~AutofillKeyboardAccessoryViewImpl() override; - // Implementation of AutofillKeyboardAccessoryAdapter::AccessoryView. + // AutofillKeyboardAccessoryView: bool Initialize() override; void Hide() override; void Show() override; @@ -87,4 +88,4 @@ } // namespace autofill -#endif // CHROME_BROWSER_UI_ANDROID_AUTOFILL_AUTOFILL_KEYBOARD_ACCESSORY_VIEW_H_ +#endif // CHROME_BROWSER_UI_ANDROID_AUTOFILL_AUTOFILL_KEYBOARD_ACCESSORY_VIEW_IMPL_H_
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninAccountPickerCoordinator.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninAccountPickerCoordinator.java index ce21444..45b8306 100644 --- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninAccountPickerCoordinator.java +++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninAccountPickerCoordinator.java
@@ -69,6 +69,8 @@ * @param delegate The delegate for this coordinator. * @param deviceLockActivityLauncher The launcher to start up the device lock page. * @param signinManager The sign-in manager to start the sign-in. + * @param bottomSheetStrings The object containing the strings shown by the bottom sheet. + * @param accountPickerLaunchMode Indicate the first bottom sheet view shown to the user. * @param signinAccessPoint The entry point for the sign-in. */ public SigninAccountPickerCoordinator( @@ -93,7 +95,7 @@ } private void initAndShowBottomSheet( - AccountPickerBottomSheetStrings bottomSheetStrings, + @NonNull AccountPickerBottomSheetStrings bottomSheetStrings, @AccountPickerLaunchMode int accountPickerLaunchMode) { ViewGroup sheetContainer = new FrameLayout(mActivity); sheetContainer.setLayoutParams( @@ -151,6 +153,11 @@ mSigninAccessPoint); } + /** Called when an account is added on the device when there was none previously. */ + public void onFirstAccountAdded(@NonNull String accountEmail) { + mAccountPickerBottomSheetCoordinator.onFirstAccountAdded(accountEmail); + } + /** Called when the account picker is destroyed after dismissal. */ @Override public void onAccountPickerDestroy() {
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninAndHistoryOptInCoordinator.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninAndHistoryOptInCoordinator.java index 4b09f14..c2311c6 100644 --- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninAndHistoryOptInCoordinator.java +++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninAndHistoryOptInCoordinator.java
@@ -70,6 +70,9 @@ /** This is a delegate that the embedder needs to implement. */ public interface Delegate { + /** Called when the user starts the Google Play Services "add account" flow. */ + void addAccount(); + /** Called when the whole flow finishes. */ void onFlowComplete(); } @@ -192,6 +195,15 @@ // TODO(crbug.com/41493768): Implement the loading state UI. } + /** + * Called when an account is added via Google Play Services "add account" flow started at the + * activity level. + */ + public void onAccountAdded(@NonNull String accountEmail) { + showSigninBottomSheet(); + mAccountPickerCoordinator.onFirstAccountAdded(accountEmail); + } + /** Called when the sign-in successfully finishes. */ @Override public void onSignInComplete() { @@ -303,7 +315,7 @@ showSigninBottomSheet(); break; case NoAccountSigninMode.ADD_ACCOUNT: - showAddAccount(); + showAddFirstAccount(); break; case NoAccountSigninMode.NO_SIGNIN: // TODO(crbug.com/41493768): Implement the error state UI. @@ -339,11 +351,12 @@ mDidShowSigninStep = true; } - private void showAddAccount() { + // This step skips the bottom sheet and leads directly to the Google Play "add account" flow, + // contrary to other bottom sheet based variants. Note that once the account is added, the + // signing in bottom sheet will be shown and the account will be signed-in right away. + private void showAddFirstAccount() { mDidShowSigninStep = true; - // TODO(crbug.com/41493767): Implement the no-account sign-in flow. - assert false : "Not implemented."; - onFlowComplete(); + mDelegate.addAccount(); } private void showHistoryOptInOrFinish() {
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninUtils.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninUtils.java index 76535ab..0e02442 100644 --- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninUtils.java +++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/SigninUtils.java
@@ -13,7 +13,9 @@ import androidx.annotation.Nullable; +import org.chromium.base.BuildInfo; import org.chromium.base.IntentUtils; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.signin.services.DisplayableProfileData; import org.chromium.chrome.browser.signin.services.SigninManager; import org.chromium.chrome.browser.signin.services.SigninManager.SignInCallback; @@ -204,4 +206,14 @@ listener, signinManager.extractDomainName(coreAccountInfo.getEmail())); } + + /** + * Returns whether the new sign-in flow should be shown instead of the usual one (sign-in and + * enable sync for instance) for an sign-in access point eligible to the new flow. + */ + public static boolean shouldShowNewSigninFlow() { + return ChromeFeatureList.isEnabled( + ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS) + && !BuildInfo.getInstance().isAutomotive; + } }
diff --git a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetCoordinator.java b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetCoordinator.java index 15e5c14..6a9bb40 100644 --- a/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetCoordinator.java +++ b/chrome/browser/ui/android/signin/java/src/org/chromium/chrome/browser/ui/signin/account_picker/AccountPickerBottomSheetCoordinator.java
@@ -7,9 +7,11 @@ import android.view.View; import androidx.annotation.MainThread; +import androidx.annotation.NonNull; import org.chromium.chrome.browser.signin.services.SigninMetricsUtils; import org.chromium.chrome.browser.signin.services.SigninPreferencesManager; +import org.chromium.chrome.browser.ui.signin.SigninUtils; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.SheetState; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.StateChangeReason; @@ -126,6 +128,17 @@ } } + /** + * Called when an account is added on the device when there was none previously. Will sign the + * account in in the UNO sign-in flow and may trigger the bottom sheet and the flow dismissal in + * this case. + */ + public void onFirstAccountAdded(@NonNull String accountEmail) { + if (SigninUtils.shouldShowNewSigninFlow()) { + mAccountPickerBottomSheetMediator.onAccountSelected(accountEmail); + } + } + public View getBottomSheetViewForTesting() { return mView.getContentView(); }
diff --git a/chrome/browser/ui/ash/picker/picker_client_impl.cc b/chrome/browser/ui/ash/picker/picker_client_impl.cc index 9305233e..429af9b 100644 --- a/chrome/browser/ui/ash/picker/picker_client_impl.cc +++ b/chrome/browser/ui/ash/picker/picker_client_impl.cc
@@ -255,7 +255,8 @@ } switch (*category) { - case ash::PickerCategory::kEditor: + case ash::PickerCategory::kEditorWrite: + case ash::PickerCategory::kEditorRewrite: case ash::PickerCategory::kExpressions: case ash::PickerCategory::kClipboard: case ash::PickerCategory::kDatesTimes: @@ -407,7 +408,8 @@ PickerClientImpl::CreateSearchProviderForCategory( ash::PickerCategory category) { switch (category) { - case ash::PickerCategory::kEditor: + case ash::PickerCategory::kEditorWrite: + case ash::PickerCategory::kEditorRewrite: case ash::PickerCategory::kExpressions: case ash::PickerCategory::kClipboard: case ash::PickerCategory::kDatesTimes:
diff --git a/chrome/browser/ui/ash/shelf/browser_app_shelf_controller_browsertest.cc b/chrome/browser/ui/ash/shelf/browser_app_shelf_controller_browsertest.cc index 1dc7583..bf3f865 100644 --- a/chrome/browser/ui/ash/shelf/browser_app_shelf_controller_browsertest.cc +++ b/chrome/browser/ui/ash/shelf/browser_app_shelf_controller_browsertest.cc
@@ -44,6 +44,7 @@ #include "content/public/test/browser_test.h" #include "testing/gmock/include/gmock/gmock.h" #include "ui/events/base_event_utils.h" +#include "ui/wm/core/window_util.h" using ::app_constants::kChromeAppId; using ::app_constants::kLacrosAppId; @@ -278,7 +279,8 @@ [&app_id](const apps::BrowserAppInstance& instance) { return instance.app_id == app_id; }); - return app && app->is_browser_active && app->is_web_contents_active; + return app && wm::IsActiveWindow(app->window) && + app->is_web_contents_active; } // Get unique titles of all app instances.
diff --git a/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.cc b/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.cc index e38f465..e5ce839 100644 --- a/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.cc +++ b/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.cc
@@ -15,6 +15,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" +#include "chrome/browser/ui/autofill/autofill_keyboard_accessory_view.h" #include "chrome/browser/ui/autofill/autofill_suggestion_controller.h" #include "components/autofill/core/browser/filling_product.h" #include "components/autofill/core/browser/metrics/granular_filling_metrics.h"
diff --git a/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.h b/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.h index 8b9952e..9994e49 100644 --- a/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.h +++ b/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.h
@@ -25,6 +25,8 @@ namespace autofill { +class AutofillKeyboardAccessoryView; + // This adapter allows the AutofillSuggestionController to treat the keyboard // accessory like any other implementation of AutofillPopupView. // From the controller's perspective, this behaves like a real AutofillPopupView @@ -42,34 +44,7 @@ ~AutofillKeyboardAccessoryAdapter() override; - // Interface describing the minimal capabilities for the native view. - class AccessoryView { - public: - virtual ~AccessoryView() = default; - - // Initializes the Java-side of this bridge. Returns true after a successful - // creation and false otherwise. - virtual bool Initialize() = 0; - - // Requests to dismiss this view. - virtual void Hide() = 0; - - // Requests to show this view with the data provided by the controller. - virtual void Show() = 0; - - // Makes announcement for acessibility. - virtual void AxAnnounce(const std::u16string& text); - - // Ask to confirm a deletion. Triggers the callback upon the user confirming - // or declining the deletion. The detection callback parameter specifies - // whether the deletion was confirmed or declined. - virtual void ConfirmDeletion( - const std::u16string& confirmation_title, - const std::u16string& confirmation_body, - base::OnceCallback<void(bool)> deletion_callback) = 0; - }; - - void SetAccessoryView(std::unique_ptr<AccessoryView> view) { + void SetAccessoryView(std::unique_ptr<AutofillKeyboardAccessoryView> view) { view_ = std::move(view); } @@ -139,7 +114,7 @@ int OffsetIndexFor(int element_index) const; base::WeakPtr<AutofillKeyboardAccessoryController> controller_; - std::unique_ptr<AutofillKeyboardAccessoryAdapter::AccessoryView> view_; + std::unique_ptr<AutofillKeyboardAccessoryView> view_; // The labels to be used for the input chips. std::vector<std::u16string> labels_;
diff --git a/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter_unittest.cc b/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter_unittest.cc index 155be755..ed71e13b 100644 --- a/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter_unittest.cc +++ b/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter_unittest.cc
@@ -19,6 +19,7 @@ #include "base/types/cxx23_to_underlying.h" #include "build/build_config.h" #include "chrome/browser/ui/autofill/autofill_keyboard_accessory_controller.h" +#include "chrome/browser/ui/autofill/autofill_keyboard_accessory_view.h" #include "chrome/browser/ui/autofill/autofill_popup_view.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/ui/popup_item_ids.h" @@ -148,8 +149,7 @@ weak_ptr_factory_{this}; }; -class MockAccessoryView - : public AutofillKeyboardAccessoryAdapter::AccessoryView { +class MockAccessoryView : public AutofillKeyboardAccessoryView { public: MockAccessoryView() {} @@ -280,7 +280,7 @@ MockAccessoryView* view() { return accessory_view_; } private: - raw_ptr<StrictMock<MockAccessoryView>> accessory_view_; + raw_ptr<MockAccessoryView> accessory_view_ = nullptr; std::unique_ptr<MockAutofillKeyboardAccessoryController> popup_controller_; std::unique_ptr<AutofillKeyboardAccessoryAdapter> autofill_accessory_adapter_; };
diff --git a/chrome/browser/ui/autofill/autofill_keyboard_accessory_view.h b/chrome/browser/ui/autofill/autofill_keyboard_accessory_view.h new file mode 100644 index 0000000..5352b247 --- /dev/null +++ b/chrome/browser/ui/autofill/autofill_keyboard_accessory_view.h
@@ -0,0 +1,39 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_KEYBOARD_ACCESSORY_VIEW_H_ +#define CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_KEYBOARD_ACCESSORY_VIEW_H_ + +namespace autofill { + +// The interface that the native view for the Keyboard Accessory implements. +class AutofillKeyboardAccessoryView { + public: + virtual ~AutofillKeyboardAccessoryView() = default; + + // Initializes the Java-side of this bridge. Returns true after a successful + // creation and false otherwise. + virtual bool Initialize() = 0; + + // Requests to dismiss this view. + virtual void Hide() = 0; + + // Requests to show this view with the data provided by the controller. + virtual void Show() = 0; + + // Makes announcement for acessibility. + virtual void AxAnnounce(const std::u16string& text); + + // Ask to confirm a deletion. Triggers the callback upon the user confirming + // or declining the deletion. The detection callback parameter specifies + // whether the deletion was confirmed or declined. + virtual void ConfirmDeletion( + const std::u16string& confirmation_title, + const std::u16string& confirmation_body, + base::OnceCallback<void(bool)> deletion_callback) = 0; +}; + +} // namespace autofill + +#endif // CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_KEYBOARD_ACCESSORY_VIEW_H_
diff --git a/chrome/browser/ui/browser_focus_uitest.cc b/chrome/browser/ui/browser_focus_uitest.cc index b797e69..b9fffd4a 100644 --- a/chrome/browser/ui/browser_focus_uitest.cc +++ b/chrome/browser/ui/browser_focus_uitest.cc
@@ -153,13 +153,13 @@ // window occlusion is turned off. Turn it on to match the production // environment. base::FieldTrialParams field_trial_params{ - { features::kApplyNativeOcclusionToCompositorType.Get(), + { features::kApplyNativeOcclusionToCompositorType.name, features::kApplyNativeOcclusionToCompositorTypeRelease }}; scoped_feature_list_.InitWithFeaturesAndParameters( /*enabled_features=*/ - {{features::kAlwaysTrackNativeWindowOcclusionForTest, {}}, - { features::kApplyNativeOcclusionToCompositor, - field_trial_params }}, + {{features::kApplyNativeOcclusionToCompositor, field_trial_params}, + { features::kAlwaysTrackNativeWindowOcclusionForTest, + {} }}, /*disabled_features=*/{}); #endif }
diff --git a/chrome/browser/ui/lens/lens_overlay_controller_browsertest.cc b/chrome/browser/ui/lens/lens_overlay_controller_browsertest.cc index af95bebe..1c9074b 100644 --- a/chrome/browser/ui/lens/lens_overlay_controller_browsertest.cc +++ b/chrome/browser/ui/lens/lens_overlay_controller_browsertest.cc
@@ -392,8 +392,16 @@ ASSERT_TRUE(base::test::RunUntil([&]() { return observer.request_shown(); })); } +// TODO(b/335801964): Test flaky on Mac. +#if BUILDFLAG(IS_MAC) +#define MAYBE_ShowSidePanelAfterManualRegionSelection \ + DISABLED_ShowSidePanelAfterManualRegionSelection +#else +#define MAYBE_ShowSidePanelAfterManualRegionSelection \ + ShowSidePanelAfterManualRegionSelection +#endif IN_PROC_BROWSER_TEST_F(LensOverlayControllerBrowserTest, - ShowSidePanelAfterManualRegionSelection) { + MAYBE_ShowSidePanelAfterManualRegionSelection) { WaitForPaint(); // State should start in off.
diff --git a/chrome/browser/ui/views/profiles/avatar_toolbar_button_browsertest.cc b/chrome/browser/ui/views/profiles/avatar_toolbar_button_browsertest.cc index e5211d74..6093b6d4 100644 --- a/chrome/browser/ui/views/profiles/avatar_toolbar_button_browsertest.cc +++ b/chrome/browser/ui/views/profiles/avatar_toolbar_button_browsertest.cc
@@ -1527,8 +1527,14 @@ #endif // !BUILDFLAG(IS_WIN) +// TODO(b/335775210): Flaky on win-asan +#if (BUILDFLAG(IS_WIN) && defined(ADDRESS_SANITIZER)) +#define MAYBE_SigninPaused_ThenSignout DISABLED_SigninPaused_ThenSignout +#else +#define MAYBE_SigninPaused_ThenSignout SigninPaused_ThenSignout +#endif IN_PROC_BROWSER_TEST_F(AvatarToolbarButtonWithExplicitBrowserSigninBrowserTest, - SigninPaused_ThenSignout) { + MAYBE_SigninPaused_ThenSignout) { SigninAndWait(u"test@gmail.com"); AvatarToolbarButton* avatar = GetAvatarToolbarButton(browser());
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view.cc b/chrome/browser/ui/views/profiles/profile_menu_view.cc index 4c526bd1..4105fe3c 100644 --- a/chrome/browser/ui/views/profiles/profile_menu_view.cc +++ b/chrome/browser/ui/views/profiles/profile_menu_view.cc
@@ -710,10 +710,18 @@ bool show_account_card = false; if (!account_info.IsEmpty()) { - description = - l10n_util::GetStringUTF16(IDS_PROFILES_DICE_NOT_SYNCING_TITLE); - button_text = l10n_util::GetStringUTF16(IDS_PROFILES_DICE_SIGNIN_BUTTON); - show_sync_badge = true; + if (switches::IsExplicitBrowserSigninUIOnDesktopEnabled( + switches::ExplicitBrowserSigninPhase::kFull)) { + description = + l10n_util::GetStringUTF16(IDS_SYNC_ERROR_USER_MENU_VERIFY_MESSAGE); + button_text = l10n_util::GetStringUTF16( + IDS_SYNC_ERROR_USER_MENU_RECOVERABILITY_BUTTON); + } else { + description = + l10n_util::GetStringUTF16(IDS_PROFILES_DICE_NOT_SYNCING_TITLE); + button_text = l10n_util::GetStringUTF16(IDS_PROFILES_DICE_SIGNIN_BUTTON); + show_sync_badge = true; + } } else if (switches::IsExplicitBrowserSigninUIOnDesktopEnabled( switches::ExplicitBrowserSigninPhase::kExperimental) && !account_info_for_promos.IsEmpty()) {
diff --git a/chrome/browser/ui/webauthn/sheet_models.cc b/chrome/browser/ui/webauthn/sheet_models.cc index c615501..b27ec32 100644 --- a/chrome/browser/ui/webauthn/sheet_models.cc +++ b/chrome/browser/ui/webauthn/sheet_models.cc
@@ -1878,7 +1878,9 @@ std::u16string AuthenticatorGPMArbitraryPinSheetModel::GetAcceptButtonLabel() const { - return l10n_util::GetStringUTF16(IDS_WEBAUTHN_CONTINUE); + return mode_ == Mode::kPinEntry + ? l10n_util::GetStringUTF16(IDS_WEBAUTHN_PIN_ENTRY_NEXT) + : l10n_util::GetStringUTF16(IDS_CONFIRM); } void AuthenticatorGPMArbitraryPinSheetModel::OnAccept() {
diff --git a/chrome/browser/ui/webui/ash/mako/mako_bubble_coordinator.cc b/chrome/browser/ui/webui/ash/mako/mako_bubble_coordinator.cc index a3fbbcd..02b392b 100644 --- a/chrome/browser/ui/webui/ash/mako/mako_bubble_coordinator.cc +++ b/chrome/browser/ui/webui/ash/mako/mako_bubble_coordinator.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include <optional> +#include "ash/constants/ash_features.h" #include "base/check.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/ash/mako/mako_consent_view.h" @@ -62,6 +63,10 @@ preset_query_id); url = net::AppendOrReplaceQueryParameter(url, kOrcaFreeformParamKey, freeform_text); + if (base::FeatureList::IsEnabled(ash::features::kOrcaResizingSupport)) { + url = net::AppendOrReplaceQueryParameter(url, kOrcaResizingEnabledParamKey, + "true"); + } contents_wrapper_ = std::make_unique<WebUIContentsWrapperT<MakoUntrustedUI>>( url, profile, IDS_ACCNAME_ORCA, /*webui_resizes_host=*/true,
diff --git a/chrome/browser/ui/webui/ash/mako/url_constants.cc b/chrome/browser/ui/webui/ash/mako/url_constants.cc index 55ff869f..9a64789e6 100644 --- a/chrome/browser/ui/webui/ash/mako/url_constants.cc +++ b/chrome/browser/ui/webui/ash/mako/url_constants.cc
@@ -18,4 +18,6 @@ const char kOrcaPresetParamKey[] = "preset"; const char kOrcaFreeformParamKey[] = "freeform"; +const char kOrcaResizingEnabledParamKey[] = "resizing-enabled"; + } // namespace ash
diff --git a/chrome/browser/ui/webui/ash/mako/url_constants.h b/chrome/browser/ui/webui/ash/mako/url_constants.h index 6a5354d..748479e7 100644 --- a/chrome/browser/ui/webui/ash/mako/url_constants.h +++ b/chrome/browser/ui/webui/ash/mako/url_constants.h
@@ -19,6 +19,8 @@ extern const char kOrcaPresetParamKey[]; extern const char kOrcaFreeformParamKey[]; +extern const char kOrcaResizingEnabledParamKey[]; + } // namespace ash #endif // CHROME_BROWSER_UI_WEBUI_ASH_MAKO_URL_CONSTANTS_H_
diff --git a/chrome/browser/ui/webui/password_manager/password_manager_ui.cc b/chrome/browser/ui/webui/password_manager/password_manager_ui.cc index ce85a12..1f95472c 100644 --- a/chrome/browser/ui/webui/password_manager/password_manager_ui.cc +++ b/chrome/browser/ui/webui/password_manager/password_manager_ui.cc
@@ -326,6 +326,7 @@ {"passwordManager", IDS_PASSWORD_BUBBLES_PASSWORD_MANAGER_LINK_TEXT_SYNCED_TO_ACCOUNT}, // Header for the page, always "Password Manager". + {"passwordManagerPinChanged", IDS_PASSWORD_MANAGER_PIN_CHANGED}, {"passwordManagerString", IDS_PASSWORD_MANAGER_UI_TITLE}, // Page title, branded. "Google Password Manager" or "Password Manager" // depending on the build.
diff --git a/chrome/browser/webauthn/change_pin_controller.cc b/chrome/browser/webauthn/change_pin_controller.cc index 554e908..2d10d673 100644 --- a/chrome/browser/webauthn/change_pin_controller.cc +++ b/chrome/browser/webauthn/change_pin_controller.cc
@@ -24,14 +24,6 @@ ChangePinController::~ChangePinController() = default; -bool ChangePinController::IsChangePinFlowAvailable() { - return false; -} - -bool ChangePinController::StartChangePin() { - return false; -} - // static ChangePinController* ChangePinController::ForWebContents( content::WebContents* web_contents) {
diff --git a/chrome/browser/webauthn/change_pin_controller.h b/chrome/browser/webauthn/change_pin_controller.h index dce2ba0..ff1ee0bc 100644 --- a/chrome/browser/webauthn/change_pin_controller.h +++ b/chrome/browser/webauthn/change_pin_controller.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_WEBAUTHN_CHANGE_PIN_CONTROLLER_H_ #define CHROME_BROWSER_WEBAUTHN_CHANGE_PIN_CONTROLLER_H_ +#include "base/functional/callback.h" #include "base/memory/raw_ptr.h" namespace content { @@ -15,6 +16,8 @@ class ChangePinController { public: + using SuccessCallback = base::OnceCallback<void(bool)>; + static ChangePinController* ForWebContents( content::WebContents* web_contents); @@ -22,10 +25,10 @@ // Checks whether changing PIN flow is available. Changing the PIN is only // possible when the `EnclaveManager` is ready and has a wrapped PIN. - virtual bool IsChangePinFlowAvailable(); + virtual bool IsChangePinFlowAvailable() = 0; - // Starts the change PIN flow. Returns true if the flow has started. - virtual bool StartChangePin(); + // Starts the change PIN flow. The callback is run once the flow is completed. + virtual void StartChangePin(SuccessCallback callback) = 0; static void set_instance_for_testing(ChangePinController* controller) { instance_for_testing_ = controller;
diff --git a/chrome/browser/webauthn/change_pin_controller_impl.cc b/chrome/browser/webauthn/change_pin_controller_impl.cc index 8fa2edf..32e1135 100644 --- a/chrome/browser/webauthn/change_pin_controller_impl.cc +++ b/chrome/browser/webauthn/change_pin_controller_impl.cc
@@ -40,7 +40,11 @@ model_observation_.Observe(&model_->observers); } -ChangePinControllerImpl::~ChangePinControllerImpl() = default; +ChangePinControllerImpl::~ChangePinControllerImpl() { + if (!notify_pin_change_callback_.is_null()) { + std::move(notify_pin_change_callback_).Run(false); + } +} // static ChangePinControllerImpl* ChangePinControllerImpl::ForWebContents( @@ -68,17 +72,21 @@ return sync_enabled && enclave_valid; } -bool ChangePinControllerImpl::StartChangePin() { +void ChangePinControllerImpl::StartChangePin(SuccessCallback callback) { if (!IsChangePinFlowAvailable()) { - return false; + std::move(callback).Run(false); + return; } + notify_pin_change_callback_ = std::move(callback); // TODO(enclave): use local UV instead of GPM reauth when available. model_->SetStep(Step::kGPMReauthAccount); - return true; } void ChangePinControllerImpl::CancelAuthenticatorRequest() { // User clicked "Cancel" in the GPM dialog. + if (!notify_pin_change_callback_.is_null()) { + std::move(notify_pin_change_callback_).Run(false); + } Reset(); } @@ -89,6 +97,9 @@ void ChangePinControllerImpl::OnRecoverSecurityDomainClosed() { // User closed the reauth window. + if (!notify_pin_change_callback_.is_null()) { + std::move(notify_pin_change_callback_).Run(false); + } Reset(); } @@ -101,6 +112,13 @@ weak_ptr_factory_.GetWeakPtr())); } +void ChangePinControllerImpl::OnGPMPinOptionChanged(bool is_arbitrary) { + CHECK(model_->step() == Step::kGPMCreatePin || + model_->step() == Step::kGPMCreateArbitraryPin); + model_->SetStep(is_arbitrary ? Step::kGPMCreateArbitraryPin + : Step::kGPMCreatePin); +} + void ChangePinControllerImpl::Reset() { model_observation_.Reset(); model_->SetStep(Step::kNotStarted); @@ -112,6 +130,8 @@ model_->SetStep(Step::kGPMError); return; } - // TODO(derinel): Display success UI Reset(); + if (!notify_pin_change_callback_.is_null()) { + std::move(notify_pin_change_callback_).Run(success); + } }
diff --git a/chrome/browser/webauthn/change_pin_controller_impl.h b/chrome/browser/webauthn/change_pin_controller_impl.h index a4d44eb..94de0ac5 100644 --- a/chrome/browser/webauthn/change_pin_controller_impl.h +++ b/chrome/browser/webauthn/change_pin_controller_impl.h
@@ -41,7 +41,7 @@ // │ OnReauthComplete ───────────────┼─────────────┼───────────┐ │ // │ │ │ │ │ // │ │ Cancelled │ ▼ │ -// │ CancelAuthenticatorRequest ◄────┼─────────────┼── kGPMCreatePin │ +// │ CancelAuthenticatorRequest ◄────┼─────────────┼── kGPMCreatePin* │ // │ │ │ │ │ // │ │ PIN entered │ │ │ // │ ┌────────────────────────┼─────────────┼───────────┘ │ @@ -59,6 +59,9 @@ // │ OnGpmPinChanged │ │ │ // │ │ │ │ // └─────────────────────────────────┘ └────────────────┘ +// +// *: this can also be kGPMCreateArbitraryPin when the user switches the step in +// the view. class ChangePinControllerImpl : public ChangePinController, public base::SupportsUserData::Data, @@ -78,13 +81,14 @@ bool IsChangePinFlowAvailable() override; // Starts the change PIN flow. Returns true if the flow has started. - bool StartChangePin() override; + void StartChangePin(SuccessCallback callback) override; // AuthenticatorRequestDialogModel::Observer void CancelAuthenticatorRequest() override; void OnReauthComplete(std::string rapt) override; void OnRecoverSecurityDomainClosed() override; void OnGPMPinEntered(const std::u16string& pin) override; + void OnGPMPinOptionChanged(bool is_arbitrary) override; private: void OnGpmPinChanged(bool success); @@ -92,8 +96,10 @@ const bool enclave_enabled_; std::unique_ptr<AuthenticatorRequestDialogModel> model_; + SuccessCallback notify_pin_change_callback_; // EnclaveManager is a KeyedService. raw_ptr<EnclaveManager> enclave_manager_ = nullptr; + // SyncService is a KeyedService. raw_ptr<syncer::SyncService> sync_service_ = nullptr; std::optional<std::string> rapt_ = std::nullopt;
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt index 0d99184..91538b3c 100644 --- a/chrome/build/android-arm32.pgo.txt +++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@ -chrome-android32-main-1713484561-d78fb7603cf113259fabb5e04edfe8f7c943a6c2-9f1721f07da35be11e0164b09553d85361b8bb28.profdata +chrome-android32-main-1713506149-f88b765fe526927d535f473c1e18ff632e489df6-f7a4ca430269770d819ad7eae565cb2ffd02f94c.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 1eaf5bf..3630b363 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1713463187-dbf5b9436a1f46a90ee316f44d91d8a67da68350-62be926cd6b6c0421dddfcd23ae9da0781b73344.profdata +chrome-linux-main-1713506149-9c3feea0f552e9442f64b526508a97de98b5c2e8-f7a4ca430269770d819ad7eae565cb2ffd02f94c.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt index d8d8fdb1..844afe8 100644 --- a/chrome/build/win-arm64.pgo.txt +++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@ -chrome-win-arm64-main-1713484561-514756e61e8cc54ae9df5c0b9727ec3f655df2dc-9f1721f07da35be11e0164b09553d85361b8bb28.profdata +chrome-win-arm64-main-1713506149-4e72df38de61d3923e84dc0097ad4232e079688d-f7a4ca430269770d819ad7eae565cb2ffd02f94c.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index be10f98..aa4332e 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1713473843-8cfddd58020bd151973dba3c6c371b01e4552635-81fdb072844881cb7a6440bbad3eace782228f05.profdata +chrome-win32-main-1713506149-fa3eda90155d36846a91924f82311956957edc6f-f7a4ca430269770d819ad7eae565cb2ffd02f94c.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 2408e49..ab9c443 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1713484561-bf1472dce7ecfddb6e36385faaf140130abf1071-9f1721f07da35be11e0164b09553d85361b8bb28.profdata +chrome-win64-main-1713506149-40867073795b76466e893f5fd70922ace62beb46-f7a4ca430269770d819ad7eae565cb2ffd02f94c.profdata
diff --git a/chrome/common/extensions/api/passwords_private.idl b/chrome/common/extensions/api/passwords_private.idl index 3ee760ad..23f753a9 100644 --- a/chrome/common/extensions/api/passwords_private.idl +++ b/chrome/common/extensions/api/passwords_private.idl
@@ -357,6 +357,7 @@ callback CredentialsWithReusedPasswordCallback = void(PasswordUiEntryList[] entries); callback PasswordManagerPinAvailableCallback = void(boolean available); + callback PasswordManagerPinChangedCallback = void(boolean success); interface Functions { // Function that logs that the Passwords page was accessed from the Chrome @@ -552,7 +553,8 @@ static void showExportedFileInShell(DOMString file_path); // Shows a dialog for changing the Password Manager PIN. - static void changePasswordManagerPin(); + static void changePasswordManagerPin( + optional PasswordManagerPinChangedCallback callback); // Checks whether changing Password Manager PIN is possible. static void isPasswordManagerPinAvailable(
diff --git a/chrome/renderer/autofill/form_autocomplete_browsertest.cc b/chrome/renderer/autofill/form_autocomplete_browsertest.cc index 0555f42..477fc39 100644 --- a/chrome/renderer/autofill/form_autocomplete_browsertest.cc +++ b/chrome/renderer/autofill/form_autocomplete_browsertest.cc
@@ -215,14 +215,14 @@ FormFieldData field_data; field_data.set_name(u"fname"); field_data.set_value(u"John"); - field_data.is_autofilled = true; + field_data.set_is_autofilled(true); field_data.set_renderer_id(form_util::GetFieldRendererId(fname_element)); data.fields.push_back(field_data); if (!lname_element.IsNull()) { field_data.set_name(u"lname"); field_data.set_value(u"Smith"); - field_data.is_autofilled = true; + field_data.set_is_autofilled(true); field_data.set_renderer_id(form_util::GetFieldRendererId(lname_element)); data.fields.push_back(field_data); } @@ -296,20 +296,20 @@ FormFieldData field; field.set_name(u"fname"); field.set_value(u"John"); - field.is_autofilled = true; + field.set_is_autofilled(true); field.set_renderer_id(form_util::GetFieldRendererId(fname_element)); form.fields.push_back(field); field.set_name(u"lname"); field.set_value(u"Smith"); - field.is_autofilled = true; + field.set_is_autofilled(true); field.set_renderer_id(form_util::GetFieldRendererId(lname_element)); form.fields.push_back(field); // Additional non-autofillable field. field.set_name(u"mname"); field.set_value(u"James"); - field.is_autofilled = false; + field.set_is_autofilled(false); field.set_renderer_id(form_util::GetFieldRendererId(mname_element)); form.fields.push_back(field);
diff --git a/chrome/renderer/autofill/form_autofill_browsertest.cc b/chrome/renderer/autofill/form_autofill_browsertest.cc index 79fa37ee..35be3d61 100644 --- a/chrome/renderer/autofill/form_autofill_browsertest.cc +++ b/chrome/renderer/autofill/form_autofill_browsertest.cc
@@ -345,7 +345,7 @@ expected.set_name(names[i]); expected.set_value(values[i]); expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); fields.push_back(expected); } ExpectLabelsAndTypes(html, fields); @@ -470,11 +470,11 @@ SCOPED_TRACE(base::StringPrintf("Verify initial value for field %s", field_cases[i].id_attribute)); expected.set_form_control_type(field_cases[i].form_control_type); - expected.max_length = + expected.set_max_length( (expected.form_control_type() == FormControlType::kInputText || expected.form_control_type() == FormControlType::kTextArea) ? FormFieldData::kDefaultMaxLength - : 0; + : 0); expected.set_id_attribute(ASCIIToUTF16(field_cases[i].id_attribute)); expected.set_name(expected.id_attribute()); expected.set_value(ASCIIToUTF16(field_cases[i].initial_value)); @@ -489,7 +489,7 @@ // Fill the form_data for the field. form.fields[i].set_value(ASCIIToUTF16(field_cases[i].autofill_value)); // Set the is_autofilled property for the field. - form.fields[i].is_autofilled = field_cases[i].should_be_autofilled; + form.fields[i].set_is_autofilled(field_cases[i].should_be_autofilled); } // Autofill the form using the given fill form function. @@ -706,7 +706,7 @@ FormFieldData expected; expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); expected.set_id_attribute(u"firstname"); expected.set_name(expected.id_attribute()); @@ -770,7 +770,7 @@ expected.set_value(u"John"); expected.set_label(u"John"); expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]); expected.set_id_attribute(u"lastname"); @@ -778,7 +778,7 @@ expected.set_value(u"Smith"); expected.set_label(u"Smith"); expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]); expected.set_id_attribute(u"email"); @@ -787,7 +787,7 @@ expected.set_label(u"john@example.com"); expected.autocomplete_attribute = "off"; expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]); expected.autocomplete_attribute = {}; @@ -796,7 +796,7 @@ expected.set_value(u"123 Fantasy Ln.\nApt. 42"); expected.set_label({}); expected.set_form_control_type(FormControlType::kTextArea); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[3]); EXPECT_FORM_FIELD_DATA_EQUALS(expected, field); } @@ -830,29 +830,29 @@ expected.set_id_attribute(u"firstname"); expected.set_name(expected.id_attribute()); - expected.max_length = 5; - expected.is_autofilled = false; + expected.set_max_length(5); + expected.set_is_autofilled(false); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]); expected.set_id_attribute(u"lastname"); expected.set_name(expected.id_attribute()); - expected.max_length = 7; - expected.is_autofilled = false; + expected.set_max_length(7); + expected.set_is_autofilled(false); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]); expected.set_id_attribute(u"email"); expected.set_name(expected.id_attribute()); - expected.max_length = 9; - expected.is_autofilled = false; + expected.set_max_length(9); + expected.set_is_autofilled(false); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]); // Fill the form. form.fields[0].set_value(u"Brother"); form.fields[1].set_value(u"Jonathan"); form.fields[2].set_value(u"brotherj@example.com"); - form.fields[0].is_autofilled = true; - form.fields[1].is_autofilled = true; - form.fields[2].is_autofilled = true; + form.fields[0].set_is_autofilled(true); + form.fields[1].set_is_autofilled(true); + form.fields[2].set_is_autofilled(true); ExecuteJavaScriptForTests("document.getElementById('firstname').focus();"); ApplyFieldsAction(input_element.GetDocument(), form.fields, mojom::ActionPersistence::kFill); @@ -874,22 +874,22 @@ expected.set_id_attribute(u"firstname"); expected.set_name(expected.id_attribute()); expected.set_value(u"Broth"); - expected.max_length = 5; - expected.is_autofilled = true; + expected.set_max_length(5); + expected.set_is_autofilled(true); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]); expected.set_id_attribute(u"lastname"); expected.set_name(expected.id_attribute()); expected.set_value(u"Jonatha"); - expected.max_length = 7; - expected.is_autofilled = true; + expected.set_max_length(7); + expected.set_is_autofilled(true); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]); expected.set_id_attribute(u"email"); expected.set_name(expected.id_attribute()); expected.set_value(u"brotherj@"); - expected.max_length = 9; - expected.is_autofilled = true; + expected.set_max_length(9); + expected.set_is_autofilled(true); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]); } @@ -919,7 +919,7 @@ FormFieldData expected; expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); expected.set_id_attribute(u"firstname"); expected.set_name(expected.id_attribute()); @@ -995,7 +995,7 @@ FormFieldData expected; expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); expected.set_id_attribute(u"firstname"); expected.set_name(expected.id_attribute()); @@ -1030,7 +1030,7 @@ ASSERT_EQ(3U, fields2.size()); expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); expected.set_id_attribute(u"firstname"); expected.set_name(expected.id_attribute()); @@ -1076,30 +1076,30 @@ FormFieldData expected; expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); expected.set_id_attribute(u"apple"); expected.set_name(expected.id_attribute()); - expected.is_autofilled = false; + expected.set_is_autofilled(false); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[unowned_offset]); expected.set_id_attribute(u"banana"); expected.set_name(expected.id_attribute()); - expected.is_autofilled = false; + expected.set_is_autofilled(false); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[unowned_offset + 1]); expected.set_id_attribute(u"cantelope"); expected.set_name(expected.id_attribute()); - expected.is_autofilled = false; + expected.set_is_autofilled(false); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[unowned_offset + 2]); // Fill the form. form.fields[unowned_offset + 0].set_value(u"Red"); form.fields[unowned_offset + 1].set_value(u"Yellow"); form.fields[unowned_offset + 2].set_value(u"Also Yellow"); - form.fields[unowned_offset + 0].is_autofilled = true; - form.fields[unowned_offset + 1].is_autofilled = true; - form.fields[unowned_offset + 2].is_autofilled = true; + form.fields[unowned_offset + 0].set_is_autofilled(true); + form.fields[unowned_offset + 1].set_is_autofilled(true); + form.fields[unowned_offset + 2].set_is_autofilled(true); ExecuteJavaScriptForTests("document.getElementById('apple').focus();"); ApplyFieldsAction(input_element.GetDocument(), form.fields, mojom::ActionPersistence::kFill); @@ -1119,19 +1119,19 @@ expected.set_id_attribute(u"apple"); expected.set_name(expected.id_attribute()); expected.set_value(u"Red"); - expected.is_autofilled = true; + expected.set_is_autofilled(true); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[unowned_offset + 0]); expected.set_id_attribute(u"banana"); expected.set_name(expected.id_attribute()); expected.set_value(u"Yellow"); - expected.is_autofilled = true; + expected.set_is_autofilled(true); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[unowned_offset + 1]); expected.set_id_attribute(u"cantelope"); expected.set_name(expected.id_attribute()); expected.set_value(u"Also Yellow"); - expected.is_autofilled = true; + expected.set_is_autofilled(true); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[unowned_offset + 2]); } @@ -1170,7 +1170,7 @@ FormFieldData expected; expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); expected.set_id_attribute(u"firstname"); expected.set_name(expected.id_attribute()); @@ -1179,7 +1179,7 @@ expected.set_label(ASCIIToUTF16(placeholder_firstname)); expected.placeholder = ASCIIToUTF16(placeholder_firstname); } - expected.is_autofilled = false; + expected.set_is_autofilled(false); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]); expected.set_id_attribute(u"lastname"); @@ -1195,7 +1195,7 @@ expected.set_label({}); expected.set_value({}); } - expected.is_autofilled = false; + expected.set_is_autofilled(false); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]); expected.set_id_attribute(u"email"); @@ -1211,16 +1211,16 @@ expected.set_label({}); expected.set_value({}); } - expected.is_autofilled = false; + expected.set_is_autofilled(false); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]); // Preview the form and verify that the cursor position has been updated. form.fields[0].set_value(u"Wyatt"); form.fields[1].set_value(u"Earp"); form.fields[2].set_value(u"wyatt@example.com"); - form.fields[0].is_autofilled = true; - form.fields[1].is_autofilled = true; - form.fields[2].is_autofilled = true; + form.fields[0].set_is_autofilled(true); + form.fields[1].set_is_autofilled(true); + form.fields[2].set_is_autofilled(true); ExecuteJavaScriptForTests("document.getElementById('firstname').focus();"); ApplyFieldsAction(input_element.GetDocument(), form.fields, mojom::ActionPersistence::kPreview); @@ -1254,7 +1254,7 @@ expected.set_label({}); expected.placeholder = {}; } - expected.is_autofilled = true; + expected.set_is_autofilled(true); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]); expected.set_id_attribute(u"lastname"); @@ -1267,7 +1267,7 @@ expected.set_label({}); expected.placeholder = {}; } - expected.is_autofilled = true; + expected.set_is_autofilled(true); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]); expected.set_id_attribute(u"email"); @@ -1280,7 +1280,7 @@ expected.set_label({}); expected.placeholder = {}; } - expected.is_autofilled = true; + expected.set_is_autofilled(true); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]); // Verify that the cursor position has been updated. @@ -1363,12 +1363,12 @@ form.fields[3].set_value(u"1111-2222-3333-4444"); form.fields[4].set_value(u"Montreal"); form.fields[5].set_value(u"AA"); - form.fields[0].is_autofilled = true; - form.fields[1].is_autofilled = true; - form.fields[2].is_autofilled = true; - form.fields[3].is_autofilled = true; - form.fields[4].is_autofilled = true; - form.fields[5].is_autofilled = true; + form.fields[0].set_is_autofilled(true); + form.fields[1].set_is_autofilled(true); + form.fields[2].set_is_autofilled(true); + form.fields[3].set_is_autofilled(true); + form.fields[4].set_is_autofilled(true); + form.fields[5].set_is_autofilled(true); ExecuteJavaScriptForTests("document.getElementById('firstname').focus();"); ApplyFieldsAction(input_element.GetDocument(), form.fields, mojom::ActionPersistence::kPreview); @@ -1389,7 +1389,7 @@ FormFieldData expected; expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); expected.set_id_attribute(u"firstname"); expected.set_name(expected.id_attribute()); @@ -1401,7 +1401,7 @@ expected.set_label({}); expected.placeholder = {}; } - expected.is_autofilled = true; + expected.set_is_autofilled(true); expected.is_user_edited = false; EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]); @@ -1416,7 +1416,7 @@ expected.set_label({}); expected.placeholder = {}; } - expected.is_autofilled = false; + expected.set_is_autofilled(false); expected.is_user_edited = true; EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]); @@ -1430,7 +1430,7 @@ expected.set_label({}); expected.placeholder = {}; } - expected.is_autofilled = true; + expected.set_is_autofilled(true); expected.is_user_edited = false; EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]); @@ -1444,7 +1444,7 @@ expected.set_label({}); expected.placeholder = {}; } - expected.is_autofilled = true; + expected.set_is_autofilled(true); expected.is_user_edited = false; EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[3]); @@ -1458,7 +1458,7 @@ expected.set_label({}); expected.placeholder = {}; } - expected.is_autofilled = true; + expected.set_is_autofilled(true); expected.is_user_edited = false; EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[4]); @@ -1474,9 +1474,9 @@ expected.set_label({}); expected.placeholder = {}; } - expected.is_autofilled = true; + expected.set_is_autofilled(true); expected.is_user_edited = false; - expected.max_length = 0; + expected.set_max_length(0); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[5]); } @@ -1525,9 +1525,9 @@ form.fields[0].set_value(u"Wyatt"); form.fields[1].set_value(u"Earpagus"); form.fields[2].set_value(u"susan@smith.com"); - form.fields[0].is_autofilled = true; - form.fields[1].is_autofilled = true; - form.fields[2].is_autofilled = false; + form.fields[0].set_is_autofilled(true); + form.fields[1].set_is_autofilled(true); + form.fields[2].set_is_autofilled(false); ExecuteJavaScriptForTests("document.getElementById('firstname').focus();"); ApplyFieldsAction(input_element.GetDocument(), form.fields, mojom::ActionPersistence::kPreview); @@ -1548,7 +1548,7 @@ FormFieldData expected; expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); expected.set_id_attribute(u"firstname"); expected.set_name(expected.id_attribute()); @@ -1560,7 +1560,7 @@ expected.set_label({}); expected.placeholder = {}; } - expected.is_autofilled = true; + expected.set_is_autofilled(true); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]); expected.set_id_attribute(u"lastname"); @@ -1573,7 +1573,7 @@ expected.set_label({}); expected.placeholder = {}; } - expected.is_autofilled = true; + expected.set_is_autofilled(true); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]); // The email field is not filled, because there is a value in it. @@ -1587,7 +1587,7 @@ expected.set_label({}); expected.placeholder = {}; } - expected.is_autofilled = false; + expected.set_is_autofilled(false); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]); } @@ -1636,9 +1636,9 @@ form.fields[0].set_value(u"1111-2222-3333-4444"); form.fields[1].set_value(u"03/2030"); form.fields[2].set_value(u"Susan Smith"); - form.fields[0].is_autofilled = true; - form.fields[1].is_autofilled = true; - form.fields[2].is_autofilled = true; + form.fields[0].set_is_autofilled(true); + form.fields[1].set_is_autofilled(true); + form.fields[2].set_is_autofilled(true); ExecuteJavaScriptForTests("document.getElementById('cc').focus();"); ApplyFieldsAction(input_element.GetDocument(), form.fields, mojom::ActionPersistence::kPreview); @@ -1662,7 +1662,7 @@ FormFieldData expected; expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); expected.set_id_attribute(u"cc"); expected.set_name(expected.id_attribute()); @@ -1674,7 +1674,7 @@ expected.set_label({}); expected.placeholder = {}; } - expected.is_autofilled = true; + expected.set_is_autofilled(true); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]); expected.set_id_attribute(u"expiration_date"); @@ -1687,7 +1687,7 @@ expected.set_label({}); expected.placeholder = {}; } - expected.is_autofilled = true; + expected.set_is_autofilled(true); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]); expected.set_id_attribute(u"name"); @@ -1700,7 +1700,7 @@ expected.set_label({}); expected.placeholder = {}; } - expected.is_autofilled = false; + expected.set_is_autofilled(false); expected.is_user_edited = true; EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]); @@ -1758,9 +1758,9 @@ form.fields[0].set_value(u"1111-2222-3333-4444"); form.fields[1].set_value(u"03/2030"); form.fields[2].set_value(u"Susan Smith"); - form.fields[0].is_autofilled = true; - form.fields[1].is_autofilled = true; - form.fields[2].is_autofilled = true; + form.fields[0].set_is_autofilled(true); + form.fields[1].set_is_autofilled(true); + form.fields[2].set_is_autofilled(true); ExecuteJavaScriptForTests("document.getElementById('cc').focus();"); ApplyFieldsAction(input_element.GetDocument(), form.fields, mojom::ActionPersistence::kPreview); @@ -1784,7 +1784,7 @@ FormFieldData expected; expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); expected.set_id_attribute(u"cc"); expected.set_name(expected.id_attribute()); @@ -1796,7 +1796,7 @@ expected.set_label({}); expected.placeholder = {}; } - expected.is_autofilled = true; + expected.set_is_autofilled(true); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[0]); expected.set_id_attribute(u"expiration_date"); @@ -1809,7 +1809,7 @@ expected.set_label({}); expected.placeholder = {}; } - expected.is_autofilled = true; + expected.set_is_autofilled(true); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[1]); expected.set_id_attribute(u"name"); @@ -1822,7 +1822,7 @@ expected.set_label({}); expected.placeholder = {}; } - expected.is_autofilled = false; + expected.set_is_autofilled(false); expected.is_user_edited = true; EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields2[2]); @@ -1876,7 +1876,7 @@ FormFieldData expected; expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); expected.set_id_attribute(u"firstname"); expected.set_name(expected.id_attribute()); @@ -1903,7 +1903,7 @@ EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[3]); expected.set_form_control_type(FormControlType::kInputMonth); - expected.max_length = 0; + expected.set_max_length(0); expected.set_id_attribute(u"month"); expected.set_name(expected.id_attribute()); expected.set_value({}); @@ -1918,7 +1918,7 @@ expected.set_form_control_type(FormControlType::kTextArea); expected.set_id_attribute(u"textarea"); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); expected.set_name(expected.id_attribute()); expected.set_value({}); expected.set_label({}); @@ -2012,10 +2012,10 @@ FormFieldData expected; expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); // shipping section - expected.is_autofilled = false; + expected.set_is_autofilled(false); expected.set_id_attribute(u"firstname-shipping"); expected.set_name(expected.id_attribute()); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]); @@ -2029,7 +2029,7 @@ EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]); // billing section - expected.is_autofilled = true; + expected.set_is_autofilled(true); expected.set_id_attribute(u"firstname-billing"); expected.set_name(expected.id_attribute()); expected.set_value(u"John"); @@ -2098,14 +2098,14 @@ expected.set_name(expected.id_attribute()); expected.set_value({}); expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]); expected.set_id_attribute(u"lastname"); expected.set_name(expected.id_attribute()); expected.set_value({}); expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]); expected.set_id_attribute(u"state"); @@ -2113,7 +2113,7 @@ expected.set_name(expected.name_attribute()); expected.set_value(u"?"); expected.set_form_control_type(FormControlType::kSelectOne); - expected.max_length = 0; + expected.set_max_length(0); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]); // Verify that the cursor position has been updated. @@ -2373,7 +2373,7 @@ FormFieldData expected; expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); expected.set_id_attribute(u"element"); expected.set_name(expected.id_attribute()); @@ -2407,7 +2407,7 @@ expected.set_value(u"value"); expected.set_form_control_type(FormControlType::kInputText); expected.autocomplete_attribute = "off"; - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); EXPECT_FORM_FIELD_DATA_EQUALS(expected, result); } @@ -2428,7 +2428,7 @@ expected.set_name(expected.id_attribute()); expected.set_value(u"value"); expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = 5; + expected.set_max_length(5); EXPECT_FORM_FIELD_DATA_EQUALS(expected, result); } @@ -2450,8 +2450,8 @@ expected.set_name(expected.id_attribute()); expected.set_value(u"value"); expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; - expected.is_autofilled = true; + expected.set_max_length(FormFieldData::kDefaultMaxLength); + expected.set_is_autofilled(true); EXPECT_FORM_FIELD_DATA_EQUALS(expected, result); } @@ -2475,8 +2475,8 @@ expected.set_name(expected.id_attribute()); expected.set_value(u"mail"); expected.set_form_control_type(FormControlType::kInputCheckbox); - expected.max_length = 0; - expected.is_autofilled = true; + expected.set_max_length(0); + expected.set_is_autofilled(true); expected.check_status = FormFieldData::CheckStatus::kChecked; EXPECT_FORM_FIELD_DATA_EQUALS(expected, result); @@ -2488,8 +2488,8 @@ expected.set_name(expected.id_attribute()); expected.set_value(u"male"); expected.set_form_control_type(FormControlType::kInputRadio); - expected.max_length = 0; - expected.is_autofilled = true; + expected.set_max_length(0); + expected.set_is_autofilled(true); expected.check_status = FormFieldData::CheckStatus::kCheckableButUnchecked; EXPECT_FORM_FIELD_DATA_EQUALS(expected, result); } @@ -2512,7 +2512,7 @@ FormFieldData expected; expected.set_id_attribute(u"element"); expected.set_name(expected.id_attribute()); - expected.max_length = 0; + expected.set_max_length(0); expected.set_form_control_type(FormControlType::kSelectOne); expected.set_value(u"CA"); @@ -2559,10 +2559,10 @@ FormFieldData expected; expected.set_id_attribute(u"element"); expected.set_name(expected.id_attribute()); - expected.max_length = 0; + expected.set_max_length(0); expected.set_form_control_type(FormControlType::kSelectOne); // We check that the extra attributes have been copied to `result1`. - expected.is_autofilled = true; + expected.set_is_autofilled(true); expected.autocomplete_attribute = "off"; expected.should_autocomplete = false; expected.is_focusable = true; @@ -2653,7 +2653,7 @@ FormFieldData expected; expected.set_id_attribute(u"element"); expected.set_name(expected.id_attribute()); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); expected.set_form_control_type(FormControlType::kTextArea); EXPECT_FORM_FIELD_DATA_EQUALS(expected, result_sans_value); @@ -2681,7 +2681,7 @@ FormFieldData expected; expected.set_id_attribute(u"element"); expected.set_name(expected.id_attribute()); - expected.max_length = 0; + expected.set_max_length(0); expected.set_form_control_type(FormControlType::kInputMonth); EXPECT_FORM_FIELD_DATA_EQUALS(expected, result_sans_value); @@ -2707,7 +2707,7 @@ {ExtractOption::kValue}, &result); FormFieldData expected; - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); expected.set_id_attribute(u"password"); expected.set_name(expected.id_attribute()); expected.set_form_control_type(FormControlType::kInputPassword); @@ -2784,11 +2784,11 @@ expected.set_id_attribute(ASCIIToUTF16(test_case.element_id)); expected.set_name(expected.id_attribute()); expected.set_form_control_type(test_case.form_control_type); - expected.max_length = + expected.set_max_length( (test_case.form_control_type == FormControlType::kInputText || test_case.form_control_type == FormControlType::kTextArea) ? FormFieldData::kDefaultMaxLength - : 0; + : 0); expected.autocomplete_attribute = test_case.autocomplete_attribute; expected.parsed_autocomplete = ParseAutocompleteAttribute(test_case.autocomplete_attribute); @@ -2992,7 +2992,7 @@ expected.set_value(u"John"); expected.set_label(u"First name:"); expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]); expected.set_id_attribute(u"lastname"); @@ -3000,7 +3000,7 @@ expected.set_value(u"Smith"); expected.set_label(u"Last name:"); expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]); expected.set_id_attribute(u"street-address"); @@ -3008,7 +3008,7 @@ expected.set_value(u"123 Fantasy Ln.\nApt. 42"); expected.set_label(u"Address:"); expected.set_form_control_type(FormControlType::kTextArea); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]); expected.set_id_attribute(u"state"); @@ -3016,7 +3016,7 @@ expected.set_value(u"CA"); expected.set_label(u"State:"); expected.set_form_control_type(FormControlType::kSelectOne); - expected.max_length = 0; + expected.set_max_length(0); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[3]); expected.set_id_attribute(u"password"); @@ -3024,7 +3024,7 @@ expected.set_value(u"secret"); expected.set_label(u"Password:"); expected.set_form_control_type(FormControlType::kInputPassword); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[4]); expected.set_id_attribute(u"month"); @@ -3032,7 +3032,7 @@ expected.set_value(u"2011-12"); expected.set_label(u"Card expiration:"); expected.set_form_control_type(FormControlType::kInputMonth); - expected.max_length = 0; + expected.set_max_length(0); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[5]); // Check renderer_id. @@ -3282,7 +3282,7 @@ FormFieldData expected; expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); expected.set_id_attribute(u"firstname"); expected.set_name(expected.id_attribute()); @@ -3366,7 +3366,7 @@ FormFieldData expected; expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); expected.set_id_attribute(u"firstname"); expected.set_name(expected.id_attribute()); @@ -4003,7 +4003,7 @@ expected.set_name(expected.id_attribute()); expected.set_value(u"John"); expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); fields.push_back(expected); expected.set_id_attribute(u"middlename"); @@ -4012,7 +4012,7 @@ expected.set_name(expected.id_attribute()); expected.set_value(u"Joe"); expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); fields.push_back(expected); expected.set_id_attribute(u"lastname"); @@ -4021,7 +4021,7 @@ expected.set_name(expected.id_attribute()); expected.set_value(u"Smith"); expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); fields.push_back(expected); expected.set_id_attribute(u"country"); @@ -4030,7 +4030,7 @@ expected.set_name(expected.id_attribute()); expected.set_value(u"US"); expected.set_form_control_type(FormControlType::kSelectOne); - expected.max_length = 0; + expected.set_max_length(0); fields.push_back(expected); expected.set_id_attribute(u"email"); @@ -4039,7 +4039,7 @@ expected.set_name(expected.id_attribute()); expected.set_value(u"john@example.com"); expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); fields.push_back(expected); ExpectLabelsAndTypes( @@ -4795,7 +4795,7 @@ FormFieldData expected; expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); expected.set_label(u"Phone:"); expected.set_name_attribute(u"dayphone1"); @@ -4854,39 +4854,39 @@ expected.set_name_attribute(u"dayphone1"); expected.set_label(u"Phone:"); expected.set_name(expected.name_attribute()); - expected.max_length = 3; + expected.set_max_length(3); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]); expected.set_name_attribute(u"dayphone2"); expected.set_label(u""); expected.set_name(expected.name_attribute()); - expected.max_length = 3; + expected.set_max_length(3); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]); expected.set_name_attribute(u"dayphone3"); expected.set_label(u""); expected.set_name(expected.name_attribute()); - expected.max_length = 4; + expected.set_max_length(4); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]); expected.set_name_attribute(u"dayphone4"); expected.set_label(u"ext.:"); expected.set_name(expected.name_attribute()); - expected.max_length = 5; + expected.set_max_length(5); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[3]); // When unspecified `size`, default is returned. expected.set_name_attribute(u"default1"); expected.set_label({}); expected.set_name(expected.name_attribute()); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[4]); // When invalid `size`, default is returned. expected.set_name_attribute(u"invalid1"); expected.set_label({}); expected.set_name(expected.name_attribute()); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[5]); } @@ -5078,7 +5078,7 @@ : i == 2 ? u"select_option" : u"selectlist_option"; form.fields[i].set_value(u"undo_" + type + u"_1"); - form.fields[i].is_autofilled = false; + form.fields[i].set_is_autofilled(false); undo_fields.push_back(form.fields[i]); } @@ -5387,7 +5387,7 @@ expected.set_value(u"John"); expected.set_label(u"John"); expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]); expected.set_id_attribute(u"lastname"); @@ -5395,7 +5395,7 @@ expected.set_value(u"Smith"); expected.set_label(u"Smith"); expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]); expected.set_id_attribute(u"country"); @@ -5403,7 +5403,7 @@ expected.set_value(u"Albania"); expected.set_label({}); expected.set_form_control_type(FormControlType::kSelectOne); - expected.max_length = 0; + expected.set_max_length(0); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]); form.fields.clear(); @@ -5421,7 +5421,7 @@ expected.set_value(u"John"); expected.set_label(u"John"); expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[0]); expected.set_id_attribute(u"lastname"); @@ -5429,7 +5429,7 @@ expected.set_value(u"Smith"); expected.set_label(u"Smith"); expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[1]); expected.set_id_attribute(u"country"); @@ -5437,7 +5437,7 @@ expected.set_value(u"AL"); expected.set_label({}); expected.set_form_control_type(FormControlType::kSelectOne); - expected.max_length = 0; + expected.set_max_length(0); EXPECT_FORM_FIELD_DATA_EQUALS(expected, fields[2]); } @@ -5463,7 +5463,7 @@ FormFieldData expected; expected.set_form_control_type(FormControlType::kInputText); - expected.max_length = FormFieldData::kDefaultMaxLength; + expected.set_max_length(FormFieldData::kDefaultMaxLength); expected.set_id_attribute(u"firstname"); expected.set_name(expected.id_attribute());
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index fcb11e89..efc12dc 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -5589,6 +5589,7 @@ sources = [ "../browser/accessibility/live_caption/live_caption_surface_browsertest.cc", + "../browser/apps/app_service/lacros_browser_shelf_lacros_browsertest.cc", "../browser/chromeos/enterprise/cloud_storage/one_drive_pref_observer_browsertest.cc", "../browser/chromeos/extensions/contact_center_insights/contact_center_insights_extension_manager_lacros_browsertest.cc", "../browser/chromeos/extensions/info_private_lacros_apitest.cc", @@ -5758,6 +5759,7 @@ "//chromeos/ui/frame", "//chromeos/ui/frame:test_support", "//components/account_manager_core:test_support", + "//components/app_constants", "//components/captive_portal/content:content", "//components/captive_portal/core:buildflags", "//components/feature_engagement/public:public",
diff --git a/chrome/test/chromedriver/chrome/devtools_client_impl.cc b/chrome/test/chromedriver/chrome/devtools_client_impl.cc index c5d3b9f..2e5a423 100644 --- a/chrome/test/chromedriver/chrome/devtools_client_impl.cc +++ b/chrome/test/chromedriver/chrome/devtools_client_impl.cc
@@ -91,7 +91,7 @@ return Status{kUnknownError, "name is missing in the Runtime.bindingCalled params"}; } - if (*name != "sendBidiResponse") { + if (*name != "sendBidiResponse" && *name != "sendDebugMessage") { return Status{kOk}; } @@ -287,6 +287,16 @@ return status; } } + if (IsVLogOn(Log::kDebug)) { + // If debug logs are on, provide a channel for Mapper debug logs. + base::Value::Dict params; + params.Set("name", "sendDebugMessage"); + status = + SendCommandAndIgnoreResponse("Runtime.addBinding", std::move(params)); + if (status.IsError()) { + return status; + } + } { base::Value::Dict params; params.Set("expression", std::move(bidi_mapper_script));
diff --git a/chrome/test/data/extensions/api_test/passwords_private/test.js b/chrome/test/data/extensions/api_test/passwords_private/test.js index 32fdb2af..1e393392 100644 --- a/chrome/test/data/extensions/api_test/passwords_private/test.js +++ b/chrome/test/data/extensions/api_test/passwords_private/test.js
@@ -739,13 +739,15 @@ }, function changePasswordManagerPin() { - chrome.passwordsPrivate.changePasswordManagerPin(); - chrome.test.assertNoLastError(); - chrome.test.succeed(); + chrome.passwordsPrivate.changePasswordManagerPin(success => { + chrome.test.assertFalse(success); + chrome.test.assertNoLastError(); + chrome.test.succeed(); + }); }, function isPasswordManagerPinAvailable() { var callback = function(available) { - chrome.test.assertEq(available, false); + chrome.test.assertFalse(available); chrome.test.succeed(); };
diff --git a/chrome/test/data/webui/cr_components/most_visited_test.ts b/chrome/test/data/webui/cr_components/most_visited_test.ts index dbeec2d4..27b1ed2 100644 --- a/chrome/test/data/webui/cr_components/most_visited_test.ts +++ b/chrome/test/data/webui/cr_components/most_visited_test.ts
@@ -1295,7 +1295,7 @@ await handler.whenCalled('prerenderMostVisitedTile'); }); - test('prerender cancelation', async () => { + test('prerender cancelation and retrigger', async () => { // Arrange. await addTiles(1); @@ -1317,5 +1317,15 @@ // Make sure Prerendering has been canceled. await handler.whenCalled('cancelPrerender'); + + tileLink.dispatchEvent(mouseEnterEvent); + + // Make sure Prerendering can be re-triggered + await handler.whenCalled('prerenderMostVisitedTile'); + + tileLink.dispatchEvent(mouseExitEvent); + + // Make sure Prerendering has been canceled. + await handler.whenCalled('cancelPrerender'); }); });
diff --git a/chrome/test/data/webui/password_manager/settings_section_test.ts b/chrome/test/data/webui/password_manager/settings_section_test.ts index 2bd3cde..44d06fbd 100644 --- a/chrome/test/data/webui/password_manager/settings_section_test.ts +++ b/chrome/test/data/webui/password_manager/settings_section_test.ts
@@ -685,4 +685,38 @@ assertFalse(!!changePasswordManagerPinRow); }); + + test('After successful PIN Change toast is shown', async function() { + passwordManager.data.isPasswordManagerPinAvailable = true; + + const section = document.createElement('settings-section'); + document.body.appendChild(section); + await flushTasks(); + + const changePasswordManagerPinRow = + section.shadowRoot!.querySelector<HTMLElement>( + '#changePasswordManagerPinRow'); + + assertTrue(!!changePasswordManagerPinRow); + + changePasswordManagerPinRow.click(); + + await passwordManager.whenCalled('changePasswordManagerPin'); + assertFalse(section.$.toast.open); + + passwordManager.data.changePasswordManagerPinSuccesful = false; + changePasswordManagerPinRow.click(); + + await passwordManager.whenCalled('changePasswordManagerPin'); + assertFalse(section.$.toast.open); + + passwordManager.data.changePasswordManagerPinSuccesful = true; + changePasswordManagerPinRow.click(); + + await passwordManager.whenCalled('changePasswordManagerPin'); + assertTrue(section.$.toast.open); + assertEquals( + loadTimeData.getString('passwordManagerPinChanged'), + section.$.toast.textContent!.trim()); + }); });
diff --git a/chrome/test/data/webui/password_manager/test_password_manager_proxy.ts b/chrome/test/data/webui/password_manager/test_password_manager_proxy.ts index 426c785..db5fae2 100644 --- a/chrome/test/data/webui/password_manager/test_password_manager_proxy.ts +++ b/chrome/test/data/webui/password_manager/test_password_manager_proxy.ts
@@ -25,6 +25,7 @@ isAccountStorageDefault: boolean, passwords: chrome.passwordsPrivate.PasswordUiEntry[], isPasswordManagerPinAvailable: boolean, + changePasswordManagerPinSuccesful: boolean|null, }; listeners: { @@ -103,6 +104,7 @@ isAccountStorageDefault: false, passwords: [], isPasswordManagerPinAvailable: false, + changePasswordManagerPinSuccesful: null, }; // Holds listeners so they can be called when needed. @@ -383,6 +385,10 @@ changePasswordManagerPin() { this.methodCalled('changePasswordManagerPin'); + if (this.data.changePasswordManagerPinSuccesful !== null) { + return Promise.resolve(this.data.changePasswordManagerPinSuccesful); + } + return Promise.reject(new Error()); } isPasswordManagerPinAvailable(): Promise<boolean> {
diff --git a/chrome/test/data/webui/settings/site_list_entry_test.ts b/chrome/test/data/webui/settings/site_list_entry_test.ts index 29fdf5b..69c3a07 100644 --- a/chrome/test/data/webui/settings/site_list_entry_test.ts +++ b/chrome/test/data/webui/settings/site_list_entry_test.ts
@@ -189,6 +189,26 @@ assertEquals('', siteDescription.textContent); }); + // Verify that tracking protection exceptions don't have an embedding-origin + // description. + test('tracking protection exception', function() { + testElement.model = { + category: ContentSettingsTypes.TRACKING_PROTECTION, + controlledBy: chrome.settingsPrivate.ControlledBy.OWNER, + displayName: '', + embeddingOrigin: 'http://example.com', + description: '', + enforcement: null, + incognito: false, + isEmbargoed: false, + origin: SITE_EXCEPTION_WILDCARD, + setting: ContentSetting.DEFAULT, + }; + flush(); + const siteDescription = testElement.$$('#siteDescription')!; + assertEquals('', siteDescription.textContent); + }); + // Verify that exceptions with both patterns have proper description for both // lists. test('cookies exception with both patterns set', function() {
diff --git a/chrome/test/data/webui/settings/site_list_test.ts b/chrome/test/data/webui/settings/site_list_test.ts index 68ee78f9..15e7ac99 100644 --- a/chrome/test/data/webui/settings/site_list_test.ts +++ b/chrome/test/data/webui/settings/site_list_test.ts
@@ -1521,4 +1521,20 @@ assertEquals(primaryPattern, expectedPattern); assertEquals(secondaryPattern, SITE_EXCEPTION_WILDCARD); }); + + test('add tracking protection exception', async function() { + dialog.set('category', ContentSettingsTypes.TRACKING_PROTECTION); + flush(); + + // Enter a pattern and click the button. + const expectedPattern = 'foo-bar.com'; + await inputText(expectedPattern); + dialog.$.add.click(); + + // The created exception has primary pattern wildcard. + const [primaryPattern, secondaryPattern] = + await browserProxy.whenCalled('setCategoryPermissionForPattern'); + assertEquals(primaryPattern, SITE_EXCEPTION_WILDCARD); + assertEquals(secondaryPattern, expectedPattern); + }); });
diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt index 8a96c496..484d384 100644 --- a/chromeos/profiles/atom.afdo.newest.txt +++ b/chromeos/profiles/atom.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-atom-125-6411.0-1713176715-benchmark-126.0.6423.0-r1-redacted.afdo.xz +chromeos-chrome-amd64-atom-125-6411.0-1713176715-benchmark-126.0.6423.0-r2-redacted.afdo.xz
diff --git a/chromeos/profiles/bigcore.afdo.newest.txt b/chromeos/profiles/bigcore.afdo.newest.txt index e35b8cb..76d7dbf2 100644 --- a/chromeos/profiles/bigcore.afdo.newest.txt +++ b/chromeos/profiles/bigcore.afdo.newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-bigcore-125-6398.0-1713174332-benchmark-126.0.6423.0-r1-redacted.afdo.xz +chromeos-chrome-amd64-bigcore-125-6398.0-1713174332-benchmark-126.0.6423.0-r2-redacted.afdo.xz
diff --git a/clank b/clank index 4799cd3..6e6172a 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit 4799cd305fe7062e4a6e9b455b2bb2c4db50060d +Subproject commit 6e6172a7ecc30400437bbe53d6c8c006ab8f3f48
diff --git a/components/affiliations/core/browser/affiliation_backend.cc b/components/affiliations/core/browser/affiliation_backend.cc index 86f549e8..ae76d17c 100644 --- a/components/affiliations/core/browser/affiliation_backend.cc +++ b/components/affiliations/core/browser/affiliation_backend.cc
@@ -115,8 +115,10 @@ return; facet_manager_it->second->CancelPrefetch(keep_fresh_until); - if (facet_manager_it->second->CanBeDiscarded()) + if (facet_manager_it->second->CanBeDiscarded()) { facet_managers_.erase(facet_uri); + TrimCacheForFacetURI(facet_uri); + } } void AffiliationBackend::KeepPrefetchForFacets(
diff --git a/components/affiliations/core/browser/affiliation_prefetcher.cc b/components/affiliations/core/browser/affiliation_prefetcher.cc index 6d128151..ead0c5b 100644 --- a/components/affiliations/core/browser/affiliation_prefetcher.cc +++ b/components/affiliations/core/browser/affiliation_prefetcher.cc
@@ -66,11 +66,6 @@ for (const FacetURI& facet_uri : facets) { if (facet_uri.is_valid()) { affiliation_service_->CancelPrefetch(facet_uri, base::Time::Max()); - // TODO(b/328037758): Implement `TrimCacheForFacetURI` as part of - // `CancelPrefetch` and remove it from the API. Since now it's a - // responsibility of a source to call `OnFacetsAdded` first before - // invoking `OnFacetsRemoved`. - affiliation_service_->TrimCacheForFacetURI(facet_uri); } } }
diff --git a/components/affiliations/core/browser/affiliation_prefetcher_unittest.cc b/components/affiliations/core/browser/affiliation_prefetcher_unittest.cc index a9b45138..1fb5c2a5 100644 --- a/components/affiliations/core/browser/affiliation_prefetcher_unittest.cc +++ b/components/affiliations/core/browser/affiliation_prefetcher_unittest.cc
@@ -159,12 +159,8 @@ RunUntilIdle(); FacetURI facet = FacetURI::FromCanonicalSpec("https://foo.com"); - { - testing::InSequence in_sequence; - EXPECT_CALL(*mock_affiliation_service(), - CancelPrefetch(facet, base::Time::Max())); - EXPECT_CALL(*mock_affiliation_service(), TrimCacheForFacetURI(facet)); - } + EXPECT_CALL(*mock_affiliation_service(), + CancelPrefetch(facet, base::Time::Max())); src_ptr->RemoveFacet(facet); }
diff --git a/components/affiliations/core/browser/affiliation_service.h b/components/affiliations/core/browser/affiliation_service.h index 24059ffe..ab99e22 100644 --- a/components/affiliations/core/browser/affiliation_service.h +++ b/components/affiliations/core/browser/affiliation_service.h
@@ -91,14 +91,6 @@ // also deletes cache which is no longer needed. virtual void KeepPrefetchForFacets(std::vector<FacetURI> facet_uris) = 0; - // Wipes results of on-demand fetches and expired prefetches from the - // cache, but retains information corresponding to facets that are being - // kept fresh. As no required data is deleted, there will be no network - // requests directly triggered by this call. It will only potentially - // remove data corresponding to the given |facet_uri|, but still only as - // long as the data is no longer needed. - virtual void TrimCacheForFacetURI(const FacetURI& facet_uri) = 0; - // Wipes results from cache which don't correspond to the any facet from // |facet_uris|. virtual void TrimUnusedCache(std::vector<FacetURI> facet_uris) = 0;
diff --git a/components/affiliations/core/browser/affiliation_service_impl.cc b/components/affiliations/core/browser/affiliation_service_impl.cc index cc039f6..ea3cf59 100644 --- a/components/affiliations/core/browser/affiliation_service_impl.cc +++ b/components/affiliations/core/browser/affiliation_service_impl.cc
@@ -243,10 +243,6 @@ std::move(facet_uris)); } -void AffiliationServiceImpl::TrimCacheForFacetURI(const FacetURI& facet_uri) { - PostToBackend(&AffiliationBackend::TrimCacheForFacetURI, facet_uri); -} - void AffiliationServiceImpl::TrimUnusedCache(std::vector<FacetURI> facet_uris) { PostToBackend(&AffiliationBackend::TrimUnusedCache, std::move(facet_uris)); }
diff --git a/components/affiliations/core/browser/affiliation_service_impl.h b/components/affiliations/core/browser/affiliation_service_impl.h index 5d08480..0f2bc959 100644 --- a/components/affiliations/core/browser/affiliation_service_impl.h +++ b/components/affiliations/core/browser/affiliation_service_impl.h
@@ -121,7 +121,6 @@ void CancelPrefetch(const FacetURI& facet_uri, const base::Time& keep_fresh_until) override; - void TrimCacheForFacetURI(const FacetURI& facet_uri) override; void KeepPrefetchForFacets(std::vector<FacetURI> facet_uris) override; void TrimUnusedCache(std::vector<FacetURI> facet_uris) override; void GetGroupingInfo(std::vector<FacetURI> facet_uris,
diff --git a/components/affiliations/core/browser/fake_affiliation_service.cc b/components/affiliations/core/browser/fake_affiliation_service.cc index d1646d7..2000d2f 100644 --- a/components/affiliations/core/browser/fake_affiliation_service.cc +++ b/components/affiliations/core/browser/fake_affiliation_service.cc
@@ -38,7 +38,6 @@ const base::Time& keep_fresh_until) {} void FakeAffiliationService::KeepPrefetchForFacets( std::vector<FacetURI> facet_uris) {} -void FakeAffiliationService::TrimCacheForFacetURI(const FacetURI& facet_uri) {} void FakeAffiliationService::TrimUnusedCache(std::vector<FacetURI> facet_uris) { } void FakeAffiliationService::GetGroupingInfo(std::vector<FacetURI> facet_uris,
diff --git a/components/affiliations/core/browser/fake_affiliation_service.h b/components/affiliations/core/browser/fake_affiliation_service.h index 7e7c5f6..69c2b85 100644 --- a/components/affiliations/core/browser/fake_affiliation_service.h +++ b/components/affiliations/core/browser/fake_affiliation_service.h
@@ -27,7 +27,6 @@ void CancelPrefetch(const FacetURI& facet_uri, const base::Time& keep_fresh_until) override; void KeepPrefetchForFacets(std::vector<FacetURI> facet_uris) override; - void TrimCacheForFacetURI(const FacetURI& facet_uri) override; void TrimUnusedCache(std::vector<FacetURI> facet_uris) override; void GetGroupingInfo(std::vector<FacetURI> facet_uris, GroupsCallback callback) override;
diff --git a/components/affiliations/core/browser/mock_affiliation_service.h b/components/affiliations/core/browser/mock_affiliation_service.h index 5878c60..c1f0326 100644 --- a/components/affiliations/core/browser/mock_affiliation_service.h +++ b/components/affiliations/core/browser/mock_affiliation_service.h
@@ -43,7 +43,6 @@ (const FacetURI&, const base::Time&), (override)); MOCK_METHOD(void, KeepPrefetchForFacets, (std::vector<FacetURI>), (override)); - MOCK_METHOD(void, TrimCacheForFacetURI, (const FacetURI&), (override)); MOCK_METHOD(void, TrimUnusedCache, (std::vector<FacetURI>), (override)); MOCK_METHOD(void, GetGroupingInfo,
diff --git a/components/android_autofill/browser/android_autofill_manager.cc b/components/android_autofill/browser/android_autofill_manager.cc index 300dc4e..a595a7a 100644 --- a/components/android_autofill/browser/android_autofill_manager.cc +++ b/components/android_autofill/browser/android_autofill_manager.cc
@@ -214,7 +214,7 @@ std::erase_if(form.fields, [&](const FormFieldData& field) { // The renderer doesn't fill such fields, and therefore they can be removed // from here to reduce IPC traffic and avoid accidental filling. - return !field.is_autofilled || field.value().empty(); + return !field.is_autofilled() || field.value().empty(); }); driver().ApplyFormAction(mojom::FormActionType::kFill, action_persistence, form, triggered_origin, {});
diff --git a/components/android_autofill/browser/android_autofill_provider.cc b/components/android_autofill/browser/android_autofill_provider.cc index 4e3fe1d..80b6426f 100644 --- a/components/android_autofill/browser/android_autofill_provider.cc +++ b/components/android_autofill/browser/android_autofill_provider.cc
@@ -587,7 +587,7 @@ const FormFieldData& field) const { size_t field_index = 0u; return form_ && form_->GetFieldIndex(field, &field_index) && - form_->form().fields[field_index].is_autofilled; + form_->form().fields[field_index].is_autofilled(); } bool AndroidAutofillProvider::IntendsToShowBottomSheet(
diff --git a/components/android_autofill/browser/form_field_data_android.cc b/components/android_autofill/browser/form_field_data_android.cc index 5537c580..5acc192 100644 --- a/components/android_autofill/browser/form_field_data_android.cc +++ b/components/android_autofill/browser/form_field_data_android.cc
@@ -72,7 +72,7 @@ void FormFieldDataAndroid::OnFormFieldDidChange(std::u16string_view value) { field_->set_value(std::u16string(value)); - field_->is_autofilled = false; + field_->set_is_autofilled(false); bridge_->UpdateValue(value); }
diff --git a/components/android_autofill/browser/form_field_data_android_bridge_impl.cc b/components/android_autofill/browser/form_field_data_android_bridge_impl.cc index 47315bd2..740f9e1 100644 --- a/components/android_autofill/browser/form_field_data_android_bridge_impl.cc +++ b/components/android_autofill/browser/form_field_data_android_bridge_impl.cc
@@ -81,7 +81,7 @@ /*optionValues=*/ProjectOptions(field.options, &SelectOption::value), /*optionContents=*/ProjectOptions(field.options, &SelectOption::content), IsCheckable(field.check_status), IsChecked(field.check_status), - field.max_length, + field.max_length(), /*heuristicType=*/field_types.heuristic_type.IsUnknown() ? nullptr : ConvertUTF8ToJavaString(env, @@ -95,7 +95,7 @@ ProjectOptions(field.datalist_options, &SelectOption::value), /*datalistLabels=*/ ProjectOptions(field.datalist_options, &SelectOption::content), - /*visible=*/field.IsFocusable(), field.is_autofilled); + /*visible=*/field.IsFocusable(), field.is_autofilled()); java_ref_ = JavaObjectWeakGlobalRef(env, obj); return obj; } @@ -108,7 +108,7 @@ return; } - field.is_autofilled = Java_FormFieldData_isAutofilled(env, obj); + field.set_is_autofilled(Java_FormFieldData_isAutofilled(env, obj)); if (IsCheckable(field.check_status)) { SetCheckStatus(&field, true, Java_FormFieldData_isChecked(env, obj)); return;
diff --git a/components/android_autofill/browser/form_field_data_android_unittest.cc b/components/android_autofill/browser/form_field_data_android_unittest.cc index 60422103..332b72d 100644 --- a/components/android_autofill/browser/form_field_data_android_unittest.cc +++ b/components/android_autofill/browser/form_field_data_android_unittest.cc
@@ -105,11 +105,11 @@ constexpr std::u16string_view kSampleValue = u"SomeValue"; FormFieldData field; - field.is_autofilled = true; + field.set_is_autofilled(true); FormFieldDataAndroid field_android(&field); EXPECT_CALL(bridge(), UpdateValue(kSampleValue)); field_android.OnFormFieldDidChange(kSampleValue); - EXPECT_FALSE(field.is_autofilled); + EXPECT_FALSE(field.is_autofilled()); EXPECT_EQ(field.value(), kSampleValue); }
diff --git a/components/autofill/content/browser/content_autofill_driver_unittest.cc b/components/autofill/content/browser/content_autofill_driver_unittest.cc index 7eb0d269b..6f023bd 100644 --- a/components/autofill/content/browser/content_autofill_driver_unittest.cc +++ b/components/autofill/content/browser/content_autofill_driver_unittest.cc
@@ -87,8 +87,8 @@ return lhs_field.value() == rhs_field.value && lhs_field.renderer_id() == rhs_field.renderer_id && lhs_field.host_form_id == rhs_field.host_form_id && - lhs_field.section == rhs_field.section && - lhs_field.is_autofilled == rhs_field.is_autofilled && + lhs_field.section() == rhs_field.section && + lhs_field.is_autofilled() == rhs_field.is_autofilled && lhs_field.force_override == rhs_field.force_override; }
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc index c196060..ec557ee 100644 --- a/components/autofill/content/renderer/autofill_agent.cc +++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -1521,7 +1521,7 @@ &FormFieldData::renderer_id); it != provisionally_saved_form()->fields.end()) { it->set_value(element.Value().Utf16()); - it->is_autofilled = element.IsAutofilled(); + it->set_is_autofilled(element.IsAutofilled()); } } if (!was_autofilled) {
diff --git a/components/autofill/content/renderer/autofill_agent_browsertest.cc b/components/autofill/content/renderer/autofill_agent_browsertest.cc index e6de44a..2dae23b6 100644 --- a/components/autofill/content/renderer/autofill_agent_browsertest.cc +++ b/components/autofill/content/renderer/autofill_agent_browsertest.cc
@@ -664,7 +664,7 @@ std::u16string prior_value = form.fields[0].value(); form.fields[0].set_value(form.fields[0].value() + u"AUTOFILLED"); - form.fields[0].is_autofilled = true; + form.fields[0].set_is_autofilled(true); ASSERT_EQ(field.GetAutofillState(), blink::WebAutofillState::kNotFilled); autofill_agent().ApplyFieldsAction(mojom::FormActionType::kFill, @@ -761,7 +761,7 @@ {form_util::ExtractOption::kValue}, &form_field); form_field.set_value(u"autofilled"); - form_field.is_autofilled = true; + form_field.set_is_autofilled(true); ASSERT_EQ(field.GetAutofillState(), blink::WebAutofillState::kNotFilled); FormData form; @@ -803,7 +803,7 @@ ASSERT_EQ(1u, form.fields.size()); form.fields[0].set_value(u"autofilled"); - form.fields[0].is_autofilled = true; + form.fields[0].set_is_autofilled(true); ASSERT_EQ(field.GetAutofillState(), blink::WebAutofillState::kNotFilled); autofill_agent().ApplyFieldsAction(mojom::FormActionType::kFill, @@ -1036,7 +1036,7 @@ for (FormFieldData& field : form->fields) { field.set_value(field.id_attribute() + u" autofilled"); - field.is_autofilled = true; + field.set_is_autofilled(true); } // Update `AutofillAgent::last_queried_element_`.
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc index b915ae39..b69e519 100644 --- a/components/autofill/content/renderer/form_autofill_util.cc +++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -1931,7 +1931,7 @@ field->form_control_ax_id = element.GetAxId(); field->set_form_control_type( ToAutofillFormControlType(element.FormControlTypeForAutofill())); - field->max_length = GetMaxLength(element); + field->set_max_length(GetMaxLength(element)); field->autocomplete_attribute = GetAutocompleteAttribute(element); field->parsed_autocomplete = ParseAutocompleteAttribute(field->autocomplete_attribute); @@ -2001,7 +2001,7 @@ } // The browser doesn't need to differentiate between preview and autofill. - field->is_autofilled = element.IsAutofilled(); + field->set_is_autofilled(element.IsAutofilled()); field->is_user_edited = element.UserHasEditedTheField(); field->is_focusable = IsWebElementFocusableForAutofill(element); field->is_visible = kAutofillDetectFieldVisibilityEnabled
diff --git a/components/autofill/content/renderer/form_cache_browsertest.cc b/components/autofill/content/renderer/form_cache_browsertest.cc index 2c4cb04..ec4ced1 100644 --- a/components/autofill/content/renderer/form_cache_browsertest.cc +++ b/components/autofill/content/renderer/form_cache_browsertest.cc
@@ -435,7 +435,7 @@ values_to_fill, field_to_fill.element->NameForAutofill()); ASSERT_TRUE(value_to_fill != nullptr); value_to_fill->set_value(field_to_fill.value); - value_to_fill->is_autofilled = true; + value_to_fill->set_is_autofilled(true); } if (checkbox_element) { @@ -443,7 +443,7 @@ FindFieldByName(values_to_fill, checkbox_element->NameForAutofill()); ASSERT_TRUE(value_to_fill != nullptr); value_to_fill->check_status = fill_checkbox_check_status; - value_to_fill->is_autofilled = true; + value_to_fill->set_is_autofilled(true); } std::vector<FormFieldData::FillData> fields_to_fill;
diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc index e12c1db..8978f89c 100644 --- a/components/autofill/core/browser/autofill_external_delegate.cc +++ b/components/autofill/core/browser/autofill_external_delegate.cc
@@ -885,7 +885,7 @@ // filling granularity. The exact type is not important, what matters here // is that the user targeted one ONE field, i.e, field-by-field filling. last_field_types_to_fill_for_address_form_section_[autofill_trigger_field - ->section] = { + ->section()] = { *suggestion.field_by_field_filling_type_used}; } const bool is_triggering_field_address = @@ -1002,7 +1002,7 @@ if (autofill_trigger_field && kAutofillAddressSuggestions.contains(popup_item_id) && !is_preview) { last_field_types_to_fill_for_address_form_section_[autofill_trigger_field - ->section] = + ->section()] = trigger_details.field_types_to_fill; } }
diff --git a/components/autofill/core/browser/autofill_external_delegate_unittest.cc b/components/autofill/core/browser/autofill_external_delegate_unittest.cc index dfce06e..427b2c9 100644 --- a/components/autofill/core/browser/autofill_external_delegate_unittest.cc +++ b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
@@ -2000,7 +2000,7 @@ EXPECT_EQ( external_delegate().GetLastFieldTypesToFillForSection( - params.section.value_or(get_triggering_autofill_field()->section)), + params.section.value_or(get_triggering_autofill_field()->section())), params.expected_last_field_types_to_fill_for_section); }
diff --git a/components/autofill/core/browser/autofill_feedback_data.cc b/components/autofill/core/browser/autofill_feedback_data.cc index 57bcdd0..327cd5f 100644 --- a/components/autofill/core/browser/autofill_feedback_data.cc +++ b/components/autofill/core/browser/autofill_feedback_data.cc
@@ -50,7 +50,7 @@ field_data.Set("serverTypeIsOverride", field->server_type_prediction_is_override()); field_data.Set("htmlType", FieldTypeToStringView(field->html_type())); - field_data.Set("section", field->section.ToString()); + field_data.Set("section", field->section().ToString()); field_data.Set("rank", base::NumberToString(field->rank())); field_data.Set("rankInSignatureGroup", base::NumberToString(field->rank_in_signature_group()));
diff --git a/components/autofill/core/browser/autofill_form_test_utils.cc b/components/autofill/core/browser/autofill_form_test_utils.cc index 49819d6..4babd7f1 100644 --- a/components/autofill/core/browser/autofill_form_test_utils.cc +++ b/components/autofill/core/browser/autofill_form_test_utils.cc
@@ -121,12 +121,12 @@ ff.placeholder = *fd.placeholder; } if (fd.max_length) { - ff.max_length = *fd.max_length; + ff.set_max_length(*fd.max_length); } if (fd.origin) { ff.origin = *fd.origin; } - ff.is_autofilled = fd.is_autofilled.value_or(false); + ff.set_is_autofilled(fd.is_autofilled.value_or(false)); ff.should_autocomplete = fd.should_autocomplete; ff.properties_mask = fd.properties_mask; ff.check_status = fd.check_status; @@ -218,7 +218,7 @@ if (test_case.form_flags.section_count) { std::set<Section> section_names; for (const auto& field : *form_structure) - section_names.insert(field->section); + section_names.insert(field->section()); EXPECT_EQ(*test_case.form_flags.section_count, static_cast<int>(section_names.size())); }
diff --git a/components/autofill/core/browser/autofill_suggestion_generator.cc b/components/autofill/core/browser/autofill_suggestion_generator.cc index ef59a75..db14fb2 100644 --- a/components/autofill/core/browser/autofill_suggestion_generator.cc +++ b/components/autofill/core/browser/autofill_suggestion_generator.cc
@@ -1036,7 +1036,7 @@ std::vector<raw_ptr<const AutofillProfile, VectorExperimental>> profiles_to_suggest = GetProfilesToSuggest( trigger_field_type, field_value_for_filtering, - trigger_field.is_autofilled, field_types, trigger_source); + trigger_field.is_autofilled(), field_types, trigger_source); // If autofill for addresses is triggered from the context menu on an address // field and no suggestions can be shown (i.e. if a user has only addresses // without emails and then triggers autofill from the context menu on an email @@ -1058,12 +1058,12 @@ } std::vector<Suggestion> suggestions = CreateSuggestionsFromProfiles( profiles_to_suggest, field_types, last_targeted_fields, - trigger_field_type, trigger_field.max_length); + trigger_field_type, trigger_field.max_length()); if (suggestions.empty()) { return suggestions; } - base::ranges::move(GetAddressFooterSuggestions(trigger_field.is_autofilled), + base::ranges::move(GetAddressFooterSuggestions(trigger_field.is_autofilled()), std::back_inserter(suggestions)); return suggestions; } @@ -1434,7 +1434,7 @@ base::ranges::move( GetCreditCardFooterSuggestions( should_show_scan_credit_card, should_show_cards_from_account, - trigger_field.is_autofilled, display_gpay_logo), + trigger_field.is_autofilled(), display_gpay_logo), std::back_inserter(suggestions)); return suggestions; } @@ -1497,7 +1497,7 @@ base::ranges::move( GetCreditCardFooterSuggestions(/*should_show_scan_credit_card=*/false, /*should_show_cards_from_account=*/false, - trigger_field.is_autofilled, + trigger_field.is_autofilled(), /*with_gpay_logo=*/true), std::back_inserter(suggestions)); @@ -1649,7 +1649,7 @@ field_contents, trigger_field_type, credit_card->record_type() == CreditCard::RecordType::kMaskedServerCard, - trigger_field.is_autofilled)) { + trigger_field.is_autofilled())) { continue; } if (include_virtual_cards && ShouldShowVirtualCardOption(credit_card)) {
diff --git a/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc b/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc index 3f87988..c4d4a8c 100644 --- a/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc +++ b/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc
@@ -2277,7 +2277,7 @@ personal_data().AddProfile(test::GetFullProfile()); FormFieldData field; - field.is_autofilled = true; + field.set_is_autofilled(true); std::vector<Suggestion> suggestions = suggestion_generator().GetSuggestionsForProfiles( {NAME_FIRST}, field, NAME_FIRST, @@ -2296,7 +2296,7 @@ personal_data().AddProfile(test::GetFullProfile()); FormFieldData field; - field.is_autofilled = true; + field.set_is_autofilled(true); std::vector<Suggestion> suggestions = suggestion_generator().GetSuggestionsForProfiles( {NAME_FIRST}, field, NAME_FIRST, @@ -2492,7 +2492,7 @@ {server_card.guid(), VirtualCardUsageData::VirtualCardLastFour(u"4444")}); autofill_metrics::CardMetadataLoggingContext metadata_logging_context; FormFieldData field; - field.is_autofilled = true; + field.set_is_autofilled(true); std::vector<Suggestion> suggestions = suggestion_generator().GetSuggestionsForVirtualCardStandaloneCvc( field, metadata_logging_context, virtual_card_guid_to_last_four_map); @@ -2520,7 +2520,7 @@ {server_card.guid(), VirtualCardUsageData::VirtualCardLastFour(u"4444")}); autofill_metrics::CardMetadataLoggingContext metadata_logging_context; FormFieldData field; - field.is_autofilled = true; + field.set_is_autofilled(true); std::vector<Suggestion> suggestions = suggestion_generator().GetSuggestionsForVirtualCardStandaloneCvc( field, metadata_logging_context, virtual_card_guid_to_last_four_map); @@ -2649,7 +2649,7 @@ bool with_cvc; autofill_metrics::CardMetadataLoggingContext metadata_logging_context; FormFieldData field; - field.is_autofilled = true; + field.set_is_autofilled(true); std::vector<Suggestion> suggestions = suggestion_generator().GetSuggestionsForCreditCards( field, CREDIT_CARD_NUMBER, kDefaultTriggerSource, @@ -2716,7 +2716,7 @@ bool with_cvc; autofill_metrics::CardMetadataLoggingContext metadata_logging_context; FormFieldData field; - field.is_autofilled = true; + field.set_is_autofilled(true); std::vector<Suggestion> suggestions = suggestion_generator().GetSuggestionsForCreditCards( field, CREDIT_CARD_NUMBER, kDefaultTriggerSource, @@ -2741,7 +2741,7 @@ bool with_cvc; autofill_metrics::CardMetadataLoggingContext metadata_logging_context; FormFieldData field; - field.is_autofilled = true; + field.set_is_autofilled(true); std::vector<Suggestion> suggestions = suggestion_generator().GetSuggestionsForCreditCards( field, CREDIT_CARD_NUMBER, kDefaultTriggerSource,
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc index 59897bf..7b32468 100644 --- a/components/autofill/core/browser/browser_autofill_manager.cc +++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -811,7 +811,7 @@ #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) if (autofill_field->autocomplete_attribute == "off" && autofill_field->did_trigger_suggestions() && - !autofill_field->is_autofilled && + !autofill_field->is_autofilled() && !autofill_field->previously_autofilled() && base::FeatureList::IsEnabled( features::kAutofillSuggestionNStrikeModel)) { @@ -1034,21 +1034,21 @@ UpdatePendingForm(form); - if (!user_did_type_ || autofill_field->is_autofilled) { + if (!user_did_type_ || autofill_field->is_autofilled()) { user_did_type_ = true; form_interactions_ukm_logger()->LogTextFieldDidChange(*form_structure, *autofill_field); } auto* logger = GetEventFormLogger(*autofill_field); - if (!autofill_field->is_autofilled) { + if (!autofill_field->is_autofilled()) { if (logger) { logger->OnTypedIntoNonFilledField(); } } - if (autofill_field->is_autofilled) { - autofill_field->is_autofilled = false; + if (autofill_field->is_autofilled()) { + autofill_field->set_is_autofilled(false); autofill_field->set_previously_autofilled(true); if (logger) { logger->OnEditedAutofilledField(); @@ -2260,7 +2260,7 @@ CHECK(form_structure && trigger_autofill_field); std::optional<FieldTypeSet> last_address_fields_to_fill_for_section = external_delegate_->GetLastFieldTypesToFillForSection( - trigger_autofill_field->section); + trigger_autofill_field->section()); // Getting the filling-relevant fields so that suggestions are based only on // those fields. Function BrowserAutofillManager::GetFieldFillingSkipReasons // assumes that the passed FormData and FormStructure have the same size. If
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc index 6886380..8b01917 100644 --- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc +++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -479,7 +479,7 @@ MOCK_METHOD(void, OnCreditCardScanned, (const CreditCard& card), (override)); MOCK_METHOD(void, ShowPaymentMethodSettings, (), (override)); MOCK_METHOD(void, - SuggestionSelected, + CreditCardSuggestionSelected, (std::string unique_id, bool is_virtual), (override)); MOCK_METHOD(void, OnDismissed, (bool dismissed_by_user), (override)); @@ -1857,7 +1857,7 @@ // First name is already autofilled which will make the section appear as // "already autofilled". - form.fields[0].is_autofilled = true; + form.fields[0].set_is_autofilled(true); // Two profiles have the same last name, and the third shares the same first // letter for last name. @@ -1908,7 +1908,7 @@ // First name is already autofilled which will make the section appear as // "already autofilled". - form.fields[0].is_autofilled = true; + form.fields[0].set_is_autofilled(true); FormFieldData field = CreateTestFormField("First Name", "firstname", "E", FormControlType::kInputText); @@ -3346,7 +3346,7 @@ FormsSeen({form}); // Mark one of the fields as filled. - form.fields[2].is_autofilled = true; + form.fields[2].set_is_autofilled(true); GetAutofillSuggestions(form, form.fields[0]); // Test that we sent the right values to the external delegate. external_delegate()->CheckSuggestions( @@ -3378,7 +3378,7 @@ personal_data().AddProfile(profile); FormFieldData& field = form.fields[0]; - field.is_autofilled = true; + field.set_is_autofilled(true); field.set_value(u"Elvis"); GetAutofillSuggestions(form, field); // Test that we sent the right values to the external delegate. @@ -4963,11 +4963,11 @@ // Although the heuristic types of the first two fields belongs to the address // section, the final fields' section should be based on the overall // prediction, therefore they should be grouped in one section. - const auto section = form_structure->field(0)->section; - EXPECT_EQ(section, form_structure->field(1)->section); - EXPECT_EQ(section, form_structure->field(2)->section); - EXPECT_EQ(section, form_structure->field(3)->section); - EXPECT_EQ(section, form_structure->field(4)->section); + const auto section = form_structure->field(0)->section(); + EXPECT_EQ(section, form_structure->field(1)->section()); + EXPECT_EQ(section, form_structure->field(2)->section()); + EXPECT_EQ(section, form_structure->field(3)->section()); + EXPECT_EQ(section, form_structure->field(4)->section()); } // Test that the form signature for an uploaded form always matches the form
diff --git a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc index 609a466..147b4ab2 100644 --- a/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc +++ b/components/autofill/core/browser/crowdsourcing/autofill_crowdsourcing_encoding.cc
@@ -851,13 +851,13 @@ // The sections are mapped to consecutive natural numbers starting at 1. std::map<Section, size_t> section_id_map; for (const auto& field : form->fields()) { - if (!base::Contains(section_id_map, field->section)) { + if (!base::Contains(section_id_map, field->section())) { size_t next_section_id = section_id_map.size() + 1; - section_id_map[field->section] = next_section_id; + section_id_map[field->section()] = next_section_id; } field->AppendLogEventIfNotRepeated(RationalizationFieldLogEvent{ .field_type = field->Type().GetStorableType(), - .section_id = section_id_map[field->section], + .section_id = section_id_map[field->section()], .type_changed = field->Type().GetStorableType() != field->ComputedType().GetStorableType(), });
diff --git a/components/autofill/core/browser/crowdsourcing/disambiguate_possible_field_types.cc b/components/autofill/core/browser/crowdsourcing/disambiguate_possible_field_types.cc index d5cbb6e..492d71c 100644 --- a/components/autofill/core/browser/crowdsourcing/disambiguate_possible_field_types.cc +++ b/components/autofill/core/browser/crowdsourcing/disambiguate_possible_field_types.cc
@@ -48,7 +48,7 @@ // If a field was autofilled on form submission and the value was accepted, set // possible types to the autofilled type. void SetPossibleTypesToAutofilledTypeIfAvailable(AutofillField& field) { - if (field.is_autofilled && field.autofilled_type() && + if (field.is_autofilled() && field.autofilled_type() && base::FeatureList::IsEnabled( features::kAutofillDisambiguateContradictingFieldTypes)) { field.set_possible_types({*field.autofilled_type()});
diff --git a/components/autofill/core/browser/crowdsourcing/disambiguate_possible_field_types_unittest.cc b/components/autofill/core/browser/crowdsourcing/disambiguate_possible_field_types_unittest.cc index fe829c8..e3ef7fc 100644 --- a/components/autofill/core/browser/crowdsourcing/disambiguate_possible_field_types_unittest.cc +++ b/components/autofill/core/browser/crowdsourcing/disambiguate_possible_field_types_unittest.cc
@@ -48,7 +48,7 @@ test_fields[i].predicted_type)}); if (test_fields[i].is_autofilled) { field.set_autofilled_type(test_fields[i].predicted_type); - field.is_autofilled = true; + field.set_is_autofilled(true); } }
diff --git a/components/autofill/core/browser/field_filling_address_util.cc b/components/autofill/core/browser/field_filling_address_util.cc index a31206b..54e0a8b7 100644 --- a/components/autofill/core/browser/field_filling_address_util.cc +++ b/components/autofill/core/browser/field_filling_address_util.cc
@@ -432,7 +432,7 @@ } if (field_type.group() == FieldTypeGroup::kPhone) { return GetPhoneNumberValueForInput( - field_data.max_length, value, + field_data.max_length(), value, profile.GetInfo(PHONE_HOME_CITY_AND_NUMBER, app_locale)); } if (field_type.GetStorableType() == ADDRESS_HOME_STREET_ADDRESS) { @@ -442,7 +442,7 @@ if (field_type.GetStorableType() == ADDRESS_HOME_STATE) { return GetStateTextForInput( value, data_util::GetCountryCodeWithFallback(profile, app_locale), - field_data.max_length, failure_to_fill); + field_data.max_length(), failure_to_fill); } return value; }
diff --git a/components/autofill/core/browser/field_filling_address_util_unittest.cc b/components/autofill/core/browser/field_filling_address_util_unittest.cc index 1592905..5c451d1 100644 --- a/components/autofill/core/browser/field_filling_address_util_unittest.cc +++ b/components/autofill/core/browser/field_filling_address_util_unittest.cc
@@ -115,7 +115,7 @@ auto test_case = GetParam(); AutofillField field; field.SetHtmlType(test_case.field_type, HtmlFieldMode()); - field.max_length = test_case.field_max_length; + field.set_max_length(test_case.field_max_length); AutofillProfile profile(AddressCountryCode("US")); profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, @@ -383,7 +383,7 @@ auto test_case = GetParam(); AutofillField field; field.SetHtmlType(test_case.field_type, HtmlFieldMode()); - field.max_length = test_case.field_max_length; + field.set_max_length(test_case.field_max_length); AutofillProfile profile = test::GetFullProfile(); profile.SetRawInfo(ADDRESS_HOME_STATE, test_case.value_to_fill); @@ -702,7 +702,7 @@ AutofillField field(test::CreateTestFormField("State", "state", "", FormControlType::kInputText)); field.set_heuristic_type(GetActiveHeuristicSource(), ADDRESS_HOME_STATE); - field.max_length = 4; + field.set_max_length(4); AutofillProfile profile(AddressCountryCode("DE")); profile.SetRawInfo(ADDRESS_HOME_STATE, u"Bavaria"); @@ -776,7 +776,7 @@ AutofillField field{test::CreateTestFormField("State", "state", "", FormControlType::kInputText)}; field.set_heuristic_type(GetActiveHeuristicSource(), ADDRESS_HOME_STATE); - field.max_length = 4; + field.set_max_length(4); AutofillProfile profile(AddressCountryCode("DE")); profile.SetRawInfo(ADDRESS_HOME_STATE, u"Bavaria");
diff --git a/components/autofill/core/browser/field_filling_payments_util.cc b/components/autofill/core/browser/field_filling_payments_util.cc index 5498ea4..4fd9de56 100644 --- a/components/autofill/core/browser/field_filling_payments_util.cc +++ b/components/autofill/core/browser/field_filling_payments_util.cc
@@ -352,8 +352,8 @@ std::u16string expiration_candidate = base::StrCat({mm, format.separator, format.digits_in_expiration_year == 4 ? yyyy : yy}); - if (field.max_length != 0 && - expiration_candidate.length() > field.max_length) { + if (field.max_length() != 0 && + expiration_candidate.length() > field.max_length()) { if (failure_to_fill) { *failure_to_fill += "Field to fill must have a max length of at least 4. "; @@ -382,7 +382,7 @@ action_persistence, cvc); case CREDIT_CARD_NUMBER: return GetCreditCardNumberForInput( - credit_card, field.credit_card_number_offset(), field.max_length, + credit_card, field.credit_card_number_offset(), field.max_length(), app_locale, action_persistence); case CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR: case CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR: @@ -390,7 +390,7 @@ case CREDIT_CARD_EXP_2_DIGIT_YEAR: case CREDIT_CARD_EXP_4_DIGIT_YEAR: return GetExpirationYearForInput(credit_card, storable_type, - field.max_length); + field.max_length()); default: // All other cases handled here. return credit_card.GetInfo(storable_type, app_locale); @@ -425,7 +425,7 @@ : CreditCard::GetMidlineEllipsisPlainDots(/*num_dots=*/3); case CREDIT_CARD_NUMBER: return GetVirtualCardNumberForPreviewInput( - virtual_card, field.credit_card_number_offset(), field.max_length); + virtual_card, field.credit_card_number_offset(), field.max_length()); case CREDIT_CARD_EXP_MONTH: case CREDIT_CARD_EXP_2_DIGIT_YEAR: case CREDIT_CARD_EXP_4_DIGIT_YEAR: @@ -522,7 +522,7 @@ [&trigger_autofill_field, &IsFillableField](const std::unique_ptr<AutofillField>& autofill_field) { return autofill_field->Type().GetStorableType() == CREDIT_CARD_NUMBER && - autofill_field->section == trigger_autofill_field.section && + autofill_field->section() == trigger_autofill_field.section() && IsFillableField(*autofill_field); };
diff --git a/components/autofill/core/browser/field_filling_payments_util_unittest.cc b/components/autofill/core/browser/field_filling_payments_util_unittest.cc index f3d462c8..aee1b26 100644 --- a/components/autofill/core/browser/field_filling_payments_util_unittest.cc +++ b/components/autofill/core/browser/field_filling_payments_util_unittest.cc
@@ -175,7 +175,7 @@ TEST_F(FieldFillingPaymentsUtilTest, FillFormField_MaxLength_CreditCardField_MaxLengthExceedsLength) { AutofillField field; - field.max_length = 30; + field.set_max_length(30); field.set_credit_card_number_offset(2); field.set_heuristic_type(GetActiveHeuristicSource(), CREDIT_CARD_NUMBER); @@ -191,7 +191,7 @@ TEST_F(FieldFillingPaymentsUtilTest, FillFormField_MaxLength_CreditCardField_OffsetExceedsLength) { AutofillField field; - field.max_length = 18; + field.set_max_length(18); field.set_credit_card_number_offset(19); field.set_heuristic_type(GetActiveHeuristicSource(), CREDIT_CARD_NUMBER); @@ -207,7 +207,7 @@ TEST_F(FieldFillingPaymentsUtilTest, FillFormField_MaxLength_CreditCardField_WithOffset) { AutofillField field; - field.max_length = 1; + field.set_max_length(1); field.set_credit_card_number_offset(3); field.set_heuristic_type(GetActiveHeuristicSource(), CREDIT_CARD_NUMBER); @@ -223,7 +223,7 @@ // Verify that only the truncated value of the credit card number is set. TEST_F(FieldFillingPaymentsUtilTest, FillFormField_MaxLength_CreditCardField) { AutofillField field; - field.max_length = 1; + field.set_max_length(1); field.set_heuristic_type(GetActiveHeuristicSource(), CREDIT_CARD_NUMBER); CreditCard credit_card; @@ -362,7 +362,7 @@ AutofillField field; field.set_form_control_type(FormControlType::kInputText); field.SetHtmlType(test_case.field_type, HtmlFieldMode()); - field.max_length = test_case.field_max_length; + field.set_max_length(test_case.field_max_length); CreditCard credit_card = test::GetCreditCard(); credit_card.SetExpirationDateFromString(u"12/2023"); @@ -470,7 +470,7 @@ AutofillField field; field.set_form_control_type(FormControlType::kInputText); field.SetHtmlType(test_case.field_type, HtmlFieldMode()); - field.max_length = test_case.field_max_length; + field.set_max_length(test_case.field_max_length); CreditCardFieldParser::ExpirationDateFormat format = CreditCardFieldParser::DetermineExpirationDateFormat( @@ -990,7 +990,7 @@ for (size_t i = 0; i < test.total_splits_; ++i) { AutofillField field; field.set_heuristic_type(GetActiveHeuristicSource(), CREDIT_CARD_NUMBER); - field.max_length = test.splits_[i]; + field.set_max_length(test.splits_[i]); field.set_credit_card_number_offset(4 * i); // Fill with a card-number; should fill just the card_number_part. @@ -1032,7 +1032,7 @@ for (size_t i = 0; i < test.total_splits_; ++i) { AutofillField field; field.set_heuristic_type(GetActiveHeuristicSource(), CREDIT_CARD_NUMBER); - field.max_length = test.splits_[i]; + field.set_max_length(test.splits_[i]); field.set_credit_card_number_offset(4 * i); // Fill with a card-number; should fill just the card_number_part. @@ -1071,7 +1071,7 @@ for (size_t i = 0; i < test.total_splits_; ++i) { AutofillField field; field.set_heuristic_type(GetActiveHeuristicSource(), CREDIT_CARD_NUMBER); - field.max_length = test.splits_[i]; + field.set_max_length(test.splits_[i]); field.set_credit_card_number_offset(GetNumberOffset(i, test)); // Fill with a card-number; should fill just the card_number_part. @@ -1116,7 +1116,7 @@ for (size_t i = 0; i < test.total_splits_; ++i) { AutofillField field; field.set_heuristic_type(GetActiveHeuristicSource(), CREDIT_CARD_NUMBER); - field.max_length = test.splits_[i]; + field.set_max_length(test.splits_[i]); field.set_credit_card_number_offset(GetNumberOffset(i, test)); // Fill with a card-number; should fill just the card_number_part. @@ -1231,7 +1231,7 @@ TEST_F(FieldFillingPaymentsUtilTest, PreviewVirtualShortenedYear) { // Test reducing 4 digit year to 2 digits. AutofillField field; - field.max_length = 2; + field.set_max_length(2); field.set_form_control_type(FormControlType::kInputText); field.set_heuristic_type(GetActiveHeuristicSource(), CREDIT_CARD_EXP_4_DIGIT_YEAR); @@ -1249,7 +1249,7 @@ field.set_form_control_type(FormControlType::kInputText); field.set_heuristic_type(GetActiveHeuristicSource(), CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR); - field.max_length = 7; + field.set_max_length(7); // A date that has a year containing four digits should return two dots for // month and four dots for year. @@ -1267,7 +1267,7 @@ // month and two for year. field.set_heuristic_type(GetActiveHeuristicSource(), CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR); - field.max_length = 5; + field.set_max_length(5); expected = base::StrCat({kMidlineEllipsis2DotsWithoutPadding, slash, kMidlineEllipsis2DotsWithoutPadding}); EXPECT_EQ(expected, GetFillingValueForCreditCard( @@ -1279,7 +1279,7 @@ // Test reducing dates to various max length field values. AutofillField field; field.set_form_control_type(FormControlType::kInputText); - field.max_length = 4; + field.set_max_length(4); field.set_heuristic_type(GetActiveHeuristicSource(), CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR); @@ -1291,7 +1291,7 @@ credit_card, /*cvc=*/u"", kAppLocale, mojom::ActionPersistence::kPreview, field)); - field.max_length = 5; + field.set_max_length(5); std::u16string slash = u"/"; // Expected: MM/YY = ••/••. expected = base::StrCat({kMidlineEllipsis2DotsWithoutPadding, slash, @@ -1300,7 +1300,7 @@ credit_card, /*cvc=*/u"", kAppLocale, mojom::ActionPersistence::kPreview, field)); - field.max_length = 6; + field.set_max_length(6); // Expected: MMYYYY = ••••••. expected = base::StrCat({kMidlineEllipsis2DotsWithoutPadding, kMidlineEllipsis4DotsWithoutPadding}); @@ -1308,7 +1308,7 @@ credit_card, /*cvc=*/u"", kAppLocale, mojom::ActionPersistence::kPreview, field)); - field.max_length = 7; + field.set_max_length(7); // Expected: MM/YYYY = ••/••••. expected = base::StrCat({kMidlineEllipsis2DotsWithoutPadding, slash, kMidlineEllipsis4DotsWithoutPadding}); @@ -1369,7 +1369,7 @@ TEST_F(FieldFillingPaymentsUtilTest, PreviewVirtualCardNumber_OffsetExceedsLength) { AutofillField field; - field.max_length = 17; + field.set_max_length(17); field.set_credit_card_number_offset(18); field.set_form_control_type(FormControlType::kInputText); field.set_heuristic_type(GetActiveHeuristicSource(), CREDIT_CARD_NUMBER);
diff --git a/components/autofill/core/browser/form_autofill_history.cc b/components/autofill/core/browser/form_autofill_history.cc index 4120f15..a393e45b3 100644 --- a/components/autofill/core/browser/form_autofill_history.cc +++ b/components/autofill/core/browser/form_autofill_history.cc
@@ -77,7 +77,7 @@ .field_filling_entries .emplace(field->global_id(), FieldFillingEntry( - field->value(), field->is_autofilled, + field->value(), field->is_autofilled(), autofill_field->autofill_source_profile_guid(), autofill_field->autofilled_type())) .second;
diff --git a/components/autofill/core/browser/form_autofill_history_unittest.cc b/components/autofill/core/browser/form_autofill_history_unittest.cc index eae08ec..8514296 100644 --- a/components/autofill/core/browser/form_autofill_history_unittest.cc +++ b/components/autofill/core/browser/form_autofill_history_unittest.cc
@@ -34,7 +34,7 @@ FieldType field_type, bool is_autofilled = false) { FormFieldData field = test::CreateTestFormField(label, name, value, type); - field.is_autofilled = is_autofilled; + field.set_is_autofilled(is_autofilled); filled_fields_.push_back(field); AutofillField autofill_field(field); autofill_field.SetTypeTo(AutofillType(field_type));
diff --git a/components/autofill/core/browser/form_data_importer.cc b/components/autofill/core/browser/form_data_importer.cc index 9a7ba00..8a3c47a2 100644 --- a/components/autofill/core/browser/form_data_importer.cc +++ b/components/autofill/core/browser/form_data_importer.cc
@@ -378,7 +378,7 @@ std::map<Section, std::vector<const AutofillField*>> section_fields; for (const auto& field : form) { if (IsAddressType(field->Type().GetStorableType())) { - section_fields[field->section].push_back(field.get()); + section_fields[field->section()].push_back(field.get()); } }
diff --git a/components/autofill/core/browser/form_data_importer_unittest.cc b/components/autofill/core/browser/form_data_importer_unittest.cc index 7a1f440c..a12639f 100644 --- a/components/autofill/core/browser/form_data_importer_unittest.cc +++ b/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -1305,8 +1305,8 @@ ConstructDefaultProfileFormStructure(); // Assign the address field another section than the other fields. - form_structure->field(4)->section = - Section::FromAutocomplete({.section = "another_section"}); + form_structure->field(4)->set_section( + Section::FromAutocomplete({.section = "another_section"})); ExtractAddressProfileAndVerifyExtractionOfDefaultProfile(*form_structure); } @@ -1409,12 +1409,12 @@ {ADDRESS_HOME_ZIP, kDefaultZip}, {ADDRESS_HOME_COUNTRY, kDefaultCountry}}); - form_data.fields[3].max_length = 3; - form_data.fields[4].max_length = 3; - form_data.fields[5].max_length = 4; - form_data.fields[6].max_length = 3; - form_data.fields[7].max_length = 3; - form_data.fields[8].max_length = 4; + form_data.fields[3].set_max_length(3); + form_data.fields[4].set_max_length(3); + form_data.fields[5].set_max_length(4); + form_data.fields[6].set_max_length(3); + form_data.fields[7].set_max_length(3); + form_data.fields[8].set_max_length(4); std::unique_ptr<FormStructure> form_structure = ConstructFormStructureFromFormData(form_data); @@ -1515,9 +1515,9 @@ // Define the length of the phone number fields to allow the parser to // identify them as area code, prefix and suffix. - form_data.fields[3].max_length = 3; - form_data.fields[4].max_length = 3; - form_data.fields[5].max_length = 4; + form_data.fields[3].set_max_length(3); + form_data.fields[4].set_max_length(3); + form_data.fields[5].set_max_length(4); std::unique_ptr<FormStructure> form_structure = ConstructFormStructureFromFormData(form_data); @@ -2082,7 +2082,7 @@ FormControlType::kInputText), CreateTestFormField("Exp Year:", "exp_year", "45", FormControlType::kInputText)}; - form.fields.back().max_length = 2; + form.fields.back().set_max_length(2); SubmitFormAndExpectImportedCardWithData(form, "John Smith", "4111111111111111", "05", "2045"); @@ -4379,7 +4379,7 @@ AutofillField& f = test_api(form_).PushField(); f.set_server_predictions({test::CreateFieldPrediction(field_type)}); f.set_value(std::move(value)); - f.is_autofilled = mode == Mode::kAutofilled; + f.set_is_autofilled(mode == Mode::kAutofilled); f.is_user_edited = mode == Mode::kUserEdited; }
diff --git a/components/autofill/core/browser/form_filler.cc b/components/autofill/core/browser/form_filler.cc index c8add510..978f5aa 100644 --- a/components/autofill/core/browser/form_filler.cc +++ b/components/autofill/core/browser/form_filler.cc
@@ -149,7 +149,7 @@ const bool is_trigger_field = autofill_field.global_id() == trigger_field.global_id(); - if (autofill_field.section != trigger_field.section) { + if (autofill_field.section() != trigger_field.section()) { return FieldFillingSkipReason::kNotInFilledSection; } @@ -190,7 +190,7 @@ // Don't fill previously autofilled fields except the initiating field or // when it's a refill. - if (field.is_autofilled && !is_trigger_field && !is_refill) { + if (field.is_autofilled() && !is_trigger_field && !is_refill) { return FieldFillingSkipReason::kAutofilledFieldsNotRefill; } @@ -377,7 +377,7 @@ std::erase_if(form.fields, [this, &operation, &cached_fields](const FormFieldData& field) { // Skip not-autofilled fields as undo only acts on autofilled fields. - return !field.is_autofilled || + return !field.is_autofilled() || // Skip fields whose last autofill operations is different than // the one of the trigger field. form_autofill_history_.GetLastFillingOperationForField( @@ -393,11 +393,11 @@ operation.GetFieldFillingEntry(field.global_id()); // Update the FormFieldData to be sent for the renderer. field.set_value(previous_state.value); - field.is_autofilled = previous_state.is_autofilled; + field.set_is_autofilled(previous_state.is_autofilled); // Update the cached AutofillField in the browser. // TODO(crbug.com/1345089): Consider updating the value too. - autofill_field.is_autofilled = previous_state.is_autofilled; + autofill_field.set_is_autofilled(previous_state.is_autofilled); autofill_field.set_autofill_source_profile_guid( previous_state.autofill_source_profile_guid); autofill_field.set_autofilled_type(previous_state.autofilled_type); @@ -443,7 +443,7 @@ base::make_span(&autofill_field, 1u), GetFillingProductFromPopupItemId(popup_item_id), /*is_refill=*/false); - autofill_field->is_autofilled = true; + autofill_field->set_is_autofilled(true); autofill_field->AppendLogEventIfNotRepeated(FillFieldLogEvent{ .fill_event_id = GetNextFillEventId(), .had_value_before_filling = ToOptionalBoolean(!field.value().empty()), @@ -483,7 +483,7 @@ LOG_AF(buffer) << Tag{"table"}; form_structure->RationalizePhoneNumbersInSection( - autofill_trigger_field->section); + autofill_trigger_field->section()); // TODO(crbug/1203667#c9): Skip if the form has changed in the meantime, which // may happen with refills. @@ -553,7 +553,7 @@ CHECK_EQ(result_form.fields.size(), form_structure->field_count()); for (size_t i = 0; i < form_structure->field_count(); ++i) { // On the renderer, the section is used regardless of the autofill status. - result_form.fields[i].section = form_structure->field(i)->section; + result_form.fields[i].set_section(form_structure->field(i)->section()); } base::flat_map<FieldGlobalId, FieldFillingSkipReason> skip_reasons = @@ -663,7 +663,8 @@ result_form.fields[i], should_notify, cvc.has_value() ? *cvc : u"", action_persistence, &failure_to_fill); const bool autofilled_value_did_not_change = - form.fields[i].is_autofilled && result_form.fields[i].is_autofilled && + form.fields[i].is_autofilled() && + result_form.fields[i].is_autofilled() && form.fields[i].value() == result_form.fields[i].value(); if (is_newly_autofilled && !autofilled_value_did_not_change) { newly_filled_field_ids.insert(result_form.fields[i].global_id()); @@ -676,8 +677,8 @@ } const bool has_value_after = !result_form.fields[i].value().empty(); - const bool is_autofilled_before = form.fields[i].is_autofilled; - const bool is_autofilled_after = result_form.fields[i].is_autofilled; + const bool is_autofilled_before = form.fields[i].is_autofilled(); + const bool is_autofilled_after = result_form.fields[i].is_autofilled(); // Log when the suggestion is selected and log on non-checkable fields that // have been filled. @@ -1063,7 +1064,7 @@ if (action_persistence == mojom::ActionPersistence::kFill) { // Mark the cached field as autofilled, so that we can detect when a // user edits an autofilled field (for metrics). - autofill_field.is_autofilled = true; + autofill_field.set_is_autofilled(true); if (const AutofillProfile** profile = absl::get_if<const AutofillProfile*>(&profile_or_credit_card)) { autofill_field.set_autofill_source_profile_guid((*profile)->guid()); @@ -1074,7 +1075,7 @@ // Mark the field as autofilled when a non-empty value is assigned to // it. This allows the renderer to distinguish autofilled fields from // fields with non-empty values, such as select-one fields. - field_data.is_autofilled = true; + field_data.set_is_autofilled(true); if (should_notify) { DCHECK(absl::holds_alternative<const AutofillProfile*>(
diff --git a/components/autofill/core/browser/form_filler_unittest.cc b/components/autofill/core/browser/form_filler_unittest.cc index 8dc199d..dc273ea 100644 --- a/components/autofill/core/browser/form_filler_unittest.cc +++ b/components/autofill/core/browser/form_filler_unittest.cc
@@ -107,12 +107,12 @@ // Takes a FormFieldData argument. MATCHER_P(AutofilledWith, value, "") { - return arg.is_autofilled && arg.value() == value; + return arg.is_autofilled() && arg.value() == value; } // Takes an AutofillField argument. MATCHER_P(AutofilledWithProfile, profile, "") { - return arg->is_autofilled && arg->autofill_source_profile_guid() && + return arg->is_autofilled() && arg->autofill_source_profile_guid() && *arg->autofill_source_profile_guid() == profile.guid(); } @@ -298,7 +298,7 @@ ASSERT_EQ(filled_form.fields.size(), 2u); EXPECT_THAT(filled_form.fields[0], AutofilledWith(profile.GetInfo(NAME_FIRST, kAppLocale))); - EXPECT_FALSE(filled_form.fields[1].is_autofilled); + EXPECT_FALSE(filled_form.fields[1].is_autofilled()); EXPECT_TRUE(filled_form.fields[1].value().empty()); } @@ -313,14 +313,14 @@ // Assign different sections to the fields. base::flat_map<LocalFrameToken, size_t> frame_token_ids; for (const std::unique_ptr<AutofillField>& field : form_structure->fields()) { - field->section = Section::FromFieldIdentifier(*field, frame_token_ids); + field->set_section(Section::FromFieldIdentifier(*field, frame_token_ids)); } AutofillProfile profile = test::GetFullProfile(); FillAutofillFormData(form, form.fields[1], &profile); - EXPECT_FALSE(form_structure->field(0)->is_autofilled); - EXPECT_TRUE(form_structure->field(1)->is_autofilled); + EXPECT_FALSE(form_structure->field(0)->is_autofilled()); + EXPECT_TRUE(form_structure->field(1)->is_autofilled()); } // Test that if the form cache is outdated because a field has changed, filling @@ -401,7 +401,7 @@ EXPECT_THAT(filled_form.fields[2], AutofilledWith(profile.GetInfo(EMAIL_ADDRESS, kAppLocale))); expect_hash(filled_form.fields[2], std::nullopt); - EXPECT_FALSE(filled_form.fields[3].is_autofilled); + EXPECT_FALSE(filled_form.fields[3].is_autofilled()); EXPECT_EQ(filled_form.fields[3].value(), form.fields[3].value()); expect_hash(filled_form.fields[3], base::FastHash(base::UTF16ToUTF8( @@ -447,9 +447,9 @@ AutofilledWith(profile.GetInfo(NAME_FIRST, kAppLocale))); EXPECT_THAT(filled_form.fields[1], AutofilledWith(profile.GetInfo(NAME_LAST, kAppLocale))); - EXPECT_FALSE(filled_form.fields[2].is_autofilled); + EXPECT_FALSE(filled_form.fields[2].is_autofilled()); EXPECT_EQ(filled_form.fields[2].value(), form.fields[2].value()); - EXPECT_FALSE(filled_form.fields[3].is_autofilled); + EXPECT_FALSE(filled_form.fields[3].is_autofilled()); EXPECT_EQ(filled_form.fields[3].value(), form.fields[3].value()); EXPECT_THAT(filled_form.fields[4], AutofilledWith(kToBeFilledState)); } @@ -496,21 +496,21 @@ AutofillField filled_autofill_field(form.fields.front()); FormFieldData* field_ptr = &form.fields.front(); AutofillField* autofill_field_ptr = &filled_autofill_field; - form.fields.front().is_autofilled = false; + form.fields.front().set_is_autofilled(false); test_api(*browser_autofill_manager_) .AddFormFillEntry(base::make_span(&field_ptr, 1u), base::make_span(&autofill_field_ptr, 1u), FillingProduct::kAddress, /*is_refill=*/false); - form.fields.front().is_autofilled = true; + form.fields.front().set_is_autofilled(true); FormsSeen({form}); const AutofillField* autofill_field = GetAutofillField(form, form.fields.front()); - ASSERT_TRUE(autofill_field->is_autofilled); + ASSERT_TRUE(autofill_field->is_autofilled()); browser_autofill_manager_->UndoAutofill(mojom::ActionPersistence::kFill, form, form.fields.front()); - EXPECT_FALSE(autofill_field->is_autofilled); + EXPECT_FALSE(autofill_field->is_autofilled()); } TEST_F(FormFillerTest, FillOrPreviewDataModelFormCallsDidFillOrPreviewForm) { @@ -545,7 +545,7 @@ FormData filled_form = FillAutofillFormData(form, form.fields[0], &profile); EXPECT_THAT(filled_form.fields[0], AutofilledWith(profile.GetInfo(NAME_FIRST, kAppLocale))); - EXPECT_FALSE(filled_form.fields[1].is_autofilled); + EXPECT_FALSE(filled_form.fields[1].is_autofilled()); EXPECT_THAT(filled_form.fields[2], AutofilledWith(profile.GetInfo(NAME_LAST, kAppLocale))); @@ -585,7 +585,7 @@ EXPECT_THAT(filled_form.fields[3], AutofilledWith(credit_card.GetInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, kAppLocale))); - EXPECT_FALSE(filled_form.fields[4].is_autofilled); + EXPECT_FALSE(filled_form.fields[4].is_autofilled()); } // Test that whitespace and separators are stripped from the credit card number. @@ -652,7 +652,7 @@ EXPECT_THAT(filled_form.fields[1], AutofilledWith(credit_card.GetInfo( CREDIT_CARD_NUMBER, kAppLocale))); EXPECT_EQ(filled_form.fields[2].value(), GetParam().expected_filled_date); - EXPECT_FALSE(filled_form.fields[3].is_autofilled); + EXPECT_FALSE(filled_form.fields[3].is_autofilled()); } // Test that only the first 19 credit card number fields are filled. @@ -674,7 +674,7 @@ << i; } // Verify that the 20th. credit card number field is not filled. - EXPECT_FALSE(filled_form.fields.back().is_autofilled); + EXPECT_FALSE(filled_form.fields.back().is_autofilled()); } // Test the credit card number is filled correctly into single-digit fields. @@ -685,7 +685,7 @@ 20, {.autocomplete_attribute = "cc-number"})}); // Set the size limit of the first nineteen fields to 1. for (size_t i = 0; i < 19; i++) { - form.fields[i].max_length = 1; + form.fields[i].set_max_length(1); } FormsSeen({form}); @@ -703,7 +703,7 @@ : card_number)) << i; } - EXPECT_FALSE(filled_form.fields[19].is_autofilled); + EXPECT_FALSE(filled_form.fields[19].is_autofilled()); EXPECT_TRUE(filled_form.fields[19].value().empty()); } @@ -729,7 +729,7 @@ EXPECT_THAT(filled_form.fields[4], AutofilledWith(credit_card.GetInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, kAppLocale))); - EXPECT_FALSE(filled_form.fields[5].is_autofilled); + EXPECT_FALSE(filled_form.fields[5].is_autofilled()); EXPECT_TRUE(filled_form.fields[5].value().empty()); } @@ -769,7 +769,7 @@ for (size_t i = 21; i < 30; ++i) { EXPECT_THAT(filled_form.fields[i], AutofilledWith(u"US")) << i; } - EXPECT_FALSE(filled_form.fields[30].is_autofilled); + EXPECT_FALSE(filled_form.fields[30].is_autofilled()); EXPECT_TRUE(filled_form.fields[30].value().empty()); } @@ -879,11 +879,11 @@ CREDIT_CARD_NAME_FULL, kAppLocale))); EXPECT_THAT(filled_form.fields[1], AutofilledWith(expired_card.GetInfo( CREDIT_CARD_NUMBER, kAppLocale))); - EXPECT_FALSE(filled_form.fields[2].is_autofilled); + EXPECT_FALSE(filled_form.fields[2].is_autofilled()); EXPECT_TRUE(filled_form.fields[2].value().empty()); - EXPECT_FALSE(filled_form.fields[3].is_autofilled); + EXPECT_FALSE(filled_form.fields[3].is_autofilled()); EXPECT_TRUE(filled_form.fields[3].value().empty()); - EXPECT_FALSE(filled_form.fields[4].is_autofilled); + EXPECT_FALSE(filled_form.fields[4].is_autofilled()); EXPECT_TRUE(filled_form.fields[4].value().empty()); } @@ -944,9 +944,9 @@ ASSERT_EQ(4u, filled_form.fields.size()); EXPECT_THAT(filled_form.fields[0], AutofilledWith(profile.GetInfo(NAME_FULL, kAppLocale))); - EXPECT_FALSE(filled_form.fields[1].is_autofilled); + EXPECT_FALSE(filled_form.fields[1].is_autofilled()); EXPECT_TRUE(filled_form.fields[1].value().empty()); - EXPECT_FALSE(filled_form.fields[2].is_autofilled); + EXPECT_FALSE(filled_form.fields[2].is_autofilled()); EXPECT_TRUE(filled_form.fields[2].value().empty()); EXPECT_THAT(filled_form.fields[3], AutofilledWith(u"US")); } @@ -975,11 +975,11 @@ // TODO(b/40264633): Replace with GetInfo. EXPECT_THAT(filled_form.fields[0], AutofilledWith(profile.GetRawInfo(ADDRESS_HOME_COUNTRY))); - EXPECT_FALSE(filled_form.fields[1].is_autofilled); + EXPECT_FALSE(filled_form.fields[1].is_autofilled()); EXPECT_TRUE(filled_form.fields[1].value().empty()); - EXPECT_FALSE(filled_form.fields[2].is_autofilled); + EXPECT_FALSE(filled_form.fields[2].is_autofilled()); EXPECT_TRUE(filled_form.fields[2].value().empty()); - EXPECT_FALSE(filled_form.fields[3].is_autofilled); + EXPECT_FALSE(filled_form.fields[3].is_autofilled()); EXPECT_TRUE(filled_form.fields[3].value().empty()); EXPECT_THAT(filled_form.fields[4], AutofilledWith(profile.GetInfo(EMAIL_ADDRESS, kAppLocale))); @@ -987,30 +987,30 @@ // Fill the address portion of the billing section. filled_form = FillAutofillFormData(form, form.fields[1], &profile); ASSERT_EQ(filled_form.fields.size(), 5u); - EXPECT_FALSE(filled_form.fields[0].is_autofilled); + EXPECT_FALSE(filled_form.fields[0].is_autofilled()); EXPECT_TRUE(filled_form.fields[0].value().empty()); EXPECT_THAT(filled_form.fields[1], AutofilledWith(profile.GetInfo(ADDRESS_HOME_LINE1, kAppLocale))); - EXPECT_FALSE(filled_form.fields[2].is_autofilled); + EXPECT_FALSE(filled_form.fields[2].is_autofilled()); EXPECT_TRUE(filled_form.fields[2].value().empty()); - EXPECT_FALSE(filled_form.fields[3].is_autofilled); + EXPECT_FALSE(filled_form.fields[3].is_autofilled()); EXPECT_TRUE(filled_form.fields[3].value().empty()); - EXPECT_FALSE(filled_form.fields[4].is_autofilled); + EXPECT_FALSE(filled_form.fields[4].is_autofilled()); EXPECT_TRUE(filled_form.fields[4].value().empty()); // Fill the credit card portion of the billing section. CreditCard credit_card = test::GetCreditCard(); filled_form = FillAutofillFormData(form, form.fields[2], &credit_card); ASSERT_EQ(filled_form.fields.size(), 5u); - EXPECT_FALSE(filled_form.fields[0].is_autofilled); + EXPECT_FALSE(filled_form.fields[0].is_autofilled()); EXPECT_TRUE(filled_form.fields[0].value().empty()); - EXPECT_FALSE(filled_form.fields[1].is_autofilled); + EXPECT_FALSE(filled_form.fields[1].is_autofilled()); EXPECT_TRUE(filled_form.fields[1].value().empty()); EXPECT_THAT(filled_form.fields[2], AutofilledWith(credit_card.GetInfo( CREDIT_CARD_NAME_FULL, kAppLocale))); EXPECT_THAT(filled_form.fields[3], AutofilledWith(credit_card.GetInfo( CREDIT_CARD_NUMBER, kAppLocale))); - EXPECT_FALSE(filled_form.fields[4].is_autofilled); + EXPECT_FALSE(filled_form.fields[4].is_autofilled()); EXPECT_TRUE(filled_form.fields[4].value().empty()); } @@ -1041,7 +1041,7 @@ {.fields = {{.role = NAME_FULL, .autocomplete_attribute = "name"}, {.role = EMAIL_ADDRESS, .autocomplete_attribute = "email"}}}); for (FormFieldData& field : form.fields) { - field.is_autofilled = true; + field.set_is_autofilled(true); } FormsSeen({form}); @@ -1063,7 +1063,7 @@ {.role = CREDIT_CARD_NUMBER, .autocomplete_attribute = "cc-number"}}}); for (FormFieldData& field : form.fields) { - field.is_autofilled = true; + field.set_is_autofilled(true); } FormsSeen({form}); @@ -1100,7 +1100,7 @@ AutofilledWith(profile.GetInfo(NAME_FIRST, kAppLocale))); EXPECT_THAT(filled_form.fields[1], AutofilledWith(profile.GetInfo(NAME_MIDDLE, kAppLocale))); - EXPECT_FALSE(filled_form.fields[2].is_autofilled); + EXPECT_FALSE(filled_form.fields[2].is_autofilled()); } // Test that we correctly fill a partly manually filled credit card form. @@ -1128,7 +1128,7 @@ ASSERT_EQ(filled_form.fields.size(), 3u); EXPECT_THAT(filled_form.fields[0], AutofilledWith(credit_card.GetInfo( CREDIT_CARD_NAME_FIRST, kAppLocale))); - EXPECT_FALSE(filled_form.fields[1].is_autofilled); + EXPECT_FALSE(filled_form.fields[1].is_autofilled()); EXPECT_THAT(filled_form.fields[2], AutofilledWith(credit_card.GetInfo( CREDIT_CARD_NUMBER, kAppLocale))); } @@ -1165,7 +1165,7 @@ test_field.max_length); form_with_us_number_max_length.fields.push_back(field); - field.max_length = default_max_length; + field.set_max_length(default_max_length); field.autocomplete_attribute = test_field.autocomplete_attribute; field.parsed_autocomplete = ParseAutocompleteAttribute(test_field.autocomplete_attribute); @@ -1461,8 +1461,8 @@ AutofilledWith(profile.GetInfo(NAME_FULL, kAppLocale))); EXPECT_THAT(filled_form.fields[1], AutofilledWith(u"US")); EXPECT_THAT(filled_form.fields[2], AutofilledWith(u"CA")); - EXPECT_FALSE(filled_form.fields[3].is_autofilled); - EXPECT_FALSE(filled_form.fields[4].is_autofilled); + EXPECT_FALSE(filled_form.fields[3].is_autofilled()); + EXPECT_FALSE(filled_form.fields[4].is_autofilled()); } TEST_F(FormFillerTest, FillFirstPhoneNumber_MultipleSectionFilledCorrectly) { @@ -1567,8 +1567,8 @@ AutofilledWith(profile.GetInfo(NAME_FULL, kAppLocale))); EXPECT_THAT(filled_form.fields[1], AutofilledWith(profile.GetInfo(ADDRESS_HOME_LINE1, kAppLocale))); - EXPECT_FALSE(filled_form.fields[2].is_autofilled); - EXPECT_FALSE(filled_form.fields[3].is_autofilled); + EXPECT_FALSE(filled_form.fields[2].is_autofilled()); + EXPECT_FALSE(filled_form.fields[3].is_autofilled()); // Two other fields will show up. Select the second profile. The fields that // were already filled, would be left unchanged, and the rest would be filled @@ -1684,7 +1684,7 @@ filled_form, filled_form.fields[0], gfx::RectF(), base::TimeTicks::Now()); ASSERT_TRUE(form_structure->field(0)->previously_autofilled()); - EXPECT_FALSE(form_structure->field(0)->is_autofilled); + EXPECT_FALSE(form_structure->field(0)->is_autofilled()); EXPECT_THAT(form_structure->field(0)->autofill_source_profile_guid(), Optional(profile.guid())); EXPECT_THAT(form_structure->field(1), AutofilledWithProfile(profile));
diff --git a/components/autofill/core/browser/form_parsing/credit_card_field_parser.cc b/components/autofill/core/browser/form_parsing/credit_card_field_parser.cc index 6f46b18..18233fc 100644 --- a/components/autofill/core/browser/form_parsing/credit_card_field_parser.cc +++ b/components/autofill/core/browser/form_parsing/credit_card_field_parser.cc
@@ -614,7 +614,7 @@ scanner->RewindTo(month_year_saved_cursor); // Bail out if the field cannot fit a 2-digit year expiration date. - const uint64_t current_field_max_length = scanner->Cursor()->max_length; + const uint64_t current_field_max_length = scanner->Cursor()->max_length(); if (!FieldCanFitDataForFieldType(current_field_max_length, CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR)) return false; @@ -683,7 +683,7 @@ // For text fields, look for placeholder patterns. if (field.IsTextInputElement()) { - if (field.max_length == 2) { + if (field.max_length() == 2) { return CREDIT_CARD_EXP_2_DIGIT_YEAR; } // If you add new languages, also update other places labeled with @@ -698,7 +698,7 @@ MatchesRegex<kYYRegex>(field.label(), nullptr)) { return CREDIT_CARD_EXP_2_DIGIT_YEAR; } - if (field.max_length == 4) { + if (field.max_length() == 4) { return CREDIT_CARD_EXP_4_DIGIT_YEAR; } } @@ -776,8 +776,8 @@ /*server_hint=*/NO_SERVER_DATA, /*forced_field_type=*/NO_SERVER_DATA); } - return expiration_year_->max_length == 2 ? CREDIT_CARD_EXP_2_DIGIT_YEAR - : CREDIT_CARD_EXP_4_DIGIT_YEAR; + return expiration_year_->max_length() == 2 ? CREDIT_CARD_EXP_2_DIGIT_YEAR + : CREDIT_CARD_EXP_4_DIGIT_YEAR; } bool CreditCardFieldParser::HasExpiration() const { @@ -884,7 +884,7 @@ for (uint8_t year_length : year_length_candidates) { for (const std::u16string& separator : separator_candidates) { uint8_t candidate_size = kMonthLength + separator.length() + year_length; - if (field.max_length == 0 || candidate_size <= field.max_length) { + if (field.max_length() == 0 || candidate_size <= field.max_length()) { return {separator, year_length}; } } @@ -892,7 +892,7 @@ // Now use to the `field.max_length` attribute to guess an appropriate // format. - switch (field.max_length) { + switch (field.max_length()) { case 1: case 2: case 3:
diff --git a/components/autofill/core/browser/form_parsing/credit_card_field_parser_unittest.cc b/components/autofill/core/browser/form_parsing/credit_card_field_parser_unittest.cc index dd380c24..50a1a11 100644 --- a/components/autofill/core/browser/form_parsing/credit_card_field_parser_unittest.cc +++ b/components/autofill/core/browser/form_parsing/credit_card_field_parser_unittest.cc
@@ -163,7 +163,7 @@ AddTextFormFieldData("ccyear", "Exp Year", CREDIT_CARD_EXP_2_DIGIT_YEAR); // Even though the placehodler indicates YYYY, the max-length only enables // a YY expiration format. - fields_.back()->max_length = 2u; + fields_.back()->set_max_length(2u); fields_.back()->placeholder = u"YYYY"; ClassifyAndVerify(ParseResult::kParsed); } @@ -734,7 +734,7 @@ SCOPED_TRACE(test_case().is_server_override); AutofillField field; - field.max_length = test_case().max_length; + field.set_max_length(test_case().max_length); field.set_label(base::UTF8ToUTF16(test_case().label)); FieldType fallback_type = CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR;
diff --git a/components/autofill/core/browser/form_parsing/form_field_parser_unittest.cc b/components/autofill/core/browser/form_parsing/form_field_parser_unittest.cc index 64fedb5..90856066 100644 --- a/components/autofill/core/browser/form_parsing/form_field_parser_unittest.cc +++ b/components/autofill/core/browser/form_parsing/form_field_parser_unittest.cc
@@ -287,7 +287,7 @@ // is a string. for (size_t i = 0; i < n; i++) { FormFieldData form_field_data; - form_field_data.max_length = i; + form_field_data.set_max_length(i); fields.push_back(std::make_unique<AutofillField>(form_field_data)); } @@ -296,7 +296,7 @@ // `testcase.field_matches_parser`. auto Matches = [](AutofillScanner* scanner, const std::vector<bool>& matching_ids) -> bool { - return matching_ids[scanner->Cursor()->max_length]; + return matching_ids[scanner->Cursor()->max_length()]; }; // Construct n parsers from `testcase.field_matches_parser`.
diff --git a/components/autofill/core/browser/form_parsing/parsing_test_utils.cc b/components/autofill/core/browser/form_parsing/parsing_test_utils.cc index ad8e3fd..02f3003 100644 --- a/components/autofill/core/browser/form_parsing/parsing_test_utils.cc +++ b/components/autofill/core/browser/form_parsing/parsing_test_utils.cc
@@ -68,7 +68,7 @@ field_data.set_form_control_type(control_type); field_data.set_name(base::UTF8ToUTF16(name)); field_data.set_label(base::UTF8ToUTF16(label)); - field_data.max_length = max_length; + field_data.set_max_length(max_length); field_data.set_renderer_id(MakeFieldRendererId()); fields_.push_back(std::make_unique<AutofillField>(field_data)); expected_classifications_.insert(
diff --git a/components/autofill/core/browser/form_parsing/phone_field_parser.cc b/components/autofill/core/browser/form_parsing/phone_field_parser.cc index 46b70808..36835726 100644 --- a/components/autofill/core/browser/form_parsing/phone_field_parser.cc +++ b/components/autofill/core/browser/form_parsing/phone_field_parser.cc
@@ -235,8 +235,8 @@ } if (rule.max_size != 0 && - (parsed_fields[rule.phone_part]->max_length == 0 || - rule.max_size < parsed_fields[rule.phone_part]->max_length)) { + (parsed_fields[rule.phone_part]->max_length() == 0 || + rule.max_size < parsed_fields[rule.phone_part]->max_length())) { return false; } }
diff --git a/components/autofill/core/browser/form_parsing/phone_field_parser_unittest.cc b/components/autofill/core/browser/form_parsing/phone_field_parser_unittest.cc index a5e7829..bbb842f3 100644 --- a/components/autofill/core/browser/form_parsing/phone_field_parser_unittest.cc +++ b/components/autofill/core/browser/form_parsing/phone_field_parser_unittest.cc
@@ -121,7 +121,7 @@ field.set_form_control_type(field_data.type); field.set_label(field_data.label); field.set_name(field_data.name); - field.max_length = field_data.max_length; + field.set_max_length(field_data.max_length); for (auto* const element : field_data.options) { field.options.push_back( {.value = u"", .content = base::UTF8ToUTF16(element)});
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc index f8dbb94a..60d3fce 100644 --- a/components/autofill/core/browser/form_structure.cc +++ b/components/autofill/core/browser/form_structure.cc
@@ -222,13 +222,13 @@ // The sections are mapped to consecutive natural numbers starting at 1. std::map<Section, size_t> section_id_map; for (const auto& field : fields_) { - if (!base::Contains(section_id_map, field->section)) { + if (!base::Contains(section_id_map, field->section())) { size_t next_section_id = section_id_map.size() + 1; - section_id_map[field->section] = next_section_id; + section_id_map[field->section()] = next_section_id; } field->AppendLogEventIfNotRepeated(RationalizationFieldLogEvent{ .field_type = field->Type().GetStorableType(), - .section_id = section_id_map[field->section], + .section_id = section_id_map[field->section()], .type_changed = field->Type().GetStorableType() != field->ComputedType().GetStorableType(), }); @@ -293,7 +293,7 @@ annotated_field.overall_type = std::string(field->Type().ToStringView()); annotated_field.parseable_name = base::UTF16ToUTF8(field->parseable_name()); - annotated_field.section = field->section.ToString(); + annotated_field.section = field->section().ToString(); annotated_field.rank = field->rank(); annotated_field.rank_in_signature_group = field->rank_in_signature_group(); @@ -535,7 +535,7 @@ features::kAutofillDontPreserveAutofillState)) { // Preserve state whether the field was autofilled before. if (reason == RetrieveFromCacheReason::kFormParsing) - field->is_autofilled = cached_field->is_autofilled; + field->set_is_autofilled(cached_field->is_autofilled()); } field->set_autofill_source_profile_guid( @@ -559,7 +559,7 @@ field->set_heuristic_type(s, cached_field->heuristic_type(s)); } field->SetHtmlType(cached_field->html_type(), cached_field->html_mode()); - field->section = cached_field->section; + field->set_section(cached_field->section()); field->set_only_fill_when_focused(cached_field->only_fill_when_focused()); // During import, the final field type is used to decide which @@ -645,15 +645,16 @@ bool has_autocomplete = false; for (const auto& field : fields_) { if (!field->parsed_autocomplete) { - field->section = Section(); + field->set_section(Section()); continue; } - field->section = Section::FromAutocomplete( + field->set_section(Section::FromAutocomplete( {.section = field->parsed_autocomplete->section, - .mode = field->parsed_autocomplete->mode}); - if (field->section) + .mode = field->parsed_autocomplete->mode})); + if (field->section()) { has_autocomplete = true; + } } return has_autocomplete; } @@ -807,7 +808,7 @@ credit_card_section = Section::FromFieldIdentifier(*field, frame_token_ids); } - field->section = credit_card_section; + field->set_section(credit_card_section); continue; } @@ -858,9 +859,9 @@ // derived from the autocomplete attribute and its section is different than // the previous field's section. bool different_autocomplete_section_than_previous_field_section = - field->section.is_from_autocomplete() && + field->section().is_from_autocomplete() && (field_index == 0 || - fields_[field_index - 1]->section != field->section); + fields_[field_index - 1]->section() != field->section()); // Start a new section if the `current_type` was already seen or the section // is derived from the autocomplete attribute which is different than the @@ -877,19 +878,19 @@ } if (!is_hidden_section && - (!field->section.is_from_autocomplete() || + (!field->section().is_from_autocomplete() || different_autocomplete_section_than_previous_field_section)) { seen_types.clear(); } - if (field->section.is_from_autocomplete() && + if (field->section().is_from_autocomplete() && !previous_autocomplete_section_present) { // If this field is the first field within the section with a defined // autocomplete section, then change the section attribute of all the // parsed fields in the current section to `field->section`. int i = static_cast<int>(field_index - 1); - while (i >= 0 && fields_[i]->section == current_section) { - fields_[i]->section = field->section; + while (i >= 0 && fields_[i]->section() == current_section) { + fields_[i]->set_section(field->section()); i--; } } @@ -899,11 +900,12 @@ // The section described in the autocomplete section attribute // overrides the value determined by the heuristic. - if (field->section.is_from_autocomplete()) - current_section = field->section; + if (field->section().is_from_autocomplete()) { + current_section = field->section(); + } previous_autocomplete_section_present = - field->section.is_from_autocomplete(); + field->section().is_from_autocomplete(); } // Only consider a type "seen" if it was not ignored. Some forms have @@ -919,7 +921,7 @@ is_hidden_section = false; } - field->section = current_section; + field->set_section(current_section); } } @@ -951,7 +953,7 @@ credit_card_section = Section::FromFieldIdentifier(*field, frame_token_ids); } - field->section = credit_card_section; + field->set_section(credit_card_section); } } @@ -1045,7 +1047,7 @@ is_hidden_section = false; } - field->section = current_section; + field->set_section(current_section); } } } @@ -1208,7 +1210,7 @@ << base::StrCat({type, " (heuristic: ", heuristic_type, ", server: ", server_type, is_override, html_type_description, ")"}); - buffer << "\n Section: " << field->section; + buffer << "\n Section: " << field->section(); constexpr size_t kMaxLabelSize = 100; const std::u16string truncated_label = field->label().substr( @@ -1289,7 +1291,7 @@ buffer << Tr{} << "Type:" << base::StrCat({type, " (heuristic: ", heuristic_type, ", server: ", server_type, html_type_description, ")"}); - buffer << Tr{} << "Section:" << field->section; + buffer << Tr{} << "Section:" << field->section(); constexpr size_t kMaxLabelSize = 100; // TODO(crbug/1165780): Remove once shared labels are launched.
diff --git a/components/autofill/core/browser/form_structure_rationalizer.cc b/components/autofill/core/browser/form_structure_rationalizer.cc index a92ce58e..86b2930 100644 --- a/components/autofill/core/browser/form_structure_rationalizer.cc +++ b/components/autofill/core/browser/form_structure_rationalizer.cc
@@ -109,7 +109,7 @@ if (!is_text_field) { continue; } - if (field->max_length == 1) { + if (field->max_length() == 1) { set_html_type(HtmlFieldType::kAdditionalNameInitial); } break; @@ -139,9 +139,9 @@ ? HtmlFieldType::kCreditCardExpDate4DigitYear : HtmlFieldType::kCreditCardExpDate2DigitYear); } else { - if (field->max_length == 5) { + if (field->max_length() == 5) { set_html_type(HtmlFieldType::kCreditCardExpDate2DigitYear); - } else if (field->max_length == 7) { + } else if (field->max_length() == 7) { set_html_type(HtmlFieldType::kCreditCardExpDate4DigitYear); } } @@ -174,9 +174,9 @@ ? HtmlFieldType::kCreditCardExp4DigitYear : HtmlFieldType::kCreditCardExp2DigitYear); } else { - if (field->max_length == 2) { + if (field->max_length() == 2) { set_html_type(HtmlFieldType::kCreditCardExp2DigitYear); - } else if (field->max_length == 4) { + } else if (field->max_length() == 4) { set_html_type(HtmlFieldType::kCreditCardExp4DigitYear); } } @@ -494,12 +494,13 @@ return f->ComputedType().GetStorableType() == CREDIT_CARD_NUMBER; })); size_t last = group.size() - 1; - return group[0]->max_length <= kMaxGroupElementLength && + return group[0]->max_length() <= kMaxGroupElementLength && group[last]->ComputedType().GetStorableType() == CREDIT_CARD_NUMBER && group[last]->renderer_form_id() == group[0]->renderer_form_id() && group[last]->IsFocusable() == group[0]->IsFocusable() && - (last == 0 || group[last - 1]->max_length == group[0]->max_length); + (last == 0 || + group[last - 1]->max_length() == group[0]->max_length()); }; // `has_reasonable_length({f, f + N + 1})` is true iff @@ -510,16 +511,17 @@ // 2. there are at least 2 non-overflow fields. auto has_reasonable_length = [](Group group) { DCHECK(!group.empty()); - DCHECK(base::ranges::all_of(group.first(group.size() - 1), - [group](const auto& f) { - return f->max_length == group[0]->max_length; - })); + DCHECK(base::ranges::all_of( + group.first(group.size() - 1), [group](const auto& f) { + return f->max_length() == group[0]->max_length(); + })); size_t size = group.size(); size_t last = group.size() - 1; - bool last_is_overflow = group[last]->max_length > kMaxGroupElementLength; - size_t length = group[0]->max_length * (size - 1) + group[last]->max_length; + bool last_is_overflow = group[last]->max_length() > kMaxGroupElementLength; + size_t length = + group[0]->max_length() * (size - 1) + group[last]->max_length(); size_t length_without_overflow = - length - last_is_overflow * group[last]->max_length; + length - last_is_overflow * group[last]->max_length(); return length >= kMinValidCardNumberSize && length_without_overflow <= kMaxValidCardNumberSize && size >= 2 + last_is_overflow; @@ -548,7 +550,7 @@ size_t offset = 0; for (auto& field : Group{begin, end}) { field->set_credit_card_number_offset(offset); - offset += field->max_length; + offset += field->max_length(); } } DCHECK(begin != end); @@ -568,7 +570,7 @@ AutofillField& previous_field = **(field - 1); if (previous_field.ComputedType().GetStorableType() != ADDRESS_HOME_STREET_ADDRESS || - previous_field.section != (*field)->section || + previous_field.section() != (*field)->section() || previous_field.server_type_prediction_is_override()) { continue; } @@ -666,8 +668,9 @@ const Section& section) { std::vector<AutofillField*> fields; for (const auto& field : *fields_) { - if (field->section != section) + if (field->section() != section) { continue; + } fields.push_back(field.get()); } rationalization_util::RationalizePhoneNumberFields(fields); @@ -835,7 +838,8 @@ GroupTypeOfFieldType( (*fields_)[field_index]->Type().GetStorableType()) == FieldTypeGroup::kAddress && - (*fields_)[field_index]->section == (*fields_)[upper_index]->section) { + (*fields_)[field_index]->section() == + (*fields_)[upper_index]->section()) { return false; } } @@ -866,8 +870,9 @@ // state and country. No rationalization needed. if (!sections_of_state_indexes->IsFinished() && !sections_of_country_indexes->IsFinished() && - (*fields_)[sections_of_state_indexes->CurrentIndex()]->section == - (*fields_)[sections_of_country_indexes->CurrentIndex()]->section) { + (*fields_)[sections_of_state_indexes->CurrentIndex()]->section() == + (*fields_)[sections_of_country_indexes->CurrentIndex()] + ->section()) { sections_of_state_indexes->WalkForwardToTheNextSection(); sections_of_country_indexes->WalkForwardToTheNextSection(); continue; @@ -972,7 +977,7 @@ .Empty() || (*fields_)[sectioned_field_indexes_by_type[current_type] .LastFieldIndex()] - ->section != field.section); + ->section() != field.section()); } }
diff --git a/components/autofill/core/browser/form_structure_rationalizer_unittest.cc b/components/autofill/core/browser/form_structure_rationalizer_unittest.cc index 295ca4e..4b55aad 100644 --- a/components/autofill/core/browser/form_structure_rationalizer_unittest.cc +++ b/components/autofill/core/browser/form_structure_rationalizer_unittest.cc
@@ -97,12 +97,12 @@ field.set_label(base::UTF8ToUTF16(field_template.label)); field.set_name(base::UTF8ToUTF16(field_template.name)); if (!field_template.section.empty()) { - field.section = Section::FromAutocomplete( - {.section = std::string(field_template.section)}); + field.set_section(Section::FromAutocomplete( + {.section = std::string(field_template.section)})); } field.set_form_control_type(field_template.form_control_type); field.is_focusable = field_template.is_focusable; - field.max_length = field_template.max_length; + field.set_max_length(field_template.max_length); field.parsed_autocomplete = field_template.parsed_autocomplete; field.role = field_template.role; field.origin = @@ -275,7 +275,7 @@ {"Cell Phone", "cellPhoneNumber", PHONE_HOME_WHOLE_NUMBER}, }, /*run_heuristics=*/false); - Section s = form_structure->field(0)->section; + Section s = form_structure->field(0)->section(); EXPECT_FALSE(test_api(*form_structure).phone_rationalized(s)); form_structure->RationalizePhoneNumbersInSection(s); EXPECT_TRUE(test_api(*form_structure).phone_rationalized(s));
diff --git a/components/autofill/core/browser/form_structure_sectioning_util.cc b/components/autofill/core/browser/form_structure_sectioning_util.cc index 8fb89e7b..9593e01 100644 --- a/components/autofill/core/browser/form_structure_sectioning_util.cc +++ b/components/autofill/core/browser/form_structure_sectioning_util.cc
@@ -75,15 +75,17 @@ auto first_cc_field = base::ranges::find_if( fields, [](const std::unique_ptr<AutofillField>& field) { return field->Type().group() == FieldTypeGroup::kCreditCard && - !field->section; + !field->section(); }); if (first_cc_field == fields.end()) return; Section cc_section = Section::FromFieldIdentifier(**first_cc_field, frame_token_ids); for (const auto& field : fields) { - if (field->Type().group() == FieldTypeGroup::kCreditCard && !field->section) - field->section = cc_section; + if (field->Type().group() == FieldTypeGroup::kCreditCard && + !field->section()) { + field->set_section(cc_section); + } } } @@ -95,7 +97,7 @@ {.section = field->parsed_autocomplete->section, .mode = field->parsed_autocomplete->mode}); if (autocomplete_section) - field->section = autocomplete_section; + field->set_section(autocomplete_section); } } } @@ -107,22 +109,23 @@ return; Section s = Section::FromFieldIdentifier(**section.begin(), frame_token_ids); for (const auto& field : section) { - if (!field->section && IsSectionable(*field)) - field->section = s; + if (!field->section() && IsSectionable(*field)) { + field->set_section(s); + } } } void ExpandSections(base::span<const std::unique_ptr<AutofillField>> fields) { auto HasSection = [](auto& field) { - return IsSectionable(*field) && field->section; + return IsSectionable(*field) && field->section(); }; auto it = base::ranges::find_if(fields, HasSection); while (it != fields.end()) { auto end = base::ranges::find_if(it + 1, fields.end(), HasSection); - if (end != fields.end() && (*it)->section == (*end)->section) { + if (end != fields.end() && (*it)->section() == (*end)->section()) { for (auto& field : base::make_span(it + 1, end)) { if (IsSectionable(*field)) { - field->section = (*it)->section; + field->set_section((*it)->section()); } } } @@ -133,8 +136,9 @@ bool BelongsToCurrentSection(const FieldTypeSet& seen_types, const AutofillField& current_field, const AutofillField& previous_field) { - if (current_field.section) + if (current_field.section()) { return !features::kAutofillSectioningModeCreateGaps.Get(); + } const FieldType current_type = current_field.Type().GetStorableType(); if (current_type == UNKNOWN_TYPE) @@ -169,7 +173,7 @@ FindBeginOfNextSection( base::span<const std::unique_ptr<AutofillField>>::iterator begin, base::span<const std::unique_ptr<AutofillField>>::iterator end) { - while (begin != end && ((*begin)->section || !(*begin)->IsFocusable())) { + while (begin != end && ((*begin)->section() || !(*begin)->IsFocusable())) { begin++; } return begin; @@ -192,7 +196,7 @@ !BelongsToCurrentSection(seen_types, field, *prev_field)) { return it; } - if (!field.section) { + if (!field.section()) { seen_types.insert(field.Type().GetStorableType()); prev_field = &field; } @@ -204,7 +208,7 @@ void AssignSections(base::span<const std::unique_ptr<AutofillField>> fields) { for (const auto& field : fields) - field->section = Section(); + field->set_section(Section()); // Create a unique identifier based on the field for the section. base::flat_map<LocalFrameToken, size_t> frame_token_ids; @@ -236,7 +240,7 @@ if (!IsSectionable(*field) || !field->IsFieldFillable()) { continue; } - ++fields_per_section[field->section]; + ++fields_per_section[field->section()]; } AutofillMetrics::LogSectioningMetrics(fields_per_section); // UKM: @@ -257,7 +261,7 @@ continue; } size_t section_id = - section_ids.emplace(field->section, section_ids.size()).first->second; + section_ids.emplace(field->section(), section_ids.size()).first->second; signature << section_id; } return StrToHash32Bit(signature.str());
diff --git a/components/autofill/core/browser/form_structure_sectioning_util_unittest.cc b/components/autofill/core/browser/form_structure_sectioning_util_unittest.cc index a6d20c97..e99ab35e 100644 --- a/components/autofill/core/browser/form_structure_sectioning_util_unittest.cc +++ b/components/autofill/core/browser/form_structure_sectioning_util_unittest.cc
@@ -77,7 +77,7 @@ std::vector<Section> sections; sections.reserve(fields.size()); for (const auto& field : fields) - sections.push_back(field->section); + sections.push_back(field->section()); return sections; }
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc index 21e1744e..b8c66f35 100644 --- a/components/autofill/core/browser/form_structure_unittest.cc +++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -1047,7 +1047,7 @@ // sections. std::set<Section> section_names; for (size_t i = 0; i < 9; ++i) { - section_names.insert(form_structure.field(i)->section); + section_names.insert(form_structure.field(i)->section()); } EXPECT_EQ(9U, section_names.size()); } @@ -1086,7 +1086,7 @@ // section. std::set<Section> section_names; for (size_t i = 0; i < 6; ++i) { - section_names.insert(form_structure.field(i)->section); + section_names.insert(form_structure.field(i)->section()); } EXPECT_EQ(1U, section_names.size()); } @@ -1113,7 +1113,7 @@ // section. std::set<Section> section_names; for (size_t i = 0; i < 2; ++i) { - section_names.insert(form_structure.field(i)->section); + section_names.insert(form_structure.field(i)->section()); } EXPECT_EQ(1U, section_names.size()); } @@ -1155,7 +1155,8 @@ // form, we do not apply these usual heuristics. EXPECT_EQ(u"one", form_structure.field(0)->name()); EXPECT_EQ(u"two", form_structure.field(3)->name()); - EXPECT_EQ(form_structure.field(0)->section, form_structure.field(3)->section); + EXPECT_EQ(form_structure.field(0)->section(), + form_structure.field(3)->section()); } TEST_F(FormStructureTestImpl, HeuristicsSample8) { @@ -1849,27 +1850,27 @@ field.set_label(u"Phone:"); field.set_name(u"dayphone1"); - field.max_length = 0; + field.set_max_length(0); field.set_renderer_id(test::MakeFieldRendererId()); form.fields.push_back(field); field.set_label(u"-"); field.set_name(u"dayphone2"); - field.max_length = 3; // Size of prefix is 3. + field.set_max_length(3); // Size of prefix is 3. field.set_renderer_id(test::MakeFieldRendererId()); form.fields.push_back(field); field.set_label(u"-"); field.set_name(u"dayphone3"); - field.max_length = 4; // Size of suffix is 4. If unlimited size is - // passed, phone will be parsed as - // <country code> - <area code> - <phone>. + field.set_max_length(4); // Size of suffix is 4. If unlimited size is + // passed, phone will be parsed as + // <country code> - <area code> - <phone>. field.set_renderer_id(test::MakeFieldRendererId()); form.fields.push_back(field); field.set_label(u"ext.:"); field.set_name(u"dayphone4"); - field.max_length = 0; + field.set_max_length(0); field.set_renderer_id(test::MakeFieldRendererId()); form.fields.push_back(field); @@ -2333,7 +2334,7 @@ form.url = GURL("http://foo.com"); FormFieldData field; field.set_form_control_type(FormControlType::kInputText); - field.max_length = 10000; + field.set_max_length(10000); field.set_label(u"Full Name"); field.set_name(u"fullName"); @@ -2377,12 +2378,12 @@ // Assert the correct number of fields. ASSERT_EQ(6U, form_structure.field_count()); - EXPECT_EQ("fullName_0_11", form_structure.field(0)->section.ToString()); - EXPECT_EQ("fullName_0_11", form_structure.field(1)->section.ToString()); - EXPECT_EQ("fullName_0_11", form_structure.field(2)->section.ToString()); - EXPECT_EQ("fullName_0_14", form_structure.field(3)->section.ToString()); - EXPECT_EQ("fullName_0_14", form_structure.field(4)->section.ToString()); - EXPECT_EQ("fullName_0_14", form_structure.field(5)->section.ToString()); + EXPECT_EQ("fullName_0_11", form_structure.field(0)->section().ToString()); + EXPECT_EQ("fullName_0_11", form_structure.field(1)->section().ToString()); + EXPECT_EQ("fullName_0_11", form_structure.field(2)->section().ToString()); + EXPECT_EQ("fullName_0_14", form_structure.field(3)->section().ToString()); + EXPECT_EQ("fullName_0_14", form_structure.field(4)->section().ToString()); + EXPECT_EQ("fullName_0_14", form_structure.field(5)->section().ToString()); } // Tests that the immediate recurrence of the |PHONE_HOME_NUMBER| type does not @@ -2424,13 +2425,13 @@ // Assert the correct number of fields. ASSERT_EQ(7U, form_structure.field_count()); - EXPECT_EQ("blue-billing", form_structure.field(0)->section.ToString()); - EXPECT_EQ("blue-billing", form_structure.field(1)->section.ToString()); - EXPECT_EQ("blue-billing", form_structure.field(2)->section.ToString()); - EXPECT_EQ("blue-billing", form_structure.field(3)->section.ToString()); - EXPECT_EQ("blue-billing", form_structure.field(4)->section.ToString()); - EXPECT_EQ("blue-billing", form_structure.field(5)->section.ToString()); - EXPECT_EQ("blue-billing", form_structure.field(6)->section.ToString()); + EXPECT_EQ("blue-billing", form_structure.field(0)->section().ToString()); + EXPECT_EQ("blue-billing", form_structure.field(1)->section().ToString()); + EXPECT_EQ("blue-billing", form_structure.field(2)->section().ToString()); + EXPECT_EQ("blue-billing", form_structure.field(3)->section().ToString()); + EXPECT_EQ("blue-billing", form_structure.field(4)->section().ToString()); + EXPECT_EQ("blue-billing", form_structure.field(5)->section().ToString()); + EXPECT_EQ("blue-billing", form_structure.field(6)->section().ToString()); } // Tests that adjacent name field types are not split into different sections. @@ -2462,12 +2463,17 @@ // Assert the correct number of fields. ASSERT_EQ(6U, form_structure.field_count()); - EXPECT_EQ(form_structure.field(0)->section, form_structure.field(1)->section); - EXPECT_EQ(form_structure.field(0)->section, form_structure.field(2)->section); - EXPECT_EQ(form_structure.field(0)->section, form_structure.field(3)->section); - EXPECT_EQ(form_structure.field(0)->section, form_structure.field(4)->section); + EXPECT_EQ(form_structure.field(0)->section(), + form_structure.field(1)->section()); + EXPECT_EQ(form_structure.field(0)->section(), + form_structure.field(2)->section()); + EXPECT_EQ(form_structure.field(0)->section(), + form_structure.field(3)->section()); + EXPECT_EQ(form_structure.field(0)->section(), + form_structure.field(4)->section()); // The non-adjacent name field should be split into a different section. - EXPECT_NE(form_structure.field(0)->section, form_structure.field(5)->section); + EXPECT_NE(form_structure.field(0)->section(), + form_structure.field(5)->section()); } // Tests if a new logical form is started with the second appearance of a field @@ -2502,10 +2508,10 @@ // Assert the correct number of fields. ASSERT_EQ(4U, form_structure.field_count()); - EXPECT_EQ("blue-shipping", form_structure.field(0)->section.ToString()); - EXPECT_EQ("blue-shipping", form_structure.field(1)->section.ToString()); - EXPECT_EQ("blue-shipping", form_structure.field(2)->section.ToString()); - EXPECT_EQ("country_2_14", form_structure.field(3)->section.ToString()); + EXPECT_EQ("blue-shipping", form_structure.field(0)->section().ToString()); + EXPECT_EQ("blue-shipping", form_structure.field(1)->section().ToString()); + EXPECT_EQ("blue-shipping", form_structure.field(2)->section().ToString()); + EXPECT_EQ("country_2_14", form_structure.field(3)->section().ToString()); } // Tests if a new logical form is started with the second appearance of a field @@ -2541,10 +2547,10 @@ // Assert the correct number of fields. ASSERT_EQ(4U, form_structure.field_count()); - EXPECT_EQ("blue-shipping", form_structure.field(0)->section.ToString()); - EXPECT_EQ("blue-billing", form_structure.field(1)->section.ToString()); - EXPECT_EQ("blue-billing", form_structure.field(2)->section.ToString()); - EXPECT_EQ("country_2_14", form_structure.field(3)->section.ToString()); + EXPECT_EQ("blue-shipping", form_structure.field(0)->section().ToString()); + EXPECT_EQ("blue-billing", form_structure.field(1)->section().ToString()); + EXPECT_EQ("blue-billing", form_structure.field(2)->section().ToString()); + EXPECT_EQ("country_2_14", form_structure.field(3)->section().ToString()); } // namespace autofill // Tests if a new logical form is started with the second appearance of a field @@ -2579,10 +2585,10 @@ // Assert the correct number of fields. ASSERT_EQ(4U, form_structure.field_count()); - EXPECT_EQ("blue-shipping", form_structure.field(0)->section.ToString()); - EXPECT_EQ("blue-shipping", form_structure.field(1)->section.ToString()); - EXPECT_EQ("blue-billing", form_structure.field(2)->section.ToString()); - EXPECT_EQ("blue-billing", form_structure.field(3)->section.ToString()); + EXPECT_EQ("blue-shipping", form_structure.field(0)->section().ToString()); + EXPECT_EQ("blue-shipping", form_structure.field(1)->section().ToString()); + EXPECT_EQ("blue-billing", form_structure.field(2)->section().ToString()); + EXPECT_EQ("blue-billing", form_structure.field(3)->section().ToString()); } // Tests if a new logical form is started with the second appearance of a field @@ -2618,10 +2624,10 @@ // Assert the correct number of fields. ASSERT_EQ(4U, form_structure.field_count()); - EXPECT_EQ("blue-shipping", form_structure.field(0)->section.ToString()); - EXPECT_EQ("blue-shipping", form_structure.field(1)->section.ToString()); - EXPECT_EQ("blue-billing", form_structure.field(2)->section.ToString()); - EXPECT_EQ("blue-billing", form_structure.field(3)->section.ToString()); + EXPECT_EQ("blue-shipping", form_structure.field(0)->section().ToString()); + EXPECT_EQ("blue-shipping", form_structure.field(1)->section().ToString()); + EXPECT_EQ("blue-billing", form_structure.field(2)->section().ToString()); + EXPECT_EQ("blue-billing", form_structure.field(3)->section().ToString()); } // Tests if all the fields in the form belong to the same section when the @@ -2648,8 +2654,8 @@ // Assert the correct number of fields. ASSERT_EQ(2U, form_structure.field_count()); - EXPECT_EQ("blue-shipping", form_structure.field(0)->section.ToString()); - EXPECT_EQ("blue-shipping", form_structure.field(1)->section.ToString()); + EXPECT_EQ("blue-shipping", form_structure.field(0)->section().ToString()); + EXPECT_EQ("blue-shipping", form_structure.field(1)->section().ToString()); } // Tests if all the fields in the form belong to the same section when one of @@ -2682,9 +2688,9 @@ // Assert the correct number of fields. ASSERT_EQ(3U, form_structure.field_count()); - EXPECT_EQ("-shipping", form_structure.field(0)->section.ToString()); - EXPECT_EQ("-shipping", form_structure.field(1)->section.ToString()); - EXPECT_EQ("-shipping", form_structure.field(2)->section.ToString()); + EXPECT_EQ("-shipping", form_structure.field(0)->section().ToString()); + EXPECT_EQ("-shipping", form_structure.field(1)->section().ToString()); + EXPECT_EQ("-shipping", form_structure.field(2)->section().ToString()); } TEST_F(FormStructureTestImpl, FindFieldsEligibleForManualFilling) { @@ -2692,7 +2698,7 @@ form.url = GURL("http://foo.com"); FormFieldData field; field.set_form_control_type(FormControlType::kInputText); - field.max_length = 10000; + field.set_max_length(10000); field.set_label(u"Full Name"); field.set_name(u"fullName");
diff --git a/components/autofill/core/browser/heuristic_classification_unittests.cc b/components/autofill/core/browser/heuristic_classification_unittests.cc index bef147c..256a1a16 100644 --- a/components/autofill/core/browser/heuristic_classification_unittests.cc +++ b/components/autofill/core/browser/heuristic_classification_unittests.cc
@@ -356,7 +356,7 @@ if (const std::string* maxlength = field_dict.FindString("maxlength_attr")) { uint64_t max_length = 0; base::StringToUint64(*maxlength, &max_length); - field.max_length = max_length; + field.set_max_length(max_length); } field.is_focusable = true; field.role = FormFieldData::RoleAttribute::kOther;
diff --git a/components/autofill/core/browser/metrics/autofill_metrics.cc b/components/autofill/core/browser/metrics/autofill_metrics.cc index f09adf0..57d6e71b 100644 --- a/components/autofill/core/browser/metrics/autofill_metrics.cc +++ b/components/autofill/core/browser/metrics/autofill_metrics.cc
@@ -509,7 +509,7 @@ // only_fill_when_focused set to true. bool DuplicatedFilling(const FormStructure& form, const AutofillField& field) { for (const auto& form_field : form) { - if (field.value() == form_field->value() && form_field->is_autofilled) { + if (field.value() == form_field->value() && form_field->is_autofilled()) { return true; } } @@ -2028,7 +2028,7 @@ .SetServerType(static_cast<int>(field.server_type())) .SetHtmlFieldType(static_cast<int>(field.html_type())) .SetHtmlFieldMode(static_cast<int>(field.html_mode())) - .SetIsAutofilled(field.is_autofilled) + .SetIsAutofilled(field.is_autofilled()) .SetIsEmpty(field.IsEmpty()) .SetMillisecondsSinceFormParsed( MillisecondsSinceFormParsed(form.form_parsed_timestamp())) @@ -2048,7 +2048,7 @@ .SetFormSignature(HashFormSignature(form.form_signature())) .SetFieldSignature(HashFieldSignature(field.GetFieldSignature())) .SetValidationEvent(static_cast<int64_t>(metric_type)) - .SetIsAutofilled(static_cast<int64_t>(field.is_autofilled)) + .SetIsAutofilled(static_cast<int64_t>(field.is_autofilled())) .SetWasPreviouslyAutofilled( static_cast<int64_t>(field.previously_autofilled())) .Record(ukm_recorder_);
diff --git a/components/autofill/core/browser/metrics/autofill_metrics_test_base.h b/components/autofill/core/browser/metrics/autofill_metrics_test_base.h index 4a8dcb90..6cdaa8a 100644 --- a/components/autofill/core/browser/metrics/autofill_metrics_test_base.h +++ b/components/autofill/core/browser/metrics/autofill_metrics_test_base.h
@@ -124,7 +124,7 @@ base::TimeTicks timestamp = {}) { // Assert that the field is actually set to a different value. ASSERT_NE(field.value(), new_value); - field.is_autofilled = false; + field.set_is_autofilled(false); field.set_value(new_value); autofill_manager().OnTextFieldDidChange(form, field, gfx::RectF(), timestamp); @@ -135,7 +135,7 @@ const FormData& form, FormFieldData& field, base::TimeTicks timestamp = {}) { - field.is_autofilled = false; + field.set_is_autofilled(false); autofill_manager().OnTextFieldDidChange(form, field, gfx::RectF(), timestamp); }
diff --git a/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc b/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc index abb17aa..49bb1a7 100644 --- a/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc +++ b/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc
@@ -670,9 +670,9 @@ "buddy@gmail.com", FormControlType::kInputText), CreateTestFormField("Phone", "phone", "2345678901", FormControlType::kInputTelephone)}); - form.fields[0].is_autofilled = true; - form.fields[1].is_autofilled = false; - form.fields[2].is_autofilled = false; + form.fields[0].set_is_autofilled(true); + form.fields[1].set_is_autofilled(false); + form.fields[2].set_is_autofilled(false); SeeForm(form); @@ -705,7 +705,7 @@ FormControlType::kInputText), CreateTestFormField("Unknown", "unknown", "garbage", FormControlType::kInputText)}); - form.fields.front().is_autofilled = true; + form.fields.front().set_is_autofilled(true); std::vector<FieldType> heuristic_types = {NAME_FULL, PHONE_HOME_NUMBER, ADDRESS_HOME_CITY, UNKNOWN_TYPE}; @@ -814,9 +814,9 @@ "buddy@gmail.com", FormControlType::kInputText), CreateTestFormField("Phone", "phone", "2345678901", FormControlType::kInputTelephone)}); - form.fields[0].is_autofilled = true; - form.fields[1].is_autofilled = true; - form.fields[2].is_autofilled = true; + form.fields[0].set_is_autofilled(true); + form.fields[1].set_is_autofilled(true); + form.fields[2].set_is_autofilled(true); std::vector<FieldType> heuristic_types = {NAME_FULL, EMAIL_ADDRESS, PHONE_HOME_CITY_AND_NUMBER}; @@ -6188,7 +6188,7 @@ field.set_value(fill_type != CREDIT_CARD_VERIFICATION_CODE ? fill_data().credit_card.GetRawInfo(fill_type) : fill_data().cvc); - field.is_autofilled = is_autofilled; + field.set_is_autofilled(is_autofilled); field.properties_mask = (field.properties_mask & ~kUserTyped) | (is_user_typed ? kUserTyped : 0); }
diff --git a/components/autofill/core/browser/metrics/autofill_metrics_utils.cc b/components/autofill/core/browser/metrics/autofill_metrics_utils.cc index b5f3c2b..fe59ff6 100644 --- a/components/autofill/core/browser/metrics/autofill_metrics_utils.cc +++ b/components/autofill/core/browser/metrics/autofill_metrics_utils.cc
@@ -52,8 +52,9 @@ !FieldHasMeaningfulPossibleFieldTypes(field); const bool possible_types_contain_type = TypeOfFieldIsPossibleType(field); - if (field.is_autofilled) + if (field.is_autofilled()) { return FieldFillingStatus::kAccepted; + } if (field.previously_autofilled()) { if (is_empty)
diff --git a/components/autofill/core/browser/metrics/field_filling_stats_and_score_metrics_unittest.cc b/components/autofill/core/browser/metrics/field_filling_stats_and_score_metrics_unittest.cc index 6397e78..74e2c89 100644 --- a/components/autofill/core/browser/metrics/field_filling_stats_and_score_metrics_unittest.cc +++ b/components/autofill/core/browser/metrics/field_filling_stats_and_score_metrics_unittest.cc
@@ -187,7 +187,7 @@ // Make all other filled fields, be `FillingMethod::kFullForm`. for (size_t i = 3; i < form_structure->fields().size(); i++) { AutofillField* field = form_structure->field(i); - if (field->is_autofilled) { + if (field->is_autofilled()) { field->AppendLogEventIfNotRepeated( GetFillFieldLogEventWithFillingMethod(FillingMethod::kFullForm)); }
diff --git a/components/autofill/core/browser/metrics/quality_metrics.cc b/components/autofill/core/browser/metrics/quality_metrics.cc index 5c50dcc..bb0f905 100644 --- a/components/autofill/core/browser/metrics/quality_metrics.cc +++ b/components/autofill/core/browser/metrics/quality_metrics.cc
@@ -87,7 +87,7 @@ // The form was not perfectly filled if a field was user-edited. Notice that // this means that in a perfect filling, a field must either be autofilled, // empty, have same value as pageload or have value set by JavaScript. - if (field->is_user_edited && !field->is_autofilled) { + if (field->is_user_edited && !field->is_autofilled()) { perfect_filling = false; } @@ -96,7 +96,7 @@ if (observed_submission) { // If the field was either autofilled and accepted or corrected, emit the // FieldWiseCorrectness metric. - if (field->is_autofilled || field->previously_autofilled()) { + if (field->is_autofilled() || field->previously_autofilled()) { AutofillMetrics::LogEditedAutofilledFieldAtSubmission( form_interactions_ukm_logger, form_structure, *field); } @@ -140,10 +140,10 @@ FormTypeToStringView(form_type_of_field); LogPreFilledFieldStatus(form_type_name, field->initial_value_changed(), type.GetStorableType()); - LogPreFilledValueChanged(form_type_name, field->initial_value_changed(), - field->value(), field->field_log_events(), - field->possible_types(), - type.GetStorableType(), field->is_autofilled); + LogPreFilledValueChanged( + form_type_name, field->initial_value_changed(), field->value(), + field->field_log_events(), field->possible_types(), + type.GetStorableType(), field->is_autofilled()); LogPreFilledFieldClassifications( form_type_name, field->initial_value_changed(), field->may_use_prefilled_placeholder()); @@ -175,7 +175,7 @@ // If there was a collision, log if the NUMERIC_QUANTITY was a false // positive since the field was correctly filled. - if ((field->is_autofilled || field->previously_autofilled()) && + if ((field->is_autofilled() || field->previously_autofilled()) && field_has_non_empty_server_prediction && !base::FeatureList::IsEnabled( features::kAutofillGivePrecedenceToNumericQuantities)) { @@ -193,11 +193,11 @@ ++num_detected_field_types; - if (field->is_autofilled) { + if (field->is_autofilled()) { did_autofill_some_possible_fields = true; } - if (field->is_autofilled) { + if (field->is_autofilled()) { autofilled_field_types.insert(type.GetStorableType()); } @@ -205,7 +205,7 @@ frames_of_detected_fields.insert(field->host_frame); if (group == FieldTypeGroup::kCreditCard) { frames_of_detected_credit_card_fields.insert(field->host_frame); - if (field->is_autofilled) { + if (field->is_autofilled()) { frames_of_autofilled_credit_card_fields.insert(field->host_frame); } }
diff --git a/components/autofill/core/browser/metrics/quality_metrics_unittest.cc b/components/autofill/core/browser/metrics/quality_metrics_unittest.cc index 76b1880..22f7f31 100644 --- a/components/autofill/core/browser/metrics/quality_metrics_unittest.cc +++ b/components/autofill/core/browser/metrics/quality_metrics_unittest.cc
@@ -185,7 +185,7 @@ // RATIONALIZATION_OK because it's a type mismatch. CreateTestFormField("Phone3", "phone3", "Elvis Aaron Presley", FormControlType::kInputText)}); - form.fields[2].is_autofilled = true; + form.fields[2].set_is_autofilled(true); std::vector<FieldType> heuristic_types = {NAME_FULL, ADDRESS_HOME_LINE1, @@ -233,7 +233,7 @@ // RATIONALIZATION_GOOD because it's empty. CreateTestFormField("Phone1", "phone1", "", FormControlType::kInputText)}); - form.fields[2].is_autofilled = true; + form.fields[2].set_is_autofilled(true); std::vector<FieldType> field_types = {NAME_FULL, ADDRESS_HOME_LINE1, PHONE_HOME_CITY_AND_NUMBER, @@ -274,7 +274,7 @@ CreateTestFormField("Phone1", "phone1", "2345678901", FormControlType::kInputText), }); - form.fields[2].is_autofilled = true; + form.fields[2].set_is_autofilled(true); std::vector<FieldType> heuristic_types = {NAME_FULL, ADDRESS_HOME_LINE1, PHONE_HOME_CITY_AND_NUMBER, @@ -324,7 +324,7 @@ // FALSE_NEGATIVE_MISMATCH + RATIONALIZATION_OK CreateTestFormField("Phone3", "phone3", "Elvis Aaron Presley", FormControlType::kInputText)}); - form.fields[2].is_autofilled = true; + form.fields[2].set_is_autofilled(true); std::vector<FieldType> heuristic_types = {NAME_FULL, ADDRESS_HOME_LINE1, @@ -714,8 +714,8 @@ FormControlType::kSelectOne), CreateTestFormField("Phone", "phone", "2345678901", FormControlType::kInputTelephone)}); - form.fields.front().is_autofilled = true; - form.fields.back().is_autofilled = true; + form.fields.front().set_is_autofilled(true); + form.fields.back().set_is_autofilled(true); std::vector<FieldType> heuristic_types = { NAME_FULL, PHONE_HOME_NUMBER, NAME_FULL,
diff --git a/components/autofill/core/browser/metrics/ukm_metrics_test_utils.cc b/components/autofill/core/browser/metrics/ukm_metrics_test_utils.cc index 0d74765..1e93a7b 100644 --- a/components/autofill/core/browser/metrics/ukm_metrics_test_utils.cc +++ b/components/autofill/core/browser/metrics/ukm_metrics_test_utils.cc
@@ -116,7 +116,7 @@ {UkmFieldFillStatusType::kFieldSignatureName, field_signature.value()}, {UkmFieldFillStatusType::kValidationEventName, metric_type}, {UkmTextFieldDidChangeType::kIsAutofilledName, - field.is_autofilled ? 1 : 0}, + field.is_autofilled() ? 1 : 0}, {UkmFieldFillStatusType::kWasPreviouslyAutofilledName, 0}}); } }
diff --git a/components/autofill/core/browser/profile_token_quality.cc b/components/autofill/core/browser/profile_token_quality.cc index 1d70265..9c78668 100644 --- a/components/autofill/core/browser/profile_token_quality.cc +++ b/components/autofill/core/browser/profile_token_quality.cc
@@ -267,7 +267,7 @@ [](AutofillProfile* p) { return p->guid(); })); const FieldType type = field.Type().GetStorableType(); - if (field.is_autofilled) { + if (field.is_autofilled()) { // The filled value was accepted without editing. return GetDatabaseStoredTypesOfAutofillProfile().contains(type) ? ObservationType::kAccepted
diff --git a/components/autofill/core/browser/ui/touch_to_fill_delegate.h b/components/autofill/core/browser/ui/touch_to_fill_delegate.h index bd6cc29..3e6bdb8 100644 --- a/components/autofill/core/browser/ui/touch_to_fill_delegate.h +++ b/components/autofill/core/browser/ui/touch_to_fill_delegate.h
@@ -46,7 +46,8 @@ virtual void ScanCreditCard() = 0; virtual void OnCreditCardScanned(const CreditCard& card) = 0; virtual void ShowPaymentMethodSettings() = 0; - virtual void SuggestionSelected(std::string unique_id, bool is_virtual) = 0; + virtual void CreditCardSuggestionSelected(std::string unique_id, + bool is_virtual) = 0; virtual void OnDismissed(bool dismissed_by_user) = 0; virtual void LogMetricsAfterSubmission(
diff --git a/components/autofill/core/common/autofill_test_utils.cc b/components/autofill/core/common/autofill_test_utils.cc index 3049f9e..a45eea6 100644 --- a/components/autofill/core/common/autofill_test_utils.cc +++ b/components/autofill/core/common/autofill_test_utils.cc
@@ -113,7 +113,7 @@ FormData AsAutofilled(FormData form, bool is_autofilled) { for (FormFieldData& field : form.fields) { - field.is_autofilled = is_autofilled; + field.set_is_autofilled(is_autofilled); } return form; } @@ -168,7 +168,7 @@ FormFieldData field = CreateTestFormField(label, name, value, type); // First, set the `max_length`, as the `parsed_autocomplete` is set based on // this value. - field.max_length = max_length; + field.set_max_length(max_length); field.autocomplete_attribute = autocomplete; field.parsed_autocomplete = ParseAutocompleteAttribute(autocomplete); return field;
diff --git a/components/autofill/core/common/form_data_unittest.cc b/components/autofill/core/common/form_data_unittest.cc index cadec1c..201855e 100644 --- a/components/autofill/core/common/form_data_unittest.cc +++ b/components/autofill/core/common/form_data_unittest.cc
@@ -156,8 +156,8 @@ field_data.set_value(u"value"); field_data.set_form_control_type(FormControlType::kInputPassword); field_data.autocomplete_attribute = "off"; - field_data.max_length = 200; - field_data.is_autofilled = true; + field_data.set_max_length(200); + field_data.set_is_autofilled(true); field_data.check_status = FormFieldData::CheckStatus::kChecked; field_data.is_focusable = true; field_data.should_autocomplete = false; @@ -167,7 +167,7 @@ data->fields.push_back(field_data); // Change a few fields. - field_data.max_length = 150; + field_data.set_max_length(150); field_data.options = {{.value = u"Third", .content = u"Third"}}; data->fields.push_back(field_data); }
diff --git a/components/autofill/core/common/form_field_data.cc b/components/autofill/core/common/form_field_data.cc index 5df60f9..a67e123 100644 --- a/components/autofill/core/common/form_field_data.cc +++ b/components/autofill/core/common/form_field_data.cc
@@ -110,8 +110,8 @@ field_data->set_name(std::move(name)); field_data->set_value(std::move(value)); field_data->autocomplete_attribute = std::move(autocomplete_attribute); - field_data->max_length = max_length; - field_data->is_autofilled = std::move(is_autofilled); + field_data->set_max_length(max_length); + field_data->set_is_autofilled(std::move(is_autofilled)); // Form control types are serialized as strings for legacy reasons. // TODO(crbug.com/1353392,crbug.com/1482526): Why does the Password Manager // (de)serialize form control types? Remove it or migrate it to the enum @@ -254,7 +254,7 @@ return std::tuple_cat( std::tie(f.label(), f.name(), f.name_attribute(), f.id_attribute(), f.form_control_type(), f.autocomplete_attribute, f.placeholder, - f.max_length, f.css_classes, f.is_focusable, + f.max_length(), f.css_classes, f.is_focusable, f.should_autocomplete, f.role, f.text_direction, f.options), std::make_tuple(IsCheckable(f.check_status))); } @@ -418,8 +418,8 @@ : value(field.value()), renderer_id(field.renderer_id()), host_form_id(field.host_form_id), - section(field.section), - is_autofilled(field.is_autofilled), + section(field.section()), + is_autofilled(field.is_autofilled()), force_override(field.force_override) {} FormFieldData::FillData::FillData(const FillData&) = default; @@ -488,8 +488,8 @@ pickle->WriteString(FormControlTypeToString(field_data.form_control_type())); // We don't serialize the `parsed_autocomplete`. See http://crbug.com/1353392. pickle->WriteString(field_data.autocomplete_attribute); - pickle->WriteUInt64(field_data.max_length); - pickle->WriteBool(field_data.is_autofilled); + pickle->WriteUInt64(field_data.max_length()); + pickle->WriteBool(field_data.is_autofilled()); pickle->WriteInt(static_cast<int>(field_data.check_status)); pickle->WriteBool(field_data.is_focusable); pickle->WriteBool(field_data.should_autocomplete); @@ -654,9 +654,10 @@ ? field.parsed_autocomplete->ToString() : "") << "' " << "placeholder='" << field.placeholder << "' " - << "max_length=" << field.max_length << " " << "css_classes='" - << field.css_classes << "' " << "autofilled=" << field.is_autofilled - << " " << "check_status=" << field.check_status << " " + << "max_length=" << field.max_length() << " " << "css_classes='" + << field.css_classes << "' " + << "autofilled=" << field.is_autofilled() << " " + << "check_status=" << field.check_status << " " << "is_focusable=" << field.is_focusable << " " << "should_autocomplete=" << field.should_autocomplete << " " << "role=" << field.role << " " @@ -694,7 +695,7 @@ : ""); buffer << Tr{} << "Aria label:" << field.aria_label; buffer << Tr{} << "Aria description:" << field.aria_description; - buffer << Tr{} << "Section:" << field.section; + buffer << Tr{} << "Section:" << field.section(); buffer << Tr{} << "Is focusable:" << field.is_focusable; buffer << Tr{} << "Is enabled:" << field.is_enabled; buffer << Tr{} << "Is readonly:" << field.is_readonly;
diff --git a/components/autofill/core/common/form_field_data.h b/components/autofill/core/common/form_field_data.h index f069cd2..027fa8f1 100644 --- a/components/autofill/core/common/form_field_data.h +++ b/components/autofill/core/common/form_field_data.h
@@ -349,7 +349,8 @@ // The unique identifier of the section (e.g. billing vs. shipping address) // of this field. - Section section; + const Section& section() const { return section_; } + void set_section(Section section) { section_ = std::move(section); } // The default value for text fields that have no maxlength attribute // specified. We choose the maximum 32 bit, rather than 64 bit, number because @@ -372,9 +373,15 @@ // which could span 32 & 64 bit processes. We chose uint64_t instead of // uint32_t to maintain compatibility with old code which used size_t // (base::Pickle used to serialize that as 64 bit). - uint64_t max_length = std::numeric_limits<uint32_t>::max(); + const uint64_t& max_length() const { return max_length_; } + void set_max_length(uint64_t max_length) { + max_length_ = std::move(max_length); + } - bool is_autofilled = false; + const bool& is_autofilled() const { return is_autofilled_; } + void set_is_autofilled(bool is_autofilled) { + is_autofilled_ = std::move(is_autofilled); + } // Whether the user has edited this field since page load or resetting the // field. @@ -443,6 +450,9 @@ std::u16string value_; FormControlType form_control_type_ = FormControlType::kInputText; FieldRendererId renderer_id_; + uint64_t max_length_ = std::numeric_limits<uint32_t>::max(); + Section section_; + bool is_autofilled_ = false; }; // Structure containing necessary information to be sent from the browser to the @@ -526,11 +536,11 @@ EXPECT_EQ(expected.autocomplete_attribute, actual.autocomplete_attribute); \ EXPECT_EQ(expected.parsed_autocomplete, actual.parsed_autocomplete); \ EXPECT_EQ(expected.placeholder, actual.placeholder); \ - EXPECT_EQ(expected.max_length, actual.max_length); \ + EXPECT_EQ(expected.max_length(), actual.max_length()); \ EXPECT_EQ(expected.css_classes, actual.css_classes); \ - EXPECT_EQ(expected.is_autofilled, actual.is_autofilled); \ + EXPECT_EQ(expected.is_autofilled(), actual.is_autofilled()); \ EXPECT_EQ(expected.is_user_edited, actual.is_user_edited); \ - EXPECT_EQ(expected.section, actual.section); \ + EXPECT_EQ(expected.section(), actual.section()); \ EXPECT_EQ(expected.check_status, actual.check_status); \ EXPECT_EQ(expected.properties_mask, actual.properties_mask); \ EXPECT_EQ(expected.id_attribute(), actual.id_attribute()); \
diff --git a/components/autofill/core/common/form_field_data_unittest.cc b/components/autofill/core/common/form_field_data_unittest.cc index 3b20600..7cd0862 100644 --- a/components/autofill/core/common/form_field_data_unittest.cc +++ b/components/autofill/core/common/form_field_data_unittest.cc
@@ -20,8 +20,8 @@ data->set_value(u"value"); data->set_form_control_type(FormControlType::kInputPassword); data->autocomplete_attribute = "off"; - data->max_length = 200; - data->is_autofilled = true; + data->set_max_length(200); + data->set_is_autofilled(true); data->check_status = FormFieldData::CheckStatus::kChecked; data->is_focusable = true; data->should_autocomplete = false; @@ -61,8 +61,8 @@ pickle->WriteString16(data.value()); pickle->WriteString(FormControlTypeToString(data.form_control_type())); pickle->WriteString(data.autocomplete_attribute); - pickle->WriteUInt64(data.max_length); - pickle->WriteBool(data.is_autofilled); + pickle->WriteUInt64(data.max_length()); + pickle->WriteBool(data.is_autofilled()); } void WriteSection3(const FormFieldData& data, base::Pickle* pickle) {
diff --git a/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc b/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc index 4c9e632..7a4c1d25 100644 --- a/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc +++ b/components/autofill/core/common/mojom/autofill_types_mojom_traits.cc
@@ -269,7 +269,7 @@ if (!data.ReadSection(§ion)) { return false; } - out->section = std::move(section); + out->set_section(std::move(section)); } out->properties_mask = data.properties_mask(); @@ -291,9 +291,9 @@ } out->form_control_ax_id = data.form_control_ax_id(); - out->max_length = data.max_length(); + out->set_max_length(data.max_length()); out->is_user_edited = data.is_user_edited(); - out->is_autofilled = data.is_autofilled(); + out->set_is_autofilled(data.is_autofilled()); { autofill::FormFieldData::CheckStatus check_status;
diff --git a/components/autofill/core/common/mojom/autofill_types_mojom_traits.h b/components/autofill/core/common/mojom/autofill_types_mojom_traits.h index 50abfbc..afc2ef7b 100644 --- a/components/autofill/core/common/mojom/autofill_types_mojom_traits.h +++ b/components/autofill/core/common/mojom/autofill_types_mojom_traits.h
@@ -265,7 +265,7 @@ } static uint64_t max_length(const autofill::FormFieldData& r) { - return r.max_length; + return r.max_length(); } static bool is_user_edited(const autofill::FormFieldData& r) { @@ -273,11 +273,11 @@ } static bool is_autofilled(const autofill::FormFieldData& r) { - return r.is_autofilled; + return r.is_autofilled(); } static const autofill::Section& section(const autofill::FormFieldData& r) { - return r.section; + return r.section(); } static autofill::FormFieldData::CheckStatus check_status(
diff --git a/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc b/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc index 8d271a3..55953f0 100644 --- a/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc +++ b/components/autofill/core/common/mojom/autofill_types_mojom_traits_unittest.cc
@@ -352,8 +352,8 @@ input.aria_description = u"aria description"; input.set_renderer_id(FieldRendererId(1234)); input.host_form_id = FormRendererId(123); - input.max_length = 12345; - input.is_autofilled = true; + input.set_max_length(12345); + input.set_is_autofilled(true); input.is_user_edited = true; input.check_status = FormFieldData::CheckStatus::kChecked; input.should_autocomplete = true; @@ -363,8 +363,8 @@ input.user_input = u"TestTypedValue"; input.bounds = gfx::RectF(1, 2, 10, 100); base::flat_map<LocalFrameToken, size_t> frame_token_ids; - input.section = Section::FromAutocomplete( - {.section = "autocomplete_section", .mode = HtmlFieldMode::kShipping}); + input.set_section(Section::FromAutocomplete( + {.section = "autocomplete_section", .mode = HtmlFieldMode::kShipping})); EXPECT_FALSE(input.host_frame.is_empty()); base::RunLoop loop; @@ -389,8 +389,8 @@ input.css_classes = u"class1"; input.aria_label = u"aria label"; input.aria_description = u"aria description"; - input.max_length = 12345; - input.is_autofilled = true; + input.set_max_length(12345); + input.set_is_autofilled(true); input.is_user_edited = true; input.check_status = FormFieldData::CheckStatus::kChecked; input.should_autocomplete = true;
diff --git a/components/autofill/ios/browser/autofill_agent.mm b/components/autofill/ios/browser/autofill_agent.mm index 7ef8772..9b4456b 100644 --- a/components/autofill/ios/browser/autofill_agent.mm +++ b/components/autofill/ios/browser/autofill_agent.mm
@@ -553,13 +553,13 @@ base::Value::Dict fieldsData; for (const auto& field : form.fields) { // Skip empty fields and those that are not autofilled. - if (field.value().empty() || !field.is_autofilled) { + if (field.value().empty() || !field.is_autofilled()) { continue; } base::Value::Dict fieldData; fieldData.Set("value", field.value()); - fieldData.Set("section", field.section.ToString()); + fieldData.Set("section", field.section().ToString()); fieldsData.Set(NumberToString(field.renderer_id().value()), std::move(fieldData)); }
diff --git a/components/autofill/ios/browser/autofill_agent_unittests.mm b/components/autofill/ios/browser/autofill_agent_unittests.mm index 014e7816..0b26d8b 100644 --- a/components/autofill/ios/browser/autofill_agent_unittests.mm +++ b/components/autofill/ios/browser/autofill_agent_unittests.mm
@@ -158,7 +158,7 @@ field.set_name_attribute(field.name()); field.set_id_attribute(u"number"); field.set_value(u"number_value"); - field.is_autofilled = true; + field.set_is_autofilled(true); field.set_renderer_id(FieldRendererId(2)); form.fields.push_back(field); field.set_label(u"Name on Card"); @@ -166,7 +166,7 @@ field.set_name_attribute(field.name()); field.set_id_attribute(u"name"); field.set_value(u"name_value"); - field.is_autofilled = true; + field.set_is_autofilled(true); field.set_renderer_id(FieldRendererId(3)); form.fields.push_back(field); field.set_label(u"Expiry Month"); @@ -174,7 +174,7 @@ field.set_name_attribute(field.name()); field.set_id_attribute(u"expiry_month"); field.set_value(u"01"); - field.is_autofilled = false; + field.set_is_autofilled(false); field.set_renderer_id(FieldRendererId(4)); form.fields.push_back(field); field.set_label(u"Unknown field"); @@ -182,7 +182,7 @@ field.set_name_attribute(field.name()); field.set_id_attribute(u"unknown"); field.set_value(u""); - field.is_autofilled = true; + field.set_is_autofilled(true); field.set_renderer_id(FieldRendererId(5)); form.fields.push_back(field); [autofill_agent_ fillFormData:form @@ -209,7 +209,7 @@ field.set_name_attribute(field.name()); field.set_id_attribute(u"number"); field.set_value(u"number_value"); - field.is_autofilled = true; + field.set_is_autofilled(true); field.set_renderer_id(FieldRendererId(2)); [autofill_agent_ @@ -236,7 +236,7 @@ field.set_name_attribute(field.name()); field.set_id_attribute(u"number"); field.set_value(u"number_value"); - field.is_autofilled = true; + field.set_is_autofilled(true); field.set_renderer_id(FieldRendererId(2)); autofill::AutofillDriverIOS* main_frame_driver = @@ -267,7 +267,7 @@ field.set_name_attribute(field.name()); field.set_id_attribute(u"number"); field.set_value(u"number_value"); - field.is_autofilled = true; + field.set_is_autofilled(true); field.set_renderer_id(FieldRendererId(2)); autofill::AutofillDriverIOS* main_frame_driver =
diff --git a/components/autofill/ios/browser/autofill_util.mm b/components/autofill/ios/browser/autofill_util.mm index 7132732c..7da08c0 100644 --- a/components/autofill/ios/browser/autofill_util.mm +++ b/components/autofill/ios/browser/autofill_util.mm
@@ -307,8 +307,8 @@ if (const std::string* value = field.FindString("value")) { field_data->set_value(base::UTF8ToUTF16(*value)); } - field_data->is_autofilled = - field.FindBool("is_autofilled").value_or(field_data->is_autofilled); + field_data->set_is_autofilled( + field.FindBool("is_autofilled").value_or(field_data->is_autofilled())); field_data->is_user_edited = field.FindBool("is_user_edited").value_or(field_data->is_user_edited); @@ -317,7 +317,7 @@ field_data->autocomplete_attribute = *autocomplete_attribute; } if (std::optional<int> max_length = field.FindInt("max_length")) { - field_data->max_length = *max_length; + field_data->set_max_length(*max_length); } field_data->parsed_autocomplete = ParseAutocompleteAttribute(field_data->autocomplete_attribute);
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn index 006febe..32b85811 100644 --- a/components/cronet/android/BUILD.gn +++ b/components/cronet/android/BUILD.gn
@@ -371,6 +371,7 @@ # by all Cronet engine implementations. android_library("cronet_impl_common_java") { sources = [ + "java/src/org/chromium/net/impl/BidirectionalStreamBuilderImpl.java", "java/src/org/chromium/net/impl/CallbackExceptionImpl.java", "java/src/org/chromium/net/impl/CronetEngineBase.java", "java/src/org/chromium/net/impl/CronetEngineBuilderImpl.java", @@ -380,8 +381,8 @@ "java/src/org/chromium/net/impl/QuicExceptionImpl.java", "java/src/org/chromium/net/impl/RefCountDelegate.java", "java/src/org/chromium/net/impl/RequestFinishedInfoImpl.java", - "java/src/org/chromium/net/impl/UrlRequestBase.java", "java/src/org/chromium/net/impl/UrlRequestBuilderImpl.java", + "java/src/org/chromium/net/impl/UrlRequestUtil.java", "java/src/org/chromium/net/impl/UrlResponseInfoImpl.java", "java/src/org/chromium/net/impl/UserAgent.java", "java/src/org/chromium/net/impl/VersionSafeCallbacks.java", @@ -502,7 +503,6 @@ "java/src/org/chromium/net/httpflags/BaseFeature.java", "java/src/org/chromium/net/httpflags/HttpFlagsLoader.java", "java/src/org/chromium/net/httpflags/ResolvedFlags.java", - "java/src/org/chromium/net/impl/BidirectionalStreamBuilderImpl.java", "java/src/org/chromium/net/impl/BidirectionalStreamNetworkException.java", "java/src/org/chromium/net/impl/CronetBidirectionalStream.java", "java/src/org/chromium/net/impl/CronetLibraryLoader.java", @@ -539,7 +539,6 @@ # loaded from AOSP (only for Android U onwards) android_library("httpengine_native_provider_java") { sources = [ - "java/src/org/chromium/net/impl/AndroidBidirectionalStreamBuilderWrapper.java", "java/src/org/chromium/net/impl/AndroidBidirectionalStreamCallbackWrapper.java", "java/src/org/chromium/net/impl/AndroidBidirectionalStreamWrapper.java", "java/src/org/chromium/net/impl/AndroidCallbackExceptionWrapper.java", @@ -551,7 +550,6 @@ "java/src/org/chromium/net/impl/AndroidQuicExceptionWrapper.java", "java/src/org/chromium/net/impl/AndroidUploadDataProviderWrapper.java", "java/src/org/chromium/net/impl/AndroidUploadDataSinkWrapper.java", - "java/src/org/chromium/net/impl/AndroidUrlRequestBuilderWrapper.java", "java/src/org/chromium/net/impl/AndroidUrlRequestCallbackWrapper.java", "java/src/org/chromium/net/impl/AndroidUrlRequestStatusListenerWrapper.java", "java/src/org/chromium/net/impl/AndroidUrlRequestWrapper.java",
diff --git a/components/cronet/android/fake/java/org/chromium/net/test/FakeCronetEngine.java b/components/cronet/android/fake/java/org/chromium/net/test/FakeCronetEngine.java index 07f3e091..50a4152a 100644 --- a/components/cronet/android/fake/java/org/chromium/net/test/FakeCronetEngine.java +++ b/components/cronet/android/fake/java/org/chromium/net/test/FakeCronetEngine.java
@@ -11,16 +11,17 @@ import org.chromium.net.BidirectionalStream; import org.chromium.net.CronetEngine; import org.chromium.net.ExperimentalBidirectionalStream; +import org.chromium.net.ExperimentalUrlRequest; import org.chromium.net.NetworkQualityRttListener; import org.chromium.net.NetworkQualityThroughputListener; import org.chromium.net.RequestFinishedInfo; +import org.chromium.net.UploadDataProvider; import org.chromium.net.UrlRequest; import org.chromium.net.impl.CronetEngineBase; import org.chromium.net.impl.CronetEngineBuilderImpl; import org.chromium.net.impl.CronetLogger.CronetSource; import org.chromium.net.impl.ImplVersion; import org.chromium.net.impl.RefCountDelegate; -import org.chromium.net.impl.UrlRequestBase; import org.chromium.net.impl.VersionSafeCallbacks; import java.io.IOException; @@ -28,6 +29,7 @@ import java.net.URL; import java.net.URLConnection; import java.net.URLStreamHandlerFactory; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; @@ -303,7 +305,7 @@ } @Override - protected UrlRequestBase createRequest( + protected ExperimentalUrlRequest createRequest( String url, UrlRequest.Callback callback, Executor userExecutor, @@ -318,7 +320,11 @@ int trafficStatsUid, RequestFinishedInfo.Listener requestFinishedListener, int idempotency, - long networkHandle) { + long networkHandle, + String method, + ArrayList<Map.Entry<String, String>> requestHeaders, + UploadDataProvider uploadDataProvider, + Executor uploadDataProviderExecutor) { if (networkHandle != DEFAULT_NETWORK_HANDLE) { throw new UnsupportedOperationException( "The multi-network API is not supported by the Fake implementation " @@ -343,7 +349,11 @@ trafficStatsUid, mController, this, - connectionAnnotations); + connectionAnnotations, + method, + requestHeaders, + uploadDataProvider, + uploadDataProviderExecutor); } }
diff --git a/components/cronet/android/fake/java/org/chromium/net/test/FakeUrlRequest.java b/components/cronet/android/fake/java/org/chromium/net/test/FakeUrlRequest.java index fb87d34..4a3084d 100644 --- a/components/cronet/android/fake/java/org/chromium/net/test/FakeUrlRequest.java +++ b/components/cronet/android/fake/java/org/chromium/net/test/FakeUrlRequest.java
@@ -10,6 +10,7 @@ import androidx.annotation.VisibleForTesting; import org.chromium.net.CronetException; +import org.chromium.net.ExperimentalUrlRequest; import org.chromium.net.InlineExecutionProhibitedException; import org.chromium.net.RequestFinishedInfo; import org.chromium.net.UploadDataProvider; @@ -24,7 +25,7 @@ import org.chromium.net.impl.Preconditions; import org.chromium.net.impl.RefCountDelegate; import org.chromium.net.impl.RequestFinishedInfoImpl; -import org.chromium.net.impl.UrlRequestBase; +import org.chromium.net.impl.UrlRequestUtil; import org.chromium.net.impl.UrlResponseInfoImpl; import java.io.ByteArrayOutputStream; @@ -33,7 +34,6 @@ import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.WritableByteChannel; -import java.util.AbstractMap; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -47,7 +47,7 @@ * Fake UrlRequest that retrieves responses from the associated FakeCronetController. Used for * testing Cronet usage on Android. */ -final class FakeUrlRequest extends UrlRequestBase { +final class FakeUrlRequest extends ExperimentalUrlRequest { // Used for logging errors. private static final String TAG = FakeUrlRequest.class.getSimpleName(); // Callback used to report responses to the client. @@ -75,8 +75,7 @@ private final List<String> mUrlChain = new ArrayList<>(); // The list of HTTP headers used by this request to establish a connection. - @GuardedBy("mLock") - private final ArrayList<Map.Entry<String, String>> mAllHeadersList = new ArrayList<>(); + private final List<Map.Entry<String, String>> mAllHeadersList; // The exception that is thrown by the request. This is the same exception as the one in // onFailed @@ -96,12 +95,10 @@ private byte[] mRequestBody; // The {@link UploadDataProvider} to retrieve a request body from. - @GuardedBy("mLock") - private UploadDataProvider mUploadDataProvider; + private final UploadDataProvider mUploadDataProvider; // The executor to call the {@link UploadDataProvider}'s callback methods with. - @GuardedBy("mLock") - private Executor mUploadExecutor; + private final Executor mUploadExecutor; // The {@link UploadDataSink} for the {@link UploadDataProvider}. @GuardedBy("mLock") @@ -117,8 +114,7 @@ private ByteBuffer mResponse; // The HTTP method used by this request to establish a connection. - @GuardedBy("mLock") - private String mHttpMethod; + private final String mHttpMethod; // True after the {@link UploadDataProvider} for this request has been closed. @GuardedBy("mLock") @@ -129,12 +125,12 @@ private int mState = State.NOT_STARTED; /** - * Holds a subset of StatusValues - {@link State#STARTED} can represent - * {@link Status#SENDING_REQUEST} or {@link Status#WAITING_FOR_RESPONSE}. While the distinction - * isn't needed to implement the logic in this class, it is needed to implement - * {@link #getStatus(StatusListener)}. + * Holds a subset of StatusValues - {@link State#STARTED} can represent {@link + * Status#SENDING_REQUEST} or {@link Status#WAITING_FOR_RESPONSE}. While the distinction isn't + * needed to implement the logic in this class, it is needed to implement {@link + * #getStatus(StatusListener)}. */ - @StatusValues private volatile int mAdditionalStatusDetails = Status.INVALID; + @UrlRequestUtil.StatusValues private volatile int mAdditionalStatusDetails = Status.INVALID; /** Used to map from HTTP status codes to the corresponding human-readable text. */ private static final Map<Integer, String> HTTP_STATUS_CODE_TO_TEXT; @@ -218,7 +214,11 @@ final int trafficStatsUid, FakeCronetController fakeCronetController, FakeCronetEngine fakeCronetEngine, - Collection<Object> requestAnnotations) { + Collection<Object> requestAnnotations, + String method, + ArrayList<Map.Entry<String, String>> requestHeaders, + UploadDataProvider uploadDataProvider, + Executor uploadDataProviderExecutor) { if (url == null) { throw new NullPointerException("URL is required"); } @@ -237,63 +237,42 @@ mFakeCronetEngine = fakeCronetEngine; mAllowDirectExecutor = allowDirectExecutor; mRequestAnnotations = requestAnnotations; + mHttpMethod = checkedHttpMethod(method); + mAllHeadersList = Collections.unmodifiableList(new ArrayList<>(requestHeaders)); + mUploadDataProvider = checkedUploadDataProvider(uploadDataProvider); + mUploadExecutor = + uploadDataProviderExecutor == null || mAllowDirectExecutor + ? uploadDataProviderExecutor + : new DirectPreventingExecutor(uploadDataProviderExecutor); } - @Override - public void setUploadDataProvider(UploadDataProvider uploadDataProvider, Executor executor) { + private UploadDataProvider checkedUploadDataProvider(UploadDataProvider uploadDataProvider) { if (uploadDataProvider == null) { - throw new NullPointerException("Invalid UploadDataProvider."); + return null; } - synchronized (mLock) { - if (!checkHasContentTypeHeader()) { - throw new IllegalArgumentException( - "Requests with upload data must have a Content-Type."); - } - checkNotStarted(); - if (mHttpMethod == null) { - mHttpMethod = "POST"; - } - mUploadExecutor = - mAllowDirectExecutor ? executor : new DirectPreventingExecutor(executor); - mUploadDataProvider = uploadDataProvider; + + if (!checkHasContentTypeHeader()) { + throw new IllegalArgumentException( + "Requests with upload data must have a Content-Type."); } + return uploadDataProvider; } - @Override - public void setHttpMethod(String method) { - synchronized (mLock) { - checkNotStarted(); - if (method == null) { - throw new NullPointerException("Method is required."); - } - if ("OPTIONS".equalsIgnoreCase(method) - || "GET".equalsIgnoreCase(method) - || "HEAD".equalsIgnoreCase(method) - || "POST".equalsIgnoreCase(method) - || "PUT".equalsIgnoreCase(method) - || "DELETE".equalsIgnoreCase(method) - || "TRACE".equalsIgnoreCase(method) - || "PATCH".equalsIgnoreCase(method)) { - mHttpMethod = method; - } else { - throw new IllegalArgumentException("Invalid http method: " + method); - } + private static String checkedHttpMethod(String method) { + if (method == null) { + throw new NullPointerException("Method is required."); } - } - - @Override - public void addHeader(String header, String value) { - synchronized (mLock) { - checkNotStarted(); - mAllHeadersList.add(new AbstractMap.SimpleEntry<String, String>(header, value)); - } - } - - /** Verifies that the request is not already started and throws an exception if it is. */ - @GuardedBy("mLock") - private void checkNotStarted() { - if (mState != State.NOT_STARTED) { - throw new IllegalStateException("Request is already started. State is: " + mState); + if ("OPTIONS".equalsIgnoreCase(method) + || "GET".equalsIgnoreCase(method) + || "HEAD".equalsIgnoreCase(method) + || "POST".equalsIgnoreCase(method) + || "PUT".equalsIgnoreCase(method) + || "DELETE".equalsIgnoreCase(method) + || "TRACE".equalsIgnoreCase(method) + || "PATCH".equalsIgnoreCase(method)) { + return method; + } else { + throw new IllegalArgumentException("Invalid http method: " + method); } } @@ -492,7 +471,7 @@ synchronized (mLock) { int extraStatus = mAdditionalStatusDetails; - @StatusValues final int status; + @UrlRequestUtil.StatusValues final int status; switch (mState) { case State.ERROR: case State.COMPLETE: @@ -799,12 +778,11 @@ } /** - * Verifies that the "content-type" header is present. Must be checked before an - * {@link UploadDataProvider} is premitted to be set. + * Verifies that the "content-type" header is present. Must be checked before an {@link + * UploadDataProvider} is premitted to be set. * * @return true if the "content-type" header is present in the request headers. */ - @GuardedBy("mLock") private boolean checkHasContentTypeHeader() { for (Map.Entry<String, String> entry : mAllHeadersList) { if (entry.getKey().equalsIgnoreCase("content-type")) {
diff --git a/components/cronet/android/fake/javatests/org/chromium/net/test/FakeUrlRequestTest.java b/components/cronet/android/fake/javatests/org/chromium/net/test/FakeUrlRequestTest.java index 4e2aefb..08a9554c 100644 --- a/components/cronet/android/fake/javatests/org/chromium/net/test/FakeUrlRequestTest.java +++ b/components/cronet/android/fake/javatests/org/chromium/net/test/FakeUrlRequestTest.java
@@ -24,6 +24,7 @@ import org.junit.Test; import org.junit.runner.RunWith; +import org.chromium.base.test.util.Batch; import org.chromium.net.CronetEngine; import org.chromium.net.CronetException; import org.chromium.net.InlineExecutionProhibitedException; @@ -51,6 +52,7 @@ import java.util.concurrent.atomic.AtomicBoolean; /** Test functionality of FakeUrlRequest. */ +@Batch(Batch.UNIT_TESTS) @RunWith(AndroidJUnit4.class) public class FakeUrlRequestTest { private CronetEngine mFakeCronetEngine; @@ -193,44 +195,39 @@ @SmallTest public void testSetHttpMethodWhenNullFails() { TestUrlRequestCallback callback = new TestUrlRequestCallback(); - FakeUrlRequest request = - (FakeUrlRequest) - mFakeCronetEngine - .newUrlRequestBuilder("url", callback, callback.getExecutor()) - .build(); - // Check exception thrown for null method. + UrlRequest.Builder builder = + mFakeCronetEngine.newUrlRequestBuilder("url", callback, callback.getExecutor()); NullPointerException e = - assertThrows(NullPointerException.class, () -> request.setHttpMethod(null)); + assertThrows(NullPointerException.class, () -> builder.setHttpMethod(null).build()); assertThat(e).hasMessageThat().isEqualTo("Method is required."); } @Test @SmallTest public void testSetHttpMethodWhenInvalidFails() { - TestUrlRequestCallback callback = new TestUrlRequestCallback(); - FakeUrlRequest request = - (FakeUrlRequest) - mFakeCronetEngine - .newUrlRequestBuilder("url", callback, callback.getExecutor()) - .build(); - - // Check exception thrown for invalid method. String method = "BADMETHOD"; + TestUrlRequestCallback callback = new TestUrlRequestCallback(); + UrlRequest.Builder builder = + mFakeCronetEngine.newUrlRequestBuilder("url", callback, callback.getExecutor()); IllegalArgumentException e = - assertThrows(IllegalArgumentException.class, () -> request.setHttpMethod(method)); + assertThrows( + IllegalArgumentException.class, + () -> builder.setHttpMethod(method).build()); assertThat(e).hasMessageThat().isEqualTo("Invalid http method: " + method); } @Test @SmallTest public void testSetHttpMethodSetsMethodToCorrectMethod() { + String testMethod = "PUT"; TestUrlRequestCallback callback = new TestUrlRequestCallback(); FakeUrlRequest request = (FakeUrlRequest) mFakeCronetEngine .newUrlRequestBuilder("url", callback, callback.getExecutor()) + .setHttpMethod(testMethod) .build(); - String testMethod = "PUT"; + // Use an atomic because it is set in an inner class. We do not actually need atomic for a // multi-threaded operation here. AtomicBoolean foundMethod = new AtomicBoolean(); @@ -250,9 +247,6 @@ } }); - // Check no exception for correct method. - request.setHttpMethod(testMethod); - // Run the request so that the ResponseMatcher we set is checked. request.start(); callback.blockForDone(); @@ -263,15 +257,16 @@ @Test @SmallTest public void testAddHeader() { + String headerKey = "HEADERNAME"; + String headerValue = "HEADERVALUE"; TestUrlRequestCallback callback = new TestUrlRequestCallback(); FakeUrlRequest request = (FakeUrlRequest) mFakeCronetEngine .newUrlRequestBuilder("TEST_URL", callback, callback.getExecutor()) + .addHeader(headerKey, headerValue) .build(); - String headerKey = "HEADERNAME"; - String headerValue = "HEADERVALUE"; - request.addHeader(headerKey, headerValue); + // Use an atomic because it is set in an inner class. We do not actually need atomic for a // multi-threaded operation here. AtomicBoolean foundEntry = new AtomicBoolean(); @@ -549,34 +544,6 @@ @Test @SmallTest - public void testSetUploadDataProviderAfterStart() { - TestUrlRequestCallback callback = new TestUrlRequestCallback(); - FakeUrlRequest request = - (FakeUrlRequest) - mFakeCronetEngine - .newUrlRequestBuilder("", callback, callback.getExecutor()) - .addHeader("Content-Type", "useless/string") - .build(); - String body = "body"; - request.setUploadDataProvider( - UploadDataProviders.create(body.getBytes()), callback.getExecutor()); - request.start(); - // Must wait for the request to prevent a race in the State since it is reported in the - // error. - callback.blockForDone(); - - IllegalStateException e = - assertThrows( - IllegalStateException.class, - () -> - request.setUploadDataProvider( - UploadDataProviders.create(body.getBytes()), - callback.getExecutor())); - assertThat(e).hasMessageThat().isEqualTo("Request is already started. State is: 7"); - } - - @Test - @SmallTest public void testUrlChainIsCorrectForSuccessRequest() { TestUrlRequestCallback callback = new TestUrlRequestCallback(); String testUrl = "TEST_URL";
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/AndroidBidirectionalStreamBuilderWrapper.java b/components/cronet/android/java/src/org/chromium/net/impl/AndroidBidirectionalStreamBuilderWrapper.java deleted file mode 100644 index 8f4c7ed..0000000 --- a/components/cronet/android/java/src/org/chromium/net/impl/AndroidBidirectionalStreamBuilderWrapper.java +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.net.impl; - -import static org.chromium.net.impl.HttpEngineNativeProvider.EXT_API_LEVEL; -import static org.chromium.net.impl.HttpEngineNativeProvider.EXT_VERSION; - -import android.net.Network; - -import androidx.annotation.RequiresExtension; - -import org.chromium.net.CronetEngine; - -@RequiresExtension(extension = EXT_API_LEVEL, version = EXT_VERSION) -class AndroidBidirectionalStreamBuilderWrapper - extends org.chromium.net.ExperimentalBidirectionalStream.Builder { - private final android.net.http.BidirectionalStream.Builder mBackend; - - public AndroidBidirectionalStreamBuilderWrapper( - android.net.http.BidirectionalStream.Builder backend) { - this.mBackend = backend; - } - - @Override - public org.chromium.net.ExperimentalBidirectionalStream.Builder setHttpMethod(String method) { - mBackend.setHttpMethod(method); - return this; - } - - @Override - public org.chromium.net.ExperimentalBidirectionalStream.Builder addHeader( - String header, String value) { - mBackend.addHeader(header, value); - return this; - } - - @Override - public org.chromium.net.ExperimentalBidirectionalStream.Builder setPriority(int priority) { - mBackend.setPriority(priority); - return this; - } - - @Override - public org.chromium.net.ExperimentalBidirectionalStream.Builder bindToNetwork( - long networkHandle) { - // Network#fromNetworkHandle throws IAE if networkHandle does not translate to a valid - // Network. Though, this can only happen if we're given a fake networkHandle (in which case - // we will throw, which is fine). - Network network = - networkHandle == CronetEngine.UNBIND_NETWORK_HANDLE - ? null - : Network.fromNetworkHandle(networkHandle); - // TODO(b/309112420): Stop no-op'ing this. - return this; - } - - @Override - public org.chromium.net.ExperimentalBidirectionalStream.Builder - delayRequestHeadersUntilFirstFlush(boolean delayRequestHeadersUntilFirstFlush) { - mBackend.setDelayRequestHeadersUntilFirstFlushEnabled(delayRequestHeadersUntilFirstFlush); - return this; - } - - @Override - public org.chromium.net.ExperimentalBidirectionalStream build() { - return new AndroidBidirectionalStreamWrapper(mBackend.build()); - } -}
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/AndroidBidirectionalStreamCallbackWrapper.java b/components/cronet/android/java/src/org/chromium/net/impl/AndroidBidirectionalStreamCallbackWrapper.java index 7aa6ad605..bf4921340 100644 --- a/components/cronet/android/java/src/org/chromium/net/impl/AndroidBidirectionalStreamCallbackWrapper.java +++ b/components/cronet/android/java/src/org/chromium/net/impl/AndroidBidirectionalStreamCallbackWrapper.java
@@ -21,6 +21,7 @@ class AndroidBidirectionalStreamCallbackWrapper implements android.net.http.BidirectionalStream.Callback { private final org.chromium.net.BidirectionalStream.Callback mBackend; + private AndroidBidirectionalStreamWrapper mWrappedStream; public AndroidBidirectionalStreamCallbackWrapper( org.chromium.net.BidirectionalStream.Callback backend) { @@ -30,9 +31,7 @@ @Override public void onStreamReady(android.net.http.BidirectionalStream bidirectionalStream) { - AndroidBidirectionalStreamWrapper stream = - new AndroidBidirectionalStreamWrapper(bidirectionalStream); - mBackend.onStreamReady(stream); + mBackend.onStreamReady(mWrappedStream); } @Override @@ -41,9 +40,7 @@ android.net.http.UrlResponseInfo urlResponseInfo) { AndroidUrlResponseInfoWrapper specializedResponseInfo = AndroidUrlResponseInfoWrapper.createForBidirectionalStream(urlResponseInfo); - AndroidBidirectionalStreamWrapper specializedStream = - new AndroidBidirectionalStreamWrapper(bidirectionalStream); - mBackend.onResponseHeadersReceived(specializedStream, specializedResponseInfo); + mBackend.onResponseHeadersReceived(mWrappedStream, specializedResponseInfo); } @Override @@ -54,10 +51,7 @@ boolean endOfStream) { AndroidUrlResponseInfoWrapper specializedResponseInfo = AndroidUrlResponseInfoWrapper.createForBidirectionalStream(urlResponseInfo); - AndroidBidirectionalStreamWrapper specializedStream = - new AndroidBidirectionalStreamWrapper(bidirectionalStream); - mBackend.onReadCompleted( - specializedStream, specializedResponseInfo, byteBuffer, endOfStream); + mBackend.onReadCompleted(mWrappedStream, specializedResponseInfo, byteBuffer, endOfStream); } @Override @@ -68,10 +62,7 @@ boolean endOfStream) { AndroidUrlResponseInfoWrapper specializedResponseInfo = AndroidUrlResponseInfoWrapper.createForBidirectionalStream(urlResponseInfo); - AndroidBidirectionalStreamWrapper specializedStream = - new AndroidBidirectionalStreamWrapper(bidirectionalStream); - mBackend.onWriteCompleted( - specializedStream, specializedResponseInfo, byteBuffer, endOfStream); + mBackend.onWriteCompleted(mWrappedStream, specializedResponseInfo, byteBuffer, endOfStream); } @Override @@ -81,12 +72,10 @@ @NonNull android.net.http.HeaderBlock headerBlock) { AndroidUrlResponseInfoWrapper specializedResponseInfo = AndroidUrlResponseInfoWrapper.createForBidirectionalStream(urlResponseInfo); - AndroidBidirectionalStreamWrapper specializedStream = - new AndroidBidirectionalStreamWrapper(bidirectionalStream); AndroidHeaderBlockWrapper specializedHeaderBlock = new AndroidHeaderBlockWrapper(headerBlock); mBackend.onResponseTrailersReceived( - specializedStream, specializedResponseInfo, specializedHeaderBlock); + mWrappedStream, specializedResponseInfo, specializedHeaderBlock); } @Override @@ -95,9 +84,7 @@ android.net.http.UrlResponseInfo urlResponseInfo) { AndroidUrlResponseInfoWrapper specializedResponseInfo = AndroidUrlResponseInfoWrapper.createForBidirectionalStream(urlResponseInfo); - AndroidBidirectionalStreamWrapper specializedStream = - new AndroidBidirectionalStreamWrapper(bidirectionalStream); - mBackend.onSucceeded(specializedStream, specializedResponseInfo); + mBackend.onSucceeded(mWrappedStream, specializedResponseInfo); } @Override @@ -107,10 +94,8 @@ HttpException e) { AndroidUrlResponseInfoWrapper specializedResponseInfo = AndroidUrlResponseInfoWrapper.createForBidirectionalStream(urlResponseInfo); - AndroidBidirectionalStreamWrapper specializedStream = - new AndroidBidirectionalStreamWrapper(bidirectionalStream); mBackend.onFailed( - specializedStream, + mWrappedStream, specializedResponseInfo, CronetExceptionTranslationUtils.translateCheckedAndroidCronetException(e)); } @@ -121,8 +106,10 @@ @Nullable android.net.http.UrlResponseInfo urlResponseInfo) { AndroidUrlResponseInfoWrapper specializedResponseInfo = AndroidUrlResponseInfoWrapper.createForBidirectionalStream(urlResponseInfo); - AndroidBidirectionalStreamWrapper specializedStream = - new AndroidBidirectionalStreamWrapper(bidirectionalStream); - mBackend.onCanceled(specializedStream, specializedResponseInfo); + mBackend.onCanceled(mWrappedStream, specializedResponseInfo); + } + + void setStream(AndroidBidirectionalStreamWrapper stream) { + mWrappedStream = stream; } }
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/AndroidBidirectionalStreamWrapper.java b/components/cronet/android/java/src/org/chromium/net/impl/AndroidBidirectionalStreamWrapper.java index c0586ba..fe10826ca 100644 --- a/components/cronet/android/java/src/org/chromium/net/impl/AndroidBidirectionalStreamWrapper.java +++ b/components/cronet/android/java/src/org/chromium/net/impl/AndroidBidirectionalStreamWrapper.java
@@ -15,7 +15,7 @@ class AndroidBidirectionalStreamWrapper extends org.chromium.net.ExperimentalBidirectionalStream { private final android.net.http.BidirectionalStream mBackend; - AndroidBidirectionalStreamWrapper(android.net.http.BidirectionalStream backend) { + private AndroidBidirectionalStreamWrapper(android.net.http.BidirectionalStream backend) { this.mBackend = backend; } @@ -48,4 +48,20 @@ public boolean isDone() { return mBackend.isDone(); } + + /** + * Creates an {@link AndroidUrlRequestWrapper} that is stored on the callback. + * + * @param backend the http UrlRequest + * @param callback the stream's callback + * @return the wrapped request + */ + static AndroidBidirectionalStreamWrapper createAndAddToCallback( + android.net.http.BidirectionalStream backend, + AndroidBidirectionalStreamCallbackWrapper callback) { + AndroidBidirectionalStreamWrapper wrappedStream = + new AndroidBidirectionalStreamWrapper(backend); + callback.setStream(wrappedStream); + return wrappedStream; + } }
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/AndroidHttpEngineWrapper.java b/components/cronet/android/java/src/org/chromium/net/impl/AndroidHttpEngineWrapper.java index 9b35112..16d54c01 100644 --- a/components/cronet/android/java/src/org/chromium/net/impl/AndroidHttpEngineWrapper.java +++ b/components/cronet/android/java/src/org/chromium/net/impl/AndroidHttpEngineWrapper.java
@@ -10,19 +10,29 @@ import android.net.Network; import android.net.http.HttpEngine; +import androidx.annotation.Nullable; import androidx.annotation.RequiresExtension; -import org.chromium.net.ExperimentalCronetEngine; +import org.chromium.net.BidirectionalStream; +import org.chromium.net.CronetEngine; +import org.chromium.net.RequestFinishedInfo; +import org.chromium.net.UploadDataProvider; +import org.chromium.net.UrlRequest; import java.io.IOException; import java.net.Proxy; import java.net.URL; import java.net.URLConnection; import java.net.URLStreamHandlerFactory; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.concurrent.Executor; @RequiresExtension(extension = EXT_API_LEVEL, version = EXT_VERSION) -class AndroidHttpEngineWrapper extends ExperimentalCronetEngine { +class AndroidHttpEngineWrapper extends CronetEngineBase { private final HttpEngine mBackend; public AndroidHttpEngineWrapper(HttpEngine backend) { @@ -59,12 +69,8 @@ public void bindToNetwork(long networkHandle) { // Network#fromNetworkHandle throws IAE if networkHandle does not translate to a valid // Network. Though, this can only happen if we're given a fake networkHandle (in which case - // we will throw, which is fine). - Network network = - networkHandle == UNBIND_NETWORK_HANDLE - ? null - : Network.fromNetworkHandle(networkHandle); - mBackend.bindToNetwork(network); + // we will throw, which is fine) + mBackend.bindToNetwork(getNetwork(networkHandle)); } @Override @@ -95,16 +101,103 @@ @Override public org.chromium.net.ExperimentalBidirectionalStream.Builder newBidirectionalStreamBuilder( String url, org.chromium.net.BidirectionalStream.Callback callback, Executor executor) { - return new AndroidBidirectionalStreamBuilderWrapper( - mBackend.newBidirectionalStreamBuilder( - url, executor, new AndroidBidirectionalStreamCallbackWrapper(callback))); + return new BidirectionalStreamBuilderImpl(url, callback, executor, this); } @Override - public org.chromium.net.ExperimentalUrlRequest.Builder newUrlRequestBuilder( - String url, org.chromium.net.UrlRequest.Callback callback, Executor executor) { - return new AndroidUrlRequestBuilderWrapper( - mBackend.newUrlRequestBuilder( - url, executor, new AndroidUrlRequestCallbackWrapper(callback))); + public org.chromium.net.ExperimentalBidirectionalStream createBidirectionalStream( + String url, + BidirectionalStream.Callback callback, + Executor executor, + String httpMethod, + List<Entry<String, String>> requestHeaders, + @StreamPriority int priority, + boolean delayRequestHeadersUntilFirstFlush, + Collection<Object> requestAnnotations /* not in HttpEngine */, + boolean trafficStatsTagSet, + int trafficStatsTag, + boolean trafficStatsUidSet, + int trafficStatsUid, + long networkHandle /* TODO(b/309112420): add to HttpEngine */) { + AndroidBidirectionalStreamCallbackWrapper wrappedCallback = + new AndroidBidirectionalStreamCallbackWrapper(callback); + + android.net.http.BidirectionalStream.Builder streamBuilder = + mBackend.newBidirectionalStreamBuilder(url, executor, wrappedCallback); + streamBuilder.setHttpMethod(httpMethod); + for (Map.Entry<String, String> header : requestHeaders) { + streamBuilder.addHeader(header.getKey(), header.getValue()); + } + streamBuilder.setPriority(priority); + streamBuilder.setDelayRequestHeadersUntilFirstFlushEnabled( + delayRequestHeadersUntilFirstFlush); + if (trafficStatsTagSet) { + streamBuilder.setTrafficStatsTag(trafficStatsTag); + } + if (trafficStatsUidSet) { + streamBuilder.setTrafficStatsUid(trafficStatsUid); + } + + return AndroidBidirectionalStreamWrapper.createAndAddToCallback( + streamBuilder.build(), wrappedCallback); + } + + @Override + public org.chromium.net.ExperimentalUrlRequest createRequest( + String url, + UrlRequest.Callback callback, + Executor executor, + @RequestPriority int priority, + Collection<Object> requestAnnotations /* not in HttpEngine */, + boolean disableCache, + boolean disableConnectionMigration /* not in HttpEngine */, + boolean allowDirectExecutor, + boolean trafficStatsTagSet, + int trafficStatsTag, + boolean trafficStatsUidSet, + int trafficStatsUid, + @Nullable RequestFinishedInfo.Listener requestFinishedListener /* not in HttpEngine */, + @Idempotency int idempotency /* not in HttpEngine */, + long networkHandle, + String method, + ArrayList<Map.Entry<String, String>> requestHeaders, + UploadDataProvider uploadDataProvider, + Executor uploadDataProviderExecutor) { + AndroidUrlRequestCallbackWrapper wrappedCallback = + new AndroidUrlRequestCallbackWrapper(callback); + android.net.http.UrlRequest.Builder requestBuilder = + mBackend.newUrlRequestBuilder(url, executor, wrappedCallback); + + requestBuilder.setPriority(priority); + requestBuilder.setCacheDisabled(disableCache); + requestBuilder.setDirectExecutorAllowed(allowDirectExecutor); + if (trafficStatsTagSet) { + requestBuilder.setTrafficStatsTag(trafficStatsTag); + } + if (trafficStatsUidSet) { + requestBuilder.setTrafficStatsTag(trafficStatsUid); + } + requestBuilder.bindToNetwork(getNetwork(networkHandle)); + requestBuilder.setHttpMethod(method); + for (Map.Entry<String, String> header : requestHeaders) { + requestBuilder.addHeader(header.getKey(), header.getValue()); + } + if (uploadDataProvider != null) { + requestBuilder.setUploadDataProvider( + new AndroidUploadDataProviderWrapper(uploadDataProvider), + uploadDataProviderExecutor); + } + + return AndroidUrlRequestWrapper.createAndAddToCallback( + requestBuilder.build(), wrappedCallback); + } + + private Network getNetwork(long networkHandle) { + // Network#fromNetworkHandle throws IAE if networkHandle does not translate to a valid + // Network. Though, this can only happen if we're given a fake networkHandle (in which case + // we will throw, which is fine). + return networkHandle == CronetEngine.UNBIND_NETWORK_HANDLE + ? null + : Network.fromNetworkHandle(networkHandle); } }
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/AndroidUrlRequestBuilderWrapper.java b/components/cronet/android/java/src/org/chromium/net/impl/AndroidUrlRequestBuilderWrapper.java deleted file mode 100644 index 63bc86b..0000000 --- a/components/cronet/android/java/src/org/chromium/net/impl/AndroidUrlRequestBuilderWrapper.java +++ /dev/null
@@ -1,81 +0,0 @@ -// Copyright 2023 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.net.impl; - -import static org.chromium.net.impl.HttpEngineNativeProvider.EXT_API_LEVEL; -import static org.chromium.net.impl.HttpEngineNativeProvider.EXT_VERSION; - -import android.net.Network; - -import androidx.annotation.RequiresExtension; - -import org.chromium.net.CronetEngine; - -import java.util.concurrent.Executor; - -@RequiresExtension(extension = EXT_API_LEVEL, version = EXT_VERSION) -class AndroidUrlRequestBuilderWrapper extends org.chromium.net.ExperimentalUrlRequest.Builder { - private final android.net.http.UrlRequest.Builder mBackend; - - public AndroidUrlRequestBuilderWrapper(android.net.http.UrlRequest.Builder backend) { - this.mBackend = backend; - } - - @Override - public org.chromium.net.ExperimentalUrlRequest.Builder setHttpMethod(String method) { - mBackend.setHttpMethod(method); - return this; - } - - @Override - public org.chromium.net.ExperimentalUrlRequest.Builder addHeader(String header, String value) { - mBackend.addHeader(header, value); - return this; - } - - @Override - public org.chromium.net.ExperimentalUrlRequest.Builder disableCache() { - mBackend.setCacheDisabled(true); - return this; - } - - @Override - public org.chromium.net.ExperimentalUrlRequest.Builder setPriority(int priority) { - mBackend.setPriority(priority); - return this; - } - - @Override - public org.chromium.net.ExperimentalUrlRequest.Builder setUploadDataProvider( - org.chromium.net.UploadDataProvider uploadDataProvider, Executor executor) { - mBackend.setUploadDataProvider( - new AndroidUploadDataProviderWrapper(uploadDataProvider), executor); - return this; - } - - @Override - public org.chromium.net.ExperimentalUrlRequest.Builder allowDirectExecutor() { - mBackend.setDirectExecutorAllowed(true); - return this; - } - - @Override - public org.chromium.net.ExperimentalUrlRequest.Builder bindToNetwork(long networkHandle) { - // Network#fromNetworkHandle throws IAE if networkHandle does not translate to a valid - // Network. Though, this can only happen if we're given a fake networkHandle (in which case - // we will throw, which is fine). - Network network = - networkHandle == CronetEngine.UNBIND_NETWORK_HANDLE - ? null - : Network.fromNetworkHandle(networkHandle); - mBackend.bindToNetwork(network); - return this; - } - - @Override - public org.chromium.net.ExperimentalUrlRequest build() { - return new AndroidUrlRequestWrapper(mBackend.build()); - } -}
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/AndroidUrlRequestCallbackWrapper.java b/components/cronet/android/java/src/org/chromium/net/impl/AndroidUrlRequestCallbackWrapper.java index 3e8b1b5..1f09ab7 100644 --- a/components/cronet/android/java/src/org/chromium/net/impl/AndroidUrlRequestCallbackWrapper.java +++ b/components/cronet/android/java/src/org/chromium/net/impl/AndroidUrlRequestCallbackWrapper.java
@@ -20,6 +20,7 @@ @SuppressWarnings("Override") class AndroidUrlRequestCallbackWrapper implements android.net.http.UrlRequest.Callback { private final org.chromium.net.UrlRequest.Callback mBackend; + private AndroidUrlRequestWrapper mWrappedRequest; public AndroidUrlRequestCallbackWrapper(org.chromium.net.UrlRequest.Callback backend) { Objects.requireNonNull(backend, "Callback is required."); @@ -41,10 +42,8 @@ () -> { AndroidUrlResponseInfoWrapper specializedResponseInfo = AndroidUrlResponseInfoWrapper.createForUrlRequest(info); - AndroidUrlRequestWrapper specializedRequest = - new AndroidUrlRequestWrapper(request); mBackend.onRedirectReceived( - specializedRequest, specializedResponseInfo, newLocationUrl); + mWrappedRequest, specializedResponseInfo, newLocationUrl); return null; }, Exception.class); @@ -58,9 +57,7 @@ () -> { AndroidUrlResponseInfoWrapper specializedResponseInfo = AndroidUrlResponseInfoWrapper.createForUrlRequest(info); - AndroidUrlRequestWrapper specializedRequest = - new AndroidUrlRequestWrapper(request); - mBackend.onResponseStarted(specializedRequest, specializedResponseInfo); + mBackend.onResponseStarted(mWrappedRequest, specializedResponseInfo); return null; }, Exception.class); @@ -76,10 +73,7 @@ () -> { AndroidUrlResponseInfoWrapper specializedResponseInfo = AndroidUrlResponseInfoWrapper.createForUrlRequest(info); - AndroidUrlRequestWrapper specializedRequest = - new AndroidUrlRequestWrapper(request); - mBackend.onReadCompleted( - specializedRequest, specializedResponseInfo, byteBuffer); + mBackend.onReadCompleted(mWrappedRequest, specializedResponseInfo, byteBuffer); return null; }, Exception.class); @@ -90,8 +84,7 @@ android.net.http.UrlRequest request, android.net.http.UrlResponseInfo info) { AndroidUrlResponseInfoWrapper specializedResponseInfo = AndroidUrlResponseInfoWrapper.createForUrlRequest(info); - AndroidUrlRequestWrapper specializedRequest = new AndroidUrlRequestWrapper(request); - mBackend.onSucceeded(specializedRequest, specializedResponseInfo); + mBackend.onSucceeded(mWrappedRequest, specializedResponseInfo); } @Override @@ -101,9 +94,8 @@ HttpException error) { AndroidUrlResponseInfoWrapper specializedResponseInfo = AndroidUrlResponseInfoWrapper.createForUrlRequest(info); - AndroidUrlRequestWrapper specializedRequest = new AndroidUrlRequestWrapper(request); mBackend.onFailed( - specializedRequest, + mWrappedRequest, specializedResponseInfo, CronetExceptionTranslationUtils.translateCheckedAndroidCronetException(error)); } @@ -114,7 +106,10 @@ @Nullable android.net.http.UrlResponseInfo info) { AndroidUrlResponseInfoWrapper specializedResponseInfo = AndroidUrlResponseInfoWrapper.createForUrlRequest(info); - AndroidUrlRequestWrapper specializedRequest = new AndroidUrlRequestWrapper(request); - mBackend.onCanceled(specializedRequest, specializedResponseInfo); + mBackend.onCanceled(mWrappedRequest, specializedResponseInfo); + } + + void setRequest(AndroidUrlRequestWrapper request) { + mWrappedRequest = request; } }
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/AndroidUrlRequestWrapper.java b/components/cronet/android/java/src/org/chromium/net/impl/AndroidUrlRequestWrapper.java index 3d42ed4..2c67875 100644 --- a/components/cronet/android/java/src/org/chromium/net/impl/AndroidUrlRequestWrapper.java +++ b/components/cronet/android/java/src/org/chromium/net/impl/AndroidUrlRequestWrapper.java
@@ -48,4 +48,18 @@ public void getStatus(StatusListener listener) { mBackend.getStatus(new AndroidUrlRequestStatusListenerWrapper(listener)); } + + /** + * Creates an {@link AndroidUrlRequestWrapper} that is recorded on the callback. + * + * @param backend the http UrlRequest + * @param callback the stream's callback + * @return the wrapped request + */ + static AndroidUrlRequestWrapper createAndAddToCallback( + android.net.http.UrlRequest backend, AndroidUrlRequestCallbackWrapper callback) { + AndroidUrlRequestWrapper wrappedRequest = new AndroidUrlRequestWrapper(backend); + callback.setRequest(wrappedRequest); + return wrappedRequest; + } }
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/CronetEngineBase.java b/components/cronet/android/java/src/org/chromium/net/impl/CronetEngineBase.java index baaee78..5547a5f 100644 --- a/components/cronet/android/java/src/org/chromium/net/impl/CronetEngineBase.java +++ b/components/cronet/android/java/src/org/chromium/net/impl/CronetEngineBase.java
@@ -11,11 +11,13 @@ import org.chromium.net.ExperimentalCronetEngine; import org.chromium.net.ExperimentalUrlRequest; import org.chromium.net.RequestFinishedInfo; +import org.chromium.net.UploadDataProvider; import org.chromium.net.UrlRequest; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.net.URL; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; @@ -33,40 +35,37 @@ protected static final long DEFAULT_NETWORK_HANDLE = -1; /** - * Creates a {@link UrlRequest} object. All callbacks will - * be called on {@code executor}'s thread. {@code executor} must not run - * tasks on the current thread to prevent blocking networking operations - * and causing exceptions during shutdown. + * Creates a {@link UrlRequest} object. All callbacks will be called on {@code executor}'s + * thread. {@code executor} must not run tasks on the current thread to prevent blocking + * networking operations and causing exceptions during shutdown. * * @param url {@link URL} for the request. * @param callback callback object that gets invoked on different events. * @param executor {@link Executor} on which all callbacks will be invoked. - * @param priority priority of the request which should be one of the - * {@link UrlRequest.Builder#REQUEST_PRIORITY_IDLE REQUEST_PRIORITY_*} - * values. - * @param requestAnnotations Objects to pass on to - * {@link org.chromium.net.RequestFinishedInfo.Listener}. - * @param disableCache disables cache for the request. - * If context is not set up to use cache this param has no effect. - * @param disableConnectionMigration disables connection migration for this - * request if it is enabled for the session. - * @param allowDirectExecutor whether executors used by this request are permitted - * to execute submitted tasks inline. + * @param priority priority of the request which should be one of the {@link + * UrlRequest.Builder#REQUEST_PRIORITY_IDLE REQUEST_PRIORITY_*} values. + * @param requestAnnotations Objects to pass on to {@link + * org.chromium.net.RequestFinishedInfo.Listener}. + * @param disableCache disables cache for the request. If context is not set up to use cache + * this param has no effect. + * @param disableConnectionMigration disables connection migration for this request if it is + * enabled for the session. + * @param allowDirectExecutor whether executors used by this request are permitted to execute + * submitted tasks inline. * @param trafficStatsTagSet {@code true} if {@code trafficStatsTag} represents a TrafficStats - * tag to apply to sockets used to perform this request. + * tag to apply to sockets used to perform this request. * @param trafficStatsTag TrafficStats tag to apply to sockets used to perform this request. * @param trafficStatsUidSet {@code true} if {@code trafficStatsUid} represents a UID to - * attribute traffic used to perform this request. + * attribute traffic used to perform this request. * @param trafficStatsUid UID to attribute traffic used to perform this request. * @param requestFinishedListener callback to get invoked with metrics when request is finished. - * Set to {@code null} if not used. - * @param idempotency idempotency of the request which should be one of the - * {@link ExperimentalUrlRequest.Builder#DEFAULT_IDEMPOTENCY IDEMPOTENT NOT_IDEMPOTENT} - * values. + * Set to {@code null} if not used. + * @param idempotency idempotency of the request which should be one of the {@link + * ExperimentalUrlRequest.Builder#DEFAULT_IDEMPOTENCY IDEMPOTENT NOT_IDEMPOTENT} values. * @param network network to be used to send this request. Set to {@code null} if not specified. * @return new request. */ - protected abstract UrlRequestBase createRequest( + protected abstract ExperimentalUrlRequest createRequest( String url, UrlRequest.Callback callback, Executor executor, @@ -81,32 +80,33 @@ int trafficStatsUid, @Nullable RequestFinishedInfo.Listener requestFinishedListener, @Idempotency int idempotency, - long networkHandle); + long networkHandle, + String method, + ArrayList<Map.Entry<String, String>> requestHeaders, + UploadDataProvider uploadDataProvider, + Executor uploadDataProviderExecutor); /** - * Creates a {@link BidirectionalStream} object. {@code callback} methods will - * be invoked on {@code executor}. {@code executor} must not run - * tasks on the current thread to prevent blocking networking operations - * and causing exceptions during shutdown. + * Creates a {@link BidirectionalStream} object. {@code callback} methods will be invoked on + * {@code executor}. {@code executor} must not run tasks on the current thread to prevent + * blocking networking operations and causing exceptions during shutdown. * * @param url the URL for the stream * @param callback the object whose methods get invoked upon different events * @param executor the {@link Executor} on which all callbacks will be called * @param httpMethod the HTTP method to use for the stream * @param requestHeaders the list of request headers - * @param priority priority of the stream which should be one of the - * {@link BidirectionalStream.Builder#STREAM_PRIORITY_IDLE STREAM_PRIORITY_*} - * values. - * @param delayRequestHeadersUntilFirstFlush whether to delay sending request - * headers until flush() is called, and try to combine them - * with the next data frame. - * @param requestAnnotations Objects to pass on to - * {@link org.chromium.net.RequestFinishedInfo.Listener}. + * @param priority priority of the stream which should be one of the {@link + * BidirectionalStream.Builder#STREAM_PRIORITY_IDLE STREAM_PRIORITY_*} values. + * @param delayRequestHeadersUntilFirstFlush whether to delay sending request headers until + * flush() is called, and try to combine them with the next data frame. + * @param requestAnnotations Objects to pass on to {@link + * org.chromium.net.RequestFinishedInfo.Listener}. * @param trafficStatsTagSet {@code true} if {@code trafficStatsTag} represents a TrafficStats - * tag to apply to sockets used to perform this request. + * tag to apply to sockets used to perform this request. * @param trafficStatsTag TrafficStats tag to apply to sockets used to perform this request. * @param trafficStatsUidSet {@code true} if {@code trafficStatsUid} represents a UID to - * attribute traffic used to perform this request. + * attribute traffic used to perform this request. * @param trafficStatsUid UID to attribute traffic used to perform this request. * @param network network to be used to send this request. Set to {@code null} if not specified. * @return a new stream.
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequest.java b/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequest.java index bbfbc98..ca898d9 100644 --- a/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequest.java +++ b/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequest.java
@@ -19,6 +19,7 @@ import org.chromium.base.Log; import org.chromium.net.CallbackException; import org.chromium.net.CronetException; +import org.chromium.net.ExperimentalUrlRequest; import org.chromium.net.Idempotency; import org.chromium.net.InlineExecutionProhibitedException; import org.chromium.net.NetworkException; @@ -43,17 +44,16 @@ import javax.annotation.concurrent.GuardedBy; /** - * UrlRequest using Chromium HTTP stack implementation. Could be accessed from - * any thread on Executor. Cancel can be called from any thread. - * All @CallByNative methods are called on native network thread - * and post tasks with listener calls onto Executor. Upon return from listener - * callback native request adapter is called on executive thread and posts - * native tasks to native network thread. Because Cancel could be called from - * any thread it is protected by mUrlRequestAdapterLock. + * UrlRequest using Chromium HTTP stack implementation. Could be accessed from any thread on + * Executor. Cancel can be called from any thread. All @CallByNative methods are called on native + * network thread and post tasks with listener calls onto Executor. Upon return from listener + * callback native request adapter is called on executive thread and posts native tasks to native + * network thread. Because Cancel could be called from any thread it is protected by + * mUrlRequestAdapterLock. */ @JNINamespace("cronet") @VisibleForTesting -public final class CronetUrlRequest extends UrlRequestBase { +public final class CronetUrlRequest extends ExperimentalUrlRequest { private final boolean mAllowDirectExecutor; /* Native adapter object, owned by UrlRequest. */ @@ -88,8 +88,8 @@ private final String mInitialUrl; private final int mPriority; private final int mIdempotency; - private String mInitialMethod; - private final HeadersList mRequestHeaders = new HeadersList(); + private final String mInitialMethod; + private final List<Map.Entry<String, String>> mRequestHeaders; private final Collection<Object> mRequestAnnotations; private final boolean mDisableCache; private final boolean mDisableConnectionMigration; @@ -101,7 +101,7 @@ private final long mNetworkHandle; private final CronetLogger mLogger; - private CronetUploadDataStream mUploadDataStream; + private final CronetUploadDataStream mUploadDataStream; private UrlResponseInfoImpl mResponseInfo; @@ -122,9 +122,6 @@ @GuardedBy("mUrlRequestAdapterLock") private Runnable mOnDestroyedCallbackForTesting; - @VisibleForTesting - static final class HeadersList extends ArrayList<Map.Entry<String, String>> {} - private final class OnReadCompletedRunnable implements Runnable { // Buffer passed back from current invocation of onReadCompleted. ByteBuffer mByteBuffer; @@ -166,7 +163,11 @@ int trafficStatsUid, RequestFinishedInfo.Listener requestFinishedListener, int idempotency, - long networkHandle) { + long networkHandle, + String method, + ArrayList<Map.Entry<String, String>> requestHeaders, + UploadDataProvider uploadDataProvider, + Executor uploadDataProviderExecutor) { Objects.requireNonNull(url, "URL is required"); Objects.requireNonNull(callback, "Listener is required"); Objects.requireNonNull(executor, "Executor is required"); @@ -193,30 +194,13 @@ : null; mIdempotency = convertIdempotency(idempotency); mNetworkHandle = networkHandle; - } - - @Override - public void setHttpMethod(String method) { - checkNotStarted(); - Objects.requireNonNull(method, "Method is required."); mInitialMethod = method; - } - - @Override - public void addHeader(String header, String value) { - checkNotStarted(); - Objects.requireNonNull(header, "Invalid header name."); - Objects.requireNonNull(value, "Invalid header value."); - mRequestHeaders.add(new AbstractMap.SimpleImmutableEntry<String, String>(header, value)); - } - - @Override - public void setUploadDataProvider(UploadDataProvider uploadDataProvider, Executor executor) { - Objects.requireNonNull(uploadDataProvider, "Invalid UploadDataProvider."); - if (mInitialMethod == null) { - mInitialMethod = "POST"; - } - mUploadDataStream = new CronetUploadDataStream(uploadDataProvider, executor, this); + mRequestHeaders = Collections.unmodifiableList(new ArrayList<>(requestHeaders)); + mUploadDataStream = + uploadDataProvider == null + ? null + : new CronetUploadDataStream( + uploadDataProvider, uploadDataProviderExecutor, this); } @Override @@ -241,12 +225,9 @@ mIdempotency, mNetworkHandle); mRequestContext.onRequestStarted(); - if (mInitialMethod != null) { - if (!CronetUrlRequestJni.get() - .setHttpMethod( - mUrlRequestAdapter, CronetUrlRequest.this, mInitialMethod)) { - throw new IllegalArgumentException("Invalid http method " + mInitialMethod); - } + if (!CronetUrlRequestJni.get() + .setHttpMethod(mUrlRequestAdapter, CronetUrlRequest.this, mInitialMethod)) { + throw new IllegalArgumentException("Invalid http method " + mInitialMethod); } boolean hasContentType = false; @@ -491,11 +472,11 @@ } /** - * Estimates the byte size of the headers in their on-wire format. - * We are not really interested in their specific size but something which is close enough. + * Estimates the byte size of the headers in their on-wire format. We are not really interested + * in their specific size but something which is close enough. */ @VisibleForTesting - static long estimateHeadersSizeInBytes(HeadersList headers) { + static long estimateHeadersSizeInBytes(List<Map.Entry<String, String>> headers) { if (headers == null) return 0; long responseHeaderSizeInBytes = 0; for (Map.Entry<String, String> entry : headers) { @@ -515,7 +496,7 @@ String negotiatedProtocol, String proxyServer, long receivedByteCount) { - HeadersList headersList = new HeadersList(); + ArrayList<Map.Entry<String, String>> headersList = new ArrayList<>(); for (int i = 0; i < headers.length; i += 2) { headersList.add( new AbstractMap.SimpleImmutableEntry<String, String>( @@ -852,7 +833,7 @@ new Runnable() { @Override public void run() { - listener.onStatus(convertLoadState(loadState)); + listener.onStatus(UrlRequestUtil.convertLoadState(loadState)); } }; postTaskToExecutor(task);
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java b/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java index 940b5f09..1eb94714 100644 --- a/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java +++ b/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java
@@ -22,11 +22,13 @@ import org.chromium.net.BidirectionalStream; import org.chromium.net.EffectiveConnectionType; import org.chromium.net.ExperimentalBidirectionalStream; +import org.chromium.net.ExperimentalUrlRequest; import org.chromium.net.NetworkQualityRttListener; import org.chromium.net.NetworkQualityThroughputListener; import org.chromium.net.RequestContextConfigOptions; import org.chromium.net.RequestFinishedInfo; import org.chromium.net.RttThroughputValues; +import org.chromium.net.UploadDataProvider; import org.chromium.net.UrlRequest; import org.chromium.net.impl.CronetLogger.CronetVersion; import org.chromium.net.urlconnection.CronetHttpURLConnection; @@ -408,7 +410,7 @@ } @Override - public UrlRequestBase createRequest( + public ExperimentalUrlRequest createRequest( String url, UrlRequest.Callback callback, Executor executor, @@ -423,7 +425,11 @@ int trafficStatsUid, RequestFinishedInfo.Listener requestFinishedListener, int idempotency, - long networkHandle) { + long networkHandle, + String method, + ArrayList<Map.Entry<String, String>> requestHeaders, + UploadDataProvider uploadDataProvider, + Executor uploadDataProviderExecutor) { // if this request is not bound to network, use the network bound to the engine. if (networkHandle == DEFAULT_NETWORK_HANDLE) { networkHandle = mNetworkHandle; @@ -446,7 +452,11 @@ trafficStatsUid, requestFinishedListener, idempotency, - networkHandle); + networkHandle, + method, + requestHeaders, + uploadDataProvider, + uploadDataProviderExecutor); } }
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/JavaCronetEngine.java b/components/cronet/android/java/src/org/chromium/net/impl/JavaCronetEngine.java index ef9c68cb..33765e6 100644 --- a/components/cronet/android/java/src/org/chromium/net/impl/JavaCronetEngine.java +++ b/components/cronet/android/java/src/org/chromium/net/impl/JavaCronetEngine.java
@@ -13,9 +13,11 @@ import org.chromium.net.BidirectionalStream; import org.chromium.net.ExperimentalBidirectionalStream; +import org.chromium.net.ExperimentalUrlRequest; import org.chromium.net.NetworkQualityRttListener; import org.chromium.net.NetworkQualityThroughputListener; import org.chromium.net.RequestFinishedInfo; +import org.chromium.net.UploadDataProvider; import org.chromium.net.UrlRequest; import org.chromium.net.impl.CronetLogger.CronetSource; import org.chromium.net.impl.CronetLogger.CronetVersion; @@ -26,6 +28,7 @@ import java.net.URLConnection; import java.net.URLStreamHandler; import java.net.URLStreamHandlerFactory; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; @@ -135,7 +138,7 @@ } @Override - public UrlRequestBase createRequest( + public ExperimentalUrlRequest createRequest( String url, UrlRequest.Callback callback, Executor executor, @@ -150,7 +153,11 @@ int trafficStatsUid, RequestFinishedInfo.Listener requestFinishedListener, int idempotency, - long networkHandle) { + long networkHandle, + String method, + ArrayList<Map.Entry<String, String>> requestHeaders, + UploadDataProvider uploadDataProvider, + Executor uploadDataProviderExecutor) { if (networkHandle != DEFAULT_NETWORK_HANDLE) { mNetworkHandle = networkHandle; } @@ -166,7 +173,11 @@ trafficStatsTag, trafficStatsUidSet, trafficStatsUid, - mNetworkHandle); + mNetworkHandle, + method, + requestHeaders, + uploadDataProvider, + uploadDataProviderExecutor); } @Override
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/JavaUrlRequest.java b/components/cronet/android/java/src/org/chromium/net/impl/JavaUrlRequest.java index 7849f72a..6e7e4ec 100644 --- a/components/cronet/android/java/src/org/chromium/net/impl/JavaUrlRequest.java +++ b/components/cronet/android/java/src/org/chromium/net/impl/JavaUrlRequest.java
@@ -16,15 +16,18 @@ import androidx.annotation.VisibleForTesting; import org.chromium.net.CronetException; +import org.chromium.net.ExperimentalUrlRequest; import org.chromium.net.InlineExecutionProhibitedException; import org.chromium.net.NetworkException; import org.chromium.net.ThreadStatsUid; import org.chromium.net.UploadDataProvider; +import org.chromium.net.UrlRequest; import org.chromium.net.UrlResponseInfo; import org.chromium.net.impl.CronetLogger.CronetTrafficInfo; import org.chromium.net.impl.JavaUrlRequestUtils.CheckedRunnable; import org.chromium.net.impl.JavaUrlRequestUtils.DirectPreventingExecutor; import org.chromium.net.impl.JavaUrlRequestUtils.State; +import org.chromium.net.impl.VersionSafeCallbacks.UploadDataProviderWrapper; import java.io.IOException; import java.io.InputStream; @@ -53,7 +56,7 @@ import javax.annotation.concurrent.GuardedBy; /** Pure java UrlRequest, backed by {@link HttpURLConnection}. */ -final class JavaUrlRequest extends UrlRequestBase { +final class JavaUrlRequest extends ExperimentalUrlRequest { private static final String X_ANDROID = "X-Android"; private static final String X_ANDROID_SELECTED_TRANSPORT = "X-Android-Selected-Transport"; private static final String TAG = JavaUrlRequest.class.getSimpleName(); @@ -68,9 +71,9 @@ private final List<String> mUrlChain = new ArrayList<>(); /** - * This is the source of thread safety in this class - no other synchronization is performed. - * By compare-and-swapping from one state to another, we guarantee that operations aren't - * running concurrently. Only the winner of a CAS proceeds. + * This is the source of thread safety in this class - no other synchronization is performed. By + * compare-and-swapping from one state to another, we guarantee that operations aren't running + * concurrently. Only the winner of a CAS proceeds. * * <p>A caller can lose a CAS for three reasons - user error (two calls to read() without * waiting for the read to succeed), runtime error (network code or user code throws an @@ -83,21 +86,21 @@ private final boolean mAllowDirectExecutor; /* These don't change with redirects */ - private String mInitialMethod; + private final String mInitialMethod; private VersionSafeCallbacks.UploadDataProviderWrapper mUploadDataProvider; private Executor mUploadExecutor; /** - * Holds a subset of StatusValues - {@link State#STARTED} can represent - * {@link Status#SENDING_REQUEST} or {@link Status#WAITING_FOR_RESPONSE}. While the distinction - * isn't needed to implement the logic in this class, it is needed to implement - * {@link #getStatus(StatusListener)}. + * Holds a subset of StatusValues - {@link State#STARTED} can represent {@link + * Status#SENDING_REQUEST} or {@link Status#WAITING_FOR_RESPONSE}. While the distinction isn't + * needed to implement the logic in this class, it is needed to implement {@link + * #getStatus(StatusListener)}. * * <p>Concurrency notes - this value is not atomically updated with mState, so there is some * risk that we'd get an inconsistent snapshot of both - however, it also happens that this * value is only used with the STARTED state, so it's inconsequential. */ - @StatusValues private volatile int mAdditionalStatusDetails = Status.INVALID; + @UrlRequestUtil.StatusValues private volatile int mAdditionalStatusDetails = Status.INVALID; /* These change with redirects. */ private String mCurrentUrl; @@ -186,7 +189,7 @@ */ JavaUrlRequest( JavaCronetEngine engine, - Callback callback, + UrlRequest.Callback callback, final Executor executor, Executor userExecutor, String url, @@ -196,7 +199,11 @@ int trafficStatsTag, final boolean trafficStatsUidSet, final int trafficStatsUid, - long networkHandle) { + long networkHandle, + String method, + ArrayList<Map.Entry<String, String>> requestHeaders, + UploadDataProvider uploadDataProvider, + Executor uploadDataProviderExecutor) { Objects.requireNonNull(url, "URL is required"); Objects.requireNonNull(callback, "Listener is required"); Objects.requireNonNull(executor, "Executor is required"); @@ -232,14 +239,17 @@ mCurrentUrl = url; mUserAgent = userAgent; mNetworkHandle = networkHandle; + mInitialMethod = checkedHttpMethod(method); + setHeaders(requestHeaders); + mUploadDataProvider = checkedUploadDataProvider(uploadDataProvider); + mUploadExecutor = + uploadDataProviderExecutor == null || mAllowDirectExecutor + ? uploadDataProviderExecutor + : new DirectPreventingExecutor(uploadDataProviderExecutor); } - @Override - public void setHttpMethod(String method) { - checkNotStarted(); - if (method == null) { - throw new NullPointerException("Method is required."); - } + private static String checkedHttpMethod(String method) { + Objects.requireNonNull(method, "Method is required."); if ("OPTIONS".equalsIgnoreCase(method) || "GET".equalsIgnoreCase(method) || "HEAD".equalsIgnoreCase(method) @@ -248,32 +258,23 @@ || "DELETE".equalsIgnoreCase(method) || "TRACE".equalsIgnoreCase(method) || "PATCH".equalsIgnoreCase(method)) { - mInitialMethod = method; + return method; } else { throw new IllegalArgumentException("Invalid http method " + method); } } - private void checkNotStarted() { - @State int state = mState.get(); - if (state != State.NOT_STARTED) { - throw new IllegalStateException("Request is already started. State is: " + state); + private void setHeaders(ArrayList<Map.Entry<String, String>> requestHeaders) { + for (Map.Entry<String, String> header : requestHeaders) { + if (!isValidHeaderName(header.getKey()) || header.getValue().contains("\r\n")) { + throw new IllegalArgumentException( + "Invalid header with headername: " + header.getKey()); + } + mRequestHeaders.put(header.getKey(), header.getValue()); } } - @Override - public void addHeader(String header, String value) { - checkNotStarted(); - if (!isValidHeaderName(header) || value.contains("\r\n")) { - throw new IllegalArgumentException("Invalid header with headername: " + header); - } - if (mRequestHeaders.containsKey(header)) { - mRequestHeaders.remove(header); - } - mRequestHeaders.put(header, value); - } - - private boolean isValidHeaderName(String header) { + private static boolean isValidHeaderName(String header) { for (int i = 0; i < header.length(); i++) { char c = header.charAt(i); switch (c) { @@ -304,26 +305,17 @@ return true; } - @Override - public void setUploadDataProvider(UploadDataProvider uploadDataProvider, Executor executor) { + private UploadDataProviderWrapper checkedUploadDataProvider( + UploadDataProvider uploadDataProvider) { if (uploadDataProvider == null) { - throw new NullPointerException("Invalid UploadDataProvider."); + return null; } + if (!mRequestHeaders.containsKey("Content-Type")) { throw new IllegalArgumentException( "Requests with upload data must have a Content-Type."); } - checkNotStarted(); - if (mInitialMethod == null) { - mInitialMethod = "POST"; - } - this.mUploadDataProvider = - new VersionSafeCallbacks.UploadDataProviderWrapper(uploadDataProvider); - if (mAllowDirectExecutor) { - this.mUploadExecutor = executor; - } else { - this.mUploadExecutor = new DirectPreventingExecutor(executor); - } + return new VersionSafeCallbacks.UploadDataProviderWrapper(uploadDataProvider); } private final class OutputStreamDataSink extends JavaUploadDataSinkBase { @@ -630,9 +622,6 @@ mCurrentUrlConnection.setRequestProperty( entry.getKey(), entry.getValue()); } - if (mInitialMethod == null) { - mInitialMethod = "GET"; - } mCurrentUrlConnection.setRequestMethod(mInitialMethod); if (mUploadDataProvider != null) { mOutputStreamDataSink = @@ -811,11 +800,11 @@ } @Override - public void getStatus(StatusListener listener) { + public void getStatus(UrlRequest.StatusListener listener) { @State int state = mState.get(); int extraStatus = this.mAdditionalStatusDetails; - @StatusValues final int status; + @UrlRequestUtil.StatusValues final int status; switch (state) { case State.ERROR: case State.COMPLETE:
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/UrlRequestBuilderImpl.java b/components/cronet/android/java/src/org/chromium/net/impl/UrlRequestBuilderImpl.java index e0ef1ee..0429d96 100644 --- a/components/cronet/android/java/src/org/chromium/net/impl/UrlRequestBuilderImpl.java +++ b/components/cronet/android/java/src/org/chromium/net/impl/UrlRequestBuilderImpl.java
@@ -3,10 +3,8 @@ // found in the LICENSE file. package org.chromium.net.impl; -import android.annotation.SuppressLint; import android.os.Build; import android.util.Log; -import android.util.Pair; import org.chromium.net.CronetEngine; import org.chromium.net.ExperimentalUrlRequest; @@ -14,8 +12,11 @@ import org.chromium.net.UploadDataProvider; import org.chromium.net.UrlRequest; +import java.util.AbstractMap; import java.util.ArrayList; import java.util.Collection; +import java.util.Map; +import java.util.Objects; import java.util.concurrent.Executor; /** Implements {@link org.chromium.net.ExperimentalUrlRequest.Builder}. */ @@ -37,8 +38,8 @@ // HTTP method (e.g. GET, POST etc). private String mMethod; - // List of request headers, stored as header field name and value pairs. - private final ArrayList<Pair<String, String>> mRequestHeaders = new ArrayList<>(); + // List of request headers, stored as header field name and value map entries. + private final ArrayList<Map.Entry<String, String>> mRequestHeaders = new ArrayList<>(); // Disable the cache for just this request. private boolean mDisableCache; // Disable connection migration for just this request. @@ -108,12 +109,8 @@ @Override public UrlRequestBuilderImpl addHeader(String header, String value) { - if (header == null) { - throw new NullPointerException("Invalid header name."); - } - if (value == null) { - throw new NullPointerException("Invalid header value."); - } + Objects.requireNonNull(header, "Invalid header name."); + Objects.requireNonNull(value, "Invalid header value."); if (ACCEPT_ENCODING.equalsIgnoreCase(header)) { Log.i( TAG, @@ -123,7 +120,7 @@ new Exception()); return this; } - mRequestHeaders.add(Pair.create(header, value)); + mRequestHeaders.add(new AbstractMap.SimpleEntry<>(header, value)); return this; } @@ -154,12 +151,8 @@ @Override public UrlRequestBuilderImpl setUploadDataProvider( UploadDataProvider uploadDataProvider, Executor executor) { - if (uploadDataProvider == null) { - throw new NullPointerException("Invalid UploadDataProvider."); - } - if (executor == null) { - throw new NullPointerException("Invalid UploadDataProvider Executor."); - } + Objects.requireNonNull(uploadDataProvider, "Invalid UploadDataProvider."); + Objects.requireNonNull(executor, "Invalid UploadDataProvider Executor."); if (mMethod == null) { mMethod = "POST"; } @@ -176,9 +169,7 @@ @Override public UrlRequestBuilderImpl addRequestAnnotation(Object annotation) { - if (annotation == null) { - throw new NullPointerException("Invalid metrics annotation."); - } + Objects.requireNonNull(annotation, "Invalid metrics annotation."); if (mRequestAnnotations == null) { mRequestAnnotations = new ArrayList<>(); } @@ -217,34 +208,28 @@ } @Override - public UrlRequestBase build() { - @SuppressLint("WrongConstant") // TODO(jbudorick): Remove this after rolling to the N SDK. - final UrlRequestBase request = - mCronetEngine.createRequest( - mUrl, - mCallback, - mExecutor, - mPriority, - mRequestAnnotations, - mDisableCache, - mDisableConnectionMigration, - mAllowDirectExecutor, - mTrafficStatsTagSet, - mTrafficStatsTag, - mTrafficStatsUidSet, - mTrafficStatsUid, - mRequestFinishedListener, - mIdempotency, - mNetworkHandle); - if (mMethod != null) { - request.setHttpMethod(mMethod); - } - for (Pair<String, String> header : mRequestHeaders) { - request.addHeader(header.first, header.second); - } - if (mUploadDataProvider != null) { - request.setUploadDataProvider(mUploadDataProvider, mUploadDataProviderExecutor); - } - return request; + public ExperimentalUrlRequest build() { + // @SuppressLint("WrongConstant") // TODO(jbudorick): Remove this after rolling to the N + // SDK. + return mCronetEngine.createRequest( + mUrl, + mCallback, + mExecutor, + mPriority, + mRequestAnnotations, + mDisableCache, + mDisableConnectionMigration, + mAllowDirectExecutor, + mTrafficStatsTagSet, + mTrafficStatsTag, + mTrafficStatsUidSet, + mTrafficStatsUid, + mRequestFinishedListener, + mIdempotency, + mNetworkHandle, + mMethod == null ? "GET" : mMethod, // default to get if not set. + mRequestHeaders, + mUploadDataProvider, + mUploadDataProviderExecutor); } }
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/UrlRequestBase.java b/components/cronet/android/java/src/org/chromium/net/impl/UrlRequestUtil.java similarity index 65% rename from components/cronet/android/java/src/org/chromium/net/impl/UrlRequestBase.java rename to components/cronet/android/java/src/org/chromium/net/impl/UrlRequestUtil.java index 828d607..fab28cfb 100644 --- a/components/cronet/android/java/src/org/chromium/net/impl/UrlRequestBase.java +++ b/components/cronet/android/java/src/org/chromium/net/impl/UrlRequestUtil.java
@@ -5,53 +5,12 @@ import androidx.annotation.IntDef; -import org.chromium.net.ExperimentalUrlRequest; -import org.chromium.net.UploadDataProvider; -import org.chromium.net.UrlRequest; import org.chromium.net.UrlRequest.Status; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.concurrent.Executor; -/** - * Base class for classes that implement {@link UrlRequest} including experimental - * features. {@link CronetUrlRequest} and {@link JavaUrlRequest} extends this class. - */ -public abstract class UrlRequestBase extends ExperimentalUrlRequest { - /** - * Sets the HTTP method verb to use for this request. Must be done before - * request has started. - * - * <p>The default when this method is not called is "GET" if the request has - * no body or "POST" if it does. - * - * @param method "GET", "HEAD", "DELETE", "POST" or "PUT". - */ - protected abstract void setHttpMethod(String method); - - /** - * Adds a request header. Must be done before request has started. - * - * @param header header name. - * @param value header value. - */ - protected abstract void addHeader(String header, String value); - - /** - * Sets upload data provider. Must be done before request has started. May only be - * invoked once per request. Switches method to "POST" if not explicitly - * set. Starting the request will throw an exception if a Content-Type - * header is not set. - * - * @param uploadDataProvider responsible for providing the upload data. - * @param executor All {@code uploadDataProvider} methods will be invoked - * using this {@code Executor}. May optionally be the same - * {@code Executor} the request itself is using. - */ - protected abstract void setUploadDataProvider( - UploadDataProvider uploadDataProvider, Executor executor); - +public class UrlRequestUtil { /** Possible URL Request statuses. */ @IntDef({ Status.INVALID,
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamTest.java index 4c86f268..671cc06 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamTest.java
@@ -1804,6 +1804,9 @@ @Test @RequiresMinAndroidApi(Build.VERSION_CODES.M) + @IgnoreFor( + implementations = {CronetImplementation.AOSP_PLATFORM}, + reason = "b/309112420 BidiStream bindToNetwork API not exposed in AOSP") public void testBindToInvalidNetworkFails() { String url = Http2TestServer.getEchoMethodUrl(); TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCallback(); @@ -1822,7 +1825,7 @@ // given a fake networkHandle. assertThrows( IllegalArgumentException.class, - () -> builder.bindToNetwork(-150 /* invalid network handle */)); + () -> builder.bindToNetwork(-150 /* invalid network handle */).build()); return; } @@ -1868,10 +1871,6 @@ // object, it is an implicit expectation by our users that we should not break. // See b/328442628 for an example regression. @Test - @IgnoreFor( - implementations = {CronetImplementation.AOSP_PLATFORM}, - reason = - "b/324583507: Unignore when requests in callbacks are == to the user held one.") public void testCallbackMethod_onStreamReady_receivesSameStreamObject() { AtomicReference<BidirectionalStream> callbackStream = new AtomicReference<>(); TestBidirectionalStreamCallback callback = @@ -1891,10 +1890,6 @@ // object, it is an implicit expectation by our users that we should not break. // See b/328442628 for an example regression. @Test - @IgnoreFor( - implementations = {CronetImplementation.AOSP_PLATFORM}, - reason = - "b/324583507: Unignore when requests in callbacks are == to the user held one.") public void testCallbackMethod_onReadCompleted_receivesSameStreamObject() { AtomicReference<BidirectionalStream> callbackStream = new AtomicReference<>(); TestBidirectionalStreamCallback callback = @@ -1918,10 +1913,6 @@ // object, it is an implicit expectation by our users that we should not break. // See b/328442628 for an example regression. @Test - @IgnoreFor( - implementations = {CronetImplementation.AOSP_PLATFORM}, - reason = - "b/324583507: Unignore when requests in callbacks are == to the user held one.") public void testCallbackMethod_onWriteCompleted_receivesSameStreamObject() { AtomicReference<BidirectionalStream> callbackStream = new AtomicReference<>(); TestBidirectionalStreamCallback callback = @@ -1946,10 +1937,6 @@ // object, it is an implicit expectation by our users that we should not break. // See b/328442628 for an example regression. @Test - @IgnoreFor( - implementations = {CronetImplementation.AOSP_PLATFORM}, - reason = - "b/324583507: Unignore when requests in callbacks are == to the user held one.") public void testCallbackMethod_onResponseHeaders_receivesSameStreamObject() { AtomicReference<BidirectionalStream> callbackStream = new AtomicReference<>(); TestBidirectionalStreamCallback callback = @@ -1970,10 +1957,6 @@ // object, it is an implicit expectation by our users that we should not break. // See b/328442628 for an example regression. @Test - @IgnoreFor( - implementations = {CronetImplementation.AOSP_PLATFORM}, - reason = - "b/324583507: Unignore when requests in callbacks are == to the user held one.") public void testCallbackMethod_onResponseTrailersReceived_receivesSameStreamObject() { AtomicReference<BidirectionalStream> callbackStream = new AtomicReference<>(); TestBidirectionalStreamCallback callback = @@ -1996,10 +1979,6 @@ // object, it is an implicit expectation by our users that we should not break. // See b/328442628 for an example regression. @Test - @IgnoreFor( - implementations = {CronetImplementation.AOSP_PLATFORM}, - reason = - "b/324583507: Unignore when requests in callbacks are == to the user held one.") public void testCallbackMethod_onSucceeded_receivesSameStreamObject() { AtomicReference<BidirectionalStream> callbackStream = new AtomicReference<>(); TestBidirectionalStreamCallback callback = @@ -2019,10 +1998,6 @@ // object, it is an implicit expectation by our users that we should not break. // See b/328442628 for an example regression. @Test - @IgnoreFor( - implementations = {CronetImplementation.AOSP_PLATFORM}, - reason = - "b/324583507: Unignore when requests in callbacks are == to the user held one.") public void testCallbackMethod_onFailed_receivesSameStreamObject() { AtomicReference<BidirectionalStream> callbackStream = new AtomicReference<>(); TestBidirectionalStreamCallback callback = @@ -2046,10 +2021,6 @@ // object, it is an implicit expectation by our users that we should not break. // See b/328442628 for an example regression. @Test - @IgnoreFor( - implementations = {CronetImplementation.AOSP_PLATFORM}, - reason = - "b/324583507: Unignore when requests in callbacks are == to the user held one.") public void testCallbackMethod_onCanceled_receivesSameStreamObject() { AtomicReference<BidirectionalStream> callbackStream = new AtomicReference<>(); TestBidirectionalStreamCallback callback = @@ -2089,10 +2060,6 @@ // object, it is an implicit expectation by our users that we should not break. // See b/328442628 for an example regression. @Test - @IgnoreFor( - implementations = {CronetImplementation.AOSP_PLATFORM}, - reason = - "b/324583507: Unignore when requests in callbacks are == to the user held one.") public void testCallback_twoStreamsFromOneBuilder_receivesCorrectStreamObject() { AtomicReference<BidirectionalStream> onStreamReadyStream = new AtomicReference<>(); AtomicReference<BidirectionalStream> onResponseHeadersStream = new AtomicReference<>();
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java index a8a6c3a4..e6b49a36 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java
@@ -2928,7 +2928,7 @@ // given a fake networkHandle. assertThrows( IllegalArgumentException.class, - () -> builder.bindToNetwork(-150 /* invalid network handle */)); + () -> builder.bindToNetwork(-150 /* invalid network handle */).build()); return; } @@ -2967,10 +2967,6 @@ // object, it is an implicit expectation by our users that we should not break. // See b/328442628 for an example regression. @Test - @IgnoreFor( - implementations = {CronetImplementation.AOSP_PLATFORM}, - reason = - "b/324583507: Unignore when requests in callbacks are == to the user held one.") public void testCallbackMethod_onRedirect_receivesSameRequestObject() { AtomicReference<UrlRequest> callbackRequest = new AtomicReference<>(); TestUrlRequestCallback callback = @@ -2990,10 +2986,6 @@ // object, it is an implicit expectation by our users that we should not break. // See b/328442628 for an example regression. @Test - @IgnoreFor( - implementations = {CronetImplementation.AOSP_PLATFORM}, - reason = - "b/324583507: Unignore when requests in callbacks are == to the user held one.") public void testCallbackMethod_onResponseStarted_receivesSameRequestObject() { AtomicReference<UrlRequest> callbackRequest = new AtomicReference<>(); TestUrlRequestCallback callback = @@ -3012,10 +3004,6 @@ // object, it is an implicit expectation by our users that we should not break. // See b/328442628 for an example regression. @Test - @IgnoreFor( - implementations = {CronetImplementation.AOSP_PLATFORM}, - reason = - "b/324583507: Unignore when requests in callbacks are == to the user held one.") public void testCallbackMethod_onReadCompleted_receivesSameRequestObject() { AtomicReference<UrlRequest> callbackRequest = new AtomicReference<>(); TestUrlRequestCallback callback = @@ -3036,10 +3024,6 @@ // object, it is an implicit expectation by our users that we should not break. // See b/328442628 for an example regression. @Test - @IgnoreFor( - implementations = {CronetImplementation.AOSP_PLATFORM}, - reason = - "b/324583507: Unignore when requests in callbacks are == to the user held one.") public void testCallbackMethod_onSucceeded_receivesSameRequestObject() { AtomicReference<UrlRequest> callbackRequest = new AtomicReference<>(); TestUrlRequestCallback callback = @@ -3058,10 +3042,6 @@ // object, it is an implicit expectation by our users that we should not break. // See b/328442628 for an example regression. @Test - @IgnoreFor( - implementations = {CronetImplementation.AOSP_PLATFORM}, - reason = - "b/324583507: Unignore when requests in callbacks are == to the user held one.") public void testCallbackMethod_onCanceled_receivesSameRequestObject() { AtomicReference<UrlRequest> callbackRequest = new AtomicReference<>(); TestUrlRequestCallback callback = @@ -3081,10 +3061,6 @@ // object, it is an implicit expectation by our users that we should not break. // See b/328442628 for an example regression. @Test - @IgnoreFor( - implementations = {CronetImplementation.AOSP_PLATFORM}, - reason = - "b/324583507: Unignore when requests in callbacks are == to the user held one.") public void testCallbackMethod_onFailed_receivesSameRequestObject() { AtomicReference<UrlRequest> callbackRequest = new AtomicReference<>(); TestUrlRequestCallback callback = @@ -3118,10 +3094,6 @@ } @Test - @IgnoreFor( - implementations = {CronetImplementation.AOSP_PLATFORM}, - reason = - "b/324583507: Unignore when requests in callbacks are == to the user held one.") public void testCallback_twoRequestsFromOneBuilder_receivesCorrectRequestObject() { AtomicReference<UrlRequest> onResponseStartedRequest = new AtomicReference<>(); AtomicReference<UrlRequest> onReadCompletedRequest = new AtomicReference<>();
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/GetStatusTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/GetStatusTest.java index 6a41f8b9..ad6ccaf6 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/GetStatusTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/GetStatusTest.java
@@ -31,7 +31,7 @@ import org.chromium.net.UrlRequest.Status; import org.chromium.net.UrlRequest.StatusListener; import org.chromium.net.impl.LoadState; -import org.chromium.net.impl.UrlRequestBase; +import org.chromium.net.impl.UrlRequestUtil; import java.io.IOException; import java.util.concurrent.Executor; @@ -124,12 +124,12 @@ public void testInvalidLoadState() throws Exception { assertThrows( IllegalArgumentException.class, - () -> UrlRequestBase.convertLoadState(LoadState.OBSOLETE_WAITING_FOR_APPCACHE)); + () -> UrlRequestUtil.convertLoadState(LoadState.OBSOLETE_WAITING_FOR_APPCACHE)); // Expected throw because LoadState.WAITING_FOR_APPCACHE is not mapped. thrown.expect(Throwable.class); - UrlRequestBase.convertLoadState(-1); - UrlRequestBase.convertLoadState(16); + UrlRequestUtil.convertLoadState(-1); + UrlRequestUtil.convertLoadState(16); } @Test
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/impl/CronetLoggerTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/impl/CronetLoggerTest.java index 1866fb9..fa7cc293 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/impl/CronetLoggerTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/impl/CronetLoggerTest.java
@@ -51,12 +51,14 @@ import java.time.Duration; import java.util.AbstractMap; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Map.Entry; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; @@ -751,7 +753,7 @@ headers = null; assertThat(CronetUrlRequest.estimateHeadersSizeInBytes(headers)).isEqualTo(0); - CronetUrlRequest.HeadersList headersList = new CronetUrlRequest.HeadersList(); + ArrayList<Entry<String, String>> headersList = new ArrayList<>(); assertThat(CronetUrlRequest.estimateHeadersSizeInBytes(headersList)).isEqualTo(0); headersList = null; assertThat(CronetUrlRequest.estimateHeadersSizeInBytes(headersList)).isEqualTo(0); @@ -771,7 +773,7 @@ }; assertThat(CronetUrlRequest.estimateHeadersSizeInBytes(headers)).isEqualTo(33); - CronetUrlRequest.HeadersList headersList = new CronetUrlRequest.HeadersList(); + ArrayList<Map.Entry<String, String>> headersList = new ArrayList<>(); headersList.add( new AbstractMap.SimpleImmutableEntry<String, String>( "header1", "value1") // 7 + 6 = 13
diff --git a/components/exo/wayland/wayland_dmabuf_feedback_manager.cc b/components/exo/wayland/wayland_dmabuf_feedback_manager.cc index 13627dd..8a2c770 100644 --- a/components/exo/wayland/wayland_dmabuf_feedback_manager.cc +++ b/components/exo/wayland/wayland_dmabuf_feedback_manager.cc
@@ -297,7 +297,8 @@ void SetInert() { surface_feedback_ = nullptr; } private: - raw_ptr<WaylandDmabufSurfaceFeedback> surface_feedback_; + // Dangling when starting Borealis and Steam starts updating. + raw_ptr<WaylandDmabufSurfaceFeedback, DanglingUntriaged> surface_feedback_; raw_ptr<wl_resource> resource_; };
diff --git a/components/eye_dropper/eye_dropper_view.cc b/components/eye_dropper/eye_dropper_view.cc index 4d1247c..5013999 100644 --- a/components/eye_dropper/eye_dropper_view.cc +++ b/components/eye_dropper/eye_dropper_view.cc
@@ -29,7 +29,7 @@ #endif #if BUILDFLAG(IS_CHROMEOS_ASH) -#include "ui/aura/client/screen_position_client.h" +#include "ui/aura/window_tree_host.h" #endif namespace eye_dropper { @@ -114,6 +114,8 @@ capturer_->SelectSource(webrtc::kFullDesktopScreenId); } } + + // On ChromeOS this will capture `Screen::GetDisplayForNewWindows()`. CaptureScreen(std::nullopt); } @@ -240,15 +242,14 @@ ignore_selection_time_ = base::TimeTicks::Now() + base::Milliseconds(500); #if BUILDFLAG(IS_CHROMEOS_ASH) - GetWidget()->GetNativeWindow()->AddObserver(this); + // Add an observation so the capture can be updated as the eye dropper window + // moves between displays. + window_observation_.Observe(GetWidget()->GetNativeWindow()); #endif } EyeDropperView::~EyeDropperView() { if (GetWidget()) { -#if BUILDFLAG(IS_CHROMEOS_ASH) - GetWidget()->GetNativeWindow()->RemoveObserver(this); -#endif GetWidget()->CloseNow(); } } @@ -285,37 +286,38 @@ // Project pixels. const int pixel_count = diameter / kPixelSize; const SkBitmap frame = screen_capturer_->GetBitmap(); + gfx::Point center_position_px; + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // ChromeOS only captures a single display at a time, and we need to convert + // the cursor position to display (root window) local pixel coordinates. + aura::Window* window = GetWidget()->GetNativeWindow(); + const gfx::Point center_position = + window->GetBoundsInRootWindow().CenterPoint(); + center_position_px = + window->GetHost()->GetRootTransform().MapPoint(center_position); +#else // The captured frame is not scaled so we need to use widget's bounds in // pixels to have the magnified region match cursor position. - gfx::Point center_position = + center_position_px = display::Screen::GetScreen() ->DIPToScreenRectInWindow(GetWidget()->GetNativeWindow(), GetWidget()->GetWindowBoundsInScreen()) .CenterPoint(); - center_position.Offset(-screen_capturer_->original_offset_x(), - -screen_capturer_->original_offset_y()); - -#if BUILDFLAG(IS_CHROMEOS_ASH) - // ChromeOS only captures a single display at a time, and we need to convert - // the cursor position to local values for non primary displays. - aura::Window* window = GetWidget()->GetNativeWindow()->GetRootWindow(); - aura::client::ScreenPositionClient* screen_position_client = - aura::client::GetScreenPositionClient(window); - if (screen_position_client) { - screen_position_client->ConvertPointFromScreen(window, ¢er_position); - } + center_position_px.Offset(-screen_capturer_->original_offset_x(), + -screen_capturer_->original_offset_y()); #endif view_canvas->DrawImageInt(gfx::ImageSkia::CreateFrom1xBitmap(frame), - center_position.x() - pixel_count / 2, - center_position.y() - pixel_count / 2, pixel_count, - pixel_count, padding.width(), padding.height(), - diameter, diameter, false); + center_position_px.x() - pixel_count / 2, + center_position_px.y() - pixel_count / 2, + pixel_count, pixel_count, padding.width(), + padding.height(), diameter, diameter, false); // Store the pixel color under the cursor as it is the last color seen // by the user before selection. - selected_color_ = - screen_capturer_->GetColor(center_position.x(), center_position.y()); + selected_color_ = screen_capturer_->GetColor(center_position_px.x(), + center_position_px.y()); // Paint grid. const auto* color_provider = GetColorProvider(); @@ -383,6 +385,10 @@ display::Screen::GetScreen()->GetDisplayNearestWindow(window); CaptureScreen(display.id()); } + +void EyeDropperView::OnWindowDestroying(aura::Window* window) { + window_observation_.Reset(); +} #endif void EyeDropperView::CaptureScreen(
diff --git a/components/eye_dropper/eye_dropper_view.h b/components/eye_dropper/eye_dropper_view.h index ee8fa73..a2a893d 100644 --- a/components/eye_dropper/eye_dropper_view.h +++ b/components/eye_dropper/eye_dropper_view.h
@@ -20,6 +20,7 @@ #include "ui/views/widget/widget_delegate.h" #if BUILDFLAG(IS_CHROMEOS_ASH) +#include "base/scoped_observation.h" #include "ui/aura/window_observer.h" #endif @@ -58,6 +59,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) // aura::WindowObserver: void OnWindowAddedToRootWindow(aura::Window* window) override; + void OnWindowDestroying(aura::Window* window) override; #endif private: @@ -115,6 +117,11 @@ base::TimeTicks ignore_selection_time_; gfx::Point last_cursor_position_ = display::Screen::GetScreen()->GetCursorScreenPoint(); + +#if BUILDFLAG(IS_CHROMEOS_ASH) + base::ScopedObservation<aura::Window, aura::WindowObserver> + window_observation_{this}; +#endif }; } // namespace eye_dropper
diff --git a/components/no_state_prefetch/browser/no_state_prefetch_contents.cc b/components/no_state_prefetch/browser/no_state_prefetch_contents.cc index 64ebc28..3744b177 100644 --- a/components/no_state_prefetch/browser/no_state_prefetch_contents.cc +++ b/components/no_state_prefetch/browser/no_state_prefetch_contents.cc
@@ -174,12 +174,10 @@ browser_context_(browser_context), final_status_(FINAL_STATUS_UNKNOWN), process_pid_(base::kNullProcessId), - origin_(origin), - network_bytes_(0) { + origin_(origin) { switch (origin) { case ORIGIN_OMNIBOX: case ORIGIN_EXTERNAL_REQUEST: - case ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER: case ORIGIN_NAVIGATION_PREDICTOR: DCHECK(!initiator_origin_.has_value()); break; @@ -335,8 +333,6 @@ DCHECK_NE(ORIGIN_MAX, origin()); no_state_prefetch_manager_->RecordFinalStatus(origin(), final_status()); - no_state_prefetch_manager_->RecordNetworkBytesConsumed(origin(), - network_bytes_); if (no_state_prefetch_contents_) { no_state_prefetch_contents_->SetDelegate(nullptr); @@ -619,10 +615,4 @@ prerender_canceler_receiver_set_.Add(this, std::move(receiver)); } -void NoStatePrefetchContents::AddNetworkBytes(int64_t bytes) { - network_bytes_ += bytes; - for (Observer& observer : observer_list_) - observer.OnPrefetchNetworkBytesChanged(this); -} - } // namespace prerender
diff --git a/components/no_state_prefetch/browser/no_state_prefetch_contents.h b/components/no_state_prefetch/browser/no_state_prefetch_contents.h index 6bd81e78..0dc296c 100644 --- a/components/no_state_prefetch/browser/no_state_prefetch_contents.h +++ b/components/no_state_prefetch/browser/no_state_prefetch_contents.h
@@ -88,11 +88,6 @@ // OnPrefetchStop before being destroyed. virtual void OnPrefetchStop(NoStatePrefetchContents* contents) {} - // Signals that a resource finished loading and altered the running byte - // count. - virtual void OnPrefetchNetworkBytesChanged( - NoStatePrefetchContents* contents) {} - protected: Observer() {} virtual ~Observer() = 0; @@ -189,16 +184,10 @@ // the future: https://crbug.com/1126305 void MarkAsUsedForTesting(); - // Increments the number of bytes fetched over the network for this prerender. - void AddNetworkBytes(int64_t bytes); - bool prefetching_has_been_cancelled() const { return prefetching_has_been_cancelled_; } - // Running byte count. Increased when each resource completes loading. - int64_t network_bytes() { return network_bytes_; } - void AddPrerenderCancelerReceiver( mojo::PendingReceiver<prerender::mojom::PrerenderCanceler> receiver); @@ -315,10 +304,6 @@ // The bounds of the WebView from the launching page. gfx::Rect bounds_; - // A running tally of the number of bytes this prerender has caused to be - // transferred over the network for resources. Updated with AddNetworkBytes. - int64_t network_bytes_; - base::WeakPtrFactory<NoStatePrefetchContents> weak_factory_{this}; };
diff --git a/components/no_state_prefetch/browser/no_state_prefetch_handle.cc b/components/no_state_prefetch/browser/no_state_prefetch_handle.cc index 385ad18..eb52453 100644 --- a/components/no_state_prefetch/browser/no_state_prefetch_handle.cc +++ b/components/no_state_prefetch/browser/no_state_prefetch_handle.cc
@@ -87,13 +87,6 @@ observer_->OnPrefetchStop(this); } -void NoStatePrefetchHandle::OnPrefetchNetworkBytesChanged( - NoStatePrefetchContents* no_state_prefetch_contents) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (observer_) - observer_->OnPrefetchNetworkBytesChanged(this); -} - bool NoStatePrefetchHandle::RepresentingSamePrefetchAs( NoStatePrefetchHandle* other) const { return other && other->prefetch_data_ && prefetch_data_ &&
diff --git a/components/no_state_prefetch/browser/no_state_prefetch_handle.h b/components/no_state_prefetch/browser/no_state_prefetch_handle.h index 96b1009..e86722dd 100644 --- a/components/no_state_prefetch/browser/no_state_prefetch_handle.h +++ b/components/no_state_prefetch/browser/no_state_prefetch_handle.h
@@ -28,11 +28,6 @@ // Signals that the prefetch has stopped running. virtual void OnPrefetchStop(NoStatePrefetchHandle* handle) = 0; - // Signals that a resource finished loading and altered the running byte - // count. - virtual void OnPrefetchNetworkBytesChanged( - NoStatePrefetchHandle* handle) = 0; - protected: Observer(); virtual ~Observer(); @@ -84,8 +79,6 @@ // From NoStatePrefetchContents::Observer: void OnPrefetchStop( NoStatePrefetchContents* no_state_prefetch_contents) override; - void OnPrefetchNetworkBytesChanged( - NoStatePrefetchContents* no_state_prefetch_contents) override; raw_ptr<Observer> observer_;
diff --git a/components/no_state_prefetch/browser/no_state_prefetch_link_manager.cc b/components/no_state_prefetch/browser/no_state_prefetch_link_manager.cc index 06ee3529..96f1943 100644 --- a/components/no_state_prefetch/browser/no_state_prefetch_link_manager.cc +++ b/components/no_state_prefetch/browser/no_state_prefetch_link_manager.cc
@@ -345,7 +345,4 @@ StartLinkTriggers(); } -void NoStatePrefetchLinkManager::OnPrefetchNetworkBytesChanged( - NoStatePrefetchHandle* no_state_prefetch_handle) {} - } // namespace prerender
diff --git a/components/no_state_prefetch/browser/no_state_prefetch_link_manager.h b/components/no_state_prefetch/browser/no_state_prefetch_link_manager.h index d5b0fb8..00f1e205 100644 --- a/components/no_state_prefetch/browser/no_state_prefetch_link_manager.h +++ b/components/no_state_prefetch/browser/no_state_prefetch_link_manager.h
@@ -139,8 +139,6 @@ // From NoStatePrefetchHandle::Observer: void OnPrefetchStop(NoStatePrefetchHandle* no_state_prefetch_handle) override; - void OnPrefetchNetworkBytesChanged( - NoStatePrefetchHandle* no_state_prefetch_handle) override; bool has_shutdown_;
diff --git a/components/no_state_prefetch/browser/no_state_prefetch_manager.cc b/components/no_state_prefetch/browser/no_state_prefetch_manager.cc index 7c849de..ba076c1e 100644 --- a/components/no_state_prefetch/browser/no_state_prefetch_manager.cc +++ b/components/no_state_prefetch/browser/no_state_prefetch_manager.cc
@@ -294,17 +294,6 @@ session_storage_namespace); } -std::unique_ptr<NoStatePrefetchHandle> -NoStatePrefetchManager::AddForcedPrerenderFromExternalRequest( - const GURL& url, - const content::Referrer& referrer, - SessionStorageNamespace* session_storage_namespace, - const gfx::Rect& bounds) { - return StartPrefetchingWithPreconnectFallback( - ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER, url, referrer, std::nullopt, - bounds, session_storage_namespace); -} - void NoStatePrefetchManager::CancelAllPrerenders() { DCHECK_CURRENTLY_ON(BrowserThread::UI); while (!active_prefetches_.empty()) { @@ -1041,13 +1030,6 @@ "Consider whether a failed prefetch should fallback to preconnect"); } -void NoStatePrefetchManager::RecordNetworkBytesConsumed( - Origin origin, - int64_t prerender_bytes) { - last_recorded_browser_context_network_bytes_ = browser_context_network_bytes_; - histograms_->RecordNetworkBytesConsumed(origin, prerender_bytes); -} - void NoStatePrefetchManager::AddPrerenderProcessHost( content::RenderProcessHost* process_host) { DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/components/no_state_prefetch/browser/no_state_prefetch_manager.h b/components/no_state_prefetch/browser/no_state_prefetch_manager.h index 0a6303c0..e3b501b2a 100644 --- a/components/no_state_prefetch/browser/no_state_prefetch_manager.h +++ b/components/no_state_prefetch/browser/no_state_prefetch_manager.h
@@ -139,14 +139,6 @@ content::SessionStorageNamespace* session_storage_namespace, const gfx::Rect& bounds); - // Adds a prerender from an external request that will prerender even on - // cellular networks as long as the user setting for prerendering is ON. - std::unique_ptr<NoStatePrefetchHandle> AddForcedPrerenderFromExternalRequest( - const GURL& url, - const content::Referrer& referrer, - content::SessionStorageNamespace* session_storage_namespace, - const gfx::Rect& bounds); - // Cancels all active prerenders. void CancelAllPrerenders(); @@ -219,10 +211,6 @@ void AddObserver(std::unique_ptr<NoStatePrefetchManagerObserver> observer); - // Notification that a prerender has completed and its bytes should be - // recorded. - void RecordNetworkBytesConsumed(Origin origin, int64_t prerender_bytes); - // Registers a new ProcessHost performing a prerender. Called by // NoStatePrefetchContents. void AddPrerenderProcessHost(content::RenderProcessHost* process_host); @@ -508,13 +496,6 @@ const std::unique_ptr<PrerenderHistograms> histograms_; - // The number of bytes transferred over the network for the browser_context - // this NoStatePrefetchManager is attached to. - int64_t browser_context_network_bytes_ = 0; - - // The value of browser_context_network_bytes_ that was last recorded. - int64_t last_recorded_browser_context_network_bytes_ = 0; - // Set of process hosts being prerendered. using PrerenderProcessSet = std::set<raw_ptr<content::RenderProcessHost, SetExperimental>>;
diff --git a/components/no_state_prefetch/browser/prerender_histograms.cc b/components/no_state_prefetch/browser/prerender_histograms.cc index 722a04f8..53fda5f 100644 --- a/components/no_state_prefetch/browser/prerender_histograms.cc +++ b/components/no_state_prefetch/browser/prerender_histograms.cc
@@ -7,14 +7,11 @@ #include <string> #include "base/check_op.h" -#include "base/format_macros.h" #include "base/metrics/histogram.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/notreached.h" -#include "components/google/core/common/google_util.h" #include "components/no_state_prefetch/common/no_state_prefetch_utils.h" -#include "net/http/http_cache.h" namespace prerender { @@ -27,8 +24,6 @@ } // namespace -PrerenderHistograms::PrerenderHistograms() {} - std::string PrerenderHistograms::GetHistogramPrefix(Origin origin) { switch (origin) { case ORIGIN_OMNIBOX: @@ -45,8 +40,6 @@ return "webnext"; case ORIGIN_GWS_PRERENDER: return "gws"; - case ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER: - return "externalrequestforced"; case ORIGIN_NAVIGATION_PREDICTOR: return "navigationpredictor"; case ORIGIN_SAME_ORIGIN_SPECULATION: @@ -69,22 +62,4 @@ final_status, FINAL_STATUS_MAX); } -void PrerenderHistograms::RecordNetworkBytesConsumed( - Origin origin, - int64_t prerender_bytes) const { - const int kHistogramMin = 1; - const int kHistogramMax = 100000000; // 100M. - const int kBucketCount = 50; - - if (prerender_bytes == 0) - return; - - base::UmaHistogramCustomCounts(GetHistogramName(origin, "NetworkBytesWasted"), - prerender_bytes, kHistogramMin, kHistogramMax, - kBucketCount); - base::UmaHistogramCustomCounts(ComposeHistogramName("", "NetworkBytesWasted"), - prerender_bytes, kHistogramMin, kHistogramMax, - kBucketCount); -} - } // namespace prerender
diff --git a/components/no_state_prefetch/browser/prerender_histograms.h b/components/no_state_prefetch/browser/prerender_histograms.h index a1e054a2..7c45d45 100644 --- a/components/no_state_prefetch/browser/prerender_histograms.h +++ b/components/no_state_prefetch/browser/prerender_histograms.h
@@ -5,27 +5,15 @@ #ifndef COMPONENTS_NO_STATE_PREFETCH_BROWSER_PRERENDER_HISTOGRAMS_H_ #define COMPONENTS_NO_STATE_PREFETCH_BROWSER_PRERENDER_HISTOGRAMS_H_ -#include <stddef.h> -#include <stdint.h> - #include <string> #include "base/threading/thread_checker.h" #include "base/time/time.h" #include "components/no_state_prefetch/common/no_state_prefetch_final_status.h" #include "components/no_state_prefetch/common/prerender_origin.h" -#include "url/gurl.h" namespace prerender { -// Navigation type for histograms. -enum NavigationType { - // A normal completed navigation. - NAVIGATION_TYPE_NORMAL, - // A completed navigation or swap that began as a prerender. - NAVIGATION_TYPE_PRERENDERED, -}; - // Records histograms for NoStatePrefetchManager. // // A few histograms are dynamically constructed to avoid binary size bloat from @@ -41,7 +29,7 @@ public: // Owned by a NoStatePrefetchManager object for the lifetime of the // NoStatePrefetchManager. - PrerenderHistograms(); + PrerenderHistograms() = default; PrerenderHistograms(const PrerenderHistograms&) = delete; PrerenderHistograms& operator=(const PrerenderHistograms&) = delete; @@ -50,31 +38,9 @@ // of the prerender. static std::string GetHistogramPrefix(Origin origin); - // Record a PerSessionCount data point. - void RecordPerSessionCount(Origin origin, int count) const; - // Record a final status of a prerendered page in a histogram. void RecordFinalStatus(Origin origin, FinalStatus final_status) const; - // To be called when a new prerender is started. - void RecordPrerenderStarted(Origin origin) const; - - // Record the histogram for number of bytes consumed by the prerender. - void RecordNetworkBytesConsumed(Origin origin, int64_t prerender_bytes) const; - - // Records the time to first contentful paint with respect to a possible - // prefetch of the page. The time to first contentful paint with respect to - // the navigation start is recorded (even if the page was prererendered in - // advance of navigation start). One of several histograms is used, depending - // on whether this URL could have been prefetched before the navigation - // leading to the paint. - void RecordPrefetchFirstContentfulPaintTime( - Origin origin, - bool is_no_store, - bool was_hidden, - base::TimeDelta time, - base::TimeDelta prefetch_age) const; - private: THREAD_CHECKER(thread_checker_); };
diff --git a/components/no_state_prefetch/common/prerender_origin.h b/components/no_state_prefetch/common/prerender_origin.h index b78e7a7b..3d78e26 100644 --- a/components/no_state_prefetch/common/prerender_origin.h +++ b/components/no_state_prefetch/common/prerender_origin.h
@@ -28,7 +28,7 @@ ORIGIN_EXTERNAL_REQUEST = 10, // Obsolete: ORIGIN_INSTANT = 11, ORIGIN_LINK_REL_NEXT = 12, - ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER = 13, + // Obsolete: ORIGIN_EXTERNAL_REQUEST_FORCED_PRERENDER = 13, // Obsolete: ORIGIN_OFFLINE = 14, ORIGIN_NAVIGATION_PREDICTOR = 15, // Obsolete: ORIGIN_ISOLATED_PRERENDER = 16,
diff --git a/components/password_manager/ios/shared_password_controller.mm b/components/password_manager/ios/shared_password_controller.mm index d121980..d9d69a0 100644 --- a/components/password_manager/ios/shared_password_controller.mm +++ b/components/password_manager/ios/shared_password_controller.mm
@@ -820,7 +820,7 @@ for (const autofill::FormFieldData& field : form.fields) { if (field.renderer_id() == fieldIdentifier) { fieldSignature = CalculateFieldSignatureForField(field); - maxLength = field.max_length; + maxLength = field.max_length(); break; } }
diff --git a/components/password_manager/ios/shared_password_controller_unittest.mm b/components/password_manager/ios/shared_password_controller_unittest.mm index 189e93d5..6fc74ff 100644 --- a/components/password_manager/ios/shared_password_controller_unittest.mm +++ b/components/password_manager/ios/shared_password_controller_unittest.mm
@@ -625,7 +625,7 @@ field.set_value(u"p4ssword"); field.set_form_control_type(autofill::FormControlType::kInputPassword); field.set_renderer_id(autofill::test::MakeFieldRendererId()); - field.max_length = max_length; + field.set_max_length(max_length); form_data.fields.push_back(field); autofill::FormFieldData password_field_data = form_data.fields.back();
diff --git a/components/pdf/browser/BUILD.gn b/components/pdf/browser/BUILD.gn index fb31b3ee..fcc115e 100644 --- a/components/pdf/browser/BUILD.gn +++ b/components/pdf/browser/BUILD.gn
@@ -76,8 +76,6 @@ sources = [ "fake_pdf_stream_delegate.cc", "fake_pdf_stream_delegate.h", - "mock_url_loader_client.cc", - "mock_url_loader_client.h", "pdf_navigation_throttle_unittest.cc", "pdf_url_loader_request_interceptor_unittest.cc", "plugin_response_writer_unittest.cc", @@ -92,6 +90,7 @@ "//mojo/public/cpp/bindings", "//mojo/public/cpp/system", "//net", + "//services/network:test_support", "//services/network/public/cpp:cpp_base", "//services/network/public/mojom", "//testing/gmock",
diff --git a/components/pdf/browser/DEPS b/components/pdf/browser/DEPS index 3f0a43f..f23b84d 100644 --- a/components/pdf/browser/DEPS +++ b/components/pdf/browser/DEPS
@@ -9,6 +9,7 @@ "+pdf/pdf_features.h", "+services/network/public/cpp", "+services/network/public/mojom", + "+services/network/test", "+third_party/blink/public/common/associated_interfaces/associated_interface_provider.h", "+third_party/skia/include/core", "+ui/base",
diff --git a/components/pdf/browser/pdf_url_loader_request_interceptor_unittest.cc b/components/pdf/browser/pdf_url_loader_request_interceptor_unittest.cc index 4c31aae..e686cff0 100644 --- a/components/pdf/browser/pdf_url_loader_request_interceptor_unittest.cc +++ b/components/pdf/browser/pdf_url_loader_request_interceptor_unittest.cc
@@ -11,7 +11,6 @@ #include "base/test/gmock_callback_support.h" #include "base/test/mock_callback.h" #include "components/pdf/browser/fake_pdf_stream_delegate.h" -#include "components/pdf/browser/mock_url_loader_client.h" #include "components/pdf/browser/pdf_stream_delegate.h" #include "content/public/browser/url_loader_request_interceptor.h" #include "content/public/test/test_renderer_host.h" @@ -19,6 +18,7 @@ #include "services/network/public/cpp/resource_request.h" #include "services/network/public/mojom/fetch_api.mojom-shared.h" #include "services/network/public/mojom/url_loader.mojom.h" +#include "services/network/test/mock_url_loader_client.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -27,6 +27,8 @@ namespace { +using ::network::MockURLLoaderClient; + using ::testing::NiceMock; class PdfURLLoaderRequestInterceptorTest
diff --git a/components/pdf/browser/plugin_response_writer_unittest.cc b/components/pdf/browser/plugin_response_writer_unittest.cc index 5356597..b6c5d958 100644 --- a/components/pdf/browser/plugin_response_writer_unittest.cc +++ b/components/pdf/browser/plugin_response_writer_unittest.cc
@@ -16,7 +16,6 @@ #include "base/run_loop.h" #include "base/test/mock_callback.h" #include "base/test/task_environment.h" -#include "components/pdf/browser/mock_url_loader_client.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/system/data_pipe.h" #include "mojo/public/cpp/system/data_pipe_drainer.h" @@ -24,6 +23,7 @@ #include "net/http/http_response_headers.h" #include "services/network/public/cpp/url_loader_completion_status.h" #include "services/network/public/mojom/url_response_head.mojom.h" +#include "services/network/test/mock_url_loader_client.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -32,6 +32,8 @@ namespace { +using ::network::MockURLLoaderClient; + using ::testing::HasSubstr; using ::testing::NiceMock; using ::testing::Not;
diff --git a/components/prefs/json_pref_store.cc b/components/prefs/json_pref_store.cc index 976f066..a5d2137 100644 --- a/components/prefs/json_pref_store.cc +++ b/components/prefs/json_pref_store.cc
@@ -128,8 +128,10 @@ std::string spaceless_basename; base::ReplaceChars(path.BaseName().MaybeAsASCII(), " ", "_", &spaceless_basename); - static constexpr std::array<const char*, 3> kAllowList{ - "Secure_Preferences", "Preferences", "Local_State"}; + // Entries here should be reflected in the ImportantFileClients variant in + // histograms.xml. + static constexpr std::array<const char*, 4> kAllowList{ + "Secure_Preferences", "Preferences", "Local_State", "AccountPreferences"}; auto it = base::ranges::find(kAllowList, spaceless_basename); return it != kAllowList.end() ? *it : ""; }
diff --git a/components/sync/service/sync_service_impl.cc b/components/sync/service/sync_service_impl.cc index 3647c911..9edea60 100644 --- a/components/sync/service/sync_service_impl.cc +++ b/components/sync/service/sync_service_impl.cc
@@ -834,10 +834,21 @@ } if (!engine_) { - // Starting the engine is allowed but didn't happen. Either this was - // deferred, or the service is shutting down and there's no sense in - // restarting. For the second case, doesn't matter much what to return. - return TransportState::START_DEFERRED; + // Starting the engine is allowed but didn't happen. There are three + // possible scenarios: + // 1) Startup was deferred, in which case it can take noticeably long until + // . the engine initializes. This case can be distinguished by checking if + // . `deferring_first_start_since_` is set. + // 2) Startup is about to happen because SyncServiceImpl::TryStart() was + // . invoked, but the posted task to run SyncServiceImpl::TryStartImpl() + // . hasn't been processed yet. + // 3) The service is shutting down. + // + // This function reports TransportState::START_DEFERRED only for the first, + // which is the only real deferred case. + return deferring_first_start_since_.is_null() + ? TransportState::INITIALIZING + : TransportState::START_DEFERRED; } if (!engine_->IsInitialized() || !data_type_manager_) { @@ -1481,19 +1492,17 @@ ModelTypeSet SyncServiceImpl::GetTypesWithPendingDownloadForInitialSync() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + CHECK(data_type_manager_); if (GetTransportState() == TransportState::INITIALIZING && - engine_->GetBirthday().empty()) { + !sync_client_->GetSyncApiComponentFactory() + ->HasTransportDataIncludingFirstSync()) { // The engine is initializing for the very first sync (usually after // sign-in). In this case all types are reported as pending download, // optimistically assuming datatype preconditions will be met. return GetPreferredDataTypes(); } - if (!data_type_manager_) { - return ModelTypeSet(); - } - // Persistent auth errors lead to PAUSED, which implies // data_type_manager_==null above. CHECK(!GetAuthError().IsPersistentError());
diff --git a/components/sync/service/sync_service_impl_startup_unittest.cc b/components/sync/service/sync_service_impl_startup_unittest.cc index 3c0e17b..5d0977c 100644 --- a/components/sync/service/sync_service_impl_startup_unittest.cc +++ b/components/sync/service/sync_service_impl_startup_unittest.cc
@@ -697,6 +697,8 @@ // Prevent one model initialization, to test TransportState::CONFIGURING. SignInWithSyncConsent(); SetSyncFeatureEnabledPrefs(); + // Deferred startup is only possible if first sync completed earlier. + component_factory()->set_first_time_sync_configure_done(true); component_factory()->AllowFakeEngineInitCompletion(false); CreateSyncService({SESSIONS}); get_controller(SESSIONS)->model()->EnableManualModelStart();
diff --git a/components/sync/service/sync_service_impl_unittest.cc b/components/sync/service/sync_service_impl_unittest.cc index 7be271f..24e1697 100644 --- a/components/sync/service/sync_service_impl_unittest.cc +++ b/components/sync/service/sync_service_impl_unittest.cc
@@ -1998,16 +1998,6 @@ SignInWithoutSyncConsent(); - ASSERT_EQ(SyncService::TransportState::START_DEFERRED, - service()->GetTransportState()); - - // START_DEFERRED is very short-lived upon sign-in, so it doesn't matter - // much what the API returns (added here for documentation purposes). - EXPECT_EQ(ModelTypeSet(), - service()->GetTypesWithPendingDownloadForInitialSync()); - - base::RunLoop().RunUntilIdle(); - ASSERT_EQ(SyncService::TransportState::INITIALIZING, service()->GetTransportState()); @@ -2017,7 +2007,9 @@ service()->GetTypesWithPendingDownloadForInitialSync()); // Once fully initialized, it is delegated to DataTypeManager. + base::RunLoop().RunUntilIdle(); engine()->TriggerInitializationCompletion(/*success=*/true); + ASSERT_EQ(SyncService::TransportState::ACTIVE, service()->GetTransportState()); EXPECT_EQ(ModelTypeSet(), @@ -2034,16 +2026,6 @@ service()->GetUserSettings()->SetInitialSyncFeatureSetupComplete( syncer::SyncFirstSetupCompleteSource::BASIC_FLOW); - ASSERT_EQ(SyncService::TransportState::START_DEFERRED, - service()->GetTransportState()); - - // START_DEFERRED is very short-lived upon sign-in, so it doesn't matter - // much what the API returns (added here for documentation purposes). - EXPECT_EQ(ModelTypeSet(), - service()->GetTypesWithPendingDownloadForInitialSync()); - - base::RunLoop().RunUntilIdle(); - ASSERT_EQ(SyncService::TransportState::INITIALIZING, service()->GetTransportState()); @@ -2053,7 +2035,9 @@ service()->GetTypesWithPendingDownloadForInitialSync()); // Once fully initialized, it is delegated to DataTypeManager. + base::RunLoop().RunUntilIdle(); engine()->TriggerInitializationCompletion(/*success=*/true); + ASSERT_EQ(SyncService::TransportState::ACTIVE, service()->GetTransportState()); EXPECT_EQ(ModelTypeSet(),
diff --git a/components/sync/test/test_sync_service.cc b/components/sync/test/test_sync_service.cc index dbbf537..0906be0 100644 --- a/components/sync/test/test_sync_service.cc +++ b/components/sync/test/test_sync_service.cc
@@ -311,10 +311,6 @@ SetSignedInWithoutSyncFeature(); #endif // !BUILDFLAG(IS_CHROMEOS_ASH) - // TODO(crbug.com/40946404): Strictly speaking SyncServiceImpl enters - // START_DEFERRED for a very short time interval, until the task posted from - // TryStart() is processed. It is simplified here because INITIALIZING takes - // significantly longer. SetTransportState(TransportState::INITIALIZING); }
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.cc b/content/browser/attribution_reporting/attribution_storage_sql.cc index 59596b3..5802c96 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql.cc
@@ -1824,7 +1824,15 @@ if (!LazyInit(DbCreationPolicy::kIgnoreIfAbsent)) { return true; } - return DeleteReportInternal(report_id); + + bool success = DeleteReportInternal(report_id); + if (success) { + base::UmaHistogramCustomCounts( + "Conversions.DbVersionOnReportSentAndDeleted", kCurrentVersionNumber, + /*min=*/58, + /*exclusive_max=*/88, /*buckets=*/30); + } + return success; } bool AttributionStorageSql::DeleteReportInternal(
diff --git a/content/browser/attribution_reporting/attribution_storage_unittest.cc b/content/browser/attribution_reporting/attribution_storage_unittest.cc index f13e087..3ae50b3 100644 --- a/content/browser/attribution_reporting/attribution_storage_unittest.cc +++ b/content/browser/attribution_reporting/attribution_storage_unittest.cc
@@ -468,6 +468,8 @@ } TEST_F(AttributionStorageTest, ConversionReportDeleted_RemovedFromStorage) { + base::HistogramTester histograms; + storage()->StoreSource(SourceBuilder().Build()); EXPECT_EQ(AttributionTrigger::EventLevelResult::kSuccess, MaybeCreateAndStoreEventLevelReport(DefaultTrigger())); @@ -478,6 +480,7 @@ DeleteReports(reports); EXPECT_THAT(storage()->GetAttributionReports(base::Time::Max()), IsEmpty()); + histograms.ExpectTotalCount("Conversions.DbVersionOnReportSentAndDeleted", 1); } TEST_F(AttributionStorageTest,
diff --git a/content/browser/preloading/prerender/prerender_browsertest.cc b/content/browser/preloading/prerender/prerender_browsertest.cc index 79a9636d..bc59587d 100644 --- a/content/browser/preloading/prerender/prerender_browsertest.cc +++ b/content/browser/preloading/prerender/prerender_browsertest.cc
@@ -10363,10 +10363,18 @@ prerendered_page_background_waiter.Wait(); } +// TODO(b/335786567): Flaky on win-asan. +#if (BUILDFLAG(IS_WIN) && defined(ADDRESS_SANITIZER)) +#define MAYBE_ThemeColorSchemeChangeInNonPrimaryPage \ + DISABLED_ThemeColorSchemeChangeInNonPrimaryPage +#else +#define MAYBE_ThemeColorSchemeChangeInNonPrimaryPage \ + ThemeColorSchemeChangeInNonPrimaryPage +#endif // Tests that theme color in a prerendered page does not affect // the primary page. IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, - ThemeColorSchemeChangeInNonPrimaryPage) { + MAYBE_ThemeColorSchemeChangeInNonPrimaryPage) { const GURL kInitialUrl = GetUrl("/empty.html"); const GURL kPrerenderingUrl = GetUrl("/theme_color.html");
diff --git a/content/browser/service_worker/service_worker_context_core.cc b/content/browser/service_worker/service_worker_context_core.cc index 54e8c5f..c0e9bfa 100644 --- a/content/browser/service_worker/service_worker_context_core.cc +++ b/content/browser/service_worker/service_worker_context_core.cc
@@ -923,8 +923,8 @@ } void ServiceWorkerContextCore::AddLiveVersion(ServiceWorkerVersion* version) { - // TODO(horo): If we will see crashes here, we have to find the root cause of - // the version ID conflict. Otherwise change CHECK to DCHECK. + // TODO(crbug.com/335613089): Determine why we see these crashes. Once + // resolved change DCHECK. CHECK(!GetLiveVersion(version->version_id())); live_versions_[version->version_id()] = version; version->AddObserver(this);
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc index ebe9bd9..2ac50fa0 100644 --- a/content/browser/service_worker/service_worker_context_wrapper.cc +++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -515,6 +515,7 @@ } void ServiceWorkerContextWrapper::OnDeleteAndStartOver() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); is_deleting_and_starting_over_ = true; ClearRunningServiceWorkers(); } @@ -596,6 +597,7 @@ const GURL& scope, const blink::StorageKey& key, ResultCallback callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); UnregisterServiceWorkerImpl(scope, key, /*is_immediate=*/false, std::move(callback)); } @@ -604,6 +606,7 @@ const GURL& scope, const blink::StorageKey& key, ResultCallback callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); UnregisterServiceWorkerImpl(scope, key, /*is_immediate=*/true, std::move(callback)); } @@ -804,6 +807,7 @@ const blink::StorageKey& key, blink::TransferableMessage message, ResultCallback result_callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); // Ensure the callback is called asynchronously. auto wrapped_callback = base::BindOnce( [](ResultCallback callback, bool success) {
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index edada199..c8be746 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc
@@ -23,6 +23,7 @@ #include "base/functional/bind.h" #include "base/functional/callback_forward.h" #include "base/functional/callback_helpers.h" +#include "base/functional/concurrent_closures.h" #include "base/location.h" #include "base/memory/ptr_util.h" #include "base/memory/raw_ptr.h" @@ -351,23 +352,21 @@ dom_storage_context, std::move(callback)) : std::move(callback); - base::RepeatingClosure barrier = - base::BarrierClosure(infos.size(), std::move(done_callback)); + base::ConcurrentClosures concurrent; for (const StorageUsageInfo& info : infos) { if (storage_key_matcher && !storage_key_matcher.Run(info.storage_key, special_storage_policy.get())) { - barrier.Run(); continue; } if (info.last_modified >= delete_begin && info.last_modified <= delete_end) { - dom_storage_context->DeleteLocalStorage(info.storage_key, barrier); - } else { - barrier.Run(); + dom_storage_context->DeleteLocalStorage(info.storage_key, + concurrent.CreateClosure()); } } + std::move(concurrent).Done(std::move(done_callback)); } void OnSessionStorageUsageInfo( @@ -386,18 +385,16 @@ dom_storage_context, std::move(callback)) : std::move(callback); - base::RepeatingClosure barrier = - base::BarrierClosure(infos.size(), std::move(done_callback)); - + base::ConcurrentClosures concurrent; for (const SessionStorageUsageInfo& info : infos) { if (storage_key_matcher && !storage_key_matcher.Run(info.storage_key, special_storage_policy.get())) { - barrier.Run(); continue; } - dom_storage_context->DeleteSessionStorage(info, barrier); + dom_storage_context->DeleteSessionStorage(info, concurrent.CreateClosure()); } + std::move(concurrent).Done(std::move(done_callback)); } void ClearLocalStorageOnUIThread(
diff --git a/content/public/test/mock_render_process_host.cc b/content/public/test/mock_render_process_host.cc index 5f4e119..d06ab02 100644 --- a/content/public/test/mock_render_process_host.cc +++ b/content/public/test/mock_render_process_host.cc
@@ -114,8 +114,14 @@ termination_info.renderer_has_visible_clients = VisibleClientCount() > 0; #endif + within_process_died_observer_ = true; for (auto& observer : observers_) observer.RenderProcessExited(this, termination_info); + within_process_died_observer_ = false; + + if (delayed_cleanup_) { + Cleanup(); + } } void MockRenderProcessHost::SimulateReady() { @@ -290,6 +296,12 @@ } void MockRenderProcessHost::Cleanup() { + if (within_process_died_observer_) { + delayed_cleanup_ = true; + return; + } + delayed_cleanup_ = false; + if (listeners_.IsEmpty() && !deletion_callback_called_) { if (IsInitializedAndNotDead()) { ChildProcessTerminationInfo termination_info;
diff --git a/content/public/test/mock_render_process_host.h b/content/public/test/mock_render_process_host.h index adae4a0..6877e3d 100644 --- a/content/public/test/mock_render_process_host.h +++ b/content/public/test/mock_render_process_host.h
@@ -326,6 +326,8 @@ base::IDMap<IPC::Listener*> listeners_; bool shutdown_requested_; bool fast_shutdown_started_; + bool within_process_died_observer_ = false; + bool delayed_cleanup_ = false; bool deletion_callback_called_; bool is_for_guests_only_; bool is_process_backgrounded_;
diff --git a/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.cc b/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.cc index 3b153bc..54bba3c 100644 --- a/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.cc +++ b/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.cc
@@ -178,6 +178,10 @@ scan_response_data_) { writer.OpenVariant("o", &variant_writer); AppendScanResponseDataVariant(&variant_writer); + } else if ((property_name == + bluetooth_advertisement::kSecondaryChannelProperty)) { + writer.OpenVariant("s", &variant_writer); + variant_writer.AppendString(bluetooth_advertisement::kPhy1M); } else { std::unique_ptr<dbus::ErrorResponse> error_response = dbus::ErrorResponse::FromMethodCall( @@ -247,6 +251,7 @@ writer.OpenArray("{sv}", &array_writer); AppendType(&array_writer); + AppendSecondaryChannel(&array_writer); AppendServiceUUIDs(&array_writer); AppendManufacturerData(&array_writer); AppendSolicitUUIDs(&array_writer); @@ -295,6 +300,15 @@ array_writer->CloseContainer(&dict_entry_writer); } + void AppendSecondaryChannel(dbus::MessageWriter* array_writer) { + dbus::MessageWriter dict_entry_writer(NULL); + array_writer->OpenDictEntry(&dict_entry_writer); + dict_entry_writer.AppendString( + bluetooth_advertisement::kSecondaryChannelProperty); + dict_entry_writer.AppendVariantOfString(bluetooth_advertisement::kPhy1M); + array_writer->CloseContainer(&dict_entry_writer); + } + void AppendServiceUUIDs(dbus::MessageWriter* array_writer) { if (!service_uuids_) return;
diff --git a/docs/website b/docs/website index c50bcc0..e154573 160000 --- a/docs/website +++ b/docs/website
@@ -1 +1 @@ -Subproject commit c50bcc04d18f45a37e8b7aca67e712d20bf145c2 +Subproject commit e154573dde8bd6bab4bc32b52be8542de4aa858d
diff --git a/infra/config/generated/builders/ci/mac-code-coverage/gn-args.json b/infra/config/generated/builders/ci/mac-code-coverage/gn-args.json index 6f93845..0d8f07367 100644 --- a/infra/config/generated/builders/ci/mac-code-coverage/gn-args.json +++ b/infra/config/generated/builders/ci/mac-code-coverage/gn-args.json
@@ -7,6 +7,7 @@ "is_debug": false, "proprietary_codecs": true, "symbol_level": 0, + "target_cpu": "x64", "use_clang_coverage": true, "use_remoteexec": true, "use_siso": true
diff --git a/infra/config/generated/builders/try/mac-code-coverage/gn-args.json b/infra/config/generated/builders/try/mac-code-coverage/gn-args.json index 6f93845..0d8f07367 100644 --- a/infra/config/generated/builders/try/mac-code-coverage/gn-args.json +++ b/infra/config/generated/builders/try/mac-code-coverage/gn-args.json
@@ -7,6 +7,7 @@ "is_debug": false, "proprietary_codecs": true, "symbol_level": 0, + "target_cpu": "x64", "use_clang_coverage": true, "use_remoteexec": true, "use_siso": true
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index 2641fa4..d18b66f 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -51401,8 +51401,7 @@ name: "mac-code-coverage" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" - dimensions: "cores:12" - dimensions: "cpu:x86-64" + dimensions: "cpu:arm64" dimensions: "free_space:standard" dimensions: "os:Mac" dimensions: "pool:luci.chromium.ci" @@ -96385,7 +96384,7 @@ name: "mac-code-coverage" swarming_host: "chromium-swarm.appspot.com" dimensions: "builderless:1" - dimensions: "cpu:x86-64" + dimensions: "cpu:arm64" dimensions: "os:Mac-13|Mac-14" dimensions: "pool:luci.chromium.try" dimensions: "ssd:1"
diff --git a/infra/config/generated/testing/variants.pyl b/infra/config/generated/testing/variants.pyl index a1e33cc..efcdba7 100644 --- a/infra/config/generated/testing/variants.pyl +++ b/infra/config/generated/testing/variants.pyl
@@ -267,16 +267,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'identifier': 'Lacros version skew testing ash canary', - 'description': 'Run with ash-chrome version 126.0.6426.0', + 'description': 'Run with ash-chrome version 126.0.6427.0', 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6426.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6427.0/test_ash_chrome', ], 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v126.0.6426.0', - 'revision': 'version:126.0.6426.0', + 'location': 'lacros_version_skew_tests_v126.0.6427.0', + 'revision': 'version:126.0.6427.0', }, ], },
diff --git a/infra/config/subprojects/chromium/ci/chromium.coverage.star b/infra/config/subprojects/chromium/ci/chromium.coverage.star index e3746dea..e4cb915 100644 --- a/infra/config/subprojects/chromium/ci/chromium.coverage.star +++ b/infra/config/subprojects/chromium/ci/chromium.coverage.star
@@ -606,11 +606,13 @@ "use_clang_coverage", "no_symbols", "chrome_with_codecs", + "x64", ], ), builderless = True, - cores = 12, + cores = None, os = os.MAC_ANY, + cpu = cpu.ARM64, console_view_entry = [ consoles.console_view_entry( category = "mac",
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star index 43fb046..666f76b 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star
@@ -504,6 +504,7 @@ name = "mac-code-coverage", mirrors = ["ci/mac-code-coverage"], gn_args = "ci/mac-code-coverage", + cpu = cpu.ARM64, execution_timeout = 20 * time.hour, )
diff --git a/infra/config/targets/lacros-version-skew-variants.json b/infra/config/targets/lacros-version-skew-variants.json index ed564bda..d8423db4 100644 --- a/infra/config/targets/lacros-version-skew-variants.json +++ b/infra/config/targets/lacros-version-skew-variants.json
@@ -1,16 +1,16 @@ { "LACROS_VERSION_SKEW_CANARY": { "args": [ - "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6426.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6427.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 126.0.6426.0", + "description": "Run with ash-chrome version 126.0.6427.0", "identifier": "Lacros version skew testing ash canary", "swarming": { "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v126.0.6426.0", - "revision": "version:126.0.6426.0" + "location": "lacros_version_skew_tests_v126.0.6427.0", + "revision": "version:126.0.6427.0" } ] }
diff --git a/ios/chrome/browser/autofill/model/bottom_sheet/autofill_bottom_sheet_tab_helper.h b/ios/chrome/browser/autofill/model/bottom_sheet/autofill_bottom_sheet_tab_helper.h index 434be2bb..7ce549e 100644 --- a/ios/chrome/browser/autofill/model/bottom_sheet/autofill_bottom_sheet_tab_helper.h +++ b/ios/chrome/browser/autofill/model/bottom_sheet/autofill_bottom_sheet_tab_helper.h
@@ -80,7 +80,9 @@ autofill::VirtualCardEnrollmentCallbacks callbacks); // Send a command to show the bottom sheet to edit an address. - void ShowEditAddressBottomSheet(const autofill::AutofillProfile* profile); + // The address to be shown/worked upon in this bottom sheet is fetched via the + // `AutofillSaveUpdateAddressProfileDelegateIOS` delegate. + void ShowEditAddressBottomSheet(); // Handler for JavaScript messages. Dispatch to more specific handler. void OnFormMessageReceived(const web::ScriptMessage& message); @@ -139,10 +141,6 @@ // This value is moved and should only be retrieved once per bottom sheet. autofill::VirtualCardEnrollmentCallbacks GetVirtualCardEnrollmentCallbacks(); - std::unique_ptr<autofill::AutofillProfile> address_profile_for_edit() { - return std::move(address_profile_for_edit_); - } - private: friend class web::WebStateUserData<AutofillBottomSheetTabHelper>; @@ -213,9 +211,6 @@ // completed. autofill::VirtualCardEnrollmentCallbacks virtual_card_enrollment_callbacks_; - // Address Profile that is to be/being edited via the bottom sheet. - std::unique_ptr<autofill::AutofillProfile> address_profile_for_edit_; - WEB_STATE_USER_DATA_KEY_DECL(); };
diff --git a/ios/chrome/browser/autofill/model/bottom_sheet/autofill_bottom_sheet_tab_helper.mm b/ios/chrome/browser/autofill/model/bottom_sheet/autofill_bottom_sheet_tab_helper.mm index c6a027f..8850892 100644 --- a/ios/chrome/browser/autofill/model/bottom_sheet/autofill_bottom_sheet_tab_helper.mm +++ b/ios/chrome/browser/autofill/model/bottom_sheet/autofill_bottom_sheet_tab_helper.mm
@@ -86,10 +86,7 @@ [commands_handler_ showVirtualCardEnrollmentBottomSheet:model]; } -void AutofillBottomSheetTabHelper::ShowEditAddressBottomSheet( - const autofill::AutofillProfile* profile) { - address_profile_for_edit_ = - std::make_unique<autofill::AutofillProfile>(*profile); +void AutofillBottomSheetTabHelper::ShowEditAddressBottomSheet() { [commands_handler_ showEditAddressBottomSheet]; }
diff --git a/ios/chrome/browser/autofill/model/form_structure_browsertest.mm b/ios/chrome/browser/autofill/model/form_structure_browsertest.mm index dae422ac..94af6c3 100644 --- a/ios/chrome/browser/autofill/model/form_structure_browsertest.mm +++ b/ios/chrome/browser/autofill/model/form_structure_browsertest.mm
@@ -316,7 +316,7 @@ // to have a behavior similar to other platforms. name = ""; } - std::string section = field->section.ToString(); + std::string section = field->section().ToString(); if (base::StartsWith(section, "gChrome~field~", base::CompareCase::SENSITIVE)) { // The name has been generated by iOS JavaScript. Output an empty name @@ -324,7 +324,7 @@ size_t first_underscore = section.find_first_of('_'); section = section.substr(first_underscore); } - if (field->section.is_from_fieldidentifier()) { + if (field->section().is_from_fieldidentifier()) { // Normalize the section by replacing the unique but platform-dependent // integers in `field->section` with consecutive unique integers. // The section string is of the form "fieldname_id1_id2-suffix", where
diff --git a/ios/chrome/browser/ui/autofill/BUILD.gn b/ios/chrome/browser/ui/autofill/BUILD.gn index 74e584e..2fcdd82d 100644 --- a/ios/chrome/browser/ui/autofill/BUILD.gn +++ b/ios/chrome/browser/ui/autofill/BUILD.gn
@@ -211,6 +211,8 @@ "//ios/chrome/browser/metrics/model:eg_test_support+eg2", "//ios/chrome/browser/signin/model:fake_system_identity", "//ios/chrome/browser/ui/authentication:eg_test_support+eg2", + "//ios/chrome/browser/ui/autofill/bottom_sheet:constants", + "//ios/chrome/browser/ui/badges:public", "//ios/chrome/browser/ui/infobars:eg_test_support+eg2", "//ios/chrome/browser/ui/infobars/banners:public", "//ios/chrome/browser/ui/infobars/modals:public",
diff --git a/ios/chrome/browser/ui/autofill/autofill_constants.h b/ios/chrome/browser/ui/autofill/autofill_constants.h index fdf4a9f..f1e2f6e7 100644 --- a/ios/chrome/browser/ui/autofill/autofill_constants.h +++ b/ios/chrome/browser/ui/autofill/autofill_constants.h
@@ -11,4 +11,14 @@ extern NSString* const kAutofillCountrySelectionTableViewId; extern NSString* const kAutofillCountrySelectionSearchScrimId; +// Describes the type of the prompt in the save address flow. +enum class AutofillSaveProfilePromptMode { + // The prompt is for saving a new profile. + kNewProfile, + // The prompt is for updating an existing profile. + kUpdateProfile, + // The prompt is for migrating a profile to the account. + kMigrateProfile +}; + #endif // IOS_CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/autofill/bottom_sheet/BUILD.gn b/ios/chrome/browser/ui/autofill/bottom_sheet/BUILD.gn index 861c93b..4416c91 100644 --- a/ios/chrome/browser/ui/autofill/bottom_sheet/BUILD.gn +++ b/ios/chrome/browser/ui/autofill/bottom_sheet/BUILD.gn
@@ -11,6 +11,13 @@ ] } +source_set("constants") { + sources = [ + "bottom_sheet_constants.h", + "bottom_sheet_constants.mm", + ] +} + source_set("bottom_sheet") { sources = [ "autofill_edit_profile_bottom_sheet_coordinator.h", @@ -41,6 +48,7 @@ "//ios/chrome/browser/shared/public/commands", "//ios/chrome/browser/shared/ui/table_view", "//ios/chrome/browser/ui/autofill:autofill_shared_ui", + "//ios/chrome/browser/ui/autofill:constants", "//ios/chrome/browser/ui/autofill/cells", "//ios/web/public", "//ios/web/public/js_messaging", @@ -59,6 +67,7 @@ "payments_suggestion_bottom_sheet_view_controller.mm", ] deps = [ + ":constants", "//build:branding_buildflags", "//components/autofill/core/browser", "//components/autofill/ios/browser", @@ -74,6 +83,7 @@ "//ios/chrome/browser/shared/ui/table_view/cells", "//ios/chrome/browser/shared/ui/util", "//ios/chrome/browser/ui/autofill:autofill_shared_ui", + "//ios/chrome/browser/ui/autofill:constants", "//ios/chrome/common/ui/colors", "//ios/chrome/common/ui/confirmation_alert", "//ios/chrome/common/ui/table_view:cells_constants",
diff --git a/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_coordinator.mm b/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_coordinator.mm index 4042f58..bed873b 100644 --- a/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_coordinator.mm +++ b/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_coordinator.mm
@@ -4,6 +4,7 @@ #import "ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_coordinator.h" +#import "base/strings/sys_string_conversions.h" #import "components/autofill/core/browser/autofill_save_update_address_profile_delegate_ios.h" #import "components/autofill/core/browser/data_model/autofill_profile.h" #import "components/infobars/core/infobar.h" @@ -16,6 +17,7 @@ #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h" #import "ios/chrome/browser/shared/ui/table_view/table_view_navigation_controller.h" +#import "ios/chrome/browser/ui/autofill/autofill_constants.h" #import "ios/chrome/browser/ui/autofill/autofill_country_selection_table_view_controller.h" #import "ios/chrome/browser/ui/autofill/autofill_profile_edit_mediator.h" #import "ios/chrome/browser/ui/autofill/autofill_profile_edit_mediator_delegate.h" @@ -25,6 +27,7 @@ @interface AutofillEditProfileBottomSheetCoordinator () < AutofillCountrySelectionTableViewControllerDelegate, + AutofillEditProfileBottomSheetTableViewControllerDelegate, AutofillProfileEditMediatorDelegate> @end @@ -60,11 +63,6 @@ autofill::PersonalDataManagerFactory::GetForBrowserState(browserState); _webState = browser->GetWebStateList()->GetActiveWebState(); - AutofillBottomSheetTabHelper* bottomSheetTabHelper = - AutofillBottomSheetTabHelper::FromWebState(_webState); - - _autofillProfile = bottomSheetTabHelper->address_profile_for_edit(); - CHECK(_autofillProfile); } return self; } @@ -72,24 +70,41 @@ #pragma mark - ChromeCoordinator - (void)start { + autofill::AutofillSaveUpdateAddressProfileDelegateIOS* delegate = + [self fetchDelegateAndAcceptInfobar:NO]; + + _autofillProfile = + std::make_unique<autofill::AutofillProfile>(*delegate->GetProfile()); + + AutofillSaveProfilePromptMode saveProfilePromptMode = + AutofillSaveProfilePromptMode::kNewProfile; + if (delegate->IsMigrationToAccount()) { + saveProfilePromptMode = AutofillSaveProfilePromptMode::kMigrateProfile; + } else if (delegate->GetOriginalProfile() != nullptr) { + saveProfilePromptMode = AutofillSaveProfilePromptMode::kUpdateProfile; + } + _autofillProfileEditMediator = [[AutofillProfileEditMediator alloc] initWithDelegate:self personalDataManager:_personalDataManager autofillProfile:_autofillProfile.get() countryCode:nil - isMigrationPrompt:NO]; + isMigrationPrompt:delegate->IsMigrationToAccount()]; // Bottom sheet table VC AutofillEditProfileBottomSheetTableViewController* editModalViewController = [[AutofillEditProfileBottomSheetTableViewController alloc] - initWithStyle:UITableViewStylePlain]; + initWithDelegate:self + editSheetMode:saveProfilePromptMode]; // View controller that lays down the table views for the edit profile view. _autofillProfileEditTableViewController = [[AutofillProfileEditTableViewController alloc] initWithDelegate:_autofillProfileEditMediator - userEmail:@"" - controller:editModalViewController + userEmail:(delegate->UserAccountEmail() + ? base::SysUTF16ToNSString( + delegate->UserAccountEmail().value()) + : nil)controller:editModalViewController settingsView:NO]; _autofillProfileEditMediator.consumer = _autofillProfileEditTableViewController; @@ -148,6 +163,32 @@ } - (void)didSaveProfile { + autofill::AutofillSaveUpdateAddressProfileDelegateIOS* delegate = + [self fetchDelegateAndAcceptInfobar:YES]; + + delegate->SetProfile(_autofillProfile.get()); + delegate->EditAccepted(); + + [self stop]; +} + +#pragma mark - AutofillCountrySelectionTableViewControllerDelegate + +- (void)didSelectCountry:(CountryItem*)selectedCountry { + [_navigationController popViewControllerAnimated:YES]; + [_autofillProfileEditMediator didSelectCountry:selectedCountry]; +} + +#pragma mark - AutofillEditProfileBottomSheetTableViewControllerDelegate + +- (void)didCancelBottomSheetView { + [self stop]; +} + +#pragma mark - Private + +- (autofill::AutofillSaveUpdateAddressProfileDelegateIOS*) + fetchDelegateAndAcceptInfobar:(BOOL)acceptInfobar { InfoBarManagerImpl* manager = InfoBarManagerImpl::FromWebState(_webState); const auto it = base::ranges::find( manager->infobars(), InfobarType::kInfobarTypeSaveAutofillAddressProfile, @@ -162,17 +203,11 @@ FromInfobarDelegate(infobar->delegate()); CHECK(delegate); - delegate->SetProfile(_autofillProfile.get()); - delegate->EditAccepted(); - infobar->set_accepted(true); - [self stop]; -} + if (acceptInfobar) { + infobar->set_accepted(acceptInfobar); + } -#pragma mark - AutofillCountrySelectionTableViewControllerDelegate - -- (void)didSelectCountry:(CountryItem*)selectedCountry { - [_navigationController popViewControllerAnimated:YES]; - [_autofillProfileEditMediator didSelectCountry:selectedCountry]; + return delegate; } @end
diff --git a/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller.h b/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller.h index b1f4ad3..dbf5ad6 100644 --- a/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller.h +++ b/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller.h
@@ -6,12 +6,28 @@ #define IOS_CHROME_BROWSER_UI_AUTOFILL_BOTTOM_SHEET_AUTOFILL_EDIT_PROFILE_BOTTOM_SHEET_TABLE_VIEW_CONTROLLER_H_ #import "ios/chrome/browser/shared/ui/table_view/legacy_chrome_table_view_controller.h" +#import "ios/chrome/browser/ui/autofill/autofill_constants.h" #import "ios/chrome/browser/ui/autofill/autofill_profile_edit_handler.h" +@protocol AutofillEditProfileBottomSheetTableViewControllerDelegate + +// Invoked when the "Cancel" button is pressed. +- (void)didCancelBottomSheetView; + +@end + // The Bottom Sheet TableView for an Autofill save/update address edit menu. @interface AutofillEditProfileBottomSheetTableViewController : LegacyChromeTableViewController +- (instancetype) + initWithDelegate: + (id<AutofillEditProfileBottomSheetTableViewControllerDelegate>)delegate + editSheetMode:(AutofillSaveProfilePromptMode)editSheetMode + NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithStyle:(UITableViewStyle)style NS_UNAVAILABLE; + @property(nonatomic, weak) id<AutofillProfileEditHandler> handler; @end
diff --git a/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller.mm b/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller.mm index 27ed0fa..139bb5a 100644 --- a/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller.mm +++ b/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller.mm
@@ -7,6 +7,7 @@ #import "base/apple/foundation_util.h" #import "components/strings/grit/components_strings.h" #import "ios/chrome/browser/shared/ui/table_view/legacy_chrome_table_view_styler.h" +#import "ios/chrome/browser/ui/autofill/bottom_sheet/bottom_sheet_constants.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" #import "ios/chrome/common/ui/table_view/table_view_cells_constants.h" #import "ios/chrome/grit/ios_strings.h" @@ -26,15 +27,14 @@ } // namespace @interface AutofillEditProfileBottomSheetTableViewController () < - UITextFieldDelegate> + UITextFieldDelegate> { + // Delegate for this view controller. + __weak id<AutofillEditProfileBottomSheetTableViewControllerDelegate> + _delegate; -// TODO(crbug.com/1482269): Update via the consumer protocol. -// Yes, if the edit is done for updating the profile. -@property(nonatomic, assign) BOOL isEditForUpdate; - -// TODO(crbug.com/1482269): Update via the consumer protocol. -// Yes, if the edit is shown for the migration prompt. -@property(nonatomic, assign) BOOL migrationPrompt; + // Denotes the mode of the address save for the edit profile bottom sheet. + AutofillSaveProfilePromptMode _editSheetMode; +} @end @@ -42,6 +42,18 @@ #pragma mark - Initialization +- (instancetype) + initWithDelegate: + (id<AutofillEditProfileBottomSheetTableViewControllerDelegate>)delegate + editSheetMode:(AutofillSaveProfilePromptMode)editSheetMode { + self = [super initWithStyle:UITableViewStylePlain]; + if (self) { + _delegate = delegate; + _editSheetMode = editSheetMode; + } + return self; +} + - (void)viewDidLoad { [super viewDidLoad]; @@ -60,18 +72,25 @@ initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(handleCancelButton)]; + cancelButton.accessibilityIdentifier = kEditProfileBottomSheetCancelButton; self.navigationItem.leftBarButtonItem = cancelButton; self.navigationController.navigationBar.prefersLargeTitles = NO; - if (self.migrationPrompt) { - [self setTitle: + switch (_editSheetMode) { + case AutofillSaveProfilePromptMode::kNewProfile: + [self setTitle:l10n_util::GetNSString( + IDS_IOS_AUTOFILL_SAVE_ADDRESS_PROMPT_TITLE)]; + break; + case AutofillSaveProfilePromptMode::kUpdateProfile: + [self setTitle:l10n_util::GetNSString( + IDS_IOS_AUTOFILL_UPDATE_ADDRESS_PROMPT_TITLE)]; + break; + case AutofillSaveProfilePromptMode::kMigrateProfile: + [self + setTitle: l10n_util::GetNSString( IDS_IOS_AUTOFILL_ADDRESS_MIGRATION_TO_ACCOUNT_PROMPT_TITLE)]; - } else { - [self setTitle:l10n_util::GetNSString( - self.isEditForUpdate - ? IDS_IOS_AUTOFILL_UPDATE_ADDRESS_PROMPT_TITLE - : IDS_IOS_AUTOFILL_SAVE_ADDRESS_PROMPT_TITLE)]; + break; } self.tableView.allowsSelectionDuringEditing = YES; @@ -81,10 +100,13 @@ - (void)loadModel { [super loadModel]; - [self.handler setMigrationPrompt:self.migrationPrompt]; + [self.handler + setMigrationPrompt:(_editSheetMode == + AutofillSaveProfilePromptMode::kMigrateProfile)]; [self.handler loadModel]; [self.handler - loadMessageAndButtonForModalIfSaveOrUpdate:self.isEditForUpdate]; + loadMessageAndButtonForModalIfSaveOrUpdate: + (_editSheetMode == AutofillSaveProfilePromptMode::kUpdateProfile)]; } - (void)expandBottomSheet { @@ -151,7 +173,8 @@ #pragma mark - Actions - (void)handleCancelButton { - // TODO(crbug.com/1482269): Implement. + CHECK(_delegate); + [_delegate didCancelBottomSheetView]; } #pragma mark - UITextFieldDelegate
diff --git a/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller_unittest.mm b/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller_unittest.mm index dfa9e266..6fa350f9 100644 --- a/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/autofill/bottom_sheet/autofill_edit_profile_bottom_sheet_table_view_controller_unittest.mm
@@ -27,7 +27,8 @@ namespace { class AutofillEditProfileBottomSheetTableViewControllerTest - : public LegacyChromeTableViewControllerTest { + : public LegacyChromeTableViewControllerTest, + public ::testing::WithParamInterface<AutofillSaveProfilePromptMode> { protected: void SetUp() override { LegacyChromeTableViewControllerTest::SetUp(); @@ -44,11 +45,12 @@ LegacyChromeTableViewController* InstantiateController() override { AutofillEditProfileBottomSheetTableViewController* viewController = [[AutofillEditProfileBottomSheetTableViewController alloc] - initWithStyle:UITableViewStylePlain]; + initWithDelegate:nil + editSheetMode:GetParam()]; autofill_profile_edit_table_view_controller_ = [[AutofillProfileEditTableViewController alloc] initWithDelegate:delegate_mock_ - userEmail:nil + userEmail:@"test@gmail.com" controller:viewController settingsView:NO]; viewController.handler = autofill_profile_edit_table_view_controller_; @@ -101,9 +103,18 @@ id delegate_mock_; }; -// Tests that there are no requirement checks for the profiles saved to sync. -TEST_F(AutofillEditProfileBottomSheetTableViewControllerTest, - TestNoRequirements) { +INSTANTIATE_TEST_SUITE_P( + /* No InstantiationName */, + AutofillEditProfileBottomSheetTableViewControllerTest, + testing::Values(AutofillSaveProfilePromptMode::kNewProfile, + AutofillSaveProfilePromptMode::kUpdateProfile, + AutofillSaveProfilePromptMode::kMigrateProfile)); + +} // namespace + +// Tests that there are requirement checks for the profiles to be saved. +TEST_P(AutofillEditProfileBottomSheetTableViewControllerTest, + TestRequirements) { [autofill_profile_edit_table_view_controller_ setLine1Required:YES]; [autofill_profile_edit_table_view_controller_ setCityRequired:YES]; [autofill_profile_edit_table_view_controller_ setStateRequired:YES]; @@ -134,7 +145,6 @@ city_item.textFieldValue = @""; [autofill_profile_edit_table_view_controller_ tableViewItemDidChange:city_item]; - EXPECT_EQ(button_item.enabled, YES); + EXPECT_EQ(button_item.enabled, + GetParam() != AutofillSaveProfilePromptMode::kMigrateProfile); } - -} // namespace
diff --git a/ios/chrome/browser/ui/autofill/bottom_sheet/bottom_sheet_constants.h b/ios/chrome/browser/ui/autofill/bottom_sheet/bottom_sheet_constants.h new file mode 100644 index 0000000..e87e4bb --- /dev/null +++ b/ios/chrome/browser/ui/autofill/bottom_sheet/bottom_sheet_constants.h
@@ -0,0 +1,13 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_AUTOFILL_BOTTOM_SHEET_BOTTOM_SHEET_CONSTANTS_H_ +#define IOS_CHROME_BROWSER_UI_AUTOFILL_BOTTOM_SHEET_BOTTOM_SHEET_CONSTANTS_H_ + +#import <UIKit/UIKit.h> + +// Accessibility identifier of the Edit Address Cancel Button. +extern NSString* const kEditProfileBottomSheetCancelButton; + +#endif // IOS_CHROME_BROWSER_UI_AUTOFILL_BOTTOM_SHEET_BOTTOM_SHEET_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/autofill/bottom_sheet/bottom_sheet_constants.mm b/ios/chrome/browser/ui/autofill/bottom_sheet/bottom_sheet_constants.mm new file mode 100644 index 0000000..d06837d8 --- /dev/null +++ b/ios/chrome/browser/ui/autofill/bottom_sheet/bottom_sheet_constants.mm
@@ -0,0 +1,8 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/autofill/bottom_sheet/bottom_sheet_constants.h" + +NSString* const kEditProfileBottomSheetCancelButton = + @"EditProfileBottomSheetCancelButton";
diff --git a/ios/chrome/browser/ui/autofill/save_profile_egtest.mm b/ios/chrome/browser/ui/autofill/save_profile_egtest.mm index 16646b4..ddfb7ef 100644 --- a/ios/chrome/browser/ui/autofill/save_profile_egtest.mm +++ b/ios/chrome/browser/ui/autofill/save_profile_egtest.mm
@@ -16,6 +16,8 @@ #import "ios/chrome/browser/ui/authentication/signin_earl_grey_ui_test_util.h" #import "ios/chrome/browser/ui/autofill/autofill_app_interface.h" #import "ios/chrome/browser/ui/autofill/autofill_constants.h" +#import "ios/chrome/browser/ui/autofill/bottom_sheet/bottom_sheet_constants.h" +#import "ios/chrome/browser/ui/badges/badge_constants.h" #import "ios/chrome/browser/ui/infobars/banners/infobar_banner_constants.h" #import "ios/chrome/browser/ui/infobars/infobar_earl_grey_ui_test_util.h" #import "ios/chrome/browser/ui/infobars/modals/infobar_address_profile_modal_constants.h" @@ -141,7 +143,9 @@ - (AppLaunchConfiguration)appConfigurationForTestCase { AppLaunchConfiguration config; - if ([self isRunningTest:@selector(testUserData_LocalEditViaBottomSheet)]) { + if ([self isRunningTest:@selector(testUserData_LocalEditViaBottomSheet)] || + [self + isRunningTest:@selector(testUserData_LocalHideBottomSheetOnCancel)]) { config.features_enabled.push_back( kAutofillDynamicallyLoadsFieldsForAddressInput); } @@ -453,6 +457,38 @@ @"Profile should have been saved."); } +// Tests that the bottom sheet to edit address is just hidden on Cancel. +- (void)testUserData_LocalHideBottomSheetOnCancel { + // Fill and submit the form. + [self fillPresidentProfileAndShowSaveModal]; + + // Edit the profile. + [[EarlGrey selectElementWithMatcher:ModalEditButtonMatcher()] + performAction:grey_tap()]; + + // Tap "Cancel" + [[EarlGrey + selectElementWithMatcher:grey_allOf( + grey_accessibilityID( + kEditProfileBottomSheetCancelButton), + grey_accessibilityTrait( + UIAccessibilityTraitButton), + nil)] performAction:grey_tap()]; + + // Open modal by selecting the badge that shouldn't be accepted. + [[EarlGrey selectElementWithMatcher: + grey_accessibilityID( + kBadgeButtonSaveAddressProfileAccessibilityIdentifier)] + performAction:grey_tap()]; + + [[EarlGrey selectElementWithMatcher:ModalButtonMatcher()] + assertWithMatcher:grey_sufficientlyVisible()]; + + // Save the profile. + [[EarlGrey selectElementWithMatcher:ModalButtonMatcher()] + performAction:grey_tap()]; +} + // Tests the sticky address prompt journey where the prompt remains there when // navigating without an explicit user gesture, and then the prompt is dismissed // when navigating with a user gesture. Test with the address save prompt but
diff --git a/ios/chrome/browser/ui/context_menu/context_menu_egtest.mm b/ios/chrome/browser/ui/context_menu/context_menu_egtest.mm index 4444778..66128ff5 100644 --- a/ios/chrome/browser/ui/context_menu/context_menu_egtest.mm +++ b/ios/chrome/browser/ui/context_menu/context_menu_egtest.mm
@@ -270,6 +270,7 @@ AppLaunchConfiguration config; config.features_enabled.push_back(kTabGroupsInGrid); config.features_enabled.push_back(kTabGroupsIPad); + config.features_enabled.push_back(kModernTabStrip); config.features_disabled.push_back(web::features::kSmoothScrollingDefault); return config; } @@ -682,10 +683,6 @@ // exists in the tab grid, the option `Open in group` will become a submenu, // tapping it will result in listing all the existing tab groups. - (void)testContextMenuOpenInGroup { - // TODO(crbug.com/335584000): Test fails in some iPads. - if ([ChromeEarlGrey isIPadIdiom]) { - EARL_GREY_TEST_SKIPPED(@"Test disabled on iPad."); - } const GURL initialURL = self.testServer->GetURL(kInitialPageUrl); [ChromeEarlGrey loadURL:initialURL]; [ChromeEarlGrey
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_text_field_experimental.mm b/ios/chrome/browser/ui/omnibox/omnibox_text_field_experimental.mm index 6673b177b..eb179c7 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_text_field_experimental.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_text_field_experimental.mm
@@ -564,7 +564,8 @@ } if ([self hasAutocompleteText]) { [self acceptAutocompleteText]; - } else if (IsRichAutocompletionEnabled() && [self hasAdditionalText]) { + } + if (IsRichAutocompletionEnabled() && [self hasAdditionalText]) { [self handleUserInitiatedRemovalOfAdditionalText]; } }
diff --git a/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_coordinator.mm index bc1ba2641..39cbd39 100644 --- a/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_coordinator.mm +++ b/ios/chrome/browser/ui/overlays/infobar_modal/autofill_address_profile/save_address_profile_infobar_modal_overlay_coordinator.mm
@@ -79,15 +79,11 @@ - (void)showEditView { if (base::FeatureList::IsEnabled( kAutofillDynamicallyLoadsFieldsForAddressInput)) { - if (!self.config) { - return; - } - web::WebState* webState = self.browser->GetWebStateList()->GetActiveWebState(); AutofillBottomSheetTabHelper* bottomSheetTabHelper = AutofillBottomSheetTabHelper::FromWebState(webState); - bottomSheetTabHelper->ShowEditAddressBottomSheet(self.config->GetProfile()); + bottomSheetTabHelper->ShowEditAddressBottomSheet(); return; }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_group_item.mm b/ios/chrome/browser/ui/tab_switcher/tab_group_item.mm index 5b8dd04..bff12a1e 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_group_item.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_group_item.mm
@@ -13,6 +13,7 @@ @implementation TabGroupItem { WebStateList* _webStateList; NSMutableArray<GroupTabInfo*>* _tabGroupInfos; + base::WeakPtr<const TabGroup> _tabGroup; } - (instancetype)initWithTabGroup:(const TabGroup*)tabGroup @@ -22,50 +23,54 @@ CHECK(webStateList->ContainsGroup(tabGroup)); self = [super init]; if (self) { - _tabGroup = tabGroup; + _tabGroup = tabGroup->GetWeakPtr(); _webStateList = webStateList; _tabGroupInfos = [[NSMutableArray alloc] init]; } return self; } +- (const TabGroup*)tabGroup { + return _tabGroup.get(); +} + - (NSString*)title { - if (!_webStateList->ContainsGroup(_tabGroup)) { + if (!_webStateList->ContainsGroup(self.tabGroup)) { return nil; } return _tabGroup->GetTitle(); } - (NSString*)rawTitle { - if (!_webStateList->ContainsGroup(_tabGroup)) { + if (!_webStateList->ContainsGroup(self.tabGroup)) { return nil; } return _tabGroup->GetRawTitle(); } - (UIColor*)groupColor { - if (!_webStateList->ContainsGroup(_tabGroup)) { + if (!_webStateList->ContainsGroup(self.tabGroup)) { return nil; } return _tabGroup->GetColor(); } - (NSInteger)numberOfTabsInGroup { - if (!_webStateList->ContainsGroup(_tabGroup)) { + if (!_webStateList->ContainsGroup(self.tabGroup)) { return 0; } return _tabGroup->range().count(); } - (BOOL)collapsed { - if (!_webStateList->ContainsGroup(_tabGroup)) { + if (!_webStateList->ContainsGroup(self.tabGroup)) { return NO; } return _tabGroup->visual_data().is_collapsed(); } - (void)fetchGroupTabInfos:(GroupTabInfosFetchingCompletionBlock)completion { - if (!_webStateList->ContainsGroup(_tabGroup)) { + if (!_webStateList->ContainsGroup(self.tabGroup)) { __weak TabGroupItem* weakSelf = self; base::SequencedTaskRunner::GetCurrentDefault()->PostTask( FROM_HERE, base::BindOnce(^{ @@ -110,7 +115,7 @@ // completion if there is no new snapshot or favicon to save. - (void)notifyCompletion:(GroupTabInfosFetchingCompletionBlock)completion { - if (!_webStateList->ContainsGroup(_tabGroup)) { + if (!_webStateList->ContainsGroup(self.tabGroup)) { completion(self, @[]); return; }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_strip/coordinator/tab_strip_mediator_utils_unittest.mm b/ios/chrome/browser/ui/tab_switcher/tab_strip/coordinator/tab_strip_mediator_utils_unittest.mm index 79efe0c..e7968e2 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_strip/coordinator/tab_strip_mediator_utils_unittest.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_strip/coordinator/tab_strip_mediator_utils_unittest.mm
@@ -192,15 +192,7 @@ // Test that calling `MoveGroupBeforeTabStripItem` between browsers works as // expected. -// TODO(crbug.com/335581919): Fails on device. -#if TARGET_IPHONE_SIMULATOR -#define MAYBE_MoveGroupBeforeItemDifferentBrowser \ - MoveGroupBeforeItemDifferentBrowser -#else -#define MAYBE_MoveGroupBeforeItemDifferentBrowser \ - DISABLED_MoveGroupBeforeItemDifferentBrowser -#endif -TEST_F(TabStripMediatorUtilsTest, MAYBE_MoveGroupBeforeItemDifferentBrowser) { +TEST_F(TabStripMediatorUtilsTest, MoveGroupBeforeItemDifferentBrowser) { WebStateListBuilderFromDescription builder(web_state_list_.get()); ASSERT_TRUE(builder.BuildWebStateListFromDescription( "| [ 0 a b* ] c", base::BindRepeating(CreateWebState))); @@ -208,8 +200,6 @@ web::WebState* webstate_a = builder.GetWebStateForIdentifier('a'); web::WebState* webstate_b = builder.GetWebStateForIdentifier('b'); web::WebState* webstate_c = builder.GetWebStateForIdentifier('c'); - TabStripItemIdentifier* group_0_item_identifier = - CreateGroupItemIdentifier(group_0, web_state_list_); TabStripItemIdentifier* webstate_c_item_identifier = CreateTabItemIdentifier(webstate_c); @@ -271,7 +261,9 @@ EXPECT_EQ("| [ 1 e f ] d", other_builder.GetWebStateListDescription()); // Move `group_1` before `group_0_item_identifier` in `browser_`. - MoveGroupBeforeTabStripItem(group_1, group_0_item_identifier, browser_.get()); + MoveGroupBeforeTabStripItem( + group_1, CreateGroupItemIdentifier(group_0, web_state_list_.get()), + browser_.get()); builder.SetWebStateIdentifier(webstate_e, 'e'); builder.SetWebStateIdentifier(webstate_f, 'f'); builder.GenerateIdentifiersForWebStateList();
diff --git a/ios/chrome/browser/web/model/annotations/annotations_tab_helper.mm b/ios/chrome/browser/web/model/annotations/annotations_tab_helper.mm index 4cbdd3a..686563f0 100644 --- a/ios/chrome/browser/web/model/annotations/annotations_tab_helper.mm +++ b/ios/chrome/browser/web/model/annotations/annotations_tab_helper.mm
@@ -111,6 +111,25 @@ } } + NSTextCheckingType handled_types = + ios::provider::GetHandledIntentTypesForOneTap(web_state); + std::optional<bool> has_no_telephone = metadata.FindBool("wkNoTelephone"); + if (has_no_telephone && has_no_telephone.value()) { + handled_types = handled_types & ~NSTextCheckingTypePhoneNumber; + } + std::optional<bool> has_no_email = metadata.FindBool("wkNoEmail"); + if (has_no_email && has_no_email.value()) { + handled_types = handled_types & ~NSTextCheckingTypeLink; + } + std::optional<bool> has_no_address = metadata.FindBool("wkNoAddress"); + if (has_no_address && has_no_address.value()) { + handled_types = handled_types & ~NSTextCheckingTypeAddress; + } + std::optional<bool> has_no_date = metadata.FindBool("wkNoDate"); + if (has_no_date && has_no_date.value()) { + handled_types = handled_types & ~NSTextCheckingTypeDate; + } + // Keep latest copy. metadata_ = std::make_unique<base::Value::Dict>(metadata.Clone()); @@ -125,8 +144,7 @@ {base::MayBlock(), base::TaskPriority::USER_VISIBLE, base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, base::BindOnce(&ios::provider::ExtractTextAnnotationFromText, - metadata.Clone(), text, - ios::provider::GetHandledIntentTypesForOneTap(web_state), + metadata.Clone(), text, handled_types, ukm::GetSourceIdForWebStateDocument(web_state), std::move(model_path)), base::BindOnce(&AnnotationsTabHelper::ApplyDeferredProcessing,
diff --git a/ios/web/annotations/annotations_inttest.mm b/ios/web/annotations/annotations_inttest.mm index 33be13c..bf154c9e 100644 --- a/ios/web/annotations/annotations_inttest.mm +++ b/ios/web/annotations/annotations_inttest.mm
@@ -32,6 +32,8 @@ namespace web { namespace { +// This is for cases where no message should be sent back from Js. +constexpr base::TimeDelta kWaitForJsNotReturnTimeout = base::Milliseconds(500); const char kTestScriptName[] = "annotations_test"; const char kNoViewportScriptName[] = "annotations"; @@ -400,7 +402,7 @@ "<p>Enjoy</p>" "</body></html>")); ASSERT_TRUE(WaitForWebFramesCount(1)); - EXPECT_FALSE(WaitUntilConditionOrTimeout(kWaitForActionTimeout, ^{ + EXPECT_FALSE(WaitUntilConditionOrTimeout(kWaitForJsNotReturnTimeout, ^{ return observer()->seq_id() > seq_id; })); EXPECT_EQ("", observer()->extracted_text()); @@ -419,7 +421,7 @@ "<p>Enjoy</p>" "</body></html>")); ASSERT_TRUE(WaitForWebFramesCount(1)); - EXPECT_FALSE(WaitUntilConditionOrTimeout(kWaitForActionTimeout, ^{ + EXPECT_FALSE(WaitUntilConditionOrTimeout(kWaitForJsNotReturnTimeout, ^{ return observer()->seq_id() > seq_id; })); EXPECT_EQ("", observer()->extracted_text()); @@ -459,12 +461,46 @@ "<p>Enjoy</p>" "</body></html>")); ASSERT_TRUE(WaitForWebFramesCount(1)); - EXPECT_FALSE(WaitUntilConditionOrTimeout(kWaitForActionTimeout, ^{ + EXPECT_FALSE(WaitUntilConditionOrTimeout(kWaitForJsNotReturnTimeout, ^{ return observer()->seq_id() > seq_id; })); EXPECT_EQ("", observer()->extracted_text()); } +TEST_F(AnnotationTextManagerNoViewportTest, CheckWkMetadata) { + LoadHtmlAndExtractText( + "<html lang=\"fr\">" + "<head>" + "<meta name=\"format-detection\" content=\"telephone=no\"/>" + "</head>" + "<body>" + "<p>You'll find it on</p>" + "<p>Castro Street, <span>Mountain View</span>, CA</p>" + "<p>Enjoy</p>" + "</body></html>"); + EXPECT_TRUE(observer()->metadata().FindBool("wkNoTelephone").value()); +} + +TEST_F(AnnotationTextManagerViewportTest, CheckWkMetadata) { + int seq_id = observer()->seq_id(); + + LoadHtmlAndExtractText( + "<html lang=\"fr\">" + "<head>" + "<meta name=\"format-detection\" content=\"telephone=no\"/>" + "</head>" + "<body>" + "<p>You'll find it on</p>" + "<p>Castro Street, <span>Mountain View</span>, CA</p>" + "<p>Enjoy</p>" + "</body></html>"); + ASSERT_TRUE(WaitForWebFramesCount(1)); + EXPECT_TRUE(WaitUntilConditionOrTimeout(kWaitForActionTimeout, ^{ + return observer()->seq_id() > seq_id; + })); + EXPECT_TRUE(observer()->metadata().FindBool("wkNoTelephone").value()); +} + TEST_F(AnnotationTextManagerNoViewportTest, CheckNoMetadata) { LoadHtmlAndExtractText("<html>" "<head>"
diff --git a/ios/web/annotations/resources/annotations.ts b/ios/web/annotations/resources/annotations.ts index 7f0edf2..078f9f2 100644 --- a/ios/web/annotations/resources/annotations.ts +++ b/ios/web/annotations/resources/annotations.ts
@@ -123,6 +123,29 @@ return false; } +// Returns all types in meta tags 'format-detection', where the type is +// assigned 'no'. +function noFormatDetectionTypes(): Set<string> { + const metas = document.getElementsByTagName('meta'); + let types = new Set<string>(); + for (const meta of metas) { + if (meta.getAttribute('name') !== 'format-detection') + continue; + let content = meta.getAttribute('content'); + if (!content) + continue; + let matches = content.toLowerCase().matchAll(/([a-z]+)\s*=\s*([a-z]+)/g); + if (!matches) + continue; + for (let match of matches) { + if (match && match[2] === 'no' && match[1]) { + types.add(match[1]); + } + } + } + return types; +} + /** * Searches page elements for "notranslate" meta tag. Returns true if * "notranslate" meta tag is defined. @@ -188,6 +211,7 @@ if (decorations.length) { removeDecorations(); } + let disabledTypes = noFormatDetectionTypes(); sendWebKitMessage('annotations', { command: 'annotations.extractedText', text: getPageText(maxChars), @@ -198,6 +222,10 @@ hasNoTranslate: hasNoTranslate(), htmlLang: document.documentElement.lang, httpContentLanguage: getMetaContentByHttpEquiv('content-language'), + wkNoTelephone: disabledTypes.has('telephone'), + wkNoEmail: disabledTypes.has('email'), + wkNoAddress: disabledTypes.has('address'), + wkNoDate: disabledTypes.has('date'), }, }); }
diff --git a/ios/web/annotations/resources/text_dom_utils.ts b/ios/web/annotations/resources/text_dom_utils.ts index 25e60d2..3bf6c754 100644 --- a/ios/web/annotations/resources/text_dom_utils.ts +++ b/ios/web/annotations/resources/text_dom_utils.ts
@@ -58,6 +58,29 @@ return ''; } +// Returns all types in meta tags 'format-detection', where the type is +// assigned 'no'. +function noFormatDetectionTypes(): Set<string> { + const metas = document.getElementsByTagName('meta'); + let types = new Set<string>(); + for (const meta of metas) { + if (meta.getAttribute('name') !== 'format-detection') + continue; + let content = meta.getAttribute('content'); + if (!content) + continue; + let matches = content.toLowerCase().matchAll(/([a-z]+)\s*=\s*([a-z]+)/gi); + if (!matches) + continue; + for (let match of matches) { + if (match && match[2] === 'no' && match[1]) { + types.add(match[1]); + } + } + } + return types; +} + // Searches page elements for "nointentdetection" meta tag. Returns true if // "nointentdetection" meta tag is defined. function hasNoIntentDetection(): boolean { @@ -155,6 +178,7 @@ TextWithSymbolIndex, Rect, getMetaContentByHttpEquiv, + noFormatDetectionTypes, hasNoIntentDetection, rectFromElement, isValidNode,
diff --git a/ios/web/annotations/resources/text_dom_utils_test.ts b/ios/web/annotations/resources/text_dom_utils_test.ts index 897e1dcf..22fd072 100644 --- a/ios/web/annotations/resources/text_dom_utils_test.ts +++ b/ios/web/annotations/resources/text_dom_utils_test.ts
@@ -6,7 +6,7 @@ * @fileoverview Tests for text_dom_utils.ts. */ -import {hasNoIntentDetection, isValidNode, nextLeaf, previousLeaf} from '//ios/web/annotations/resources/text_dom_utils.js'; +import {hasNoIntentDetection, isValidNode, nextLeaf, noFormatDetectionTypes, previousLeaf} from '//ios/web/annotations/resources/text_dom_utils.js'; import {expectEq, load, loadHead, TestSuite} from '//ios/web/annotations/resources/text_test_utils.js'; class TestDomUtils extends TestSuite { @@ -67,13 +67,37 @@ } // Tests `hasNoIntentDetection`. - testhasNoIntentDetection() { + testHasNoIntentDetection() { expectEq(false, hasNoIntentDetection()); loadHead( ' <meta name="chrome" content="nointentdetection">' + ' <meta name="chrome" content="intentdetection">'); expectEq(true, hasNoIntentDetection()); } + + // Tests `noFormatDetectionTypes`. + testHasNoFormatDetection() { + expectEq(false, noFormatDetectionTypes().has('telephone')); + loadHead('<meta name="format-detection" content="telephone=no">'); + expectEq(true, noFormatDetectionTypes().has('telephone')); + + loadHead( + '<meta name="format-detection" ' + + 'content="telephone=no ,email= yes, date=no">'); + expectEq(true, noFormatDetectionTypes().has('telephone')); + expectEq(false, noFormatDetectionTypes().has('email')); + expectEq(true, noFormatDetectionTypes().has('date')); + expectEq(false, noFormatDetectionTypes().has('address')); + + loadHead( + '<meta name="format-detection" ' + + 'content="telephone=no ,email= yes, date=no">' + + '<meta name="format-detection" content="Address=NO">'); + expectEq(true, noFormatDetectionTypes().has('telephone')); + expectEq(false, noFormatDetectionTypes().has('email')); + expectEq(true, noFormatDetectionTypes().has('date')); + expectEq(true, noFormatDetectionTypes().has('address')); + } } export {TestDomUtils}
diff --git a/ios/web/annotations/resources/text_main.ts b/ios/web/annotations/resources/text_main.ts index efef68a..7166a4d 100644 --- a/ios/web/annotations/resources/text_main.ts +++ b/ios/web/annotations/resources/text_main.ts
@@ -3,7 +3,7 @@ // found in the LICENSE file. /** - * @fileoverview Interface used to monior and extract visible text on the page + * @fileoverview Interface used to monitor and extract visible text on the page * and pass it on to the annotations manager. */ @@ -12,7 +12,7 @@ import {annotationExternalData, annotationFullText} from '//ios/web/annotations/resources/text_decoration.js'; import {TextDecorator} from '//ios/web/annotations/resources/text_decorator.js'; import {TextDOMObserver} from '//ios/web/annotations/resources/text_dom_observer.js'; -import {getMetaContentByHttpEquiv, hasNoIntentDetection, HTMLElementWithSymbolIndex, NodeWithSymbolIndex, rectFromElement} from '//ios/web/annotations/resources/text_dom_utils.js'; +import {getMetaContentByHttpEquiv, hasNoIntentDetection, HTMLElementWithSymbolIndex, NodeWithSymbolIndex, noFormatDetectionTypes, rectFromElement} from '//ios/web/annotations/resources/text_dom_utils.js'; import {TextChunk, TextExtractor} from '//ios/web/annotations/resources/text_extractor.js'; import {TextIntersectionObserver} from '//ios/web/annotations/resources/text_intersection_observer.js'; import {TextStyler} from '//ios/web/annotations/resources/text_styler.js'; @@ -41,6 +41,7 @@ if (chunksInFlight.size === 1) { idleTaskTracker?.startActivityListeners(); } + let disabledTypes = noFormatDetectionTypes(); sendWebKitMessage('annotations', { command: 'annotations.extractedText', text: chunk.text, @@ -48,6 +49,10 @@ metadata: { htmlLang: document.documentElement.lang, httpContentLanguage: getMetaContentByHttpEquiv('content-language'), + wkNoTelephone: disabledTypes.has('telephone'), + wkNoEmail: disabledTypes.has('email'), + wkNoAddress: disabledTypes.has('address'), + wkNoDate: disabledTypes.has('date'), }, }); }
diff --git a/ios/web/public/annotations/annotations_text_observer.h b/ios/web/public/annotations/annotations_text_observer.h index 16739ed..bf1afd22 100644 --- a/ios/web/public/annotations/annotations_text_observer.h +++ b/ios/web/public/annotations/annotations_text_observer.h
@@ -28,6 +28,17 @@ // "". // String 'httpContentLanguage': value of content from // <meta http-equiv="content-language" content="en"> or "". + // String 'wkNoTelephone': true if the page header contains webkit's: + // <meta name="format-detection" content="telephone=no"> + // String 'wkNoEmail': true if the page header contains webkit's: + // <meta name="format-detection" content="email=no"> + // String 'wkNoAddress': true if the page header contains webkit's: + // <meta name="format-detection" content="address=no"> + // String 'wkNoDate': true if the page header contains webkit's: + // <meta name="format-detection" content="date=no"> + // Note all type=equal pairs can be also be comma separated in a single + // content attribute in a meta tag. The check is case insensitive but the + // metadata is guaranteed lowercase. virtual void OnTextExtracted(WebState* web_state, const std::string& text, int seq_id,
diff --git a/ios_internal b/ios_internal index 753730e..6b94e1a 160000 --- a/ios_internal +++ b/ios_internal
@@ -1 +1 @@ -Subproject commit 753730eaf49d6dd766d2dc2d1b3b0eaf83a3ec1a +Subproject commit 6b94e1a9bd73cfc7373ebd18c06e7f543cceec3b
diff --git a/media/mojo/clients/mojo_video_decoder.cc b/media/mojo/clients/mojo_video_decoder.cc index 2e6aa3fc..3b25e5b2 100644 --- a/media/mojo/clients/mojo_video_decoder.cc +++ b/media/mojo/clients/mojo_video_decoder.cc
@@ -4,6 +4,7 @@ #include "media/mojo/clients/mojo_video_decoder.h" +#include "base/check.h" #include "base/command_line.h" #include "base/feature_list.h" #include "base/functional/bind.h" @@ -324,6 +325,10 @@ return; } + // TODO(crbug.com/335001233): rollback the change or replace it with a CHECK + // before closing the bug. + DUMP_WILL_BE_CHECK(reset_cb); + reset_cb_ = std::move(reset_cb); remote_decoder_->Reset( base::BindOnce(&MojoVideoDecoder::OnResetDone, base::Unretained(this)));
diff --git a/net/device_bound_sessions/device_bound_session_service.cc b/net/device_bound_sessions/device_bound_session_service.cc index 6ac2d9d..3314fd6 100644 --- a/net/device_bound_sessions/device_bound_session_service.cc +++ b/net/device_bound_sessions/device_bound_session_service.cc
@@ -14,13 +14,16 @@ namespace { class DeviceBoundSessionServiceImpl : public DeviceBoundSessionService { public: + DeviceBoundSessionServiceImpl() = default; // TODO(kristianm): Implement RegisterBoundSession - void RegisterBoundSession(const DeviceBoundSessionRegistrationFetcherParam& - registration_params) override {} + void RegisterBoundSession( + DeviceBoundSessionRegistrationFetcherParam registration_params, + const IsolationInfo& isolation_info) override {} }; } // namespace -std::unique_ptr<DeviceBoundSessionService> DeviceBoundSessionService::Create() { +std::unique_ptr<DeviceBoundSessionService> DeviceBoundSessionService::Create( + const URLRequestContext* request_context) { return std::make_unique<DeviceBoundSessionServiceImpl>(); }
diff --git a/net/device_bound_sessions/device_bound_session_service.h b/net/device_bound_sessions/device_bound_session_service.h index a8bce91..70697e3 100644 --- a/net/device_bound_sessions/device_bound_session_service.h +++ b/net/device_bound_sessions/device_bound_session_service.h
@@ -12,17 +12,28 @@ namespace net { +class IsolationInfo; +class URLRequestContext; + // Main class for Device Bound Session Credentials (DBSC). // Full information can be found at https://github.com/WICG/dbsc class NET_EXPORT DeviceBoundSessionService { public: - static std::unique_ptr<DeviceBoundSessionService> Create(); + static std::unique_ptr<DeviceBoundSessionService> Create( + const URLRequestContext* request_context); - virtual void RegisterBoundSession( - const DeviceBoundSessionRegistrationFetcherParam& - registration_params) = 0; + DeviceBoundSessionService(const DeviceBoundSessionService&) = delete; + DeviceBoundSessionService& operator=(const DeviceBoundSessionService&) = + delete; virtual ~DeviceBoundSessionService() = default; + + virtual void RegisterBoundSession( + DeviceBoundSessionRegistrationFetcherParam registration_params, + const IsolationInfo& isolation_info) = 0; + + protected: + DeviceBoundSessionService() = default; }; } // namespace net
diff --git a/net/device_bound_sessions/test_util.h b/net/device_bound_sessions/test_util.h index 7d14d36..f60a24c 100644 --- a/net/device_bound_sessions/test_util.h +++ b/net/device_bound_sessions/test_util.h
@@ -16,11 +16,11 @@ DeviceBoundSessionServiceMock(); ~DeviceBoundSessionServiceMock() override; - MOCK_METHOD( - void, - RegisterBoundSession, - (const DeviceBoundSessionRegistrationFetcherParam& registration_params), - (override)); + MOCK_METHOD(void, + RegisterBoundSession, + (DeviceBoundSessionRegistrationFetcherParam registration_params, + const IsolationInfo& isolation_info), + (override)); }; } // namespace net
diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc index 4cd9a37..238a01a 100644 --- a/net/url_request/url_request_context_builder.cc +++ b/net/url_request/url_request_context_builder.cc
@@ -504,8 +504,15 @@ #endif // BUILDFLAG(ENABLE_REPORTING) #if BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS) - context->set_device_bound_session_service( - std::move(device_bound_session_service_)); + if (has_device_bound_session_service_) { + context->set_device_bound_session_service( + DeviceBoundSessionService::Create(context.get())); + } else { + if (device_bound_session_service_) { + context->set_device_bound_session_service( + std::move(device_bound_session_service_)); + } + } #endif // BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS) HttpNetworkSessionContext network_session_context;
diff --git a/net/url_request/url_request_context_builder.h b/net/url_request/url_request_context_builder.h index d638aed..a15febef 100644 --- a/net/url_request/url_request_context_builder.h +++ b/net/url_request/url_request_context_builder.h
@@ -352,6 +352,10 @@ #if BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS) void set_device_bound_session_service( std::unique_ptr<DeviceBoundSessionService> device_bound_session_service); + + void set_has_device_bound_session_service(bool enable) { + has_device_bound_session_service_ = enable; + } #endif // BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS) // Binds the context to `network`. All requests scheduled through the context @@ -461,6 +465,7 @@ std::map<std::string, std::unique_ptr<URLRequestJobFactory::ProtocolHandler>> protocol_handlers_; #if BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS) + bool has_device_bound_session_service_ = false; std::unique_ptr<DeviceBoundSessionService> device_bound_session_service_; #endif // BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS)
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index b7bc620..2fc6437c 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc
@@ -1071,8 +1071,9 @@ DeviceBoundSessionRegistrationFetcherParam::CreateIfValid( request_->url(), GetResponseHeaders()); if (auto* service = request_->context()->device_bound_session_service()) { - for (const auto& param : params) { - service->RegisterBoundSession(param); + for (auto& param : params) { + service->RegisterBoundSession(std::move(param), + request_->isolation_info()); } } }
diff --git a/services/network/BUILD.gn b/services/network/BUILD.gn index e35f165..39d4eeb 100644 --- a/services/network/BUILD.gn +++ b/services/network/BUILD.gn
@@ -624,6 +624,8 @@ "test/fake_test_cert_verifier_params_factory.h", "test/mock_devtools_observer.cc", "test/mock_devtools_observer.h", + "test/mock_url_loader_client.cc", + "test/mock_url_loader_client.h", "test/oblivious_http_request_test_helper.cc", "test/oblivious_http_request_test_helper.h", "test/test_cookie_manager.cc",
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index 5fb60171..2a4e07a 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -2709,8 +2709,7 @@ #if BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS) if (params_->device_bound_sessions_enabled) { - builder.set_device_bound_session_service( - net::DeviceBoundSessionService::Create()); + builder.set_has_device_bound_session_service(true); } #endif
diff --git a/components/pdf/browser/mock_url_loader_client.cc b/services/network/test/mock_url_loader_client.cc similarity index 71% rename from components/pdf/browser/mock_url_loader_client.cc rename to services/network/test/mock_url_loader_client.cc index 5ec1024..abe256a 100644 --- a/components/pdf/browser/mock_url_loader_client.cc +++ b/services/network/test/mock_url_loader_client.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/pdf/browser/mock_url_loader_client.h" +#include "services/network/test/mock_url_loader_client.h" -namespace pdf { +namespace network { MockURLLoaderClient::MockURLLoaderClient() = default; MockURLLoaderClient::~MockURLLoaderClient() = default; -} // namespace pdf +} // namespace network
diff --git a/components/pdf/browser/mock_url_loader_client.h b/services/network/test/mock_url_loader_client.h similarity index 88% rename from components/pdf/browser/mock_url_loader_client.h rename to services/network/test/mock_url_loader_client.h index 898051b..25e8b92 100644 --- a/components/pdf/browser/mock_url_loader_client.h +++ b/services/network/test/mock_url_loader_client.h
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_PDF_BROWSER_MOCK_URL_LOADER_CLIENT_H_ -#define COMPONENTS_PDF_BROWSER_MOCK_URL_LOADER_CLIENT_H_ +#ifndef SERVICES_NETWORK_TEST_MOCK_URL_LOADER_CLIENT_H_ +#define SERVICES_NETWORK_TEST_MOCK_URL_LOADER_CLIENT_H_ #include "services/network/public/mojom/early_hints.mojom.h" #include "services/network/public/mojom/url_loader.mojom.h" #include "services/network/public/mojom/url_response_head.mojom.h" #include "testing/gmock/include/gmock/gmock.h" -namespace pdf { +namespace network { class MockURLLoaderClient : public network::mojom::URLLoaderClient { public: @@ -50,6 +50,6 @@ (override)); }; -} // namespace pdf +} // namespace network -#endif // COMPONENTS_PDF_BROWSER_MOCK_URL_LOADER_CLIENT_H_ +#endif // SERVICES_NETWORK_TEST_MOCK_URL_LOADER_CLIENT_H_
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index b128883..0011fef 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -5482,9 +5482,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6426.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6427.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 126.0.6426.0", + "description": "Run with ash-chrome version 126.0.6427.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5494,8 +5494,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v126.0.6426.0", - "revision": "version:126.0.6426.0" + "location": "lacros_version_skew_tests_v126.0.6427.0", + "revision": "version:126.0.6427.0" } ], "dimensions": { @@ -5638,9 +5638,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6426.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6427.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 126.0.6426.0", + "description": "Run with ash-chrome version 126.0.6427.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5650,8 +5650,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v126.0.6426.0", - "revision": "version:126.0.6426.0" + "location": "lacros_version_skew_tests_v126.0.6427.0", + "revision": "version:126.0.6427.0" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json index 60af06d..2c519e5 100644 --- a/testing/buildbot/chromium.coverage.json +++ b/testing/buildbot/chromium.coverage.json
@@ -19663,9 +19663,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6426.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6427.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 126.0.6426.0", + "description": "Run with ash-chrome version 126.0.6427.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -19675,8 +19675,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v126.0.6426.0", - "revision": "version:126.0.6426.0" + "location": "lacros_version_skew_tests_v126.0.6427.0", + "revision": "version:126.0.6427.0" } ], "dimensions": { @@ -19819,9 +19819,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6426.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6427.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 126.0.6426.0", + "description": "Run with ash-chrome version 126.0.6427.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -19831,8 +19831,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v126.0.6426.0", - "revision": "version:126.0.6426.0" + "location": "lacros_version_skew_tests_v126.0.6427.0", + "revision": "version:126.0.6427.0" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 9aff4af..ec643ccf 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -41837,9 +41837,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6426.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6427.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 126.0.6426.0", + "description": "Run with ash-chrome version 126.0.6427.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -41848,8 +41848,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v126.0.6426.0", - "revision": "version:126.0.6426.0" + "location": "lacros_version_skew_tests_v126.0.6427.0", + "revision": "version:126.0.6427.0" } ], "dimensions": { @@ -41987,9 +41987,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6426.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6427.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 126.0.6426.0", + "description": "Run with ash-chrome version 126.0.6427.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -41998,8 +41998,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v126.0.6426.0", - "revision": "version:126.0.6426.0" + "location": "lacros_version_skew_tests_v126.0.6427.0", + "revision": "version:126.0.6427.0" } ], "dimensions": { @@ -43336,9 +43336,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6426.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6427.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 126.0.6426.0", + "description": "Run with ash-chrome version 126.0.6427.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -43348,8 +43348,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v126.0.6426.0", - "revision": "version:126.0.6426.0" + "location": "lacros_version_skew_tests_v126.0.6427.0", + "revision": "version:126.0.6427.0" } ], "dimensions": { @@ -43492,9 +43492,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6426.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6427.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 126.0.6426.0", + "description": "Run with ash-chrome version 126.0.6427.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -43504,8 +43504,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v126.0.6426.0", - "revision": "version:126.0.6426.0" + "location": "lacros_version_skew_tests_v126.0.6427.0", + "revision": "version:126.0.6427.0" } ], "dimensions": { @@ -44817,9 +44817,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6426.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6427.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 126.0.6426.0", + "description": "Run with ash-chrome version 126.0.6427.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -44828,8 +44828,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v126.0.6426.0", - "revision": "version:126.0.6426.0" + "location": "lacros_version_skew_tests_v126.0.6427.0", + "revision": "version:126.0.6427.0" } ], "dimensions": { @@ -44967,9 +44967,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6426.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6427.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 126.0.6426.0", + "description": "Run with ash-chrome version 126.0.6427.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -44978,8 +44978,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v126.0.6426.0", - "revision": "version:126.0.6426.0" + "location": "lacros_version_skew_tests_v126.0.6427.0", + "revision": "version:126.0.6427.0" } ], "dimensions": {
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 61df2a8..0a37b219 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -15763,12 +15763,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6426.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6427.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 126.0.6426.0", + "description": "Run with ash-chrome version 126.0.6427.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -15778,8 +15778,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v126.0.6426.0", - "revision": "version:126.0.6426.0" + "location": "lacros_version_skew_tests_v126.0.6427.0", + "revision": "version:126.0.6427.0" } ], "dimensions": { @@ -15939,12 +15939,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6426.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6427.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 126.0.6426.0", + "description": "Run with ash-chrome version 126.0.6427.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -15954,8 +15954,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v126.0.6426.0", - "revision": "version:126.0.6426.0" + "location": "lacros_version_skew_tests_v126.0.6427.0", + "revision": "version:126.0.6427.0" } ], "dimensions": {
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index a1e33cc..efcdba7 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -267,16 +267,16 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'identifier': 'Lacros version skew testing ash canary', - 'description': 'Run with ash-chrome version 126.0.6426.0', + 'description': 'Run with ash-chrome version 126.0.6427.0', 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6426.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v126.0.6427.0/test_ash_chrome', ], 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v126.0.6426.0', - 'revision': 'version:126.0.6426.0', + 'location': 'lacros_version_skew_tests_v126.0.6427.0', + 'revision': 'version:126.0.6427.0', }, ], },
diff --git a/third_party/angle b/third_party/angle index cc77051..602a6a9 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit cc770518b07ce9ef45cd1c283e9f69b3711d304e +Subproject commit 602a6a9a532fac607e3c36824a8998e270d406a4
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade.cc b/third_party/blink/renderer/core/css/resolver/style_cascade.cc index 31db144..595e04b 100644 --- a/third_party/blink/renderer/core/css/resolver/style_cascade.cc +++ b/third_party/blink/renderer/core/css/resolver/style_cascade.cc
@@ -998,18 +998,9 @@ if (const auto* v = DynamicTo<CSSFlipRevertValue>(result)) { return ResolveFlipRevert(property, *v, priority, origin, resolver); } - if (auto* auto_base_select_pair = - DynamicTo<CSSAppearanceAutoBaseSelectValuePair>(value)) { - // The UA stylesheet only uses -internal-auto-base-select() on select - // elements, which is currently the only element which supports - // appearance:base-select. - CHECK(IsA<HTMLSelectElement>(state_.GetElement())); - - if (state_.StyleBuilder().HasBaseSelectAppearance()) { - return &auto_base_select_pair->Second(); - } else { - return &auto_base_select_pair->First(); - } + if (const auto* v = DynamicTo<CSSAppearanceAutoBaseSelectValuePair>(result)) { + return ResolveAppearanceAutoBaseSelect(property, *v, priority, origin, + resolver); } if (const auto* v = DynamicTo<CSSMathFunctionValue>(result)) { return ResolveMathFunction(property, *v, priority); @@ -1260,6 +1251,22 @@ return Resolve(property, *flipped, priority, origin, resolver); } +const CSSValue* StyleCascade::ResolveAppearanceAutoBaseSelect( + const CSSProperty& property, + const CSSAppearanceAutoBaseSelectValuePair& value, + CascadePriority priority, + CascadeOrigin& origin, + CascadeResolver& resolver) { + // The UA stylesheet only uses -internal-appearance-auto-base-select(), + // on select elements, which is currently the only element which supports + // appearance:base-select. + CHECK(IsA<HTMLSelectElement>(state_.GetElement())); + const CSSValue& selected = state_.StyleBuilder().HasBaseSelectAppearance() + ? value.Second() + : value.First(); + return Resolve(property, selected, priority, origin, resolver); +} + // Math functions can become invalid at computed-value time. Currently, this // is only possible for invalid anchor*() functions. //
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade.h b/third_party/blink/renderer/core/css/resolver/style_cascade.h index 6eb69d69..469a6cd 100644 --- a/third_party/blink/renderer/core/css/resolver/style_cascade.h +++ b/third_party/blink/renderer/core/css/resolver/style_cascade.h
@@ -32,6 +32,7 @@ class CascadeInterpolations; class CascadeResolver; +class CSSAppearanceAutoBaseSelectValuePair; class CSSMathFunctionValue; class CSSParserContext; class CSSParserTokenStream; @@ -369,6 +370,12 @@ CascadePriority, CascadeOrigin&, CascadeResolver&); + const CSSValue* ResolveAppearanceAutoBaseSelect( + const CSSProperty&, + const CSSAppearanceAutoBaseSelectValuePair&, + CascadePriority, + CascadeOrigin&, + CascadeResolver&); const CSSValue* ResolveMathFunction(const CSSProperty&, const CSSMathFunctionValue&, CascadePriority);
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc b/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc index e4a951f8..3e3fc97 100644 --- a/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc +++ b/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
@@ -10,6 +10,7 @@ #include "third_party/blink/renderer/core/animation/css/css_animations.h" #include "third_party/blink/renderer/core/animation/element_animations.h" #include "third_party/blink/renderer/core/css/active_style_sheets.h" +#include "third_party/blink/renderer/core/css/css_appearance_auto_base_select_value_pair.h" #include "third_party/blink/renderer/core/css/css_flip_revert_value.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" #include "third_party/blink/renderer/core/css/css_initial_color_value.h" @@ -4159,6 +4160,47 @@ EXPECT_EQ("auto", cascade.ComputedValue("bottom")); } +TEST_F(StyleCascadeTest, RevertInAppearanceAutoBaseSelectValue) { + SetBodyInnerHTML("<select id=select></select>"); + Element* select = GetDocument().getElementById(AtomicString("select")); + ASSERT_TRUE(select); + + // left:-internal-appearance-auto-base-select(revert, 2px) + // (Not possible to create with the parser currently). + const CSSValue* first = cssvalue::CSSRevertValue::Create(); + const CSSValue* second = + css_test_helpers::ParseValue(GetDocument(), "<length>", "2px"); + auto* set = MakeGarbageCollected<MutableCSSPropertyValueSet>(kUASheetMode); + set->SetProperty(CSSPropertyID::kLeft, + *MakeGarbageCollected<CSSAppearanceAutoBaseSelectValuePair>( + first, second)); + + TestCascade cascade(GetDocument(), select); + cascade.Add("left:300px", {.origin = CascadeOrigin::kUser}); + cascade.Add(set); + cascade.Apply(); + EXPECT_EQ("300px", cascade.ComputedValue("left")); +} + +TEST_F(StyleCascadeTest, EnvInAppearanceAutoBaseSelectValue) { + SetBodyInnerHTML("<select id=select></select>"); + Element* select = GetDocument().getElementById(AtomicString("select")); + ASSERT_TRUE(select); + + // UA styles don't use var(), but they could conceivably use env(). + const CSSPropertyValueSet* set = css_test_helpers::ParseDeclarationBlock( + R"CSS( + border-left-style: solid; + border-left-width: -internal-appearance-auto-base-select(env(unknown, 7px), 42px); + )CSS", + kUASheetMode); + + TestCascade cascade(GetDocument(), select); + cascade.Add(set); + cascade.Apply(); + EXPECT_EQ("7px", cascade.ComputedValue("border-left-width")); +} + TEST_F(StyleCascadeTest, LhUnitCycle) { RegisterProperty(GetDocument(), "--x", "<length>", "0px", false);
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index f43ccfb..5ea0464 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -1247,7 +1247,9 @@ void Element::setAnchorElement(Element* new_element) { CHECK(RuntimeEnabledFeatures::HTMLAnchorAttributeEnabled()); SetElementAttribute(html_names::kAnchorAttr, new_element); - EnsureAnchorElementObserver().Notify(); + if (RuntimeEnabledFeatures::CSSAnchorPositioningEnabled()) { + EnsureAnchorElementObserver().Notify(); + } } inline void Element::SynchronizeAttribute(const QualifiedName& name) const { @@ -9964,6 +9966,7 @@ } if (const HTMLElement* html_element = DynamicTo<HTMLElement>(this)) { if (Element* anchor = html_element->anchorElement()) { + DCHECK(RuntimeEnabledFeatures::HTMLAnchorAttributeEnabled()); return anchor; } if (Element* select_list = html_element->popoverOwnerSelectListElement()) {
diff --git a/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.cc b/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.cc index 72830f5..f020a1a 100644 --- a/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.cc +++ b/third_party/blink/renderer/core/dom/layout_tree_builder_traversal.cc
@@ -377,42 +377,67 @@ if (node1 == node2) { return 0; } - HeapVector<Member<const Node>> ancestors1; - HeapVector<Member<const Node>> ancestors2; - for (const Node* anc1 = &node1; anc1; anc1 = Parent(*anc1)) { - ancestors1.emplace_back(anc1); + const Node* anc1 = &node1; + const Node* anc2 = &node2; + if (Parent(*anc1) != Parent(*anc2)) { + wtf_size_t depth1 = 0u; + for (; anc1; anc1 = Parent(*anc1)) { + if (anc1 == anc2) { + // if node2 is ancestor of node1, return 1. + return 1; + } + ++depth1; + } + wtf_size_t depth2 = 0u; + for (; anc2; anc2 = Parent(*anc2)) { + if (anc2 == anc1) { + // if node1 is ancestor of node2, return -1. + return -1; + } + ++depth2; + } + // Find LCA. + anc1 = &node1; + anc2 = &node2; + while (depth1 < depth2) { + anc2 = Parent(*anc2); + --depth2; + } + while (depth1 > depth2) { + anc1 = Parent(*anc1); + --depth1; + } + while (anc1 && anc2) { + const Node* parent1 = Parent(*anc1); + const Node* parent2 = Parent(*anc2); + if (parent1 == parent2) { + break; + } + anc1 = parent1; + anc2 = parent2; + } } - for (const Node* anc2 = &node2; anc2; anc2 = Parent(*anc2)) { - ancestors2.emplace_back(anc2); - } - int anc1 = ancestors1.size() - 1; - int anc2 = ancestors2.size() - 1; - // First let's eliminate the ancestors until we find the first that are - // inequal, meaning that we need to perform a linear search in that subtree. - while (anc1 >= 0 && anc2 >= 0 && ancestors1[anc1] == ancestors2[anc2]) { - --anc1; - --anc2; - } - if (anc1 < 0) { - return anc2 < 0 ? 0 : -1; - } - if (anc2 < 0) { + // Do some quick checks. + const Node* parent = Parent(*anc1); + DCHECK(parent); + if (NextSibling(*anc2) == anc1 || FirstChild(*parent) == anc2) { return 1; } + if (FirstChild(*parent) == anc1 || LastChild(*parent) == anc2) { + return -1; + } // Compare the children of the first common ancestor and the current top-most // ancestors of the nodes. - const Node* parent = Parent(*ancestors1[anc1]); - for (const Node* child = FirstChild(*parent); child; - child = NextSibling(*child)) { - if (child == ancestors1[anc1]) { + // Note: starting with anc1 here, as in most use cases of this function we + // want to compare two elements that are close to each other with anc1 usually + // being previously in pre-order. + DCHECK(anc1 && anc2); + for (const Node* child = anc1; child; child = NextSibling(*child)) { + if (child == anc2) { return -1; } - if (child == ancestors2[anc2]) { - return 1; - } } - NOTREACHED(); - return 0; + return 1; } } // namespace blink
diff --git a/third_party/blink/renderer/core/editing/commands/delete_selection_command_test.cc b/third_party/blink/renderer/core/editing/commands/delete_selection_command_test.cc index e1c2dd3..1343a2ac 100644 --- a/third_party/blink/renderer/core/editing/commands/delete_selection_command_test.cc +++ b/third_party/blink/renderer/core/editing/commands/delete_selection_command_test.cc
@@ -71,8 +71,7 @@ // should not be 1px. InsertStyleElement("body { font-size: 10px; }"); Selection().SetSelection( - SetSelectionTextToBody( - "<p contenteditable>a<b> ^X|</b> <ruby> </ruby></p>"), + SetSelectionTextToBody("<p contenteditable>a<b> ^X|</b> Y</p>"), SetSelectionOptions()); DeleteSelectionCommand& command = @@ -82,7 +81,7 @@ .SetSanitizeMarkup(true) .Build()); EXPECT_TRUE(command.Apply()) << "the delete command should have succeeded"; - EXPECT_EQ("<p contenteditable>a<b>\u00A0|</b>\u00A0<ruby></ruby></p>", + EXPECT_EQ("<p contenteditable>a<b> |</b>\u00A0Y</p>", GetSelectionTextFromBody()); }
diff --git a/third_party/blink/renderer/core/editing/selection_modifier_test.cc b/third_party/blink/renderer/core/editing/selection_modifier_test.cc index d1b4521..0d3b8c0 100644 --- a/third_party/blink/renderer/core/editing/selection_modifier_test.cc +++ b/third_party/blink/renderer/core/editing/selection_modifier_test.cc
@@ -173,7 +173,7 @@ TEST_F(SelectionModifierTest, PreviousSentenceWithNull) { InsertStyleElement("b {display:inline-block}"); const SelectionInDOMTree selection = - SetSelectionTextToBody("<b><ruby><a>|</a></ruby></b>"); + SetSelectionTextToBody("<b><b><a>|</a></b></b>"); SelectionModifier modifier(GetFrame(), selection); // We call |PreviousSentence()| with null-position. EXPECT_FALSE(modifier.Modify(SelectionModifyAlteration::kMove, @@ -185,7 +185,7 @@ TEST_F(SelectionModifierTest, StartOfSentenceWithNull) { InsertStyleElement("b {display:inline-block}"); const SelectionInDOMTree selection = - SetSelectionTextToBody("|<b><ruby><a></a></ruby></b>"); + SetSelectionTextToBody("|<b><b><a></a></b></b>"); SelectionModifier modifier(GetFrame(), selection); // We call |StartOfSentence()| with null-position. EXPECT_FALSE(modifier.Modify(SelectionModifyAlteration::kMove,
diff --git a/third_party/blink/renderer/core/editing/text_offset_mapping_test.cc b/third_party/blink/renderer/core/editing/text_offset_mapping_test.cc index 4086476..6264b31 100644 --- a/third_party/blink/renderer/core/editing/text_offset_mapping_test.cc +++ b/third_party/blink/renderer/core/editing/text_offset_mapping_test.cc
@@ -189,9 +189,11 @@ } TEST_F(TextOffsetMappingTest, RangeOfBlockWithRUBY) { - EXPECT_EQ("<ruby>^abc|<rt>123</rt></ruby>", + const char* whole_text_selected = "^<ruby>abc<rt>123|</rt></ruby>"; + const bool is_ruby_lb = RuntimeEnabledFeatures::RubyLineBreakableEnabled(); + EXPECT_EQ(is_ruby_lb ? whole_text_selected : "<ruby>^abc|<rt>123</rt></ruby>", GetRange("<ruby>|abc<rt>123</rt></ruby>")); - EXPECT_EQ("<ruby>abc<rt>^123|</rt></ruby>", + EXPECT_EQ(is_ruby_lb ? whole_text_selected : "<ruby>abc<rt>^123|</rt></ruby>", GetRange("<ruby>abc<rt>1|23</rt></ruby>")); } @@ -209,22 +211,26 @@ // LayoutRubyBase (anonymous) at (0,0) size 22x20 // LayoutText {#text} at (0,0) size 22x19 // text run at (0,0) width 22: "abc" + const char* whole_text_selected = "<ruby>^abc<rt>XYZ|</rt></ruby>"; + const bool is_ruby_lb = RuntimeEnabledFeatures::RubyLineBreakableEnabled(); InsertStyleElement("ruby { display: block; }"); - EXPECT_EQ("<ruby>^abc|<rt>XYZ</rt></ruby>", + EXPECT_EQ(is_ruby_lb ? whole_text_selected : "<ruby>^abc|<rt>XYZ</rt></ruby>", GetRange("|<ruby>abc<rt>XYZ</rt></ruby>")); - EXPECT_EQ("<ruby>^abc|<rt>XYZ</rt></ruby>", + EXPECT_EQ(is_ruby_lb ? whole_text_selected : "<ruby>^abc|<rt>XYZ</rt></ruby>", GetRange("<ruby>|abc<rt>XYZ</rt></ruby>")); - EXPECT_EQ("<ruby>abc<rt>^XYZ|</rt></ruby>", + EXPECT_EQ(is_ruby_lb ? whole_text_selected : "<ruby>abc<rt>^XYZ|</rt></ruby>", GetRange("<ruby>abc<rt>|XYZ</rt></ruby>")); } TEST_F(TextOffsetMappingTest, RangeOfBlockWithRubyAsInlineBlock) { + const char* whole_text_selected = "^<ruby>abc<rt>XYZ|</rt></ruby>"; + const bool is_ruby_lb = RuntimeEnabledFeatures::RubyLineBreakableEnabled(); InsertStyleElement("ruby { display: inline-block; }"); - EXPECT_EQ("<ruby>^abc|<rt>XYZ</rt></ruby>", + EXPECT_EQ(is_ruby_lb ? whole_text_selected : "<ruby>^abc|<rt>XYZ</rt></ruby>", GetRange("|<ruby>abc<rt>XYZ</rt></ruby>")); - EXPECT_EQ("<ruby>^abc|<rt>XYZ</rt></ruby>", + EXPECT_EQ(is_ruby_lb ? whole_text_selected : "<ruby>^abc|<rt>XYZ</rt></ruby>", GetRange("<ruby>|abc<rt>XYZ</rt></ruby>")); - EXPECT_EQ("<ruby>abc<rt>^XYZ|</rt></ruby>", + EXPECT_EQ(is_ruby_lb ? whole_text_selected : "<ruby>abc<rt>^XYZ|</rt></ruby>", GetRange("<ruby>abc<rt>|XYZ</rt></ruby>")); }
diff --git a/third_party/blink/renderer/core/html/resources/html.css b/third_party/blink/renderer/core/html/resources/html.css index b80c3cc..4b1a581 100644 --- a/third_party/blink/renderer/core/html/resources/html.css +++ b/third_party/blink/renderer/core/html/resources/html.css
@@ -1496,12 +1496,6 @@ display:block; } -/* Popovers using anchor positioning get their inset properties reset, to make - * it easier to position them. */ -[popover][anchor] { - inset:auto; -} - /* This rule matches popovers (dialog or not) that are currently open as a popover. */ [popover]:popover-open:not(dialog), dialog:popover-open:not([open]) {
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc b/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc index 5cf5a9f..9e368d2b 100644 --- a/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc +++ b/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc
@@ -147,11 +147,13 @@ } LayoutObject* VTTElement::CreateLayoutObject(const ComputedStyle& style) { - switch (web_vtt_node_type_) { - case kVTTNodeTypeRuby: - return MakeGarbageCollected<LayoutRuby>(this); - case kVTTNodeTypeRubyText: - return MakeGarbageCollected<LayoutRubyText>(this); + if (!RuntimeEnabledFeatures::VttCueDisplayRubyEnabled()) { + switch (web_vtt_node_type_) { + case kVTTNodeTypeRuby: + return MakeGarbageCollected<LayoutRuby>(this); + case kVTTNodeTypeRubyText: + return MakeGarbageCollected<LayoutRubyText>(this); + } } return LayoutObject::CreateObject(this, style); }
diff --git a/third_party/blink/renderer/core/layout/inline/inline_items_builder_test.cc b/third_party/blink/renderer/core/layout/inline/inline_items_builder_test.cc index a26a5c1..362e737 100644 --- a/third_party/blink/renderer/core/layout/inline/inline_items_builder_test.cc +++ b/third_party/blink/renderer/core/layout/inline/inline_items_builder_test.cc
@@ -558,6 +558,7 @@ } TEST_F(InlineItemsBuilderTest, HasRuby) { + ScopedRubyLineBreakableForTest enable_ruby_line_breakable(false); HeapVector<InlineItem> items; InlineItemsBuilder builder(GetLayoutBlockFlow(), &items); EXPECT_FALSE(HasRuby(builder)) << "has_ruby_ should be false initially."; @@ -615,6 +616,10 @@ AppendText("anno3", &builder); builder.ExitInline(orphan_rt); + auto* node_data = MakeGarbageCollected<InlineNodeData>(); + builder.DidFinishCollectInlines(node_data); + EXPECT_TRUE(node_data->HasRuby()); + wtf_size_t i = 0; EXPECT_ITEM_OFFSET(items[i], InlineItem::kOpenTag, 0u, 0u); // <ruby> EXPECT_ITEM_OFFSET(items[++i], InlineItem::kOpenRubyColumn, 0u, 1u);
diff --git a/third_party/blink/renderer/core/layout/inline/line_breaker.cc b/third_party/blink/renderer/core/layout/inline/line_breaker.cc index a7973c7..21d8546 100644 --- a/third_party/blink/renderer/core/layout/inline/line_breaker.cc +++ b/third_party/blink/renderer/core/layout/inline/line_breaker.cc
@@ -333,6 +333,10 @@ STACK_ALLOCATED(); public: + LayoutUnit MinInlineSize() const { + return LayoutUnit::FromFloatCeil(min_inline_size_); + } + LayoutUnit HyphenInlineSize(InlineItemResult& item_result) const { if (!hyphen_inline_size_) { if (!item_result.hyphen) { @@ -343,7 +347,60 @@ return *hyphen_inline_size_; } + void Add(float width) { + min_inline_size_ = std::max(width, min_inline_size_); + } + + // Add the width between the `start_offset` and the `end_offset`. + void Add(const ShapeResult& shape_result, + unsigned start_offset, + unsigned end_offset, + bool has_hyphen, + InlineItemResult& item_result) { + float width = shape_result.CachedWidth(start_offset, end_offset); + if (UNLIKELY(has_hyphen)) { + const LayoutUnit hyphen_inline_size = HyphenInlineSize(item_result); + width = (LayoutUnit::FromFloatCeil(width) + hyphen_inline_size).ToFloat(); + } + Add(width); + } + + // Hyphenate the `word` and add all parts. + void AddHyphenated(const ShapeResult& shape_result, + unsigned start_offset, + unsigned end_offset, + bool has_hyphen, + InlineItemResult& item_result, + const Hyphenation& hyphenation, + const StringView& word) { + Vector<wtf_size_t, 8> locations = hyphenation.HyphenLocations(word); + // |locations| is a list of hyphenation points in the descending order. +#if EXPENSIVE_DCHECKS_ARE_ON() + DCHECK_EQ(word.length(), end_offset - start_offset); + DCHECK(std::is_sorted(locations.rbegin(), locations.rend())); + DCHECK(!locations.Contains(0u)); + DCHECK(!locations.Contains(word.length())); +#endif // EXPENSIVE_DCHECKS_ARE_ON() + // Append 0 to process all parts the same way. + locations.push_back(0); + const LayoutUnit hyphen_inline_size = HyphenInlineSize(item_result); + LayoutUnit max_part_width; + for (const wtf_size_t location : locations) { + const unsigned part_start_offset = start_offset + location; + LayoutUnit part_width = LayoutUnit::FromFloatCeil( + shape_result.CachedWidth(part_start_offset, end_offset)); + if (has_hyphen) { + part_width += hyphen_inline_size; + } + max_part_width = std::max(part_width, max_part_width); + end_offset = part_start_offset; + has_hyphen = true; + } + Add(max_part_width.ToFloat()); + } + private: + float min_inline_size_ = 0; mutable std::optional<LayoutUnit> hyphen_inline_size_; }; @@ -1051,6 +1108,12 @@ // See LineBreakerTest.OverflowTab return can_break_after; } + // Bidi controls produced by kOpenRubyColumn/kCloseRubyColumn are ignorable. + unsigned ignorable_bidi_length = IgnorableBidiControlLength(item); + if (ignorable_bidi_length > 0u) { + return break_iterator_.IsBreakable(item.EndOffset() + + ignorable_bidi_length); + } auto* const atomic_inline_item = TryGetAtomicInlineItemAfter(item); if (!atomic_inline_item) return can_break_after; @@ -1126,6 +1189,25 @@ return nullptr; } +unsigned LineBreaker::IgnorableBidiControlLength(const InlineItem& item) const { + const InlineItem* items = Items().data(); + for (wtf_size_t i = + base::checked_cast<wtf_size_t>(std::distance(items, &item)) + 1; + i < end_item_index_; ++i) { + if (items[i].Length() == 0u) { + continue; + } + if (items[i].Type() != InlineItem::kOpenRubyColumn && + items[i].Type() != InlineItem::kCloseRubyColumn) { + return items[i].StartOffset() - item.EndOffset(); + } + } + return (end_item_index_ >= Items().size() + ? Text().length() + : items[end_item_index_].StartOffset()) - + item.EndOffset(); +} + void LineBreaker::HandleText(const InlineItem& item, const ShapeResult& shape_result, LineInfo* line_info) { @@ -1681,7 +1763,6 @@ FastMinTextContext context; const String& text = Text(); const bool should_break_spaces = item.Style()->ShouldBreakSpaces(); - float min_width = 0; unsigned last_end_offset = 0; unsigned end_offset = start_offset + 1; while (start_offset < item.EndOffset()) { @@ -1710,41 +1791,11 @@ if (UNLIKELY(hyphenation_)) { // When 'hyphens: auto', compute all hyphenation opportunities. const StringView word(text, start_offset, word_len); - Vector<wtf_size_t, 8> locations = hyphenation_->HyphenLocations(word); - // |locations| is a list of hyphenation points in the descending order. - // Append 0 to process all parts the same way. - DCHECK(std::is_sorted(locations.rbegin(), locations.rend())); - DCHECK(!locations.Contains(0u)); - DCHECK(!locations.Contains(word_len)); - locations.push_back(0); - const LayoutUnit hyphen_inline_size = - context.HyphenInlineSize(*item_result); - LayoutUnit max_part_width; - for (const wtf_size_t location : locations) { - LayoutUnit part_width = - LayoutUnit::FromFloatCeil(shape_result.CachedWidth( - start_offset + location, start_offset + word_len)); - if (has_hyphen) - part_width += hyphen_inline_size; - max_part_width = std::max(part_width, max_part_width); - word_len = location; - has_hyphen = true; - } - min_width = std::max(max_part_width.ToFloat(), min_width); + context.AddHyphenated(shape_result, start_offset, non_hangable_run_end, + has_hyphen, *item_result, *hyphenation_, word); } else { - float word_width = - shape_result.CachedWidth(start_offset, non_hangable_run_end); - - // Append hyphen-width to `word_width` if the word is hyphenated. - if (has_hyphen) { - const LayoutUnit hyphen_inline_size = - context.HyphenInlineSize(*item_result); - word_width = - (LayoutUnit::FromFloatCeil(word_width) + hyphen_inline_size) - .ToFloat(); - } - - min_width = std::max(word_width, min_width); + context.Add(shape_result, start_offset, non_hangable_run_end, + has_hyphen, *item_result); } } @@ -1766,7 +1817,7 @@ item_result->text_offset.end = std::max(last_end_offset, item_result->text_offset.start + 1); item_result->text_offset.AssertNotEmpty(); - item_result->inline_size = LayoutUnit::FromFloatCeil(min_width); + item_result->inline_size = context.MinInlineSize(); item_result->can_break_after = true; trailing_whitespace_ = WhitespaceState::kUnknown; @@ -3090,8 +3141,32 @@ bool LineBreaker::CanBreakAfterRubyColumn( const InlineItemResult& column_result) const { - // TODO(crbug.com/324111880): Implement this correctly. - return true; + DCHECK_EQ(column_result.item->Type(), InlineItem::kOpenRubyColumn); + DCHECK(column_result.ruby_column); + if (!auto_wrap_) { + return false; + } + const LineInfo& base_line = column_result.ruby_column->base_line; + if (base_line.GetBreakToken()) { + return true; + } + // Populate `text_content` with column_result's base text and text content + // after `column_result`. + StringBuilder text_content; + unsigned base_text_length = + base_line.EndTextOffset() - base_line.StartOffset(); + text_content.Append( + StringView(Text(), base_line.StartOffset(), base_text_length)); + const InlineItem& next_item = + Items()[column_result.ruby_column->annotation_line_list[0] + .EndItemIndex()]; + DCHECK_EQ(next_item.Type(), InlineItem::kCloseRubyColumn); + unsigned ignorable_bidi_length = 1 + IgnorableBidiControlLength(next_item); + text_content.Append( + StringView(Text(), next_item.StartOffset() + ignorable_bidi_length)); + LazyLineBreakIterator break_iterator(break_iterator_, + text_content.ReleaseString()); + return break_iterator.IsBreakable(base_text_length); } // Figure out if the float should be pushed after the current line. This
diff --git a/third_party/blink/renderer/core/layout/inline/line_breaker.h b/third_party/blink/renderer/core/layout/inline/line_breaker.h index ff66f37..29faaa9 100644 --- a/third_party/blink/renderer/core/layout/inline/line_breaker.h +++ b/third_party/blink/renderer/core/layout/inline/line_breaker.h
@@ -235,6 +235,7 @@ // kNoBreakSpaceCharacter (U+00A0) if |sticky_images_quirk_|. bool MayBeAtomicInline(wtf_size_t offset) const; const InlineItem* TryGetAtomicInlineItemAfter(const InlineItem& item) const; + unsigned IgnorableBidiControlLength(const InlineItem& item) const; bool ShouldPushFloatAfterLine(UnpositionedFloat*, LineInfo*); void HandleFloat(const InlineItem&,
diff --git a/third_party/blink/renderer/core/layout/inline/line_breaker_test.cc b/third_party/blink/renderer/core/layout/inline/line_breaker_test.cc index a871abe..ba24fd84 100644 --- a/third_party/blink/renderer/core/layout/inline/line_breaker_test.cc +++ b/third_party/blink/renderer/core/layout/inline/line_breaker_test.cc
@@ -944,6 +944,9 @@ C c <rt> )HTML"); + GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc); + GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kStyleClean); + GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInPerformLayout); // The test passes if we have no DCHECK failures in BreakLines(). BreakLines(node, LayoutUnit::Max()); }
diff --git a/third_party/blink/renderer/core/layout/layout_ruby_base_test.cc b/third_party/blink/renderer/core/layout/layout_ruby_base_test.cc index d7cc341..c8b56b7 100644 --- a/third_party/blink/renderer/core/layout/layout_ruby_base_test.cc +++ b/third_party/blink/renderer/core/layout/layout_ruby_base_test.cc
@@ -17,13 +17,15 @@ SetBodyInnerHTML(R"HTML( <ruby id="target">abc<span style="display:table-cell"></span></ruby> )HTML"); - auto* run_box = To<LayoutRubyColumn>( - GetLayoutObjectByElementId("target")->SlowFirstChild()); - auto* base_box = run_box->RubyBase(); + auto* ruby_object = GetLayoutObjectByElementId("target"); + auto* first_child = ruby_object->SlowFirstChild(); + if (!RuntimeEnabledFeatures::RubyLineBreakableEnabled()) { + first_child = To<LayoutRubyColumn>(first_child)->RubyBase()->FirstChild(); + } // Adding a table-cell should not move the prior Text to an anonymous block. - EXPECT_TRUE(base_box->FirstChild()->IsText()); + EXPECT_TRUE(first_child->IsText()); EXPECT_EQ(EDisplay::kInlineTable, - base_box->FirstChild()->NextSibling()->StyleRef().Display()); + first_child->NextSibling()->StyleRef().Display()); } // crbug.com/1510269 @@ -37,13 +39,15 @@ GetElementById("target")->appendChild(caption); UpdateAllLifecyclePhasesForTest(); - auto* run_box = To<LayoutRubyColumn>( - GetLayoutObjectByElementId("target")->SlowFirstChild()); - auto* base_box = run_box->RubyBase(); + auto* first_child = GetLayoutObjectByElementId("target")->SlowFirstChild(); + if (!RuntimeEnabledFeatures::RubyLineBreakableEnabled()) { + auto* run_box = To<LayoutRubyColumn>(first_child); + first_child = run_box->RubyBase()->FirstChild(); + } // Adding a LayoutImage with display:table-caption should not move the prior // Text to an anonymous block. - EXPECT_TRUE(base_box->FirstChild()->IsText()); - LayoutObject* caption_box = base_box->FirstChild()->NextSibling(); + EXPECT_TRUE(first_child->IsText()); + LayoutObject* caption_box = first_child->NextSibling(); ASSERT_TRUE(caption_box); EXPECT_TRUE(caption_box->IsImage()); EXPECT_EQ(EDisplay::kTableCaption, caption_box->StyleRef().Display()); @@ -60,14 +64,15 @@ GetElementById("target")->appendChild(input); UpdateAllLifecyclePhasesForTest(); - auto* base_box = To<LayoutRubyColumn>( - GetLayoutObjectByElementId("target")->SlowFirstChild()) - ->RubyBase(); + auto* first_child = GetLayoutObjectByElementId("target")->SlowFirstChild(); + if (!RuntimeEnabledFeatures::RubyLineBreakableEnabled()) { + first_child = To<LayoutRubyColumn>(first_child)->RubyBase()->FirstChild(); + } // Adding a table-column should not move the prior Text to an anonymous block. - EXPECT_TRUE(base_box->FirstChild()->IsText()); + EXPECT_TRUE(first_child->IsText()); // The input is not wrapped by an inline-table though it has // display:table-column. - auto* layout_special = base_box->FirstChild()->NextSibling(); + auto* layout_special = first_child->NextSibling(); ASSERT_TRUE(layout_special); EXPECT_EQ(EDisplay::kTableColumn, layout_special->StyleRef().Display()); EXPECT_TRUE(layout_special->IsInline()); @@ -81,11 +86,12 @@ CSSValueID::kRuby); UpdateAllLifecyclePhasesForTest(); - auto* base_box = To<LayoutRubyColumn>( - GetLayoutObjectByElementId("target")->SlowFirstChild()) - ->RubyBase(); + auto* first_child = GetLayoutObjectByElementId("target")->SlowFirstChild(); + if (!RuntimeEnabledFeatures::RubyLineBreakableEnabled()) { + first_child = To<LayoutRubyColumn>(first_child)->RubyBase()->FirstChild(); + } // <p> should be inlinified. - EXPECT_TRUE(base_box->FirstChild()->IsInline()) << base_box->FirstChild(); + EXPECT_TRUE(first_child->IsInline()) << first_child; } } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_ruby_column_test.cc b/third_party/blink/renderer/core/layout/layout_ruby_column_test.cc index 69b155b..fdb29b1 100644 --- a/third_party/blink/renderer/core/layout/layout_ruby_column_test.cc +++ b/third_party/blink/renderer/core/layout/layout_ruby_column_test.cc
@@ -13,6 +13,9 @@ // crbug.com/1461993 TEST_F(LayoutRubyColumnTest, StylePropagation) { + if (RuntimeEnabledFeatures::RubyLineBreakableEnabled()) { + return; + } SetBodyInnerHTML(R"HTML(<ruby id="target">Hello<rt>hola</rt></ruby>)HTML"); auto* run_box = To<LayoutRubyColumn>( GetLayoutObjectByElementId("target")->SlowFirstChild());
diff --git a/third_party/blink/renderer/core/layout/layout_theme.cc b/third_party/blink/renderer/core/layout/layout_theme.cc index 9483239..0260d45 100644 --- a/third_party/blink/renderer/core/layout/layout_theme.cc +++ b/third_party/blink/renderer/core/layout/layout_theme.cc
@@ -288,6 +288,17 @@ } String LayoutTheme::ExtraDefaultStyleSheet() { + if (RuntimeEnabledFeatures::VttCueDisplayRubyEnabled()) { + // !important is necessary because this style is loaded earlier than + // mediaControls.css. + // + // Avoid to write "video::cue" for a false-positive by + // audit_non_blink_usage.py. + return "video::" + "cue(rt) { display: ruby-text !important; }\n" + "video::" + "cue(ruby) { display: ruby; }\n"; + } return g_empty_string; }
diff --git a/third_party/blink/renderer/core/layout/physical_fragment.cc b/third_party/blink/renderer/core/layout/physical_fragment.cc index 711fde5..7c66a8dd 100644 --- a/third_party/blink/renderer/core/layout/physical_fragment.cc +++ b/third_party/blink/renderer/core/layout/physical_fragment.cc
@@ -880,9 +880,11 @@ } switch (item.Type()) { case FragmentItem::kLine: { - AddOutlineRectsForDescendant( - {item.LineBoxFragment(), item.OffsetInContainerFragment()}, - collector, additional_offset, outline_type, containing_block); + if (item.LineBoxFragment()) { + AddOutlineRectsForDescendant( + {item.LineBoxFragment(), item.OffsetInContainerFragment()}, + collector, additional_offset, outline_type, containing_block); + } break; } case FragmentItem::kGeneratedText:
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index c7fa7a9..3da074e 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -341,6 +341,7 @@ modified_runtime_features; AtomicString cookie_deprecation_label; mojom::RendererContentSettingsPtr content_settings; + int64_t body_size_from_service_worker; }; // Asserts size of DocumentLoader, so that whenever a new attribute is added to @@ -1184,6 +1185,9 @@ base::span<const char> encoded_data) { // Decoding has already happened, we don't need the decoder anymore. parser_->SetDecoder(nullptr); + if (response_.WasFetchedViaServiceWorker()) { + total_body_size_from_service_worker_ += data.length(); + } DecodedBodyData body_data(data, DocumentEncodingData(encoding_data), encoded_data); @@ -1251,6 +1255,14 @@ probe::ToCoreProbeSink(GetFrame()), main_resource_identifier_, this, completion_time, total_encoded_data_length, total_decoded_body_length); + if (response_.WasFetchedViaServiceWorker()) { + // See https://w3c.github.io/ServiceWorker/#dom-fetchevent-respondwith + // in "chunk steps": there is no difference between encoded/decoded body + // size, as encoding is handled inside the service worker. + total_encoded_body_length = total_body_size_from_service_worker_; + total_decoded_body_length = total_body_size_from_service_worker_; + } + DOMWindowPerformance::performance(*frame_->DomWindow()) ->OnBodyLoadFinished(total_encoded_body_length, total_decoded_body_length);
diff --git a/third_party/blink/renderer/core/loader/document_loader.h b/third_party/blink/renderer/core/loader/document_loader.h index 4b0cc37..b6a67a1 100644 --- a/third_party/blink/renderer/core/loader/document_loader.h +++ b/third_party/blink/renderer/core/loader/document_loader.h
@@ -867,6 +867,10 @@ // Renderer-enforced content settings are stored on a per-document basis. mojom::RendererContentSettingsPtr content_settings_; + + // When document is fetched from service worker, we keep track of the body + // size for reporting in Navigation Timing encodedBodySize/decodedBodySize. + int64_t total_body_size_from_service_worker_ = 0; }; DECLARE_WEAK_IDENTIFIER_MAP(DocumentLoader);
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn index dbb7736..2f99cd2 100644 --- a/third_party/blink/renderer/modules/BUILD.gn +++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -425,6 +425,9 @@ "canvas/offscreencanvas/offscreen_canvas_rendering_api_ukm_metrics_test.cc", "canvas/offscreencanvas/offscreen_canvas_test.cc", "canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d_test.cc", + "compute_pressure/pressure_observer_test.cc", + "compute_pressure/pressure_observer_test_utils.cc", + "compute_pressure/pressure_observer_test_utils.h", "content_extraction/inner_html_builder_unittest.cc", "content_extraction/inner_text_builder_unittest.cc", "content_index/content_description_type_converter_test.cc", @@ -772,6 +775,9 @@ "canvas/offscreencanvas/offscreen_canvas_rendering_api_ukm_metrics_test.cc", "canvas/offscreencanvas/offscreen_canvas_test.cc", "canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d_test.cc", + "compute_pressure/pressure_observer_test.cc", + "compute_pressure/pressure_observer_test_utils.cc", + "compute_pressure/pressure_observer_test_utils.h", "content_extraction/inner_html_builder_unittest.cc", "content_extraction/inner_text_builder_unittest.cc", "content_index/content_description_type_converter_test.cc",
diff --git a/third_party/blink/renderer/modules/compute_pressure/DEPS b/third_party/blink/renderer/modules/compute_pressure/DEPS index fc80b778..f15724c 100644 --- a/third_party/blink/renderer/modules/compute_pressure/DEPS +++ b/third_party/blink/renderer/modules/compute_pressure/DEPS
@@ -4,3 +4,10 @@ "+third_party/blink/renderer/modules/document_picture_in_picture", "+third_party/blink/renderer/modules/modules_export.h", ] + +specific_include_rules = { + "pressure_observer_test_utils\.cc|.+_test\.cc": [ + "+base/run_loop.h", + ], +} +
diff --git a/third_party/blink/renderer/modules/compute_pressure/change_rate_monitor.h b/third_party/blink/renderer/modules/compute_pressure/change_rate_monitor.h index a37de3c..65c0e09 100644 --- a/third_party/blink/renderer/modules/compute_pressure/change_rate_monitor.h +++ b/third_party/blink/renderer/modules/compute_pressure/change_rate_monitor.h
@@ -34,6 +34,14 @@ // allowed during the observation window's length. bool ChangeCountExceedsLimit(V8PressureSource::Enum) const; + void set_change_count_threshold_for_testing(uint64_t count) { + change_count_threshold_ = count; + } + + void set_penalty_duration_for_testing(base::TimeDelta time) { + penalty_duration_ = time; + } + // Return the penalty duration applied during the observation window's // duration; base::TimeDelta penalty_duration() const { return penalty_duration_; }
diff --git a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.cc b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.cc index 10df370..02c48ed 100644 --- a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.cc +++ b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.cc
@@ -99,6 +99,7 @@ manager_->RemoveObserver(source.AsEnum(), this); last_record_map_[source_index].Clear(); after_penalty_records_[source_index].Clear(); + pending_delayed_report_to_callback_[source_index].Cancel(); // Reject all pending promises for `source`. RejectPendingResolvers(source.AsEnum(), DOMExceptionCode::kAbortError, "Called unobserve method."); @@ -122,6 +123,11 @@ for (auto& after_penalty_record : after_penalty_records_) { after_penalty_record.Clear(); } + + for (auto& pending_callback : pending_delayed_report_to_callback_) { + pending_callback.Cancel(); + } + // Reject all pending promises. for (const auto& source : supportedSources()) { RejectPendingResolvers(source.AsEnum(), DOMExceptionCode::kAbortError,
diff --git a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.h b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.h index 839e251..f1f9371 100644 --- a/third_party/blink/renderer/modules/compute_pressure/pressure_observer.h +++ b/third_party/blink/renderer/modules/compute_pressure/pressure_observer.h
@@ -38,7 +38,7 @@ class PressureRecord; class ScriptState; -class PressureObserver final : public ScriptWrappable { +class MODULES_EXPORT PressureObserver final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: @@ -74,6 +74,10 @@ void OnBindingFailed(V8PressureSource::Enum, DOMExceptionCode); void OnConnectionError(); + ChangeRateMonitor& change_rate_monitor_for_testing() { + return change_rate_monitor_; + } + private: // Verifies if the latest update was at least longer than the sample period. bool PassesRateTest(V8PressureSource::Enum, const DOMHighResTimeStamp&) const;
diff --git a/third_party/blink/renderer/modules/compute_pressure/pressure_observer_test.cc b/third_party/blink/renderer/modules/compute_pressure/pressure_observer_test.cc new file mode 100644 index 0000000..3fe62e11e --- /dev/null +++ b/third_party/blink/renderer/modules/compute_pressure/pressure_observer_test.cc
@@ -0,0 +1,170 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/compute_pressure/pressure_observer.h" + +#include "base/run_loop.h" +#include "base/test/task_environment.h" +#include "base/time/time.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/bindings/core/v8/script_function.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_pressure_observer_options.h" +#include "third_party/blink/renderer/modules/compute_pressure/pressure_observer_test_utils.h" +#include "third_party/blink/renderer/platform/heap/garbage_collected.h" +#include "third_party/blink/renderer/platform/testing/task_environment.h" +#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" +#include "v8/include/v8.h" + +namespace blink { + +namespace { + +// Constants to modify ChangeRateMonitor settings for deterministic test. +constexpr uint64_t kChangeCount = 2; +constexpr base::TimeDelta kDelayTime = base::Seconds(1); +constexpr base::TimeDelta kPenaltyDuration = base::Seconds(4); + +// Helper class for WaitForPromiseFulfillment(). It provides a +// function that invokes |callback| when a ScriptPromiseUntyped is resolved. +class ClosureRunnerCallable final : public ScriptFunction::Callable { + public: + explicit ClosureRunnerCallable(base::OnceClosure callback) + : callback_(std::move(callback)) {} + + ScriptValue Call(ScriptState*, ScriptValue) override { + if (callback_) { + std::move(callback_).Run(); + } + return ScriptValue(); + } + + private: + base::OnceClosure callback_; +}; + +void WaitForPromiseFulfillment(ScriptState* script_state, + ScriptPromiseUntyped promise) { + base::RunLoop run_loop; + promise.Then(MakeGarbageCollected<ScriptFunction>( + script_state, + MakeGarbageCollected<ClosureRunnerCallable>(run_loop.QuitClosure()))); + // Execute pending microtasks, otherwise it can take a few seconds for the + // promise to resolve. + script_state->GetContext()->GetMicrotaskQueue()->PerformCheckpoint( + script_state->GetIsolate()); + run_loop.Run(); +} + +} // namespace + +TEST(PressureObserverTest, PressureObserverDisconnectBeforePenaltyEnd) { + test::TaskEnvironment task_environment( + base::test::TaskEnvironment::TimeSource::MOCK_TIME); + + FakePressureService pressure_service; + ComputePressureTestingContext scope(&pressure_service); + + base::RunLoop callback_run_loop; + + auto* callback_function = MakeGarbageCollected<ScriptFunction>( + scope.GetScriptState(), MakeGarbageCollected<ClosureRunnerCallable>( + callback_run_loop.QuitClosure())); + auto* callback = + V8PressureUpdateCallback::Create(callback_function->V8Function()); + + V8PressureSource source(V8PressureSource::Enum::kCpu); + auto* options = PressureObserverOptions::Create(); + auto* observer = PressureObserver::Create(callback); + auto promise = observer->observe(scope.GetScriptState(), source, options, + scope.GetExceptionState()); + + WaitForPromiseFulfillment(scope.GetScriptState(), promise); + + observer->change_rate_monitor_for_testing().set_change_count_threshold_for_testing( + kChangeCount); + observer->change_rate_monitor_for_testing().set_penalty_duration_for_testing( + kPenaltyDuration); + + // First update. + task_environment.FastForwardBy(kDelayTime); + pressure_service.SendUpdate(device::mojom::blink::PressureUpdate::New( + device::mojom::blink::PressureSource::kCpu, + device::mojom::blink::PressureState::kCritical, base::Time::Now())); + + callback_run_loop.Run(); + + // Second update triggering the penalty. + task_environment.FastForwardBy(kDelayTime); + pressure_service.SendUpdate(device::mojom::blink::PressureUpdate::New( + device::mojom::blink::PressureSource::kCpu, + device::mojom::blink::PressureState::kNominal, base::Time::Now())); + // The number of seconds here should not exceed the penalty time, we just + // want to run some code like OnUpdate() but not the pending delayed task + // that it should have created. + task_environment.FastForwardBy(kDelayTime); + + observer->disconnect(); + // This should not crash. + // The number of seconds here together with the previous FastForwardBy() call + // needs to exceed the chosen penalty time. + task_environment.FastForwardBy(kPenaltyDuration); +} + +TEST(PressureObserverTest, PressureObserverUnobserveBeforePenaltyEnd) { + test::TaskEnvironment task_environment( + base::test::TaskEnvironment::TimeSource::MOCK_TIME); + + FakePressureService pressure_service; + ComputePressureTestingContext scope(&pressure_service); + + base::RunLoop callback_run_loop; + + auto* callback_function = MakeGarbageCollected<ScriptFunction>( + scope.GetScriptState(), MakeGarbageCollected<ClosureRunnerCallable>( + callback_run_loop.QuitClosure())); + auto* callback = + V8PressureUpdateCallback::Create(callback_function->V8Function()); + + V8PressureSource source(V8PressureSource::Enum::kCpu); + auto* options = PressureObserverOptions::Create(); + auto* observer = PressureObserver::Create(callback); + auto promise = observer->observe(scope.GetScriptState(), source, options, + scope.GetExceptionState()); + + WaitForPromiseFulfillment(scope.GetScriptState(), promise); + + observer->change_rate_monitor_for_testing().set_change_count_threshold_for_testing( + kChangeCount); + observer->change_rate_monitor_for_testing().set_penalty_duration_for_testing( + kPenaltyDuration); + + // First update. + task_environment.FastForwardBy(kDelayTime); + pressure_service.SendUpdate(device::mojom::blink::PressureUpdate::New( + device::mojom::blink::PressureSource::kCpu, + device::mojom::blink::PressureState::kNominal, base::Time::Now())); + + callback_run_loop.Run(); + + // Second update triggering the penalty. + task_environment.FastForwardBy(kDelayTime); + pressure_service.SendUpdate(device::mojom::blink::PressureUpdate::New( + device::mojom::blink::PressureSource::kCpu, + device::mojom::blink::PressureState::kCritical, base::Time::Now())); + // The number of seconds here should not exceed the penalty time, we just + // want to run some code like OnUpdate() but not the pending delayed task + // that it should have created. + task_environment.FastForwardBy(kDelayTime); + + observer->unobserve(source); + // This should not crash. + // The number of seconds here together with the previous FastForwardBy() call + // needs to exceed the chosen penalty time. + task_environment.FastForwardBy(kPenaltyDuration); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/compute_pressure/pressure_observer_test_utils.cc b/third_party/blink/renderer/modules/compute_pressure/pressure_observer_test_utils.cc new file mode 100644 index 0000000..86ddb85 --- /dev/null +++ b/third_party/blink/renderer/modules/compute_pressure/pressure_observer_test_utils.cc
@@ -0,0 +1,76 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/compute_pressure/pressure_observer_test_utils.h" + +#include "base/run_loop.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "services/device/public/mojom/pressure_update.mojom-blink.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" + +namespace blink { + +FakePressureService::FakePressureService() = default; +FakePressureService::~FakePressureService() = default; + +void FakePressureService::BindRequest(mojo::ScopedMessagePipeHandle handle) { + mojo::PendingReceiver<device::mojom::blink::PressureManager> receiver( + std::move(handle)); + DCHECK(!receiver_.is_bound()); + receiver_.Bind(std::move(receiver)); + receiver_.set_disconnect_handler(WTF::BindOnce( + &FakePressureService::OnConnectionError, WTF::Unretained(this))); +} + +void FakePressureService::AddClient( + mojo::PendingRemote<device::mojom::blink::PressureClient> client, + device::mojom::PressureSource source, + AddClientCallback callback) { + client_remote_.Bind(std::move(client)); + std::move(callback).Run(device::mojom::blink::PressureStatus::kOk); +} + +void FakePressureService::SendUpdate( + device::mojom::blink::PressureUpdatePtr update) { + client_remote_->OnPressureUpdated(std::move(update)); +} + +void FakePressureService::OnConnectionError() { + receiver_.reset(); + client_remote_.reset(); +} + +ComputePressureTestingContext::ComputePressureTestingContext( + FakePressureService* mock_pressure_service) { + DomWindow()->GetBrowserInterfaceBroker().SetBinderForTesting( + device::mojom::blink::PressureManager::Name_, + WTF::BindRepeating(&FakePressureService::BindRequest, + WTF::Unretained(mock_pressure_service))); +} + +ComputePressureTestingContext::~ComputePressureTestingContext() { + // Remove the testing binder to avoid crashes between tests caused by + // our mocks rebinding an already-bound Binding. + // See https://crbug.com/1010116 for more information. + DomWindow()->GetBrowserInterfaceBroker().SetBinderForTesting( + device::mojom::blink::PressureManager::Name_, {}); +} + +LocalDOMWindow* ComputePressureTestingContext::DomWindow() { + return testing_scope_.GetFrame().DomWindow(); +} + +ScriptState* ComputePressureTestingContext::GetScriptState() { + return testing_scope_.GetScriptState(); +} + +ExceptionState& ComputePressureTestingContext::GetExceptionState() { + return testing_scope_.GetExceptionState(); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/compute_pressure/pressure_observer_test_utils.h b/third_party/blink/renderer/modules/compute_pressure/pressure_observer_test_utils.h new file mode 100644 index 0000000..88b81b50 --- /dev/null +++ b/third_party/blink/renderer/modules/compute_pressure/pressure_observer_test_utils.h
@@ -0,0 +1,61 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COMPUTE_PRESSURE_PRESSURE_OBSERVER_TEST_UTILS_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_COMPUTE_PRESSURE_PRESSURE_OBSERVER_TEST_UTILS_H_ + +#include "mojo/public/cpp/bindings/receiver.h" +#include "services/device/public/mojom/pressure_manager.mojom-blink.h" +#include "services/device/public/mojom/pressure_update.mojom-blink-forward.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" + +namespace blink { + +class ExceptionState; +class LocalDOMWindow; +class ScriptState; + +class FakePressureService final : public device::mojom::blink::PressureManager { + public: + FakePressureService(); + ~FakePressureService() override; + + void BindRequest(mojo::ScopedMessagePipeHandle handle); + + void SendUpdate(device::mojom::blink::PressureUpdatePtr update); + + // device::mojom::PressureManager implementation. + void AddClient( + mojo::PendingRemote<device::mojom::blink::PressureClient> client, + device::mojom::blink::PressureSource source, + AddClientCallback callback) override; + + private: + void OnConnectionError(); + + mojo::Remote<device::mojom::blink::PressureClient> client_remote_; + + mojo::Receiver<device::mojom::blink::PressureManager> receiver_{this}; +}; + +class ComputePressureTestingContext final { + STACK_ALLOCATED(); + + public: + explicit ComputePressureTestingContext( + FakePressureService* mock_pressure_service); + + ~ComputePressureTestingContext(); + + ScriptState* GetScriptState(); + ExceptionState& GetExceptionState(); + + private: + LocalDOMWindow* DomWindow(); + V8TestingScope testing_scope_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_COMPUTE_PRESSURE_PRESSURE_OBSERVER_TEST_UTILS_H_
diff --git a/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc b/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc index c2ac510..5acd012 100644 --- a/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc +++ b/third_party/blink/renderer/modules/media_controls/elements/media_control_popup_menu_element.cc
@@ -214,7 +214,6 @@ setTabIndex(0); setAttribute(html_names::kPopoverAttr, keywords::kAuto); - SetElementAttribute(html_names::kAnchorAttr, PopupAnchor()); SetIsWanted(false); }
diff --git a/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css b/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css index 5c6e3000..53ac1ba2 100644 --- a/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css +++ b/third_party/blink/renderer/modules/media_controls/resources/mediaControls.css
@@ -213,6 +213,14 @@ /* Cursor: pointer will cause a highlight when touch on it, this will disable it */ -webkit-tap-highlight-color: transparent; + + /* These buttons form the anchor for anchor positioning. */ + anchor-name: --internal-media-control-button-anchor; + + /* TODO(crbug.com/40281992) Once anchor-scope is implemented, verify that this + anchor name is not observable outside the media element tree. + https://drafts.csswg.org/css-anchor-position-1/#anchor-scope */ + anchor-scope: --internal-media-control-button-anchor; } /* @@ -901,6 +909,8 @@ border:0; padding: 0; /* Anchor the popover on the bottom right corner. */ + position-anchor: --internal-media-control-button-anchor; + inset: auto; bottom: calc(anchor(bottom) + 4px) !important; right: calc(anchor(right) + 4px) !important; }
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 4e99897..4ebe7269 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -4080,6 +4080,10 @@ status: "experimental", }, { + name: "VttCueDisplayRuby", + status: "stable", + }, + { // The "WakeLock" feature was originally implied_by "ScreenWakeLock" and // "SystemWakeLock". The former was removed after being promoted to // stable, but we need to keep this feature around for code and IDLs that
diff --git a/third_party/blink/web_tests/SlowTests b/third_party/blink/web_tests/SlowTests index 9aaefdf..a896b4c 100644 --- a/third_party/blink/web_tests/SlowTests +++ b/third_party/blink/web_tests/SlowTests
@@ -1214,10 +1214,6 @@ crbug.com/1046784 [ Mac11 Release ] http/tests/devtools/bindings/navigator-frame-attach-detach.js [ Slow ] crbug.com/1046784 [ Mac12 ] http/tests/devtools/bindings/navigator-frame-attach-detach.js [ Slow ] crbug.com/1046784 [ Release Win ] http/tests/devtools/bindings/navigator-frame-attach-detach.js [ Slow ] -crbug.com/1046784 [ Linux ] http/tests/devtools/forced-layout-in-microtask.js [ Slow ] -crbug.com/1046784 [ Mac11 Release ] http/tests/devtools/forced-layout-in-microtask.js [ Slow ] -crbug.com/1046784 [ Mac12 ] http/tests/devtools/forced-layout-in-microtask.js [ Slow ] -crbug.com/1046784 [ Release Win ] http/tests/devtools/forced-layout-in-microtask.js [ Slow ] crbug.com/1046784 http/tests/devtools/application-panel/resources-panel-iframe-idb.js [ Slow ] crbug.com/1046784 [ Linux ] http/tests/devtools/a11y-axe-core/sources/scope-pane-a11y-test.js [ Slow ] crbug.com/1046784 [ Mac11 Release ] http/tests/devtools/a11y-axe-core/sources/scope-pane-a11y-test.js [ Slow ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 6fdf9ab..8a61065 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1678,6 +1678,13 @@ crbug.com/40268721 [ Mac ] external/wpt/html/semantics/popovers/light-dismiss-event-ordering.html [ Pass Timeout ] crbug.com/332331836 external/wpt/html/semantics/popovers/popover-attribute-basic.html [ Pass Timeout ] +# crbug.com/335223786 Popover with anchor attribute - need html.css rule put back +crbug.com/335223786 external/wpt/html/semantics/popovers/popover-anchor-display.tentative.html [ Failure ] +crbug.com/335223786 external/wpt/html/semantics/popovers/popover-anchor-scroll-display.tentative.html [ Failure ] +crbug.com/335223786 external/wpt/html/semantics/popovers/popover-anchor-change-display.tentative.html [ Failure ] +crbug.com/335223786 external/wpt/html/semantics/popovers/popover-anchor-transition.tentative.tentative.html [ Failure ] +crbug.com/335223786 external/wpt/html/semantics/popovers/popover-anchor-display-none.tentative.html [ Failure ] + # Only virtual/threaded version of these tests pass (or running them with --enable-threaded-compositing). crbug.com/936891 fast/scrolling/document-level-touchmove-event-listener-passive-by-default.html [ Failure ] @@ -2051,9 +2058,6 @@ # Failure messages are unstable so we cannot create baselines. crbug.com/832071 external/wpt/service-workers/service-worker/worker-client-id.https.html [ Failure ] -# Service worker involved navigation timing and resource timing have 0 encode_body_length and decoded_body_length. -crbug.com/334977808 external/wpt/service-workers/service-worker/navigation-timing-sizes.https.html [ Failure ] - # failures in external/wpt/css/css-animations/ and web-animations/ from Mozilla tests crbug.com/849859 external/wpt/css/css-animations/Element-getAnimations-dynamic-changes.tentative.html [ Failure ] @@ -4190,9 +4194,6 @@ crbug.com/834302 external/wpt/permissions-policy/permissions-policy-opaque-origin.https.html [ Failure ] -# Temporary suppression to allow devtools-frontend changes -crbug.com/1041830 http/tests/devtools/tracing/timeline-js/timeline-js-line-level-profile.js [ Failure Pass ] - # Sheriff 2019-12-27 crbug.com/1038091 virtual/gpu-rasterization/images/jpeg-yuv-image-decoding.html [ Failure Pass ] crbug.com/1038139 [ Win ] virtual/gpu-rasterization/images/2-comp.html [ Failure Pass ] @@ -7245,9 +7246,7 @@ crbug.com/330761492 external/wpt/html/editing/the-hidden-attribute/beforematch-scroll-to-text-fragment.html [ Failure Pass ] # RubyLineBreakable -crbug.com/324111880 virtual/ruby-lb/editing/execCommand/insert-paragraph-into-table.html [ Crash ] -crbug.com/324111880 virtual/ruby-lb/editing/pasteboard/copy-paste-ruby-text-with-block.html [ Crash ] -crbug.com/324111880 virtual/ruby-lb/editing/pasteboard/copy-paste-ruby-text.html [ Crash ] +crbug.com/324111880 virtual/ruby-lb/editing/execCommand/insert-paragraph-into-table.html [ Failure ] crbug.com/324111880 virtual/ruby-lb/external/wpt/css/css-break/ruby-000.html [ Failure ] crbug.com/324111880 virtual/ruby-lb/external/wpt/css/css-break/ruby-001.html [ Failure ] crbug.com/324111880 virtual/ruby-lb/external/wpt/css/css-break/ruby-002.html [ Failure ] @@ -7258,23 +7257,15 @@ crbug.com/324111880 virtual/ruby-lb/external/wpt/css/css-contain/content-visibility/display-ruby-text-crash.html [ Crash ] crbug.com/324111880 virtual/ruby-lb/external/wpt/css/css-multicol/multicol-fill-balance-021.html [ Failure ] crbug.com/324111880 virtual/ruby-lb/external/wpt/css/css-ruby/br-clear-all-002.html [ Failure ] -crbug.com/324111880 virtual/ruby-lb/external/wpt/css/css-ruby/line-break-around-ruby-001.html [ Failure ] -crbug.com/324111880 virtual/ruby-lb/external/wpt/css/css-ruby/ruby-line-breaking-002.html [ Failure ] crbug.com/324111880 virtual/ruby-lb/external/wpt/css/css-text-decor/ruby-text-decoration-01.html [ Crash ] crbug.com/324111880 virtual/ruby-lb/external/wpt/css/css-writing-modes/direction-upright-002.html [ Crash Failure ] -crbug.com/324111880 virtual/ruby-lb/external/wpt/editing/run/inserthorizontalrule.html [ Crash ] -crbug.com/324111880 virtual/ruby-lb/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/bidi_ruby.html [ Crash Failure ] +crbug.com/324111880 virtual/ruby-lb/external/wpt/editing/run/inserthorizontalrule.html [ Failure ] crbug.com/324111880 virtual/ruby-lb/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/vertical_lr.html [ Crash Failure ] crbug.com/324111880 virtual/ruby-lb/external/wpt/webvtt/rendering/cues-with-video/processing-model/bidi/vertical_rl.html [ Crash Failure ] crbug.com/324111880 virtual/ruby-lb/external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue/vertical_ruby-position.html [ Crash Failure ] crbug.com/324111880 virtual/ruby-lb/fast/ruby/float-overhang-from-ruby-text.html [ Failure ] -crbug.com/324111880 virtual/ruby-lb/fast/ruby/line-break-ruby.html [ Failure ] -crbug.com/324111880 virtual/ruby-lb/fast/ruby/overhang-horizontal.html [ Failure ] -crbug.com/324111880 virtual/ruby-lb/fast/ruby/overhang-vertical.html [ Failure ] crbug.com/324111880 virtual/ruby-lb/fast/ruby/ruby-position-modern-japanese-fonts.html [ Failure ] crbug.com/324111880 virtual/ruby-lb/fast/ruby/select-ruby.html [ Failure ] -crbug.com/324111880 virtual/ruby-lb/media/track/track-cue-rendering-rtl.html [ Crash ] -crbug.com/324111880 virtual/ruby-lb/media/track/track-cue-rendering-ruby.html [ Crash Failure ] crbug.com/324111880 virtual/ruby-lb/paint/invalidation/ruby-flipped-blocks.html [ Failure ] crbug.com/324111880 virtual/ruby-lb/virtual/text-antialias/emphasis-avoid-ruby.html [ Failure ] crbug.com/324111880 virtual/ruby-lb/virtual/text-antialias/whitespace/justification-expansion-crash.html [ Crash ] @@ -7284,6 +7275,8 @@ crbug.com/324111880 virtual/ruby-lb/fast/ruby/float-object-doesnt-crash.html [ Failure ] crbug.com/324111880 virtual/ruby-lb/fast/ruby/modify-positioned-ruby-text-crash.html [ Failure ] crbug.com/324111880 virtual/ruby-lb/fast/ruby/nested-ruby.html [ Failure ] +crbug.com/324111880 virtual/ruby-lb/fast/ruby/overhang-horizontal.html [ Failure ] +crbug.com/324111880 virtual/ruby-lb/fast/ruby/overhang-vertical.html [ Failure ] crbug.com/324111880 virtual/ruby-lb/fast/ruby/percentage-height-child-crash.html [ Failure ] crbug.com/324111880 virtual/ruby-lb/fast/ruby/position-after.html [ Failure ] crbug.com/324111880 virtual/ruby-lb/fast/ruby/ruby-column-break.html [ Failure ] @@ -7297,6 +7290,7 @@ crbug.com/324111880 virtual/ruby-lb/fast/ruby/ruby-text-before-after-content.html [ Failure ] crbug.com/324111880 virtual/ruby-lb/fast/ruby/ruby-trailing.html [ Failure ] crbug.com/324111880 virtual/ruby-lb/fast/ruby/split-ruby-column-percentage-height-descendant.html [ Failure ] +crbug.com/324111880 virtual/ruby-lb/media/track/track-cue-rendering-ruby.html [ Failure ] # RubyLineBreakable; Passing in the virtual suite though failing in non-virtual crbug.com/324111880 virtual/ruby-lb/external/wpt/css/css-ruby/empty-ruby-text-container-float.html [ Pass ] crbug.com/324111880 virtual/ruby-lb/external/wpt/css/css-ruby/ruby-base-different-size.html [ Pass ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index 0bfc715..e176641 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -8193,7 +8193,14 @@ {} ] ] - } + }, + "detached-context-crash.html": [ + "56271f12c3ae76bfd0d11e3abc8d09f15167c906", + [ + null, + {} + ] + ] }, "readable-streams": { "crashtests": { @@ -8204,7 +8211,14 @@ {} ] ] - } + }, + "tee-detached-context-crash.html": [ + "9488da72732e003721fb7e04fef317c77538f4dc", + [ + null, + {} + ] + ] }, "transferable": { "gc-crash.html": [ @@ -132961,14 +132975,14 @@ }, "masonry": { "tentative": { - "align-content": { + "alignment": { "masonry-align-content-001.html": [ - "dfefd998c65c8a071faeef0991f8b9bfe9132a60", + "387ee9da5ebbbc523fda88e7f03e85055e4a8de0", [ null, [ [ - "/css/css-grid/masonry/tentative/align-content/masonry-align-content-001-ref.html", + "/css/css-grid/masonry/tentative/alignment/masonry-align-content-001-ref.html", "==" ] ], @@ -132976,12 +132990,12 @@ ] ], "masonry-align-content-002.html": [ - "75b82654fea45cf8460abbdd0c0b7df8ed8b2afe", + "be7e7a813eb8e45add2a97b8680b8f64036eb7f4", [ null, [ [ - "/css/css-grid/masonry/tentative/align-content/masonry-align-content-002-ref.html", + "/css/css-grid/masonry/tentative/alignment/masonry-align-content-002-ref.html", "==" ] ], @@ -132989,12 +133003,12 @@ ] ], "masonry-align-content-003.html": [ - "ae58e79cb2b4752e08f01e3548705cdf3af1e554", + "818d7e2d84b50c8e15428e59e560a8afb725d4eb", [ null, [ [ - "/css/css-grid/masonry/tentative/align-content/masonry-align-content-003-ref.html", + "/css/css-grid/masonry/tentative/alignment/masonry-align-content-003-ref.html", "==" ] ], @@ -133002,12 +133016,64 @@ ] ], "masonry-align-content-004.html": [ - "3f07aa1fe75b5f0a0e62e559f1d878052ebd31b3", + "747420ba465916276aeb245a2121d241d8cbf866", [ null, [ [ - "/css/css-grid/masonry/tentative/align-content/masonry-align-content-004-ref.html", + "/css/css-grid/masonry/tentative/alignment/masonry-align-content-004-ref.html", + "==" + ] + ], + {} + ] + ], + "masonry-justify-content-001.html": [ + "36ecd4f3b30ed86572ddf3e4a835cbfcdaa8fb6f", + [ + null, + [ + [ + "/css/css-grid/masonry/tentative/alignment/masonry-justify-content-001-ref.html", + "==" + ] + ], + {} + ] + ], + "masonry-justify-content-002.html": [ + "fc3696282c13002fa76fc8d6ccd8875c1a329541", + [ + null, + [ + [ + "/css/css-grid/masonry/tentative/alignment/masonry-justify-content-002-ref.html", + "==" + ] + ], + {} + ] + ], + "masonry-justify-content-003.html": [ + "e2e6ead819ad49de0d9ca0f2d644a32e544ed0c8", + [ + null, + [ + [ + "/css/css-grid/masonry/tentative/alignment/masonry-justify-content-003-ref.html", + "==" + ] + ], + {} + ] + ], + "masonry-justify-content-004.html": [ + "e309ef8870890db60dd556e85cc894400a96694e", + [ + null, + [ + [ + "/css/css-grid/masonry/tentative/alignment/masonry-justify-content-004-ref.html", "==" ] ], @@ -133071,7 +133137,7 @@ }, "fragmentation": { "masonry-fragmentation-001.html": [ - "69182c5425e80f91f883d8c670ff2fe4394ccadc", + "24a5b290610ba71c084dfbab1370d119b00a569a", [ null, [ @@ -133084,7 +133150,7 @@ ] ], "masonry-fragmentation-002.html": [ - "01c4de00b56af8a3c4c082244934ff0aafd5a410", + "76a0540fa92f1715de1a1ff5a67671548d4f15b1", [ null, [ @@ -133097,7 +133163,7 @@ ] ], "masonry-fragmentation-003.html": [ - "fe150e7f8382f9f0cb151400cdc3e9aa0b0846f3", + "7252fc169e2eca745eaad2b91bdb8a9801da242a", [ null, [ @@ -133112,7 +133178,20 @@ }, "gap": { "masonry-gap-001.html": [ - "32265b5f8c1d97e7d781a2d453a5007bbac4fb01", + "628c00135d867debb9d1d904a1426a42be7329e4", + [ + null, + [ + [ + "/css/css-grid/masonry/tentative/gap/masonry-gap-001-ref.html", + "==" + ] + ], + {} + ] + ], + "masonry-gap-002.html": [ + "6dae0a1a7296dd52c48e5b53d8a903aa2ff4d5c4", [ null, [ @@ -133127,7 +133206,7 @@ }, "grid-placement": { "masonry-grid-placement-named-lines-001.html": [ - "b6745f6973b4c0dfd180b778df5d73ef3ca853e3", + "8bb78e307d39219b11677f029bf75ca7dde4cd07", [ null, [ @@ -133140,7 +133219,7 @@ ] ], "masonry-grid-placement-named-lines-002.html": [ - "0ad0dfcea370dd12f0ebf61c5675552f93b6ce6b", + "4e51f09f94dd20d5d4902ea3c4848b9b905ed946", [ null, [ @@ -133155,7 +133234,7 @@ }, "intrinsic-sizing": { "masonry-intrinsic-sizing-001.html": [ - "0f6cdb14954214e81931aa2a5cf80873dc589d84", + "2dc9f6de2e52066d322e425967d8898c1ee407a8", [ null, [ @@ -133168,7 +133247,7 @@ ] ], "masonry-intrinsic-sizing-002.html": [ - "db83299bf5061f0c7209089facdfef277f129a5c", + "b8228cea6e8250587285d0396d4eee6caace352e", [ null, [ @@ -133181,7 +133260,7 @@ ] ], "masonry-intrinsic-sizing-003.html": [ - "e43bc86c9b9571f362e37572be57f0b019ccbfb8", + "80bf5d5d23837861cccc8ab9076a1b77550b6df5", [ null, [ @@ -133194,7 +133273,7 @@ ] ], "masonry-intrinsic-sizing-004.html": [ - "5365208c00f8220ae6427920eae846c0986cbec7", + "70a52f37f46a9a438b2e70fa86d55123ebd5121f", [ null, [ @@ -133207,7 +133286,7 @@ ] ], "masonry-intrinsic-sizing-005.html": [ - "cf9b680869f58373a24a87e105dd518c9bb2ef13", + "83afd5bafa0376e105f38de833aa94b6c2603222", [ null, [ @@ -133220,7 +133299,7 @@ ] ], "masonry-intrinsic-sizing-006.html": [ - "49fd53bb79b1e97c011c61db7aeb863067db0a01", + "fccc116d7d16a38fbe0a5c0e08dadc0b26994d4f", [ null, [ @@ -133248,7 +133327,7 @@ ] ], "masonry-item-placement-001.html": [ - "649e1edb7cb9bd903f795f6e605d12ae566390eb", + "2438df8bac8f31bbf259b83f745d9049b979744a", [ null, [ @@ -133261,7 +133340,7 @@ ] ], "masonry-item-placement-002.html": [ - "7d321bf731684173f483d6ba3abde11da307de8e", + "8833cdfcfc5e894c17cb67a5aad7a0fc6fecb47b", [ null, [ @@ -133274,7 +133353,7 @@ ] ], "masonry-item-placement-003.html": [ - "8a183cffc6bd3f59fb0c7ca58b9a85588bdab3f8", + "bde2fa0e664055066effe3a536d1515db04f185a", [ null, [ @@ -133287,7 +133366,7 @@ ] ], "masonry-item-placement-004.html": [ - "4d1a454a8654648d01dd7ab336514d6a935ab6d5", + "52867cd4a213530e8cb9640b20371a7f35bbaac8", [ null, [ @@ -133300,7 +133379,7 @@ ] ], "masonry-item-placement-005.html": [ - "ddfbc9e54e40d3ae5650a598150a5ead5027fd65", + "7d4993fb3a61a015af6098e1f79d7e5f94d1b17e", [ null, [ @@ -133313,7 +133392,7 @@ ] ], "masonry-item-placement-006.html": [ - "0082d72df26258ec61c988c7d9e46463a10f5a8f", + "467e313d339776a90d994459991724b75210e1b9", [ null, [ @@ -133326,7 +133405,7 @@ ] ], "masonry-item-placement-007.html": [ - "67a02560f45f314bb6843cd8b5e5b046aa8da695", + "4c8053ba666b5c6ddc3b61f74a2233151414e4ff", [ null, [ @@ -133339,7 +133418,7 @@ ] ], "masonry-item-placement-008.html": [ - "c68a9787b8330afd85bb01a7a48b9067df903ba9", + "bdf651d77b4ba77e9393492e9546e2a163a1c288", [ null, [ @@ -133378,62 +133457,8 @@ ] ] }, - "justify-content": { - "masonry-justify-content-001.html": [ - "3d60ac19feb130bf2d1690786c968fb72cac2cf6", - [ - null, - [ - [ - "/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-001-ref.html", - "==" - ] - ], - {} - ] - ], - "masonry-justify-content-002.html": [ - "b1db084d4e7042fa7c641a2c91a1484f38f0e877", - [ - null, - [ - [ - "/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-002-ref.html", - "==" - ] - ], - {} - ] - ], - "masonry-justify-content-003.html": [ - "772984b9e0dac31e12ee7a8859ba9b79c8471875", - [ - null, - [ - [ - "/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-003-ref.html", - "==" - ] - ], - {} - ] - ], - "masonry-justify-content-004.html": [ - "7d04ffeb4b26acd9d74f9e1c8f7c9504e2a27a81", - [ - null, - [ - [ - "/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-004-ref.html", - "==" - ] - ], - {} - ] - ] - }, "masonry-columns-item-containing-block-is-grid-content-width.html": [ - "e48b650253974a22e2dbf68eee6505ca918ddde7", + "b5eb7f4984833c9003a527126015d53c084fc239", [ null, [ @@ -133446,7 +133471,7 @@ ] ], "masonry-not-inhibited-001.html": [ - "54499d3d693a3059204a0a1015638f303ef3caa4", + "1c912feb1fa2509fb620371188c46a68d88c2bda", [ null, [ @@ -133460,7 +133485,7 @@ ], "order": { "masonry-order-001.html": [ - "d01f52ea0421199c37d04408b42d0f6929876301", + "37b3d01fb413354e77acb25b7d65530055c949e4", [ null, [ @@ -133473,7 +133498,7 @@ ] ], "masonry-order-002.html": [ - "abad3d44b8326535bb1f44832011a1a6145a47b9", + "5ebdec27193a454e98fb54ea48508c2b26b3cfa8", [ null, [ @@ -133488,7 +133513,7 @@ }, "subgrid": { "masonry-subgrid-001.html": [ - "de07dfb78d1d3a0aa6ec8728009836aa5c06a9fb", + "c71ba68612e381c26f38bb5b76274c9536823514", [ null, [ @@ -133501,7 +133526,7 @@ ] ], "masonry-subgrid-002.html": [ - "466e95eb03c7ae5eb9d09f8c58b5a3dcb166cf58", + "167f2d4496da2ed304cf6049cbbb4bf937b2c5d4", [ null, [ @@ -309198,6 +309223,10 @@ "51c6a57df7f416859ec03c427d80be542e6205a4", [] ], + "WEB_FEATURES.yml": [ + "69d08754517812caf497fc2a0c3ec412dc1dda84", + [] + ], "abspos": { "flex-abspos-staticpos-align-self-safe-001-ref.html": [ "fb1fb93ea997b1107efa595f17ae5b9c38419a92", @@ -320012,7 +320041,7 @@ [] ], "tentative": { - "align-content": { + "alignment": { "masonry-align-content-001-ref.html": [ "fff6cf21381f2ca635cc52daa0b440ef96e77cc3", [] @@ -320028,6 +320057,22 @@ "masonry-align-content-004-ref.html": [ "de11c836b8d060f94d56831bef9fda471e062ea3", [] + ], + "masonry-justify-content-001-ref.html": [ + "f7d9ccf48f1d9af15826fb12610f18e73d8e645f", + [] + ], + "masonry-justify-content-002-ref.html": [ + "6889af7eaccb0caae8acb8aac40a80d6700ae348", + [] + ], + "masonry-justify-content-003-ref.html": [ + "81d0fba41070bb5b6cba5a71f1bb33ca239d6f02", + [] + ], + "masonry-justify-content-004-ref.html": [ + "43af71fc01f9811cc2906389cf09834a33e6bc3a", + [] ] }, "baseline": { @@ -320064,45 +320109,55 @@ }, "gap": { "masonry-gap-001-ref.html": [ - "94072de3d6b991824ceafb73c1a9d6fe3cc5ba38", + "7157460267ae8556006a3383fbde53618d6dbcd6", + [] + ], + "masonry-gap-002-ref.html": [ + "834a884f7630844d75730d12b4f7871d0911b637", [] ] }, "grid-placement": { "masonry-grid-placement-named-lines-001-ref.html": [ - "c99b117f2ee5d669f99ddc3fc48cd48545387027", + "2aefa719dc4373781ff7e8c5975df68d464557ea", [] ], "masonry-grid-placement-named-lines-002-ref.html": [ - "dd589f90c5ffa06f9353d1dfaa4befa707dbc0b4", + "cfe1369e87d20046b6f0d403290e56dd446dba51", [] ] }, "intrinsic-sizing": { "masonry-intrinsic-sizing-001-ref.html": [ - "898bff16d8e32d4c8f47a6bb091a9fea341a5daa", + "bd1cddd9db0f22ea504a82ebec5e18c19b15c374", [] ], "masonry-intrinsic-sizing-002-ref.html": [ - "4f6519db949ee64dc3fd5e752e930cf3520deff5", + "37f65bace8c50dad1e82bd969d694299dfa20750", [] ], "masonry-intrinsic-sizing-003-ref.html": [ - "61eb21570df2b883245fcdde2430fa30e7a27ec1", + "886c147a90bef3c1cc64b6c1e5633de15b6f06ce", [] ], "masonry-intrinsic-sizing-004-ref.html": [ - "6a5d81fedb2ca1371a55773647a89511488dc0f6", + "166a467d4e83eecf31f8496b8f2c88ef96d7b606", [] ], "masonry-intrinsic-sizing-005-ref.html": [ - "e564fb1b3e6baf1d68980a49ac41eca4bb1c3216", + "48225803963ec31c77ca85ea1b1dd5a06cba354c", [] ], "masonry-intrinsic-sizing-006-ref.html": [ - "e1cb015cfe81f2d2f1ef43a46e822872227324bb", + "a616fadb772eee5cf0fd051378e3aabf7e62e628", [] - ] + ], + "support": { + "masonry-intrinsic-sizing-visual.css": [ + "dbb6303ab18654eb736830c323cdc7c41e5f81a6", + [] + ] + } }, "item-placement": { "masonry-columns-item-placement-auto-flow-next-001-ref.html": [ @@ -320138,7 +320193,7 @@ [] ], "masonry-item-placement-008-ref.html": [ - "e14ca3173abdda981bf7ba7e3a7d5c4760a72190", + "f3503bf071131f396111956dcc0ebddf5e9bd051", [] ], "masonry-rows-item-placement-auto-flow-next-001-ref.html": [ @@ -320150,24 +320205,6 @@ [] ] }, - "justify-content": { - "masonry-justify-content-001-ref.html": [ - "f7d9ccf48f1d9af15826fb12610f18e73d8e645f", - [] - ], - "masonry-justify-content-002-ref.html": [ - "6889af7eaccb0caae8acb8aac40a80d6700ae348", - [] - ], - "masonry-justify-content-003-ref.html": [ - "81d0fba41070bb5b6cba5a71f1bb33ca239d6f02", - [] - ], - "masonry-justify-content-004-ref.html": [ - "43af71fc01f9811cc2906389cf09834a33e6bc3a", - [] - ] - }, "masonry-not-inhibited-001-ref.html": [ "3e86b8a89b6d050e7bc4c4b5f38509c7aa7aabff", [] @@ -343495,7 +343532,7 @@ [] ], "WEB_FEATURES.yml": [ - "a545dbadcb86aa32dee062ed7b23f77636883397", + "d5352fb4a11feeec4fc0390130ccbfe2fd51a632", [] ], "add-background-attachment-fixed-during-smooth-scroll-ref.html": [ @@ -345125,7 +345162,7 @@ [] ], "WEB_FEATURES.yml": [ - "47cf05a2c0fc03f3b9d5977cb140de117a607ffb", + "4b29277607ff59f605698b5ab133669a6c7e5879", [] ], "attribute-selectors": { @@ -345322,7 +345359,7 @@ }, "invalidation": { "WEB_FEATURES.yml": [ - "4eaa2f393109a65e8ea78a77b5273cf0357ed202", + "5e6a6d0d5c0c3fcec6b45c11ba6c4adeedb3180b", [] ], "any-link-attribute-removal-ref.html": [ @@ -347027,6 +347064,10 @@ "9f9aedfac3433e18800138c0eb8b36cc1319aeb3", [] ], + "WEB_FEATURES.yml": [ + "e4fba841b62ac948a7fef93e514b02169057d494", + [] + ], "scroll_support.js": [ "e536b7d7488cf964ec5da5abdc45d5f3852d8909", [] @@ -347474,6 +347515,10 @@ "9a95fba52cc924afaa66eaa2bf1e6083ce6e1b7c", [] ], + "Range-isPointInRange-shadowdom.tentative-expected.txt": [ + "9a95fba52cc924afaa66eaa2bf1e6083ce6e1b7c", + [] + ], "Range-mutations.js": [ "23c013ac6a1d7a1563739afe50f151af49b4ffa6", [] @@ -347895,6 +347940,12 @@ [] ] }, + "edit-context": { + "WEB_FEATURES.yml": [ + "284280066aac2ffc2319ffbcab5c0fbffbb5d962", + [] + ] + }, "event-expected.txt": [ "0485b218e35d5ae646b63fb0433f96e84a7dfac8", [] @@ -384983,6 +385034,10 @@ "9f9aedfac3433e18800138c0eb8b36cc1319aeb3", [] ], + "WEB_FEATURES.yml": [ + "0b260aaaecc52767745a7580525a3fc9b390342f", + [] + ], "client-redirect.html": [ "73858969e02e64e97f1cc50a84935eeeb9068dfe", [] @@ -388318,6 +388373,10 @@ [] ], "declarative": { + "WEB_FEATURES.yml": [ + "4e31ed49627c40f145e87e867d5c0395a72783f3", + [] + ], "support": { "declarative-child-frame.html": [ "603c47743b807ecc00a483d328edcacb7ebb8d57", @@ -389675,6 +389734,10 @@ "07bdbbfb0be49fdb7ca2e6538eb89521b0f2aeaf", [] ], + "WEB_FEATURES.yml": [ + "7a24460e1bfe11d5136571729eded320e2f8e97f", + [] + ], "historical-expected.txt": [ "3310f71c342c2388e2770a0a58560ea558027061", [] @@ -390117,7 +390180,7 @@ [] ], "global-expected.txt": [ - "8da167c5695711688346c900fd480b46f7d8cf39", + "099f6bc56f03dde9054c82ee35aa0bdabe37d588", [] ], "owning-type-message-port.any-expected.txt": [ @@ -397387,6 +397450,10 @@ "8ac0e346514d2a56d36af07f76f4fda440a5ec5b", [] ], + "RTCRtpReceiver-audio-jitterBufferTarget-stats.https-expected.txt": [ + "1bb80b144c7f709e712254b8258ba79b2608b9de", + [] + ], "RTCRtpReceiver-getParameters-expected.txt": [ "715e5d349c3bfbde9c46acb5a89a2db406282f59", [] @@ -397399,6 +397466,14 @@ "d2faa213c5fe83b2a0991a3dc9e0b39db11448b6", [] ], + "RTCRtpReceiver-jitterBufferTarget-stats-helper.js": [ + "31d80926d33b559fd31c5da4b0dea8d18e3ab34c", + [] + ], + "RTCRtpReceiver-video-jitterBufferTarget-stats-expected.txt": [ + "55038bfe82d2225d4a4fb6e339dc312d0d92ea8e", + [] + ], "RTCRtpSender-setParameters-expected.txt": [ "88a6fad745224aef869022d724f9a4f33a1b9999", [] @@ -397687,10 +397762,6 @@ "7b97ceb59a756e43a1ea1d5dc60997fdffcb5310", [] ], - "RTCRtpReceiver-jitterBufferTarget-stats-helper.js": [ - "31d80926d33b559fd31c5da4b0dea8d18e3ab34c", - [] - ], "RTCRtpReceiver-video-jitterBufferTarget-stats-expected.txt": [ "10cd5db9b31c0e150371aefce434a1791af8aaee", [] @@ -438743,6 +438814,17 @@ } ] ], + "fedcm-register": { + "fedcm-no-registered-idps.https.html": [ + "7be2d397e6871961b347e89ca5aebc050a60c7ae", + [ + null, + { + "testdriver": true + } + ] + ] + }, "fedcm-reject-invalid-responses.https.html": [ "f450d568249ec7d7f2ef6f1229d5781344cfb5c5", [ @@ -446184,7 +446266,7 @@ ] ], "custom-property-style-queries.html": [ - "4ae5efca911ca011d6e979ecd3a87f9eaaea7246", + "d9152432ed1162c2f015148bd197663740fc1f83", [ null, {} @@ -454288,7 +454370,7 @@ "masonry": { "tentative": { "masonry-grid-template-columns-computed-withcontent.html": [ - "a799955553e4c39177f5712f7a2e6b244b1a499e", + "0ee2ee78c06c997c5292b336df127c6594349285", [ null, {} @@ -454296,7 +454378,7 @@ ], "parsing": { "masonry-parsing.html": [ - "e3245095fadb760ea5414af7997abc5f296aff1a", + "2204c06f72b8bd15c9662def13c3d89fb64048b4", [ null, {} @@ -461434,6 +461516,15 @@ {} ] ], + "snapchanged-scrolling-non-snapping-axis.tentative.html": [ + "e39fc0c44ee34c5a3ea56949a224e5186d9ebb2a", + [ + null, + { + "testdriver": true + } + ] + ], "snapchanged-with-proximity-strictness.tentative.html": [ "96cab337398654fd778eb42b6a84167b72c9363d", [ @@ -484563,7 +484654,7 @@ } ] ], - "Range-isPointInRange-shadowdom.html": [ + "Range-isPointInRange-shadowdom.tentative.html": [ "a90ddcf584785d0b3c2fd2ecba0a9479ba8567c5", [ null, @@ -574784,7 +574875,7 @@ {} ] ], - "iframe_sandbox_navigation_download_allow_downloads.sub.tentative.https.html": [ + "iframe_sandbox_navigation_download_allow_downloads.sub.tentative.html": [ "6b3b3104ef38a9cbc1596961e62cb7804489dd94", [ null, @@ -574842,7 +574933,7 @@ {} ] ], - "iframe_sandbox_window_open_download_allow_downloads.tentative.https.html": [ + "iframe_sandbox_window_open_download_allow_downloads.tentative.html": [ "158fc4f947bae135e7501566e94a1553d9ce9e51", [ null, @@ -579124,11 +579215,12 @@ ] ], "select-keyboard-behavior.tentative.html": [ - "2fb11ba68b06dd5518cd7b9137902c8d99b64e5e", + "8b06212169793e06e33c1bc972e965f3d77c8861", [ null, { - "testdriver": true + "testdriver": true, + "timeout": "long" } ] ], @@ -596777,7 +596869,7 @@ ] ], "loaf-stream-source-location.html": [ - "0fd30859d738dec410b9b8d20c0c9ba8c2f61294", + "5776ff5255243609132aa046e1ede5a3f8de1720", [ null, { @@ -596786,7 +596878,7 @@ ] ], "loaf-stream.html": [ - "e35bc2f9aa7d7de7a6ac224b9befde30d128e85c", + "424f2cd0d1e629ab89df5c29a206b49b2d2fff51", [ null, { @@ -633037,7 +633129,7 @@ ] ], "navigation-timing-sizes.https.html": [ - "b3b1b5fe35a0099de2892f387e0f4d0d4876fda0", + "a960cd57f3c73a8cfaa37f2c1278ad8b7dbf32b8", [ null, {} @@ -678768,6 +678860,15 @@ {} ] ], + "RTCRtpReceiver-audio-jitterBufferTarget-stats.https.html": [ + "d728ec5a9c9758e0b754ef754e881b6aa5e0f7c3", + [ + null, + { + "timeout": "long" + } + ] + ], "RTCRtpReceiver-getCapabilities.html": [ "21dcae208afc456e4ca56b690a7e75f44657457c", [ @@ -678807,6 +678908,22 @@ } ] ], + "RTCRtpReceiver-jitterBufferTarget.html": [ + "448162d3a2fbbb94d85fd87f2072026a64dd821a", + [ + null, + {} + ] + ], + "RTCRtpReceiver-video-jitterBufferTarget-stats.html": [ + "022dbe70c50b97757ca82cfc38a062d63393c73d", + [ + null, + { + "timeout": "long" + } + ] + ], "RTCRtpReceiver.https.html": [ "eea013140f393a8c04cb5c19c673bdd08f899a6c", [ @@ -679920,31 +680037,6 @@ } ] ], - "RTCRtpReceiver-audio-jitterBufferTarget-stats.https.html": [ - "d728ec5a9c9758e0b754ef754e881b6aa5e0f7c3", - [ - null, - { - "timeout": "long" - } - ] - ], - "RTCRtpReceiver-jitterBufferTarget.html": [ - "448162d3a2fbbb94d85fd87f2072026a64dd821a", - [ - null, - {} - ] - ], - "RTCRtpReceiver-video-jitterBufferTarget-stats.html": [ - "022dbe70c50b97757ca82cfc38a062d63393c73d", - [ - null, - { - "timeout": "long" - } - ] - ], "RTCRtpSynchronizationSource-captureTimestamp.html": [ "22ca5709b5f4f4e6bd4daf91e3a9c9504845b7f7", [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-color-adjust/rendering/dark-color-scheme/color-scheme-iframe-background-about-blank.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-color-adjust/rendering/dark-color-scheme/color-scheme-iframe-background-about-blank.tentative.html index a5a9843..f9ab24f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-color-adjust/rendering/dark-color-scheme/color-scheme-iframe-background-about-blank.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/css-color-adjust/rendering/dark-color-scheme/color-scheme-iframe-background-about-blank.tentative.html
@@ -8,6 +8,3 @@ </style> <p>Should not see a white frame below</p> <iframe width="600" height="400"></iframe> -<script> - document.querySelector("iframe").contentWindow.stop(); -</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/custom-property-style-queries.html b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/custom-property-style-queries.html index 4ae5efc..d915243 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/custom-property-style-queries.html +++ b/third_party/blink/web_tests/external/wpt/css/css-contain/container-queries/custom-property-style-queries.html
@@ -206,6 +206,9 @@ --inherit-no: bar; --unset-no: baz; --initial-no: baz; + --space-no: baz; + --explicit-initial: initial; + --space: ; } @container style(--initial: initial) { #initial { color: green; } @@ -225,6 +228,18 @@ @container not style(--inherit-no: inherit) { #inherit-no { color: green; } } + @container style(--explicit-initial: initial) { + #explicit-initial { color: green; } + } + @container not style(--explicit-initial) { + #explicit-initial-implicit { color: green; } + } + @container style(--space: ) { + #space { color: green; } + } + @container not style(--space-no: ) { + #space-no { color: green; } + } @container style(--unset: unset) { #unset { color: green; } } @@ -238,6 +253,10 @@ <div id="initial-implicit"></div> <div id="initial-no"></div> <div id="initial-no-implicit"></div> + <div id="explicit-initial"></div> + <div id="explicit-initial-implicit"></div> + <div id="space"></div> + <div id="space-no"></div> <div id="inherit"></div> <div id="inherit-no"></div> <div id="unset"></div> @@ -262,6 +281,22 @@ }, "Style query matching value-less query against non-initial value"); test(() => { + assert_equals(getComputedStyle(document.querySelector("#explicit-initial")).color, green); + }, "Style query 'initial' matching (with explicit 'initial' value)"); + + test(() => { + assert_equals(getComputedStyle(document.querySelector("#explicit-initial-implicit")).color, green); + }, "Style query matching negated value-less query against initial value (with explicit 'initial' value)"); + + test(() => { + assert_equals(getComputedStyle(document.querySelector("#space")).color, green); + }, "Style query 'space' matching"); + + test(() => { + assert_equals(getComputedStyle(document.querySelector("#space-no")).color, green); + }, "Style query 'space' not matching"); + + test(() => { assert_equals(getComputedStyle(document.querySelector("#inherit")).color, green); }, "Style query 'inherit' matching");
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/WEB_FEATURES.yml b/third_party/blink/web_tests/external/wpt/css/css-flexbox/WEB_FEATURES.yml new file mode 100644 index 0000000..69d0875 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/WEB_FEATURES.yml
@@ -0,0 +1,7 @@ +features: +- name: flexbox + files: "**" +# TODO: map *gap* to flexbox-gap. This is currently not possible without the +# tests being associated with both flexbox and flexbox-gap. All but one of the +# *gap* tests are passing in all browsers, so lumping them in with flexbox is +# relatively harmless.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-001-ref.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-001-ref.html rename to third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-001-ref.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-001.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-001.html similarity index 87% rename from third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-001.html rename to third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-001.html index dfefd99..387ee9d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-001.html
@@ -5,9 +5,13 @@ --> <html><head> <meta charset="utf-8"> - <title>CSS Grid Test: Masonry layout with `align-content` in masonry axis</title> + <title>CSS Grid Test: Masonry layout with `align-content` in masonry axis (horizontal writing mode)</title> + <meta name="assert" + content="Test passes if align-content shifts content + in the masonry axis of a masonry grid container + and the grid container's baseline is also shifted accordingly."> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#alignment"> <link rel="match" href="masonry-align-content-001-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-002-ref.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-002-ref.html rename to third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-002-ref.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-002.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-002.html similarity index 89% rename from third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-002.html rename to third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-002.html index 75b82654..be7e7a8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-002.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-002.html
@@ -5,9 +5,12 @@ --> <html><head> <meta charset="utf-8"> - <title>CSS Grid Test: Masonry layout with `align-content` in masonry axis</title> + <title>CSS Grid Test: Masonry layout with `align-content` in masonry axis (vertical writing mode)</title> + <meta name="assert" + content="Test passes if align-content shifts content + in the masonry axis of a vertical writing-mode masonry grid container."> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#alignment"> <link rel="match" href="masonry-align-content-002-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-003-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-003-ref.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-003-ref.html rename to third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-003-ref.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-003.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-003.html similarity index 87% rename from third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-003.html rename to third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-003.html index ae58e79..818d7e2 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-003.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-003.html
@@ -5,9 +5,13 @@ --> <html><head> <meta charset="utf-8"> - <title>CSS Grid Test: Masonry layout with `align-content` in grid axis</title> + <title>CSS Grid Test: Masonry layout with `align-content` in grid axis (horizontal writing mode)</title> + <meta name="assert" + content="Test passes if align-content distributes tracks + in the grid axis of a masonry grid container + and the grid container's baseline is also shifted accordingly."> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#alignment"> <link rel="match" href="masonry-align-content-003-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-004-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-004-ref.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-004-ref.html rename to third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-004-ref.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-004.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-004.html similarity index 89% rename from third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-004.html rename to third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-004.html index 3f07aa1f..747420ba46 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/align-content/masonry-align-content-004.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-align-content-004.html
@@ -5,9 +5,12 @@ --> <html><head> <meta charset="utf-8"> - <title>CSS Grid Test: Masonry layout with `align-content` in grid axis</title> + <title>CSS Grid Test: Masonry layout with `align-content` in grid axis (vertical writing mode)</title> + <meta name="assert" + content="Test passes if align-content distributes tracks + in the grid axis of a vertical writing-mode masonry grid container."> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#alignment"> <link rel="match" href="masonry-align-content-004-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-001-ref.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-001-ref.html rename to third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-001-ref.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-001.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-001.html similarity index 89% rename from third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-001.html rename to third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-001.html index 3d60ac1..36ecd4f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-001.html
@@ -5,9 +5,12 @@ --> <html><head> <meta charset="utf-8"> - <title>CSS Grid Test: Masonry layout with `justify-content` in grid axis</title> + <title>CSS Grid Test: Masonry layout with `justify-content` in grid axis (horizontal writing mode)</title> + <meta name="assert" + content="Test passes if justify-content distributes tracks + in the grid axis of a masonry grid container."> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#alignment"> <link rel="match" href="masonry-justify-content-001-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-002-ref.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-002-ref.html rename to third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-002-ref.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-002.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-002.html similarity index 89% rename from third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-002.html rename to third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-002.html index b1db084d..fc36962 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-002.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-002.html
@@ -5,9 +5,12 @@ --> <html><head> <meta charset="utf-8"> - <title>CSS Grid Test: Masonry layout with `justify-content` in grid axis</title> + <title>CSS Grid Test: Masonry layout with `justify-content` in grid axis (vertical writing mode)</title> + <meta name="assert" + content="Test passes if justify-content distributes tracks + in the grid axis of a vertical writing-mode masonry grid container."> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#alignment"> <link rel="match" href="masonry-justify-content-002-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-003-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-003-ref.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-003-ref.html rename to third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-003-ref.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-003.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-003.html similarity index 89% rename from third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-003.html rename to third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-003.html index 772984b..e2e6ead 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-003.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-003.html
@@ -5,9 +5,12 @@ --> <html><head> <meta charset="utf-8"> - <title>CSS Grid Test: Masonry layout with `justify-content` in masonry axis</title> + <title>CSS Grid Test: Masonry layout with `justify-content` in masonry axis (horizontal writing mode)</title> + <meta name="assert" + content="Test passes if justify-content shifts content + in the masonry axis of a masonry grid container."> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#alignment"> <link rel="match" href="masonry-justify-content-003-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-004-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-004-ref.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-004-ref.html rename to third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-004-ref.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-004.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-004.html similarity index 89% rename from third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-004.html rename to third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-004.html index 7d04ffe..e309ef88 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/justify-content/masonry-justify-content-004.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/alignment/masonry-justify-content-004.html
@@ -5,9 +5,12 @@ --> <html><head> <meta charset="utf-8"> - <title>CSS Grid Test: Masonry layout with `justify-content` in masonry axis</title> + <title>CSS Grid Test: Masonry layout with `justify-content` in masonry axis (vertical writing mode)</title> + <meta name="assert" + content="Test passes if justify-content shifts content + in the masonry axis of a vertical writing-mode masonry grid container."> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#alignment"> <link rel="match" href="masonry-justify-content-004-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/fragmentation/masonry-fragmentation-001.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/fragmentation/masonry-fragmentation-001.html index 69182c5..24a5b29 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/fragmentation/masonry-fragmentation-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/fragmentation/masonry-fragmentation-001.html
@@ -7,7 +7,7 @@ <meta charset="utf-8"> <title>CSS Grid Test: Masonry layout fragmentation</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3"> <link rel="match" href="masonry-fragmentation-001-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/fragmentation/masonry-fragmentation-002.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/fragmentation/masonry-fragmentation-002.html index 01c4de0..76a0540 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/fragmentation/masonry-fragmentation-002.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/fragmentation/masonry-fragmentation-002.html
@@ -7,7 +7,7 @@ <meta charset="utf-8"> <title>CSS Grid Test: Masonry layout fragmentation</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3"> <link rel="match" href="masonry-fragmentation-002-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/fragmentation/masonry-fragmentation-003.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/fragmentation/masonry-fragmentation-003.html index fe150e7f..7252fc16 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/fragmentation/masonry-fragmentation-003.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/fragmentation/masonry-fragmentation-003.html
@@ -7,7 +7,7 @@ <meta charset="utf-8"> <title>CSS Grid Test: Grid axis fragmentation with column masonry layout</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3"> <link rel="match" href="masonry-fragmentation-003-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/gap/masonry-gap-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/gap/masonry-gap-001-ref.html index 94072de..71574602 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/gap/masonry-gap-001-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/gap/masonry-gap-001-ref.html
@@ -27,6 +27,8 @@ padding: 20px; margin: 3px; border: 5px solid blue; + place-self: start; + grid-row: span 2; } </style> </head> @@ -34,7 +36,8 @@ <grid> <item>1</item> - <item style="padding:0; place-self:start; min-width:0">2</item> + <item style="padding:0; grid-row: span 1">2</item> <item>3</item> <item>4</item> + <item style="padding:0; grid-column: 2; grid-row: 2">5</item> </grid>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/gap/masonry-gap-001.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/gap/masonry-gap-001.html index 32265b5..628c0013 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/gap/masonry-gap-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/gap/masonry-gap-001.html
@@ -7,7 +7,7 @@ <meta charset="utf-8"> <title>CSS Grid Test: Masonry layout with definite `gap` in both axes</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#alignment"> <link rel="match" href="masonry-gap-001-ref.html"> <style> html,body { @@ -40,4 +40,5 @@ <item style="padding:0; grid-column: 2;">2</item> <item style="grid-column: 3;">3</item> <item style="grid-column: 4;">4</item> + <item style="padding:0; grid-column: 2;">5</item> </grid>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/gap/masonry-gap-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/gap/masonry-gap-002-ref.html new file mode 100644 index 0000000..834a884 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/gap/masonry-gap-002-ref.html
@@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>Reference: Masonry layout with normal `gap` in both axes</title> + <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> + <link rel="author" title="Elika J. Etemad" href="https://fantasai.inkedblade.net/contact"> + <style> +html,body { + color:black; background-color:white; font:25px/1 "Courier New", monospace; padding:0; margin:0; +} + +grid { + display: inline-grid; + gap: 0; + grid-template-columns: auto min-content repeat(2,auto); + color: #444; + border: 1px solid; + padding: 2px; +} + +item { + background-color: #444; + color: #fff; + padding: 20px; + margin: 3px; + border: 5px solid blue; + place-self: start; + grid-row: span 2; + display: block; +} +</style> +</head> +<body> + +<grid> + <item>1</item> + <item style="padding:0; grid-row: span 1">2</item> + <item>3</item> + <item>4</item> + <item style="padding:0; grid-column: 2; grid-row: 2">5</item> +</grid> + +<grid> + <item>1</item> + <item style="padding:0; grid-row: span 1">2</item> + <item>3</item> + <item>4</item> + <item style="padding:0; grid-column: 2; grid-row: 2">5</item> +</grid> + +<grid> + <div style="columns: 3; column-gap: 1em;"> + <item>1</item> + <item>2</item> + <item>3</item> + </div> +</grid> +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/gap/masonry-gap-002.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/gap/masonry-gap-002.html new file mode 100644 index 0000000..6dae0a1a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/gap/masonry-gap-002.html
@@ -0,0 +1,71 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>CSS Grid Test: Masonry layout with normal `gap` in both axes</title> + <meta name="assert" + content="Test passes if a 'normal' gap is the initial value, + is resolved to zero, + does not allow margin collapsing, + and inherits as 'normal' in masonry layout"> + <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> + <link rel="author" title="Elika J. Etemad" href="https://fantasai.inkedblade.net/contact"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#alignment"> + <link rel="match" href="masonry-gap-001-ref.html"> + <style> +html,body { + color:black; background-color:white; font:25px/1 "Courier New", monospace; padding:0; margin:0; +} + +grid { + display: inline-grid; + grid-template-columns: repeat(4,auto); + grid-template-rows: masonry; + color: #444; + border: 1px solid; + padding: 2px; +} + +item { + background-color: #444; + color: #fff; + padding: 20px; + margin: 3px; + border: 5px solid blue; + display: block; +} + +</style> +</head> +<body> + +<!-- test initial value of normal --> +<grid> + <item style="grid-column: 1;">1</item> + <item style="padding:0; grid-column: 2;">2</item> + <item style="grid-column: 3;">3</item> + <item style="grid-column: 4;">4</item> + <item style="padding:0; grid-column: 2;">5</item> +</grid> + +<!-- test that 'normal' is supported and also resolves to zero --> +<grid style="gap: 10px; gap: normal"> + <item style="grid-column: 1;">1</item> + <item style="padding:0; grid-column: 2;">2</item> + <item style="grid-column: 3;">3</item> + <item style="grid-column: 4;">4</item> + <item style="padding:0; grid-column: 2;">5</item> +</grid> + +<!-- test inheritance of normal as keyword --> + +<grid style="gap: 10px; gap: normal"> + <div style="columns: 3; gap: inherit;"> + <item>1</item> + <item>2</item> + <item>3</item> + </div> +</grid>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/grid-placement/masonry-grid-placement-named-lines-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/grid-placement/masonry-grid-placement-named-lines-001-ref.html index c99b117..2aefa719 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/grid-placement/masonry-grid-placement-named-lines-001-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/grid-placement/masonry-grid-placement-named-lines-001-ref.html
@@ -5,7 +5,7 @@ --> <html><head> <meta charset="utf-8"> - <title>Reference: Placement involving named lines</title> + <title>Reference: Definite column placement in a masonry grid (single edge)</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <style> body,html { color:black; background:white; font-size:15px/1 monospace; padding:0; margin:0; }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/grid-placement/masonry-grid-placement-named-lines-001.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/grid-placement/masonry-grid-placement-named-lines-001.html index b6745f69..8bb78e3 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/grid-placement/masonry-grid-placement-named-lines-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/grid-placement/masonry-grid-placement-named-lines-001.html
@@ -5,8 +5,9 @@ --> <html><head> <meta charset="utf-8"> - <title>CSS Grid Test: Placement involving named lines</title> + <title>CSS Grid Test: Definite column placement in a masonry grid (single edge)</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#grid-template-masonry"> <link rel="help" href="https://drafts.csswg.org/css-grid/#grid-placement-int"> <link rel="match" href="masonry-grid-placement-named-lines-001-ref.html"> <style>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/grid-placement/masonry-grid-placement-named-lines-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/grid-placement/masonry-grid-placement-named-lines-002-ref.html index dd589f90..cfe1369e8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/grid-placement/masonry-grid-placement-named-lines-002-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/grid-placement/masonry-grid-placement-named-lines-002-ref.html
@@ -5,7 +5,7 @@ --> <html><head> <meta charset="utf-8"> - <title>Reference: Placement involving named lines</title> + <title>Reference: Definite column placement in a masonry grid (double edge)</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <style> body,html { color:black; background:white; font:15px/1 monospace; padding:0; margin:0; }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/grid-placement/masonry-grid-placement-named-lines-002.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/grid-placement/masonry-grid-placement-named-lines-002.html index 0ad0dfc..4e51f09 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/grid-placement/masonry-grid-placement-named-lines-002.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/grid-placement/masonry-grid-placement-named-lines-002.html
@@ -5,8 +5,9 @@ --> <html><head> <meta charset="utf-8"> - <title>CSS Grid Test: Placement involving named lines</title> + <title>CSS Grid Test: Definite column placement in a masonry grid (double edge)</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#grid-template-masonry"> <link rel="help" href="https://drafts.csswg.org/css-grid/#grid-placement-int"> <link rel="match" href="masonry-grid-placement-named-lines-002-ref.html"> <style>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-001-ref.html index 898bff1..bd1cddd9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-001-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-001-ref.html
@@ -3,15 +3,14 @@ Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ --> -<html><head> +<html> <meta charset="utf-8"> <title>Reference: Masonry layout intrinsic sizing</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> <style> -html,body { - color:black; background-color:white; font:15px/1 Ahem; padding:0; margin:0; -} + +@import "support/masonry-intrinsic-sizing-visual.css"; grid { display: inline-grid; @@ -28,15 +27,11 @@ .mixed { grid-template-columns: 1fr 2fr min-content max-content; } - -item { - background-color: #444; - color: blue; -} </style> -</head> + <body> +<section> <grid> <item style="width:2ch">1</item> <item>2</item> @@ -111,9 +106,11 @@ <item>4</item> <item style="width:6ch; grid-column:span 3">5</item> </grid> +</section> <!-- ditto with 'fr' sizing --> +<section> <grid class="fr"> <item style="width:2ch">1</item> <item>2</item> @@ -188,10 +185,11 @@ <item>4</item> <item style="width:6ch; grid-column:span 3">5</item> </grid> - +</section> <!-- ditto with mixed sizing --> +<section> <grid class="mixed" style="grid-template-columns: 2ch 4ch 1ch 1ch"> <item style="width:2ch">1</item> <item>2</item> @@ -266,6 +264,5 @@ <item>4</item> <item style="width:6ch; grid-column:span 3">5</item> </grid> +</section> -</body> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-001.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-001.html index 0f6cdb1..2dc9f6d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-001.html
@@ -3,43 +3,40 @@ Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ --> -<html><head> +<html> <meta charset="utf-8"> - <title>CSS Grid Test: Masonry layout intrinsic sizing</title> + <title>CSS Grid Test: Masonry layout column sizing - intrinsic</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#track-sizing"> <link rel="match" href="masonry-intrinsic-sizing-001-ref.html"> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> <style> -html,body { - color:black; background-color:white; font:15px/1 Ahem; padding:0; margin:0; -} + +@import "support/masonry-intrinsic-sizing-visual.css"; grid { display: inline-grid; gap: 1px 2px; - grid-template-columns: repeat(4,auto); grid-template-rows: masonry; border: 1px solid; padding: 0 1px 0 2px; vertical-align: top; } -.fr { +.auto grid { + grid-template-columns: repeat(4,auto); +} +.fr grid { grid-template-columns: 1fr 2fr 1fr 1fr; } -.mixed { +.mixed grid { grid-template-columns: 1fr 2fr min-content max-content; } - -item { - background-color: #444; - color: blue; -} </style> -</head> + <body> -<grid> +<section class="auto"> +<grid title="Wider first item"> <item style="width:2ch">1</item> <item>2</item> <item>3</item> @@ -47,7 +44,7 @@ <item>5</item> </grid> -<grid> +<grid title="Wider last item"> <item>1</item> <item>2</item> <item>3</item> @@ -55,7 +52,7 @@ <item style="width:2ch">5</item> </grid> -<grid> +<grid title="Wider last item in col 2"> <item>1</item> <item>2</item> <item>3</item> @@ -63,7 +60,7 @@ <item style="width:2ch; grid-column:2">5</item> </grid> -<grid> +<grid title="Wider last item spanning col 2-3"> <item>1</item> <item>2</item> <item>3</item> @@ -71,7 +68,7 @@ <item style="width:4ch; grid-column:2/span 2">5</item> </grid> -<grid> +<grid title="Item spanning col 2-3, wider item spanning col 1-3"> <item>1</item> <item>2</item> <item>3</item> @@ -81,7 +78,7 @@ </grid> -<grid> +<grid title="3ch item spanning 2-3, 5ch item spanning 1-3"> <item>1</item> <item>2</item> <item>3</item> @@ -90,7 +87,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid> +<grid title="Last item spanning 4"> <item>1</item> <item>2</item> <item>3</item> @@ -98,7 +95,7 @@ <item style="grid-column:span 4">5</item> </grid> -<grid> +<grid title="6ch last item spanning 4"> <item>1</item> <item>2</item> <item>3</item> @@ -106,17 +103,19 @@ <item style="width:6ch; grid-column:span 4">5</item> </grid> -<grid> +<grid title="6ch last item spanning 3"> <item>1</item> <item>2</item> <item>3</item> <item>4</item> <item style="width:6ch; grid-column:span 3">5</item> </grid> +</section> <!-- ditto with 'fr' sizing --> -<grid class="fr"> +<section class="fr"> +<grid title="Wider first item"> <item style="width:2ch">1</item> <item>2</item> <item>3</item> @@ -124,7 +123,7 @@ <item>5</item> </grid> -<grid class="fr"> +<grid title="Wider last item"> <item>1</item> <item>2</item> <item>3</item> @@ -132,7 +131,7 @@ <item style="width:2ch">5</item> </grid> -<grid class="fr"> +<grid title="Wider last item in col 2"> <item>1</item> <item>2</item> <item>3</item> @@ -140,7 +139,7 @@ <item style="width:2ch; grid-column:2">5</item> </grid> -<grid class="fr"> +<grid title="Wider last item spanning col 2-3"> <item>1</item> <item>2</item> <item>3</item> @@ -148,7 +147,7 @@ <item style="width:4ch; grid-column:2/span 2">5</item> </grid> -<grid class="fr"> +<grid title="Item spanning col 2-3, wider item spanning col 1-3"> <item>1</item> <item>2</item> <item>3</item> @@ -158,7 +157,7 @@ </grid> -<grid class="fr"> +<grid title="3ch item spanning 2-3, 5ch item spanning 1-3"> <item>1</item> <item>2</item> <item>3</item> @@ -167,7 +166,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="fr"> +<grid title="Last item spanning 4"> <item>1</item> <item>2</item> <item>3</item> @@ -175,7 +174,7 @@ <item style="grid-column:span 4">5</item> </grid> -<grid class="fr"> +<grid title="6ch last item spanning 4"> <item>1</item> <item>2</item> <item>3</item> @@ -183,18 +182,19 @@ <item style="width:6ch; grid-column:span 4">5</item> </grid> -<grid class="fr"> +<grid title="6ch last item spanning 3"> <item>1</item> <item>2</item> <item>3</item> <item>4</item> <item style="width:6ch; grid-column:span 3">5</item> </grid> - +</section> <!-- ditto with mixed sizing --> -<grid class="mixed"> +<section class="mixed"> +<grid title="Wider first item"> <item style="width:2ch">1</item> <item>2</item> <item>3</item> @@ -202,7 +202,7 @@ <item>5</item> </grid> -<grid class="mixed"> +<grid title="Wider last item"> <item>1</item> <item>2</item> <item>3</item> @@ -210,7 +210,7 @@ <item style="width:2ch">5</item> </grid> -<grid class="mixed"> +<grid title="Wider last item in col 2"> <item>1</item> <item>2</item> <item>3</item> @@ -218,7 +218,7 @@ <item style="width:2ch; grid-column:2">5</item> </grid> -<grid class="mixed"> +<grid title="Wider last item spanning col 2-3"> <item>1</item> <item>2</item> <item>3</item> @@ -226,7 +226,7 @@ <item style="width:4ch; grid-column:2/span 2">5</item> </grid> -<grid class="mixed"> +<grid title="Item spanning col 2-3, wider item spanning col 1-3"> <item>1</item> <item>2</item> <item>3</item> @@ -236,7 +236,7 @@ </grid> -<grid class="mixed"> +<grid title="3ch item spanning 2-3, 5ch item spanning 1-3"> <item>1</item> <item>2</item> <item>3</item> @@ -245,7 +245,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="mixed"> +<grid title="Last item spanning 4"> <item>1</item> <item>2</item> <item>3</item> @@ -253,7 +253,7 @@ <item style="grid-column:span 4">5</item> </grid> -<grid class="mixed"> +<grid title="6ch last item spanning 4"> <item>1</item> <item>2</item> <item>3</item> @@ -261,13 +261,12 @@ <item style="width:6ch; grid-column:span 4">5</item> </grid> -<grid class="mixed"> +<grid title="6ch last item spanning 3"> <item>1</item> <item>2</item> <item>3</item> <item>4</item> <item style="width:6ch; grid-column:span 3">5</item> </grid> +</section> -</body> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-002-ref.html index 4f6519d..37f65bac 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-002-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-002-ref.html
@@ -3,15 +3,14 @@ Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ --> -<html><head> +<html> <meta charset="utf-8"> <title>Reference: Masonry layout intrinsic sizing</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> <style> -html,body { - color:black; background-color:white; font:15px/1 Ahem; padding:0; margin:0; -} + +@import "support/masonry-intrinsic-sizing-visual.css"; grid { display: inline-grid; @@ -29,15 +28,11 @@ .mixed { grid-template-columns: 1fr 2fr min-content max-content; } - -item { - background-color: #444; - color: blue; -} </style> -</head> + <body> +<section> <grid> <item style="width:2ch">1</item> <item>2</item> @@ -112,9 +107,11 @@ <item>4</item> <item style="width:6ch; grid-column:span 3">5</item> </grid> +</section> <!-- ditto with 'fr' sizing --> +<section> <grid class="fr"> <item style="width:2ch">1</item> <item>2</item> @@ -189,10 +186,11 @@ <item>4</item> <item style="width:6ch; grid-column:span 3">5</item> </grid> - +</section> <!-- ditto with mixed sizing --> +<section> <grid class="mixed" style="grid-template-columns: 2ch 1ch 1ch 1ch"> <item style="width:2ch">1</item> <item>2</item> @@ -267,6 +265,5 @@ <item>4</item> <item style="width:6ch; grid-column:span 3">5</item> </grid> +</section> -</body> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-002.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-002.html index db83299bf..b8228ce 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-002.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-002.html
@@ -3,44 +3,42 @@ Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ --> -<html><head> +<html> <meta charset="utf-8"> - <title>CSS Grid Test: Masonry layout intrinsic sizing</title> + <title>CSS Grid Test: Masonry layout column sizing - min-content constraint</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#track-sizing"> <link rel="match" href="masonry-intrinsic-sizing-002-ref.html"> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> <style> -html,body { - color:black; background-color:white; font:15px/1 Ahem; padding:0; margin:0; -} + +@import "support/masonry-intrinsic-sizing-visual.css"; grid { display: inline-grid; gap: 1px 2px; - grid-template-columns: repeat(4,auto); grid-template-rows: masonry; border: 1px solid; padding: 0 1px 0 2px; vertical-align: top; width: min-content; } -.fr { + +.auto grid { + grid-template-columns: repeat(4,auto); +} +.fr grid { grid-template-columns: 1fr 2fr 1fr 1fr; } -.mixed { +.mixed grid { grid-template-columns: 1fr 2fr min-content max-content; } - -item { - background-color: #444; - color: blue; -} </style> -</head> + <body> -<grid> +<section class="auto"> +<grid title="Wider first item"> <item style="width:2ch">1</item> <item>2</item> <item>3</item> @@ -48,7 +46,7 @@ <item>5</item> </grid> -<grid> +<grid title="Wider last item"> <item>1</item> <item>2</item> <item>3</item> @@ -56,7 +54,7 @@ <item style="width:2ch">5</item> </grid> -<grid> +<grid title="Wider last item in col 2"> <item>1</item> <item>2</item> <item>3</item> @@ -64,7 +62,7 @@ <item style="width:2ch; grid-column:2">5</item> </grid> -<grid> +<grid title="Wider last item spanning col 2-3"> <item>1</item> <item>2</item> <item>3</item> @@ -72,7 +70,7 @@ <item style="width:4ch; grid-column:2/span 2">5</item> </grid> -<grid> +<grid title="Item spanning col 2-3, wider item spanning col 1-3"> <item>1</item> <item>2</item> <item>3</item> @@ -82,7 +80,7 @@ </grid> -<grid> +<grid title="3ch item spanning 2-3, 5ch item spanning 1-3"> <item>1</item> <item>2</item> <item>3</item> @@ -91,7 +89,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid> +<grid title="Last item spanning 4"> <item>1</item> <item>2</item> <item>3</item> @@ -99,7 +97,7 @@ <item style="grid-column:span 4">5</item> </grid> -<grid> +<grid title="6ch last item spanning 4"> <item>1</item> <item>2</item> <item>3</item> @@ -107,17 +105,19 @@ <item style="width:6ch; grid-column:span 4">5</item> </grid> -<grid> +<grid title="6ch last item spanning 3"> <item>1</item> <item>2</item> <item>3</item> <item>4</item> <item style="width:6ch; grid-column:span 3">5</item> </grid> +</section> <!-- ditto with 'fr' sizing --> -<grid class="fr"> +<section class="fr"> +<grid title="Wider first item"> <item style="width:2ch">1</item> <item>2</item> <item>3</item> @@ -125,7 +125,7 @@ <item>5</item> </grid> -<grid class="fr"> +<grid title="Wider last item"> <item>1</item> <item>2</item> <item>3</item> @@ -133,7 +133,7 @@ <item style="width:2ch">5</item> </grid> -<grid class="fr"> +<grid title="Wider last item in col 2"> <item>1</item> <item>2</item> <item>3</item> @@ -141,7 +141,7 @@ <item style="width:2ch; grid-column:2">5</item> </grid> -<grid class="fr"> +<grid title="Wider last item spanning col 2-3"> <item>1</item> <item>2</item> <item>3</item> @@ -149,7 +149,7 @@ <item style="width:4ch; grid-column:2/span 2">5</item> </grid> -<grid class="fr"> +<grid title="Item spanning col 2-3, wider item spanning col 1-3"> <item>1</item> <item>2</item> <item>3</item> @@ -159,7 +159,7 @@ </grid> -<grid class="fr"> +<grid title="3ch item spanning 2-3, 5ch item spanning 1-3"> <item>1</item> <item>2</item> <item>3</item> @@ -168,7 +168,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="fr"> +<grid title="Last item spanning 4"> <item>1</item> <item>2</item> <item>3</item> @@ -176,7 +176,7 @@ <item style="grid-column:span 4">5</item> </grid> -<grid class="fr"> +<grid title="6ch last item spanning 4"> <item>1</item> <item>2</item> <item>3</item> @@ -184,18 +184,19 @@ <item style="width:6ch; grid-column:span 4">5</item> </grid> -<grid class="fr"> +<grid title="6ch last item spanning 3"> <item>1</item> <item>2</item> <item>3</item> <item>4</item> <item style="width:6ch; grid-column:span 3">5</item> </grid> - +</section> <!-- ditto with mixed sizing --> -<grid class="mixed"> +<section class="mixed"> +<grid title="Wider first item"> <item style="width:2ch">1</item> <item>2</item> <item>3</item> @@ -203,7 +204,7 @@ <item>5</item> </grid> -<grid class="mixed"> +<grid title="Wider last item"> <item>1</item> <item>2</item> <item>3</item> @@ -211,7 +212,7 @@ <item style="width:2ch">5</item> </grid> -<grid class="mixed"> +<grid title="Wider last item in col 2"> <item>1</item> <item>2</item> <item>3</item> @@ -219,7 +220,7 @@ <item style="width:2ch; grid-column:2">5</item> </grid> -<grid class="mixed"> +<grid title="Wider last item spanning col 2-3"> <item>1</item> <item>2</item> <item>3</item> @@ -227,7 +228,7 @@ <item style="width:4ch; grid-column:2/span 2">5</item> </grid> -<grid class="mixed"> +<grid title="Item spanning col 2-3, wider item spanning col 1-3"> <item>1</item> <item>2</item> <item>3</item> @@ -237,7 +238,7 @@ </grid> -<grid class="mixed"> +<grid title="3ch item spanning 2-3, 5ch item spanning 1-3"> <item>1</item> <item>2</item> <item>3</item> @@ -246,7 +247,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="mixed"> +<grid title="Last item spanning 4"> <item>1</item> <item>2</item> <item>3</item> @@ -254,7 +255,7 @@ <item style="grid-column:span 4">5</item> </grid> -<grid class="mixed"> +<grid title="6ch last item spanning 4"> <item>1</item> <item>2</item> <item>3</item> @@ -262,13 +263,12 @@ <item style="width:6ch; grid-column:span 4">5</item> </grid> -<grid class="mixed"> +<grid title="6ch last item spanning 3"> <item>1</item> <item>2</item> <item>3</item> <item>4</item> <item style="width:6ch; grid-column:span 3">5</item> </grid> +</section> -</body> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-003-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-003-ref.html index 61eb2157..886c147 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-003-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-003-ref.html
@@ -3,42 +3,40 @@ Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ --> -<html><head> +<html> <meta charset="utf-8"> <title>Reference: Masonry layout min-content sizing</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> <style> -html,body { - color:black; background-color:white; font:15px/1 Ahem; padding:0; margin:0; -} + +@import "support/masonry-intrinsic-sizing-visual.css"; grid { display: inline-grid; gap: 1px 2px; - grid-template-columns: repeat(4,auto); grid-auto-rows: 1em; border: 1px solid; padding: 0 1px 0 2px; vertical-align: top; width: min-content; } -.fr { +.auto grid { + grid-template-columns: repeat(4,auto); +} +.fr grid { grid-template-columns: 1fr 2fr 1fr 1fr; } -.mixed { +.mixed grid { grid-template-columns: 1fr 2fr min-content max-content; } -item { - background-color: #444; - color: blue; -} item.start { align-self: start; } </style> -</head> + <body> +<section class="auto"> <grid style="grid-template-rows: 1em 2em"> <item style="width:2ch">1</item> <item>2 2</item> @@ -112,10 +110,12 @@ <item class="start">4</item> <item style="width:6ch; grid-column:span 3">5 5</item> </grid> +</section> <!-- ditto with 'fr' sizing --> -<grid class="fr" style="grid: 1em 2em / 2ch 2fr 1fr 1fr"> +<section class="fr"> +<grid style="grid: 1em 2em / 2ch 2fr 1fr 1fr"> <item style="width:2ch" class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -123,7 +123,7 @@ <item>5 5</item> </grid> -<grid class="fr" style="grid: 1em 2em / repeat(4,1ch)"> +<grid style="grid: 1em 2em / repeat(4,1ch)"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -131,7 +131,7 @@ <item style="width:2ch">5 5</item> </grid> -<grid class="fr" style="grid: 2em 2em / 1ch 2ch repeat(2,1ch)"> +<grid style="grid: 2em 2em / 1ch 2ch repeat(2,1ch)"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -139,7 +139,7 @@ <item style="width:2ch; grid-column:2">5 5</item> </grid> -<grid class="fr" style="grid: 2em 1em / repeat(4,1ch)"> +<grid style="grid: 2em 1em / repeat(4,1ch)"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -147,7 +147,7 @@ <item style="width:4ch; grid-column:2/span 2">5 5</item> </grid> -<grid class="fr" style="grid: 2em 2em / repeat(4,1ch)"> +<grid style="grid: 2em 2em / repeat(4,1ch)"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -156,7 +156,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="fr" style="grid: 2em / repeat(4,1ch)"> +<grid style="grid: 2em / repeat(4,1ch)"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -165,7 +165,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="fr" style="grid: 2em / repeat(4,1ch)"> +<grid style="grid: 2em / repeat(4,1ch)"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -173,7 +173,7 @@ <item style="grid-column:span 4">5 5</item> </grid> -<grid class="fr" style="grid: 2em / repeat(4,1ch)"> +<grid style="grid: 2em / repeat(4,1ch)"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -181,17 +181,19 @@ <item style="width:6ch; grid-column:span 4">5 5</item> </grid> -<grid class="fr" style="grid: 2em / repeat(4,1ch)"> +<grid style="grid: 2em / repeat(4,1ch)"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> <item class="start">4</item> <item style="width:6ch; grid-column:span 3">5 5</item> </grid> +</section> <!-- ditto with mixed sizing --> -<grid class="mixed" style="grid: 1em 2em / 2ch repeat(3,1ch)"> +<section class="mixed"> +<grid style="grid: 1em 2em / 2ch repeat(3,1ch)"> <item style="width:2ch" class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -199,7 +201,7 @@ <item>5 5</item> </grid> -<grid class="mixed" style="grid: 1em 2em / repeat(4,1ch)"> +<grid style="grid: 1em 2em / repeat(4,1ch)"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -207,7 +209,7 @@ <item style="width:2ch">5 5</item> </grid> -<grid class="mixed" style="grid: 2em 2em / 1ch 2ch repeat(2,1ch)"> +<grid style="grid: 2em 2em / 1ch 2ch repeat(2,1ch)"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -215,7 +217,7 @@ <item style="width:2ch; grid-column:2">5 5</item> </grid> -<grid class="mixed" style="grid: 2em 1em / repeat(4,1ch)"> +<grid style="grid: 2em 1em / repeat(4,1ch)"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -223,7 +225,7 @@ <item style="width:4ch; grid-column:2/span 2">5 5</item> </grid> -<grid class="mixed" style="grid: 2em 2em / repeat(4,1ch)"> +<grid style="grid: 2em 2em / repeat(4,1ch)"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -232,7 +234,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="mixed" style="grid: 2em / repeat(4,1ch)"> +<grid style="grid: 2em / repeat(4,1ch)"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -241,7 +243,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="mixed" style="grid: 2em / repeat(4,1ch)"> +<grid style="grid: 2em / repeat(4,1ch)"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -249,7 +251,7 @@ <item style="grid-column:span 4">5 5</item> </grid> -<grid class="mixed" style="grid: 2em / repeat(4,1ch)"> +<grid style="grid: 2em / repeat(4,1ch)"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -257,13 +259,12 @@ <item style="width:6ch; grid-column:span 4">5 5</item> </grid> -<grid class="mixed" style="grid: 2em / repeat(4,1ch)"> +<grid style="grid: 2em / repeat(4,1ch)"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> <item class="start">4</item> <item style="width:6ch; grid-column:span 3">5 5</item> </grid> +</section> -</body> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-003.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-003.html index e43bc86c..80bf5d5d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-003.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-003.html
@@ -3,44 +3,41 @@ Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ --> -<html><head> +<html> <meta charset="utf-8"> - <title>CSS Grid Test: Masonry layout min-content sizing</title> + <title>CSS Grid Test: Masonry layout column sizing - min-content</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#track-sizing"> <link rel="match" href="masonry-intrinsic-sizing-003-ref.html"> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> <style> -html,body { - color:black; background-color:white; font:15px/1 Ahem; padding:0; margin:0; -} + +@import "support/masonry-intrinsic-sizing-visual.css"; grid { display: inline-grid; gap: 1px 2px; - grid-template-columns: repeat(4,auto); grid-template-rows: masonry; border: 1px solid; padding: 0 1px 0 2px; vertical-align: top; width: min-content; } -.fr { +.auto grid { + grid-template-columns: repeat(4,auto); +} +.fr grid { grid-template-columns: 1fr 2fr 1fr 1fr; } -.mixed { +.mixed grid { grid-template-columns: 1fr 2fr min-content max-content; } - -item { - background-color: #444; - color: blue; -} </style> -</head> + <body> -<grid> +<section class="auto"> +<grid title="Wider first item 2ch"> <item style="width:2ch">1</item> <item>2 2</item> <item>3 3</item> @@ -48,7 +45,7 @@ <item>5 5</item> </grid> -<grid> +<grid title="Wrapped last item 2ch"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -56,7 +53,7 @@ <item style="width:2ch">5 5</item> </grid> -<grid> +<grid title="Wrapped last item 2ch col 2"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -64,7 +61,7 @@ <item style="width:2ch; grid-column:2">5 5</item> </grid> -<grid> +<grid title="Last item 4ch col 2-3"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -72,7 +69,7 @@ <item style="width:4ch; grid-column:2/span 2">5 5</item> </grid> -<grid> +<grid title="Item col 2-3 + Item 5ch col 1-3"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -81,7 +78,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid> +<grid title="Item 3ch col 2-3 + Item 5ch col 1-3"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -90,7 +87,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid> +<grid title="Last item span 4"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -98,7 +95,7 @@ <item style="grid-column:span 4">5 5</item> </grid> -<grid> +<grid title="Last item 6ch span 4"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -106,17 +103,19 @@ <item style="width:6ch; grid-column:span 4">5 5</item> </grid> -<grid> +<grid title="Last item 6ch span 3"> <item>1</item> <item>2 2</item> <item>3 3</item> <item>4</item> <item style="width:6ch; grid-column:span 3">5 5</item> </grid> +</section> <!-- ditto with 'fr' sizing --> -<grid class="fr"> +<section class="fr"> +<grid title="Wider first item 2ch"> <item style="width:2ch">1</item> <item>2 2</item> <item>3 3</item> @@ -124,7 +123,7 @@ <item>5 5</item> </grid> -<grid class="fr"> +<grid title="Wrapped last item 2ch"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -132,7 +131,7 @@ <item style="width:2ch">5 5</item> </grid> -<grid class="fr"> +<grid title="Wrapped last item 2ch col 2"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -140,7 +139,7 @@ <item style="width:2ch; grid-column:2">5 5</item> </grid> -<grid class="fr"> +<grid title="Last item 4ch col 2-3"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -148,7 +147,7 @@ <item style="width:4ch; grid-column:2/span 2">5 5</item> </grid> -<grid class="fr"> +<grid title="Item col 2-3 + Item 5ch col 1-3"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -157,7 +156,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="fr"> +<grid title="Item 3ch col 2-3 + Item 5ch col 1-3"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -166,7 +165,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="fr"> +<grid title="Last item span 4"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -174,7 +173,7 @@ <item style="grid-column:span 4">5 5</item> </grid> -<grid class="fr"> +<grid title="Last item 6ch span 4"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -182,17 +181,19 @@ <item style="width:6ch; grid-column:span 4">5 5</item> </grid> -<grid class="fr"> +<grid title="Last item 6ch span 3"> <item>1</item> <item>2 2</item> <item>3 3</item> <item>4</item> <item style="width:6ch; grid-column:span 3">5 5</item> </grid> +</section> <!-- ditto with mixed sizing --> -<grid class="mixed"> +<section class="mixed"> +<grid title="Wider first item 2ch"> <item style="width:2ch">1</item> <item>2 2</item> <item>3 3</item> @@ -200,7 +201,7 @@ <item>5 5</item> </grid> -<grid class="mixed"> +<grid title="Wrapped last item 2ch"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -208,7 +209,7 @@ <item style="width:2ch">5 5</item> </grid> -<grid class="mixed"> +<grid title="Wrapped last item 2ch col 2"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -216,7 +217,7 @@ <item style="width:2ch; grid-column:2">5 5</item> </grid> -<grid class="mixed"> +<grid title="Last item 4ch col 2-3"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -224,7 +225,7 @@ <item style="width:4ch; grid-column:2/span 2">5 5</item> </grid> -<grid class="mixed"> +<grid title="Item col 2-3 + Item 5ch col 1-3"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -233,7 +234,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="mixed"> +<grid title="Item 3ch col 2-3 + Item 5ch col 1-3"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -242,7 +243,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="mixed"> +<grid title="Last item span 4"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -250,7 +251,7 @@ <item style="grid-column:span 4">5 5</item> </grid> -<grid class="mixed"> +<grid title="Last item 6ch span 4"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -258,13 +259,12 @@ <item style="width:6ch; grid-column:span 4">5 5</item> </grid> -<grid class="mixed"> +<grid title="Last item 6ch span 3"> <item>1</item> <item>2 2</item> <item>3 3</item> <item>4</item> <item style="width:6ch; grid-column:span 3">5 5</item> </grid> +</section> -</body> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-004-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-004-ref.html index 6a5d81f..166a467 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-004-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-004-ref.html
@@ -3,20 +3,18 @@ Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ --> -<html><head> +<html> <meta charset="utf-8"> <title>Reference: Masonry layout max-content sizing</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> <style> -html,body { - color:black; background-color:white; font:15px/1 Ahem; padding:0; margin:0; -} + +@import "support/masonry-intrinsic-sizing-visual.css"; grid { display: inline-grid; gap: 1px 2px; - grid-template-columns: 1ch 3ch 3ch 1ch; grid-auto-rows: 1em; border: 1px solid; padding: 0 1px 0 2px; @@ -24,22 +22,21 @@ align-items: start; width: max-content; } -.fr { +.auto grid { + grid-template-columns: 1ch 3ch 3ch 1ch; +} +.fr grid { grid-template-columns: 1fr 2fr 1fr 1fr; } -.mixed { +.mixed grid { grid-template-columns: 1fr 2fr min-content max-content; } - -item { - background-color: #444; - color: blue; -} item.start { align-self: start; } </style> -</head> + <body> +<section class="auto"> <grid style="grid: 1em 2em / 2ch 3ch 3ch 1ch"> <item style="width:2ch">1</item> <item>2 2</item> @@ -113,10 +110,12 @@ <item class="start">4</item> <item style="width:6ch; grid-column:span 3">5 5</item> </grid> +</section> <!-- ditto with 'fr' sizing --> -<grid class="fr"> +<section class="fr"> +<grid> <item style="width:2ch" class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -124,7 +123,7 @@ <item>5 5</item> </grid> -<grid class="fr" style="grid: 1em 2em / 3ch 6ch 3ch 3ch"> +<grid style="grid: 1em 2em / 3ch 6ch 3ch 3ch"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -132,7 +131,7 @@ <item style="width:2ch">5 5</item> </grid> -<grid class="fr" style="grid: 1em 2em / 3ch 6ch 3ch 3ch"> +<grid style="grid: 1em 2em / 3ch 6ch 3ch 3ch"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -140,7 +139,7 @@ <item style="width:2ch; grid-column:2">5 5</item> </grid> -<grid class="fr"> +<grid> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -148,7 +147,7 @@ <item style="width:4ch; grid-column:2/span 2">5 5</item> </grid> -<grid class="fr"> +<grid> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -157,7 +156,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="fr"> +<grid> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -166,7 +165,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="fr"> +<grid> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -174,7 +173,7 @@ <item style="grid-column:span 4">5 5</item> </grid> -<grid class="fr"> +<grid> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -182,17 +181,19 @@ <item style="width:6ch; grid-column:span 4">5 5</item> </grid> -<grid class="fr"> +<grid> <item class="start">1</item> <item>2 2</item> <item>3 3</item> <item class="start">4</item> <item style="width:6ch; grid-column:span 3">5 5</item> </grid> +</section> <!-- ditto with mixed sizing --> -<grid class="mixed" style="grid: 1em 2em / 2ch 4ch 1ch 1ch"> +<section class="mixed"> +<grid style="grid: 1em 2em / 2ch 4ch 1ch 1ch"> <item style="width:2ch" class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -200,7 +201,7 @@ <item>5 5</item> </grid> -<grid class="mixed" style="grid: 1em 2em / calc(3ch/2) 3ch 1ch 1ch"> +<grid style="grid: 1em 2em / calc(3ch/2) 3ch 1ch 1ch"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -208,7 +209,7 @@ <item style="width:2ch">5 5</item> </grid> -<grid class="mixed" style="grid: 1em 2em / calc(3ch/2) 3ch 1ch 1ch"> +<grid style="grid: 1em 2em / calc(3ch/2) 3ch 1ch 1ch"> <item class="start">1</item> <item>2 2</item> <item>3 3</item> @@ -216,7 +217,7 @@ <item style="width:2ch; grid-column:2">5 5</item> </grid> -<grid class="mixed" style="grid: 2em 1em / calc(3ch/2) 3ch 1ch 1ch"> +<grid style="grid: 2em 1em / calc(3ch/2) 3ch 1ch 1ch"> <item class="start">1</item> <item class="start">2 2</item> <item class="start">3 3</item> @@ -224,7 +225,7 @@ <item style="width:4ch; grid-column:2/span 2">5 5</item> </grid> -<grid class="mixed" style="grid: 2em 1em 1em / calc(3ch/2) 3ch 1ch 1ch"> +<grid style="grid: 2em 1em 1em / calc(3ch/2) 3ch 1ch 1ch"> <item class="start">1</item> <item class="start">2 2</item> <item class="start">3 3</item> @@ -233,7 +234,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="mixed" style="grid: 2em 1em / calc(3ch/2) 3ch 1ch 1ch"> +<grid style="grid: 2em 1em / calc(3ch/2) 3ch 1ch 1ch"> <item class="start">1</item> <item class="start">2 2</item> <item class="start">3 3</item> @@ -242,7 +243,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="mixed" style="grid: 2em 1em / calc(3ch/2) 3ch 1ch 1ch"> +<grid style="grid: 2em 1em / calc(3ch/2) 3ch 1ch 1ch"> <item class="start">1</item> <item class="start">2 2</item> <item class="start">3 3</item> @@ -250,7 +251,7 @@ <item style="grid-column:span 4">5 5</item> </grid> -<grid class="mixed" style="grid: 2em 1em / calc(3ch/2) 3ch 1ch 1ch"> +<grid style="grid: 2em 1em / calc(3ch/2) 3ch 1ch 1ch"> <item class="start">1</item> <item class="start">2 2</item> <item class="start">3 3</item> @@ -258,13 +259,12 @@ <item style="width:6ch; grid-column:span 4">5 5</item> </grid> -<grid class="mixed" style="grid: 2em 1em / calc(3ch/2) 3ch 1ch 1ch"> +<grid style="grid: 2em 1em / calc(3ch/2) 3ch 1ch 1ch"> <item class="start">1</item> <item class="start">2 2</item> <item class="start">3 3</item> <item class="start">4</item> <item style="width:6ch; grid-column:span 3">5 5</item> </grid> +</section> -</body> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-004.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-004.html index 5365208..70a52f37 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-004.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-004.html
@@ -3,44 +3,41 @@ Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ --> -<html><head> +<html> <meta charset="utf-8"> - <title>CSS Grid Test: Masonry layout max-content sizing</title> + <title>CSS Grid Test: Masonry layout column sizing - max-content</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3"> <link rel="match" href="masonry-intrinsic-sizing-004-ref.html"> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> <style> -html,body { - color:black; background-color:white; font:15px/1 Ahem; padding:0; margin:0; -} + +@import "support/masonry-intrinsic-sizing-visual.css"; grid { display: inline-grid; gap: 1px 2px; - grid-template-columns: repeat(4,auto); grid-template-rows: masonry; border: 1px solid; padding: 0 1px 0 2px; vertical-align: top; width: max-content; } -.fr { +.auto grid { + grid-template-columns: repeat(4,auto); +} +.fr grid { grid-template-columns: 1fr 2fr 1fr 1fr; } -.mixed { +.mixed grid { grid-template-columns: 1fr 2fr min-content max-content; } - -item { - background-color: #444; - color: blue; -} </style> -</head> + <body> -<grid> +<section class="auto"> +<grid title="Wider first item 2ch"> <item style="width:2ch">1</item> <item>2 2</item> <item>3 3</item> @@ -48,7 +45,7 @@ <item>5 5</item> </grid> -<grid> +<grid title="Wrapped last item 2ch"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -56,7 +53,7 @@ <item style="width:2ch">5 5</item> </grid> -<grid> +<grid title="Wrapped last item 2ch col 2"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -64,7 +61,7 @@ <item style="width:2ch; grid-column:2">5 5</item> </grid> -<grid> +<grid title="Last item 4ch col 2-3"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -72,7 +69,7 @@ <item style="width:4ch; grid-column:2/span 2">5 5</item> </grid> -<grid> +<grid title="Item col 2-3 + Item 5ch col 1-3"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -81,7 +78,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid> +<grid title="Item 3ch col 2-3 + Item 5ch col 1-3"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -90,7 +87,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid> +<grid title="Last item span 4"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -98,7 +95,7 @@ <item style="grid-column:span 4">5 5</item> </grid> -<grid> +<grid title="Last item 6ch span 4"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -106,17 +103,19 @@ <item style="width:6ch; grid-column:span 4">5 5</item> </grid> -<grid> +<grid title="Last item 6ch span 3"> <item>1</item> <item>2 2</item> <item>3 3</item> <item>4</item> <item style="width:6ch; grid-column:span 3">5 5</item> </grid> +</section> <!-- ditto with 'fr' sizing --> -<grid class="fr"> +<section class="fr"> +<grid title="Wider first item 2ch"> <item style="width:2ch">1</item> <item>2 2</item> <item>3 3</item> @@ -124,7 +123,7 @@ <item>5 5</item> </grid> -<grid class="fr"> +<grid title="Wrapped last item 2ch"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -132,7 +131,7 @@ <item style="width:2ch">5 5</item> </grid> -<grid class="fr"> +<grid title="Wrapped last item 2ch col 2"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -140,7 +139,7 @@ <item style="width:2ch; grid-column:2">5 5</item> </grid> -<grid class="fr"> +<grid title="Last item 4ch col 2-3"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -148,7 +147,7 @@ <item style="width:4ch; grid-column:2/span 2">5 5</item> </grid> -<grid class="fr"> +<grid title="Item col 2-3 + Item 5ch col 1-3"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -157,7 +156,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="fr"> +<grid title="Item 3ch col 2-3 + Item 5ch col 1-3"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -166,7 +165,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="fr"> +<grid title="Last item span 4"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -174,7 +173,7 @@ <item style="grid-column:span 4">5 5</item> </grid> -<grid class="fr"> +<grid title="Last item 6ch span 4"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -182,17 +181,19 @@ <item style="width:6ch; grid-column:span 4">5 5</item> </grid> -<grid class="fr"> +<grid title="Last item 6ch span 3"> <item>1</item> <item>2 2</item> <item>3 3</item> <item>4</item> <item style="width:6ch; grid-column:span 3">5 5</item> </grid> +</section> <!-- ditto with mixed sizing --> -<grid class="mixed"> +<section class="mixed"> +<grid title="Wider first item 2ch"> <item style="width:2ch">1</item> <item>2 2</item> <item>3 3</item> @@ -200,7 +201,7 @@ <item>5 5</item> </grid> -<grid class="mixed"> +<grid title="Wrapped last item 2ch"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -208,7 +209,7 @@ <item style="width:2ch">5 5</item> </grid> -<grid class="mixed"> +<grid title="Wrapped last item 2ch col 2"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -216,7 +217,7 @@ <item style="width:2ch; grid-column:2">5 5</item> </grid> -<grid class="mixed"> +<grid title="Last item 4ch col 2-3"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -224,7 +225,7 @@ <item style="width:4ch; grid-column:2/span 2">5 5</item> </grid> -<grid class="mixed"> +<grid title="Item col 2-3 + Item 5ch col 1-3"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -233,7 +234,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="mixed"> +<grid title="Item 3ch col 2-3 + Item 5ch col 1-3"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -242,7 +243,7 @@ <item style="width:5ch; grid-column:1/span 3">6</item> </grid> -<grid class="mixed"> +<grid title="Last item span 4"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -250,7 +251,7 @@ <item style="grid-column:span 4">5 5</item> </grid> -<grid class="mixed"> +<grid title="Last item 6ch span 4"> <item>1</item> <item>2 2</item> <item>3 3</item> @@ -258,13 +259,12 @@ <item style="width:6ch; grid-column:span 4">5 5</item> </grid> -<grid class="mixed"> +<grid title="Last item 6ch span 3"> <item>1</item> <item>2 2</item> <item>3 3</item> <item>4</item> <item style="width:6ch; grid-column:span 3">5 5</item> </grid> +</section> -</body> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-005-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-005-ref.html index e564fb1b..4822580 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-005-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-005-ref.html
@@ -3,15 +3,14 @@ Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ --> -<html><head> +<html> <meta charset="utf-8"> <title>Reference: Masonry layout intrinsic sizing</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> <style> -html,body { - color:black; background-color:white; font:15px/1 Ahem; padding:0; margin:0; -} + +@import "support/masonry-intrinsic-sizing-visual.css"; grid { display: inline-grid; @@ -21,14 +20,11 @@ padding: 0 1px 0 2px; vertical-align: top; } - item { - background-color: #444; - color: blue; writing-mode: vertical-lr; } </style> -</head> + <body> <grid style="grid-template-rows: 3ch repeat(3,1ch)"> @@ -79,5 +75,3 @@ <item>9 9</item> </grid> -</body> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-005.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-005.html index cf9b680..83afd5ba 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-005.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-005.html
@@ -3,17 +3,16 @@ Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ --> -<html><head> +<html> <meta charset="utf-8"> - <title>CSS Grid Test: Masonry layout intrinsic sizing</title> + <title>CSS Grid Test: Masonry layout row sizing (vertical writing mode)</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#track-sizing"> <link rel="match" href="masonry-intrinsic-sizing-005-ref.html"> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> <style> -html,body { - color:black; background-color:white; font:15px/1 Ahem; padding:0; margin:0; -} + +@import "support/masonry-intrinsic-sizing-visual.css"; grid { display: inline-grid; @@ -26,15 +25,13 @@ } item { - background-color: #444; - color: blue; writing-mode: vertical-lr; } </style> -</head> + <body> -<grid> +<grid title="First item 3ch"> <item style="height:3ch">1</item> <item>2</item> <item>3</item> @@ -46,7 +43,7 @@ <item>9 9</item> </grid> -<grid> +<grid title="Fifth item 3ch"> <item>1</item> <item>2</item> <item>3</item> @@ -58,7 +55,7 @@ <item>9 9</item> </grid> -<grid> +<grid title="Fifth item 3ch row 1"> <item>1</item> <item>2</item> <item>3</item> @@ -70,7 +67,7 @@ <item>9 9</item> </grid> -<grid> +<grid title="Fifth item 3ch col 1 (ignored)"> <item>1</item> <item>2</item> <item>3</item> @@ -82,5 +79,3 @@ <item>9 9</item> </grid> -</body> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-006-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-006-ref.html index e1cb015..a616fad 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-006-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-006-ref.html
@@ -3,15 +3,14 @@ Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ --> -<html><head> +<html> <meta charset="utf-8"> <title>Reference: Masonry layout intrinsic sizing</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> <style> -html,body { - color:black; background-color:white; font:15px/1 Ahem; padding:0; margin:0; -} + +@import "support/masonry-intrinsic-sizing-visual.css"; grid { display: inline-grid; @@ -23,13 +22,8 @@ padding: 0 1px 0 2px; vertical-align: top; } - -item { - background-color: #444; - color: blue; -} </style> -</head> + <body> <grid> @@ -56,5 +50,3 @@ <item style="grid-row:2">5 5</item> </grid> -</body> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-006.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-006.html index 49fd53bb..fccc116 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-006.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/masonry-intrinsic-sizing-006.html
@@ -3,17 +3,16 @@ Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ --> -<html><head> +<html> <meta charset="utf-8"> - <title>CSS Grid Test: Masonry layout intrinsic sizing</title> + <title>CSS Grid Test: Masonry layout row sizing - height constraint</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#track-sizing"> <link rel="match" href="masonry-intrinsic-sizing-006-ref.html"> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> <style> -html,body { - color:black; background-color:white; font:15px/1 Ahem; padding:0; margin:0; -} + +@import "support/masonry-intrinsic-sizing-visual.css"; grid { display: inline-grid; @@ -24,16 +23,12 @@ padding: 0 1px 0 2px; vertical-align: top; } - -item { - background-color: #444; - color: blue; -} </style> -</head> + <body> -<grid style="max-height:5em; grid-template-rows: repeat(auto-fill,1em);"> +<grid title="max-height 5em" + style="max-height:5em; grid-template-rows: repeat(auto-fill,1em);"> <item>1 1</item> <item>2</item> <item>3</item> @@ -41,7 +36,8 @@ <item>5 5</item> </grid> -<grid style="min-height:4em; grid-template-rows: repeat(auto-fill,1em);"> +<grid title="min-height 4em" + style="min-height:4em; grid-template-rows: repeat(auto-fill,1em);"> <item>1 1</item> <item>2</item> <item>3</item> @@ -49,7 +45,8 @@ <item>5 5</item> </grid> -<grid style="height:5em; grid-template-rows: repeat(auto-fill,1em);"> +<grid title="height 5em" + style="height:5em; grid-template-rows: repeat(auto-fill,1em);"> <item>1 1</item> <item>2</item> <item>3</item> @@ -57,5 +54,3 @@ <item>5 5</item> </grid> -</body> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/support/masonry-intrinsic-sizing-visual.css b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/support/masonry-intrinsic-sizing-visual.css new file mode 100644 index 0000000..dbb6303 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/intrinsic-sizing/support/masonry-intrinsic-sizing-visual.css
@@ -0,0 +1,47 @@ +/* Basic Testing Setup */ +html,body { + color: black; background: white; font: 15px/1 Ahem; + padding: 1em 0; margin: 0; + height: calc(600px - 2em); border-bottom: 1px solid orange; /* Do Not Cross */ +} + + +/* Visualization */ +grid { + margin: 0.5em; +} +item { + background-color: gray; + color: blue; +} + +/* Debugging Aid */ +section { + border-top: 1px solid gray; + counter-reset: grid; +} + +grid { + margin-inline-start: 1em; + counter-increment: grid; +} +grid::before { + position: absolute; + margin: 0 -1.1em; + font: smaller sans-serif; + content: counter(grid); + color: navy; +} + +grid:hover { + outline: navy solid; +} +grid:hover item[style] { + color: navy; +} +grid:hover::after { + content: attr(title); + position: absolute; + inset: 0.1em 0.5rem; + font: bold smaller sans-serif; +}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-001.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-001.html index 649e1ed..2438df8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-001.html
@@ -7,7 +7,7 @@ <meta charset="utf-8"> <title>CSS Grid Test: Masonry layout using `grid-column/row`</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3"> <link rel="match" href="masonry-item-placement-001-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-002.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-002.html index 7d321bf7..8833cdf 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-002.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-002.html
@@ -7,7 +7,7 @@ <meta charset="utf-8"> <title>CSS Grid Test: Masonry layout using `grid-column/row`</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3"> <link rel="match" href="masonry-item-placement-002-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-003.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-003.html index 8a183cf..bde2fa0 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-003.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-003.html
@@ -7,7 +7,7 @@ <meta charset="utf-8"> <title>CSS Grid Test: Masonry layout using `grid-column/row` and `dense`</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3"> <link rel="match" href="masonry-item-placement-003-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-004.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-004.html index 4d1a454a..52867cd4 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-004.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-004.html
@@ -7,7 +7,7 @@ <meta charset="utf-8"> <title>CSS Grid Test: Masonry layout using `grid-column/row`</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3"> <link rel="match" href="masonry-item-placement-004-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-005.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-005.html index ddfbc9e5..7d4993f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-005.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-005.html
@@ -7,7 +7,7 @@ <meta charset="utf-8"> <title>CSS Grid Test: Masonry layout using `grid-column/row`</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3"> <link rel="match" href="masonry-item-placement-005-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-006.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-006.html index 0082d72d..467e313 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-006.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-006.html
@@ -7,7 +7,7 @@ <meta charset="utf-8"> <title>CSS Grid Test: Masonry item placement</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3"> <link rel="match" href="masonry-item-placement-006-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-007.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-007.html index 67a02560..4c8053b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-007.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-007.html
@@ -7,7 +7,7 @@ <meta charset="utf-8"> <title>CSS Grid Test: Masonry item placement (RTL)</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3"> <link rel="match" href="masonry-item-placement-007-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-008-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-008-ref.html index e14ca31..f3503bf 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-008-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-008-ref.html
@@ -3,7 +3,7 @@ <meta charset="utf-8"> <title>CSS Grid Test: Masonry item placement w/ Images</title> <link rel="author" title="Brandon Stewart" href="mailto:brandonstewart@apple.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3"> </head> <body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-008.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-008.html index c68a9787..bdf651d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-008.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/item-placement/masonry-item-placement-008.html
@@ -3,7 +3,7 @@ <meta charset="utf-8"> <title>CSS Grid Test: Masonry item placement w/ Images</title> <link rel="author" title="Brandon Stewart" href="mailto:brandonstewart@apple.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3"> <link rel="match" href="masonry-item-placement-008-ref.html"> </head>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/masonry-columns-item-containing-block-is-grid-content-width.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/masonry-columns-item-containing-block-is-grid-content-width.html index e48b650..b5eb7f4 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/masonry-columns-item-containing-block-is-grid-content-width.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/masonry-columns-item-containing-block-is-grid-content-width.html
@@ -4,7 +4,7 @@ <link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com"> <link rel="help" href="https://drafts.csswg.org/css-grid-3/#containing-block"> <link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html"> -<meta name="assert" content="Svg should use grid's content logical width for its containing block size and get sized to 100px x 100px"> +<meta name="assert" content="Test passes if SVG uses grid's content logical width for its containing block size and get sized to 100px x 100px"> <style> grid { display: grid;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/masonry-grid-template-columns-computed-withcontent.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/masonry-grid-template-columns-computed-withcontent.html index a799955..0ee2ee7 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/masonry-grid-template-columns-computed-withcontent.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/masonry-grid-template-columns-computed-withcontent.html
@@ -3,7 +3,7 @@ <head> <meta charset="utf-8"> <title>CSS Masonry Test: getComputedStyle().gridTemplateColumns</title> - <link rel="help" href="https://drafts.csswg.org/css-grid-1/#propdef-grid-template-columns"> + <link rel="help" href="https://drafts.csswg.org/css-grid-1/#grid-template-masonry"> <meta name="assert" content="grid-template-columns computed value is the keyword none or a computed track list."> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/masonry-not-inhibited-001.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/masonry-not-inhibited-001.html index 54499d3d..1c912fe 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/masonry-not-inhibited-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/masonry-not-inhibited-001.html
@@ -2,7 +2,7 @@ <meta charset="utf-8"> <title>CSS Grid Test: Masonry layout shouldn't be inhibited simply due to being an independent formatting context (unlike subgrid)</title> <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> -<link rel="help" href="https://drafts.csswg.org/css-grid-3/"> +<link rel="help" href="https://drafts.csswg.org/css-grid-3/#grid-template-masonry"> <link rel="match" href="masonry-not-inhibited-001-ref.html"> <style> grid {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-001.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-001.html index d01f52ea..37b3d01 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-001.html
@@ -7,7 +7,8 @@ <meta charset="utf-8"> <title>CSS Grid Test: Masonry layout using `order`</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#masonry-layout-algorithm"> <link rel="match" href="masonry-order-001-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-002.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-002.html index abad3d4..5ebdec27 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-002.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/order/masonry-order-002.html
@@ -7,7 +7,8 @@ <meta charset="utf-8"> <title>CSS Grid Test: Masonry layout using `order` and `masonry-auto-flow: next`</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#masonry-layout-algorithm"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#masonry-auto-flow"> <link rel="match" href="masonry-order-002-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/parsing/masonry-parsing.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/parsing/masonry-parsing.html index e324509..2204c06 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/parsing/masonry-parsing.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/parsing/masonry-parsing.html
@@ -3,7 +3,8 @@ <head> <meta charset="utf-8"> <title>CSS Masonry Test: parsing properties and shortands</title> -<link rel="help" href="https://drafts.csswg.org/css-grid-2/#propdef-grid-template-columns"> +<link rel="help" href="https://drafts.csswg.org/css-grid-3/#grid-template-masonry"> +<link rel="help" href="https://drafts.csswg.org/css-grid-3/#masonry-auto-flow"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script src="/css/support/parsing-testcommon.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/subgrid/masonry-subgrid-001.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/subgrid/masonry-subgrid-001.html index de07dfb..c71ba68612 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/subgrid/masonry-subgrid-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/subgrid/masonry-subgrid-001.html
@@ -7,7 +7,7 @@ <meta charset="utf-8"> <title>CSS Grid Test: Masonry layout with a subgrid</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drafts.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#subgrids"> <link rel="match" href="masonry-subgrid-001-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/subgrid/masonry-subgrid-002.html b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/subgrid/masonry-subgrid-002.html index 466e95eb0..167f2d4 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/subgrid/masonry-subgrid-002.html +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/masonry/tentative/subgrid/masonry-subgrid-002.html
@@ -7,7 +7,7 @@ <meta charset="utf-8"> <title>CSS Grid Test: Masonry layout with a subgrid</title> <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> - <link rel="help" href="https://drats.csswg.org/css-grid-2"> + <link rel="help" href="https://drafts.csswg.org/css-grid-3/#subgrids"> <link rel="match" href="masonry-subgrid-002-ref.html"> <style> html,body {
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/WEB_FEATURES.yml b/third_party/blink/web_tests/external/wpt/css/cssom-view/WEB_FEATURES.yml index a545dba..d5352fb 100644 --- a/third_party/blink/web_tests/external/wpt/css/cssom-view/WEB_FEATURES.yml +++ b/third_party/blink/web_tests/external/wpt/css/cssom-view/WEB_FEATURES.yml
@@ -1,4 +1,7 @@ features: +- name: check-visibility + files: + - checkVisibility.html - name: scroll-into-view files: - scrollIntoView-*
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/WEB_FEATURES.yml b/third_party/blink/web_tests/external/wpt/css/selectors/WEB_FEATURES.yml index 47cf05a..4b292776 100644 --- a/third_party/blink/web_tests/external/wpt/css/selectors/WEB_FEATURES.yml +++ b/third_party/blink/web_tests/external/wpt/css/selectors/WEB_FEATURES.yml
@@ -5,3 +5,7 @@ - name: has files: - has-* +- name: user-pseudos + files: + - user-invalid.html + - user-valid.html
diff --git a/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/WEB_FEATURES.yml b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/WEB_FEATURES.yml index 4eaa2f393..5e6a6d0 100644 --- a/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/WEB_FEATURES.yml +++ b/third_party/blink/web_tests/external/wpt/css/selectors/invalidation/WEB_FEATURES.yml
@@ -4,3 +4,6 @@ - has-* - "*-in-has.*" - "*-in-has-*" +- name: user-pseudos + files: + - user-valid-user-invalid.html
diff --git a/third_party/blink/web_tests/external/wpt/dom/events/scrolling/WEB_FEATURES.yml b/third_party/blink/web_tests/external/wpt/dom/events/scrolling/WEB_FEATURES.yml new file mode 100644 index 0000000..e4fba841 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/dom/events/scrolling/WEB_FEATURES.yml
@@ -0,0 +1,4 @@ +features: +- name: scrollend + files: + - scrollend-*
diff --git a/third_party/blink/web_tests/external/wpt/dom/ranges/Range-isPointInRange-shadowdom.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/dom/ranges/Range-isPointInRange-shadowdom.tentative-expected.txt new file mode 100644 index 0000000..9a95fba --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/dom/ranges/Range-isPointInRange-shadowdom.tentative-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +[FAIL] isPointInRange() test for collapsed selection + assert_implements: GetComposedRanges is not supported undefined +[FAIL] isPointInRange() test for non-collapsed selection + assert_implements: GetComposedRanges is not supported undefined +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/dom/ranges/Range-isPointInRange-shadowdom.html b/third_party/blink/web_tests/external/wpt/dom/ranges/Range-isPointInRange-shadowdom.tentative.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/dom/ranges/Range-isPointInRange-shadowdom.html rename to third_party/blink/web_tests/external/wpt/dom/ranges/Range-isPointInRange-shadowdom.tentative.html
diff --git a/third_party/blink/web_tests/external/wpt/editing/edit-context/WEB_FEATURES.yml b/third_party/blink/web_tests/external/wpt/editing/edit-context/WEB_FEATURES.yml new file mode 100644 index 0000000..28428006 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/editing/edit-context/WEB_FEATURES.yml
@@ -0,0 +1,3 @@ +features: +- name: edit-context + files: "**"
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_navigation_download_allow_downloads.sub.tentative.https.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_navigation_download_allow_downloads.sub.tentative.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_navigation_download_allow_downloads.sub.tentative.https.html rename to third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_navigation_download_allow_downloads.sub.tentative.html
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_window_open_download_allow_downloads.tentative.https.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_window_open_download_allow_downloads.tentative.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_window_open_download_allow_downloads.tentative.https.html rename to third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_window_open_download_allow_downloads.tentative.html
diff --git a/third_party/blink/web_tests/external/wpt/scroll-to-text-fragment/WEB_FEATURES.yml b/third_party/blink/web_tests/external/wpt/scroll-to-text-fragment/WEB_FEATURES.yml new file mode 100644 index 0000000..0b260aa --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/scroll-to-text-fragment/WEB_FEATURES.yml
@@ -0,0 +1,3 @@ +features: +- name: text-fragments + files: "**"
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-timing-sizes.https.html b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-timing-sizes.https.html index b3b1b5f..a960cd57 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-timing-sizes.https.html +++ b/third_party/blink/web_tests/external/wpt/service-workers/service-worker/navigation-timing-sizes.https.html
@@ -71,10 +71,10 @@ assert_greater_than(main_page_resource_timing.decodedBodySize, 0, 'Corresponding resource timing emitted on parent page should have decodedBodySize larger than 0.'); - assert_greater_than(main_page_resource_timing.encodedBodySize, navigationEntry.decodedBodySize, + assert_equals(main_page_resource_timing.encodedBodySize, navigationEntry.decodedBodySize, 'Corresponding resource timing emitted on parent page should have equal decodedBodySize and \ encodedBodySize.'); }, 'Body sizes in a regular pass-through with gzip'); </script> -</body> \ No newline at end of file +</body>
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/WEB_FEATURES.yml b/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/WEB_FEATURES.yml new file mode 100644 index 0000000..4e31ed4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/shadow-dom/declarative/WEB_FEATURES.yml
@@ -0,0 +1,3 @@ +features: +- name: declarative-shadow-dom + files: "**"
diff --git a/third_party/blink/web_tests/external/wpt/speech-api/WEB_FEATURES.yml b/third_party/blink/web_tests/external/wpt/speech-api/WEB_FEATURES.yml new file mode 100644 index 0000000..7a24460 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/speech-api/WEB_FEATURES.yml
@@ -0,0 +1,7 @@ +features: +- name: speech-recognition + files: + - SpeechRecognition* +- name: speech-synthesis + files: + - SpeechSynthesis*
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-audio-jitterBufferTarget-stats.https-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-audio-jitterBufferTarget-stats.https-expected.txt new file mode 100644 index 0000000..1bb80b1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-audio-jitterBufferTarget-stats.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +[FAIL] measure raising and lowering audio jitterBufferTarget + promise_test: Unhandled rejection with value: object "ReferenceError: applyJitterBufferTarget is not defined" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/webrtc-extensions/RTCRtpReceiver-audio-jitterBufferTarget-stats.https.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-audio-jitterBufferTarget-stats.https.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/webrtc-extensions/RTCRtpReceiver-audio-jitterBufferTarget-stats.https.html rename to third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-audio-jitterBufferTarget-stats.https.html
diff --git a/third_party/blink/web_tests/external/wpt/webrtc-extensions/RTCRtpReceiver-jitterBufferTarget-stats-helper.js b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-jitterBufferTarget-stats-helper.js similarity index 100% rename from third_party/blink/web_tests/external/wpt/webrtc-extensions/RTCRtpReceiver-jitterBufferTarget-stats-helper.js rename to third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-jitterBufferTarget-stats-helper.js
diff --git a/third_party/blink/web_tests/external/wpt/webrtc-extensions/RTCRtpReceiver-jitterBufferTarget.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-jitterBufferTarget.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/webrtc-extensions/RTCRtpReceiver-jitterBufferTarget.html rename to third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-jitterBufferTarget.html
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-video-jitterBufferTarget-stats-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-video-jitterBufferTarget-stats-expected.txt new file mode 100644 index 0000000..55038bf --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-video-jitterBufferTarget-stats-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +[FAIL] measure raising and lowering video jitterBufferTarget + promise_test: Unhandled rejection with value: object "ReferenceError: applyJitterBufferTarget is not defined" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/webrtc-extensions/RTCRtpReceiver-video-jitterBufferTarget-stats.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-video-jitterBufferTarget-stats.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/webrtc-extensions/RTCRtpReceiver-video-jitterBufferTarget-stats.html rename to third_party/blink/web_tests/external/wpt/webrtc/RTCRtpReceiver-video-jitterBufferTarget-stats.html
diff --git a/third_party/blink/web_tests/http/tests/devtools/forced-layout-in-microtask-expected.txt b/third_party/blink/web_tests/http/tests/devtools/forced-layout-in-microtask-expected.txt deleted file mode 100644 index 1456e59d..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/forced-layout-in-microtask-expected.txt +++ /dev/null
@@ -1,41 +0,0 @@ -Tests that Layout record has correct locations of layout being invalidated and forced. - -Layout Properties: -{ - data : { - beginData : { - dirtyObjects : 4 - frame : <string> - partialLayout : false - stackTrace : <object> - totalObjects : 4 - } - endData : { - layoutRoots : [ - { - depth : 1 - nodeId : <number> - quads : [ - [ - 0 - 0 - 800 - 0 - 800 - 600 - 0 - 600 - ] - ] - } - ] - } - } - endTime : <number> - frameId : <string> - stackTrace : <object> - startTime : <number> - type : "Layout" -} -Text details for Layout: test://evaluations/0/forced-layout-in-microtask.js:23:36 -
diff --git a/third_party/blink/web_tests/http/tests/devtools/forced-layout-in-microtask.js b/third_party/blink/web_tests/http/tests/devtools/forced-layout-in-microtask.js deleted file mode 100644 index c593daa..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/forced-layout-in-microtask.js +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2017 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {TestRunner} from 'test_runner'; -import {PerformanceTestRunner} from 'performance_test_runner'; - -(async function() { - TestRunner.addResult(`Tests that Layout record has correct locations of layout being invalidated and forced.\n`); - await TestRunner.showPanel('timeline'); - await TestRunner.loadHTML(` - <style> - .test { height: 20px; } - </style> - <div id="test"></div> - `); - await TestRunner.evaluateInPagePromise(` - function performActions() - { - return fetch("${TestRunner.url('resources/source1.js')}").then(() => { - var element = document.getElementById("test"); - element.className = "test"; - var unused = element.offsetHeight; - }); - } - `); - - await PerformanceTestRunner.invokeAsyncWithTimeline('performActions'); - await PerformanceTestRunner.printTimelineRecordsWithDetails('Layout'); - TestRunner.completeTest(); -})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-js-line-level-profile-expected.txt b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-js-line-level-profile-expected.txt deleted file mode 100644 index d598f519..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-js-line-level-profile-expected.txt +++ /dev/null
@@ -1,12 +0,0 @@ -Tests that a line-level CPU profile is shown in the text editor. - -0 CodeMirror-gutter-breakpoints -.../devtools/tracing/resources/empty.js -99 CodeMirror-gutter-performance 10.0ms rgba(255, 187, 0, 0.4) -101 CodeMirror-gutter-performance 1900.0ms rgba(255, 187, 0, 0.855) -0 CodeMirror-gutter-performance 100.0ms rgba(255, 187, 0, 0.6) -1 CodeMirror-gutter-performance 200.0ms rgba(255, 187, 0, 0.66) -2 CodeMirror-gutter-performance 300.0ms rgba(255, 187, 0, 0.694) -3 CodeMirror-gutter-performance 400.0ms rgba(255, 187, 0, 0.72) -54 CodeMirror-gutter-performance 220.0ms rgba(255, 187, 0, 0.67) -
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-js-line-level-profile.js b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-js-line-level-profile.js deleted file mode 100644 index 7ae8ee4..0000000 --- a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-js-line-level-profile.js +++ /dev/null
@@ -1,61 +0,0 @@ -// Copyright 2017 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import {TestRunner} from 'test_runner'; -import {SourcesTestRunner} from 'sources_test_runner'; - -import * as PerfUI from 'devtools/ui/legacy/components/perf_ui/perf_ui.js'; -import * as SourceFrame from 'devtools/ui/legacy/components/source_frame/source_frame.js'; -import * as SDK from 'devtools/core/sdk/sdk.js'; - -(async function() { - TestRunner.addResult(`Tests that a line-level CPU profile is shown in the text editor.\n`); - await TestRunner.showPanel('timeline'); - await TestRunner.showPanel('sources'); - await TestRunner.addScriptTag('../resources/empty.js'); - - var cpuProfile = { - startTime: 10e6, - endTime: 20e6, - nodes: [ - {id: 0, callFrame: {functionName: '(root)'}, hitCount: 0, children: [1, 2]}, { - id: 1, - callFrame: {functionName: 'foo1'}, - hitCount: 100, - positionTicks: [{line: 1, ticks: 10}, {line: 2, ticks: 20}, {line: 3, ticks: 30}, {line: 4, ticks: 40}] - }, - { - id: 2, - callFrame: {functionName: 'foo2'}, - hitCount: 200, - positionTicks: [{line: 100, ticks: 1}, {line: 102, ticks: 190}], - children: [3] - }, - {id: 3, callFrame: {functionName: 'null'}, hitCount: 0, positionTicks: [], children: [4, 5]}, - {id: 4, callFrame: {functionName: 'bar'}, hitCount: 300, positionTicks: [{line: 55, ticks: 22}]}, { - id: 5, - callFrame: {functionName: 'baz'}, - hitCount: 400, - // no positionTicks for the node. - children: [] - } - ] - }; - - TestRunner.addSniffer(SourceFrame.SourcesTextEditor.prototype, 'setGutterDecoration', decorationAdded, true); - SourcesTestRunner.showScriptSource('empty.js', frameRevealed); - - function decorationAdded(line, type, element) { - TestRunner.addResult(`${line} ${type} ${element.textContent} ${element.style.backgroundColor}`); - } - - function frameRevealed(frame) { - const url = frame.uiSourceCode().url(); - TestRunner.addResult(TestRunner.formatters.formatAsURL(url)); - cpuProfile.nodes.forEach(n => n.callFrame.url = url); - const lineProfile = PerfUI.LineLevelProfile.Performance.instance(); - lineProfile.appendCPUProfile(new SDK.CPUProfileDataModel.CPUProfileDataModel(cpuProfile)); - setTimeout(() => TestRunner.completeTest(), 0); - } -})();
diff --git a/third_party/chromium-variations b/third_party/chromium-variations index cf6d4af..6a189db 160000 --- a/third_party/chromium-variations +++ b/third_party/chromium-variations
@@ -1 +1 @@ -Subproject commit cf6d4af87f019ef741ad50686e12877d84410a28 +Subproject commit 6a189db270f1b70438eb7db6a73be3d46285defd
diff --git a/third_party/dawn b/third_party/dawn index b4d05de..7913b91 160000 --- a/third_party/dawn +++ b/third_party/dawn
@@ -1 +1 @@ -Subproject commit b4d05dec16507b5a6fc832dfb56a9e6489a13302 +Subproject commit 7913b91fdaf8ec73f89407ded62cc7c335ab8da7
diff --git a/third_party/depot_tools b/third_party/depot_tools index 1a61eb6..b7ed76a 160000 --- a/third_party/depot_tools +++ b/third_party/depot_tools
@@ -1 +1 @@ -Subproject commit 1a61eb625d4b062bb2d6f0902b4979b48def4d33 +Subproject commit b7ed76a09d1953d75968cbc14a53f724c11fb5f9
diff --git a/third_party/devtools-frontend-internal b/third_party/devtools-frontend-internal index 2829e05..75f138c 160000 --- a/third_party/devtools-frontend-internal +++ b/third_party/devtools-frontend-internal
@@ -1 +1 @@ -Subproject commit 2829e054a8419e6ecf6d60eb321ca8511317d3f2 +Subproject commit 75f138cb8f9cafdfef0c8ab615bb99dbb8fc1ad4
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src index 6a303cb..caa4a36 160000 --- a/third_party/devtools-frontend/src +++ b/third_party/devtools-frontend/src
@@ -1 +1 @@ -Subproject commit 6a303cbb86cd070e504f3728d314430f17b4e53d +Subproject commit caa4a369e29db1c39171a43a5d68412add28069c
diff --git a/third_party/skia b/third_party/skia index fef9f27..0bdd0da 160000 --- a/third_party/skia +++ b/third_party/skia
@@ -1 +1 @@ -Subproject commit fef9f270935c1b1e8cc881978d510b4a5d13fdc9 +Subproject commit 0bdd0daaa3fc8ca569fd9522c0b7cd5ed0edf0a5
diff --git a/third_party/vulkan-deps b/third_party/vulkan-deps index 707349d..5b3e265 160000 --- a/third_party/vulkan-deps +++ b/third_party/vulkan-deps
@@ -1 +1 @@ -Subproject commit 707349d2ea9e104986b12655c944c6f758a2443b +Subproject commit 5b3e26527906aceb0f77f9be20a9f7a11f6b0c70
diff --git a/third_party/webgpu-cts/src b/third_party/webgpu-cts/src index a2897c3..40da315 160000 --- a/third_party/webgpu-cts/src +++ b/third_party/webgpu-cts/src
@@ -1 +1 @@ -Subproject commit a2897c33ec90d37cbfefed3b3f738f785850c6bf +Subproject commit 40da315f03a896d15fc72911cdf73262c56f7162
diff --git a/third_party/webrtc b/third_party/webrtc index ff54aee..299b285 160000 --- a/third_party/webrtc +++ b/third_party/webrtc
@@ -1 +1 @@ -Subproject commit ff54aee9ab3d5fc5ea6f9d12fb05c582115b736d +Subproject commit 299b28569682198aed2b2635f2405c6e7db471ba
diff --git a/tools/clang/scripts/package.py b/tools/clang/scripts/package.py index ec781b72..e8d6e3e6 100755 --- a/tools/clang/scripts/package.py +++ b/tools/clang/scripts/package.py
@@ -700,6 +700,23 @@ PackageInArchive(libclang_dir, libclang_dir) MaybeUpload(args.upload, args.bucket, libclang_dir + '.t*z', gcs_platform) + # Zip up Android x64 ASAN runtime support + if sys.platform.startswith('linux'): + x64_android_asan_dir = 'x64_android_asan-' + stamp + shutil.rmtree(x64_android_asan_dir, ignore_errors=True) + subdir = os.path.join('lib', 'clang', RELEASE_VERSION, 'lib', 'linux') + dst_dir = os.path.join(x64_android_asan_dir, subdir) + os.makedirs(dst_dir) + shutil.copy( + os.path.join(LLVM_RELEASE_DIR, subdir, + 'libclang_rt.asan-x86_64-android.so'), dst_dir) + shutil.copy( + os.path.join(LLVM_RELEASE_DIR, subdir, + 'libclang_rt.asan_static-x86_64-android.a'), dst_dir) + PackageInArchive(x64_android_asan_dir, x64_android_asan_dir) + MaybeUpload(args.upload, args.bucket, x64_android_asan_dir + '.t*z', + gcs_platform) + if sys.platform == 'win32' and args.upload: binaries = [f for f in want if f.endswith('.exe') or f.endswith('.dll')] assert 'bin/clang-cl.exe' in binaries
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py index 217fdb3..36c7345 100755 --- a/tools/clang/scripts/update.py +++ b/tools/clang/scripts/update.py
@@ -251,7 +251,9 @@ package_file = 'llvm-code-coverage' elif package_name == 'objdump': package_file = 'llvmobjdump' - elif package_name in ['clang-tidy', 'clangd', 'libclang', 'translation_unit']: + elif package_name in [ + 'clang-tidy', 'clangd', 'libclang', 'translation_unit', 'x64_android_asan' + ]: package_file = package_name else: print('Unknown package: "%s".' % package_name)
diff --git a/tools/metrics/histograms/README.md b/tools/metrics/histograms/README.md index 1b8792f3..22a58169 100644 --- a/tools/metrics/histograms/README.md +++ b/tools/metrics/histograms/README.md
@@ -161,6 +161,8 @@ ```c++ // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. +// +// LINT.IfChange(NewTabPageAction) enum class NewTabPageAction { kUseOmnibox = 0, kClickTitle = 1, @@ -168,8 +170,14 @@ kOpenBookmark = 3, kMaxValue = kOpenBookmark, }; +// LINT.ThenChange(//path/to/enums.xml:NewTabPageActionEnum) ``` +The `LINT.IfChange / LINT.ThenChange` comments point between the code and XML +definitions of the enum, to encourage them to be kept in sync. See +[guide](https://www.chromium.org/chromium-os/developer-library/guides/development/keep-files-in-sync/) +and [more details](http://go/gerrit-ifthisthenthat). + `kMaxValue` is a special enumerator that must share the highest enumerator value, typically done by aliasing it with the enumerator with the highest value: clang automatically checks that `kMaxValue` is correctly set for `enum @@ -213,7 +221,16 @@ ``` Finally, regardless of the programming language you are using, add the -definition of the enumerator to [enums.xml](./enums.xml). +definition of the enumerator to [enums.xml](./enums.xml), and add linter checks +to keep the C++/Java and XML values in sync: + +```xml +<!-- LINT.IfChange(NewTabPageActionEnum) --> +<enum name="NewTabPageActionEnum"> + ... +</enum> +<!-- LINT.ThenChange(//path/to/cpp_definition.h:NewTabPageAction) --> +``` #### Legacy Enums @@ -825,9 +842,9 @@ </histogram> ``` -Each token `<variant>` defines what text should be substituted for it, -both in the histogram name and in the summary text. The name part gets -substituted into the histogram name; the summary part gets substituted in +Each token `<variant>` defines what text should be substituted for it, +both in the histogram name and in the summary text. The name part gets +substituted into the histogram name; the summary part gets substituted in the summary field (the histogram description). As shorthand, a `<variant>` that omits the `summary` attribute substitutes the value of the `name` attribute in the histogram's `<summary>` text as well.
diff --git a/tools/metrics/histograms/histograms_xml_files.gni b/tools/metrics/histograms/histograms_xml_files.gni index dcc7c03..b0e9b40 100644 --- a/tools/metrics/histograms/histograms_xml_files.gni +++ b/tools/metrics/histograms/histograms_xml_files.gni
@@ -216,6 +216,7 @@ "//tools/metrics/histograms/metadata/session/histograms.xml", "//tools/metrics/histograms/metadata/settings/enums.xml", "//tools/metrics/histograms/metadata/settings/histograms.xml", + "//tools/metrics/histograms/metadata/sharing/enums.xml", "//tools/metrics/histograms/metadata/sharing/histograms.xml", "//tools/metrics/histograms/metadata/side_search/histograms.xml", "//tools/metrics/histograms/metadata/signin/enums.xml",
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml index fa6649aa..8694cb3a 100644 --- a/tools/metrics/histograms/metadata/android/histograms.xml +++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -3063,6 +3063,16 @@ </summary> </histogram> +<histogram name="Android.PageSummary.Share.SheetEvents" + enum="PageSummarySheetEvents" expires_after="2024-06-30"> + <owner>salg@google.com</owner> + <owner>ssid@google.com</owner> + <summary> + Records ocurrences of various UI events related to the page summary sharing + sheet (open sheet, dismiss sheet, send feedback, etc.). + </summary> +</histogram> + <histogram name="Android.PartnerCustomization.HomepageCustomizationOutcome" enum="PartnerCustomizationsHomepage" expires_after="2025-02-02"> <owner>donnd@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/extensions/histograms.xml b/tools/metrics/histograms/metadata/extensions/histograms.xml index 892e5a9..f2cc610 100644 --- a/tools/metrics/histograms/metadata/extensions/histograms.xml +++ b/tools/metrics/histograms/metadata/extensions/histograms.xml
@@ -419,11 +419,11 @@ </histogram> <histogram name="Extensions.ContentVerification.ComputeHashesOnInstallResult" - enum="BooleanSuccess" expires_after="2024-12-01"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> - <owner>lazyboy@chromium.org</owner> - <owner>rdevlin.cronin@chromium.org</owner> + enum="BooleanSuccess" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>extensions-core@chromium.org</owner> <summary> Whether or not computed_hashes.json file was successfully generated and @@ -436,11 +436,11 @@ </histogram> <histogram name="Extensions.ContentVerification.ComputeHashesOnInstallTime" - units="ms" expires_after="2024-12-01"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> - <owner>lazyboy@chromium.org</owner> - <owner>rdevlin.cronin@chromium.org</owner> + units="ms" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>extensions-core@chromium.org</owner> <summary> The time taken to successfully create the computed_hashes.json file for an @@ -451,11 +451,11 @@ </histogram> <histogram name="Extensions.ContentVerification.FetchFailureError" - enum="CombinedHttpResponseAndNetErrorCode" expires_after="2024-12-01"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> - <owner>lazyboy@chromium.org</owner> - <owner>rdevlin.cronin@chromium.org</owner> + enum="CombinedHttpResponseAndNetErrorCode" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>extensions-core@chromium.org</owner> <summary> Error info for fetching verified_contents.json. Recorded when the file @@ -466,10 +466,11 @@ </histogram> <histogram name="Extensions.ContentVerification.FetchResult" - enum="BooleanSuccess" expires_after="2024-09-22"> - <owner>vkovalova@google.com</owner> - <owner>lazyboy@chromium.org</owner> - <owner>rdevlin.cronin@chromium.org</owner> + enum="BooleanSuccess" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>extensions-core@chromium.org</owner> <summary> Whether or not fetching verified_contents.json succeeded. Recorded when the @@ -599,11 +600,11 @@ </histogram> <histogram name="Extensions.CorruptPolicyExtensionDetected3" - enum="ExtensionPolicyReinstallReason" expires_after="2024-12-01"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> - <owner>lazyboy@chromium.org</owner> - <owner>poromov@chromium.org</owner> + enum="ExtensionPolicyReinstallReason" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>extensions-core@chromium.org</owner> <summary> Fires when we suspect corruption in an enterprise policy forced install @@ -617,10 +618,11 @@ </histogram> <histogram name="Extensions.CorruptPolicyExtensionResolved" units="ms" - expires_after="2024-12-01"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> - <owner>lazyboy@chromium.org</owner> + expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>extensions-core@chromium.org</owner> <owner>managed-devices@google.com</owner> <summary> @@ -1707,9 +1709,11 @@ </histogram> <histogram name="Extensions.ExtensionCacheCount" units="units" - expires_after="2024-12-01"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> Number of cached extensions on disk. Reported on Chrome OS during user @@ -1718,9 +1722,11 @@ </histogram> <histogram name="Extensions.ExtensionCacheSize" units="MB" - expires_after="2024-12-01"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> Total size of .crx files in cache on disk. Reported on Chrome OS during user @@ -1912,9 +1918,11 @@ </histogram> <histogram name="Extensions.ForceInstalledAndBlockListed" units="count" - expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> Number of enterprise policy forced extensions that are blocklisted and thus @@ -1924,11 +1932,11 @@ </histogram> <histogram name="Extensions.ForceInstalledCacheStatus" - enum="ExtensionInstallationDownloadingCacheStatus" - expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> - <owner>poromov@chromium.org</owner> + enum="ExtensionInstallationDownloadingCacheStatus" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <summary> Status of cache entry about enterprise policy forced extension. Recorded for each forced extension. @@ -1936,9 +1944,11 @@ </histogram> <histogram name="Extensions.ForceInstalledCreationStage" - enum="ExtensionInstallCreationStage" expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + enum="ExtensionInstallCreationStage" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> The last known intermediate stage of extension when the extension @@ -1951,9 +1961,11 @@ </histogram> <histogram name="Extensions.ForceInstalledDownloadingStage" - enum="ExtensionInstallationDownloadingStage" expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + enum="ExtensionInstallationDownloadingStage" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> The last known downloading stage of extension downloading process if failure @@ -1966,10 +1978,11 @@ </histogram> <histogram name="Extensions.ForceInstalledFailureCacheStatus" - enum="ExtensionInstallationDownloadingCacheStatus" - expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + enum="ExtensionInstallationDownloadingCacheStatus" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> Status of cache entry about enterprise policy forced extension which failed @@ -1981,9 +1994,11 @@ </histogram> <histogram name="Extensions.ForceInstalledFailureCrxInstallError" - enum="ExtensionInstallationCrxInstallError" expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + enum="ExtensionInstallationCrxInstallError" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> Detailed reason why CRX installation failed for enterprise policy forced @@ -1994,9 +2009,11 @@ </histogram> <histogram name="Extensions.ForceInstalledFailureManifestInvalidAppStatusError" - enum="ManifestInvalidAppStatusError" expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + enum="ManifestInvalidAppStatusError" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> The detailed reason why enterprise policy forced extensions had failed to @@ -2009,9 +2026,11 @@ </histogram> <histogram name="Extensions.ForceInstalledFailureNoUpdatesInfo" - enum="ExtensionNoUpdatesInfo" expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + enum="ExtensionNoUpdatesInfo" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> The info field in the update manifest fetched from the server for enterprise @@ -2024,9 +2043,11 @@ </histogram> <histogram name="Extensions.ForceInstalledFailureSandboxUnpackFailureReason2" - enum="ExtensionUnpackFailureReason" expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + enum="ExtensionUnpackFailureReason" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> The reason why enterprise policy forced extensions had failed to unpack. @@ -2040,9 +2061,11 @@ </histogram> <histogram name="Extensions.ForceInstalledFailureSessionType{FailureReason}" - enum="SessionType" expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + enum="SessionType" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> The type of session in case enterprise policy forced extensions were not @@ -2065,9 +2088,11 @@ <histogram name="Extensions.ForceInstalledFailureStuckInInitialCreationStageAreExtensionsEnabled" - enum="BooleanEnabled" expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + enum="BooleanEnabled" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> Records whether the extensions are enabled or not. Recorded for each forced @@ -2085,9 +2110,11 @@ <histogram name="Extensions.ForceInstalledFailureWithCrxHeaderInvalidIsCWS" enum="IsForceInstalledExtensionFailedWithCrxHeaderInvalidFromCWSBoolean" - expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> Records whether the extension is from the Chrome Web Store or not. Recorded @@ -2099,9 +2126,11 @@ <histogram name="Extensions.ForceInstalledFailureWithCrxHeaderInvalidIsFromCache" - enum="BooleanCacheHit" expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + enum="BooleanCacheHit" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> Records whether the extension is downloaded from cache or not. Recorded for @@ -2112,9 +2141,11 @@ </histogram> <histogram name="Extensions.ForceInstalledLoadTime" units="ms" - expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> The amount of time elapsed during installation of enterprise policy forced @@ -2123,9 +2154,11 @@ </histogram> <histogram name="Extensions.ForceInstalledNotLoadedDisableReason" - enum="ExtensionDisableReason" expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + enum="ExtensionDisableReason" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> Records the disable reason for the enterpise policy forced extensions. @@ -2148,9 +2181,11 @@ </histogram> <histogram name="Extensions.ForceInstalledReadyTime" units="ms" - expires_after="2024-12-01"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> The amount of time elapsed for enterprise policy forced extensions to become @@ -2160,9 +2195,11 @@ <histogram name="Extensions.ForceInstalledSessionsWithNonMisconfigurationFailureOccured" - enum="Boolean" expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + enum="Boolean" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> Records whether there was a possible non-misconfiguration failure for the @@ -2176,9 +2213,11 @@ </histogram> <histogram name="Extensions.ForceInstalledStage2" - enum="ExtensionInstallationStage" expires_after="2024-12-01"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + enum="ExtensionInstallationStage" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> The last known stage of extension installation process if failure reason was @@ -2194,9 +2233,11 @@ </histogram> <histogram name="Extensions.ForceInstalledTimedOutAndNotInstalledCount" - units="units" expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + units="units" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> Number of enterprise policy forced extensions that are not installed after 5 @@ -2205,9 +2246,11 @@ </histogram> <histogram name="Extensions.ForceInstalledTimedOutCount" units="units" - expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> Number of enterprise policy forced extensions that are not loaded after 5 @@ -2216,9 +2259,11 @@ </histogram> <histogram name="Extensions.ForceInstalledTime{ExtensionInstallStages}" - units="ms" expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + units="ms" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> The amount of time elapsed during different stage of the installation @@ -2248,9 +2293,11 @@ </histogram> <histogram name="Extensions.ForceInstalledTotalCandidateCount" units="units" - expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> Total amount of extensions in force installed list. Gets recorded on profile @@ -2262,9 +2309,11 @@ </histogram> <histogram name="Extensions.ForceInstalled{ErrorType}FetchTries" - units="retries" expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + units="retries" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> Number of fetch retries made when enterprise policy forced extensions failed @@ -2284,9 +2333,11 @@ </histogram> <histogram name="Extensions.ForceInstalled{ErrorType}NetworkErrorCode" - enum="NetErrorCodes" expires_after="2024-09-15"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + enum="NetErrorCodes" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> Network error code for the last retry attempt when CRX fetch failed for @@ -5095,9 +5146,11 @@ <histogram name="Extensions.{ExtensionSource}ForceInstalledFailureManifestInvalidErrorDetail2" - enum="ManifestInvalidError" expires_after="2024-12-01"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + enum="ManifestInvalidError" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> The detailed reason why enterprise policy forced extensions had failed to @@ -5118,9 +5171,11 @@ </histogram> <histogram name="Extensions.{ExtensionSource}ForceInstalledFailureReason3" - enum="ExtensionInstallationFailureReason" expires_after="2024-09-01"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + enum="ExtensionInstallationFailureReason" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> The reason why enterprise policy forced extensions were not installed @@ -5144,9 +5199,11 @@ <histogram name="Extensions.{ExtensionSource}ForceInstalled{ErrorType}HttpErrorCode2" - enum="HttpResponseCode" expires_after="2024-04-28"> - <owner>vkovalova@google.com</owner> - <owner>burunduk@chromium.org</owner> + enum="HttpResponseCode" expires_after="never"> +<!-- expires-never: Monitoring outcomes of admin installed extensions --> + + <owner>giovax@google.com</owner> + <owner>chromeos-commercial-chrome-apps-and-extensions@google.com</owner> <owner>managed-devices@google.com</owner> <summary> HTTP error code for the last retry attempt when for enterprise policy forced
diff --git a/tools/metrics/histograms/metadata/file/histograms.xml b/tools/metrics/histograms/metadata/file/histograms.xml index 00022146..5fa823e 100644 --- a/tools/metrics/histograms/metadata/file/histograms.xml +++ b/tools/metrics/histograms/metadata/file/histograms.xml
@@ -907,7 +907,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.Errors.Drive" - enum="OfficeDriveOpenErrors" expires_after="2024-06-02"> + enum="OfficeDriveOpenErrors" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -917,7 +917,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.Errors.OneDrive" - enum="OfficeOneDriveOpenErrors" expires_after="2024-10-06"> + enum="OfficeOneDriveOpenErrors" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -927,7 +927,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.Errors.{CloudProvider}.MetricState" - enum="MetricState" expires_after="2024-10-06"> + enum="MetricState" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -938,7 +938,7 @@ <histogram name="FileBrowser.OfficeFiles.FileHandler.{RootType}.{ConnectionStatus}" - enum="OfficeFileHandler" expires_after="2024-10-06"> + enum="OfficeFileHandler" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -957,7 +957,7 @@ <histogram name="FileBrowser.OfficeFiles.FileOpen.Time.{Transfer}.{Size}.To.{CloudProvider}" - units="ms" expires_after="2024-10-06"> + units="ms" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -989,7 +989,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.ODFS.AuthAttempt" - enum="BooleanInteractive" expires_after="2024-10-06"> + enum="BooleanInteractive" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -999,7 +999,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.ODFS.AuthResult.Interactive" - enum="OfficeOneDriveAuthResultInteractive" expires_after="2024-10-06"> + enum="OfficeOneDriveAuthResultInteractive" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1009,7 +1009,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.ODFS.AuthResult.NonInteractive" - enum="OfficeOneDriveAuthResultNonInteractive" expires_after="2024-10-06"> + enum="OfficeOneDriveAuthResultNonInteractive" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1019,7 +1019,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.ODFS.DriveType" - enum="OfficeOneDriveType" expires_after="2024-10-06"> + enum="OfficeOneDriveType" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1029,7 +1029,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.ODFS.FileSize.{Direction}" units="KiB" - expires_after="2024-10-06"> + expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1043,7 +1043,7 @@ <histogram name="FileBrowser.OfficeFiles.ODFS.FileSystemProvider.Completion.{API-FSP}" - enum="FileSystemProviderOperationCompletion" expires_after="2024-10-06"> + enum="FileSystemProviderOperationCompletion" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1056,7 +1056,7 @@ <histogram name="FileBrowser.OfficeFiles.ODFS.FileSystemProvider.Error.{API-FSP}" - enum="PlatformFileError" expires_after="2024-10-06"> + enum="PlatformFileError" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1068,7 +1068,7 @@ <histogram name="FileBrowser.OfficeFiles.ODFS.FileSystemProvider.ExtendedError.{ExtendedFSPOperation}" - enum="FileSystemProviderExtendedODFSError" expires_after="2024-10-06"> + enum="FileSystemProviderExtendedODFSError" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1079,7 +1079,7 @@ <histogram name="FileBrowser.OfficeFiles.ODFS.FileSystemProvider.Time.{API-FSP}" - units="ms" expires_after="2024-10-06"> + units="ms" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1090,7 +1090,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.ODFS.GraphAPI.DeltaSize.{Case}" - units="count" expires_after="2024-10-06"> + units="count" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1106,7 +1106,7 @@ <histogram name="FileBrowser.OfficeFiles.ODFS.GraphAPI.LastResponseCode.{GetDeltaCallType}" - enum="OfficeGraphAPIResult" expires_after="2024-10-06"> + enum="OfficeGraphAPIResult" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1119,7 +1119,7 @@ <histogram name="FileBrowser.OfficeFiles.ODFS.GraphAPI.ResponseCode.{GraphAPIMethod}" - enum="OfficeGraphAPIResult" expires_after="2024-10-06"> + enum="OfficeGraphAPIResult" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1130,7 +1130,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.ODFS.GraphAPI.Time.{GraphAPIMethod}" - units="ms" expires_after="2024-10-06"> + units="ms" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1140,7 +1140,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.ODFS.MimeType.{Direction}" - enum="DownloadMimeTypeResult" expires_after="2024-06-02"> + enum="DownloadMimeTypeResult" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1153,7 +1153,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.ODFS.MountStatePostRestore" - enum="MountStatePostRestore" expires_after="2024-08-04"> + enum="MountStatePostRestore" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1163,7 +1163,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.ODFS.MountStatePreRestore" - enum="MountStatePreRestore" expires_after="2024-08-04"> + enum="MountStatePreRestore" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1173,7 +1173,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.ODFS.Throughput.{Direction}" - units="KiB/s" expires_after="2024-10-06"> + units="KiB/s" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1186,7 +1186,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.ODFS.Version" units="version" - expires_after="2024-10-06"> + expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1197,7 +1197,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.Open.CloudProvider" - enum="CloudProvider" expires_after="2024-10-06"> + enum="CloudProvider" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1209,7 +1209,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.Open.FileType.{CloudProvider}" - enum="OfficeOpenExtensions" expires_after="2024-10-06"> + enum="OfficeOpenExtensions" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1221,7 +1221,7 @@ <histogram name="FileBrowser.OfficeFiles.Open.IOTaskError.{CloudProvider}.{Transfer}" - enum="PlatformFileError" expires_after="2024-10-06"> + enum="PlatformFileError" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1241,7 +1241,7 @@ <histogram name="FileBrowser.OfficeFiles.Open.IOTaskError.{CloudProvider}.{Transfer}.MetricState" - enum="MetricState" expires_after="2024-10-06"> + enum="MetricState" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1258,7 +1258,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.Open.NumberOfFiles.{CloudProvider}" - units="count" expires_after="2024-10-06"> + units="count" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1269,7 +1269,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.Open.SourceVolume.{CloudProvider}" - enum="OfficeFilesSourceVolume" expires_after="2024-10-06"> + enum="OfficeFilesSourceVolume" expires_after="2025-05-01"> <owner>austinct@chromium.org</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1291,7 +1291,7 @@ <histogram name="FileBrowser.OfficeFiles.Open.SourceVolume.{CloudProvider}.MetricState" - enum="MetricState" expires_after="2024-10-06"> + enum="MetricState" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1302,7 +1302,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.Open.TransferRequired.{CloudProvider}" - enum="OfficeFilesTransferRequired" expires_after="2024-10-06"> + enum="OfficeFilesTransferRequired" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1314,7 +1314,7 @@ <histogram name="FileBrowser.OfficeFiles.Open.TransferRequired.{CloudProvider}.MetricState" - enum="MetricState" expires_after="2024-10-06"> + enum="MetricState" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1325,7 +1325,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.Open.UploadResult.{CloudProvider}" - enum="OfficeFilesUploadResult" expires_after="2024-10-06"> + enum="OfficeFilesUploadResult" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1337,7 +1337,7 @@ <histogram name="FileBrowser.OfficeFiles.Open.UploadResult.{CloudProvider}.MetricState" - enum="MetricState" expires_after="2024-10-06"> + enum="MetricState" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1348,7 +1348,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.Setup.CancelPage" - enum="OfficeSetupPage" expires_after="2024-10-06"> + enum="OfficeSetupPage" expires_after="2025-05-01"> <owner>austinct@chromium.org</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1359,7 +1359,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.Setup.FileHandlerSelection" - enum="OfficeSetupFileHandler" expires_after="2024-10-06"> + enum="OfficeSetupFileHandler" expires_after="2025-05-01"> <owner>austinct@chromium.org</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1370,7 +1370,7 @@ <histogram name="FileBrowser.OfficeFiles.Setup.FirstTimeMicrosoft365Availability" - enum="Microsoft365Availability" expires_after="2024-10-06"> + enum="Microsoft365Availability" expires_after="2025-05-01"> <owner>austinct@chromium.org</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1380,7 +1380,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.Setup.ODFSAvailability" - enum="BooleanAvailable" expires_after="2024-10-06"> + enum="BooleanAvailable" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1390,7 +1390,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.TaskResult.{CloudProvider}" - enum="OfficeTaskResult" expires_after="2024-10-06"> + enum="OfficeTaskResult" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1409,7 +1409,7 @@ <histogram name="FileBrowser.OfficeFiles.TaskResult.{CloudProvider}.MetricState" - enum="MetricState" expires_after="2024-10-06"> + enum="MetricState" expires_after="2025-05-01"> <owner>simmonsjosh@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary> @@ -1419,7 +1419,7 @@ </histogram> <histogram name="FileBrowser.OfficeFiles.UseOutsideDrive" - enum="OfficeFilesUseOutsideDriveHook" expires_after="2024-06-02"> + enum="OfficeFilesUseOutsideDriveHook" expires_after="2025-05-01"> <owner>cassycc@google.com</owner> <owner>src/ui/file_manager/OWNERS</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml index ea6cae6f..4403afd 100644 --- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml +++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -2895,8 +2895,6 @@ <histogram_suffixes name="PrerenderSource" separator="_" ordering="prefix"> <suffix name="" label="All prerenders."/> <suffix name="externalrequest" label="Externally triggered prerender."/> - <suffix name="externalrequestforced" - label="Forced prerender regardless of network."/> <suffix name="gws" label="GWS triggered prerender."/> <suffix name="navigationpredictor" label="Triggered by the NavigationPredictor."/>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index 0543c28..666076b8b 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -96,6 +96,7 @@ <variants name="ImportantFileClients"> <variant name="" summary="Unknown file"/> <variant name=".AccountManager" summary="ChromeOS serialized accounts file"/> + <variant name=".AccountPreferences" summary="Account Preferences file"/> <variant name=".BookmarkStorage" summary="Bookmarks file"/> <variant name=".FeedbackReport" summary="Feedback Report file"/> <variant name=".Local_State" summary="Local State file"/> @@ -3367,6 +3368,19 @@ </summary> </histogram> +<histogram name="Conversions.DbVersionOnReportSentAndDeleted" units="Report" + expires_after="2024-09-15"> + <owner>tquintanilla@chromium.org</owner> + <owner>johnidel@chromium.org</owner> + <owner>measurement-api-dev+metrics@google.com</owner> + <summary> + Records the DB version every time `AttributionStorageSql::DeleteReport` is + invoked, i.e. whenever a report is sent or hits the max number of send + attempts and is subsequently deleted. This metric was added starting with DB + version 58. + </summary> +</histogram> + <histogram name="Conversions.DbVersionOnSourceStored" units="Source" expires_after="2024-09-15"> <owner>tquintanilla@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/privacy_budget/histograms.xml b/tools/metrics/histograms/metadata/privacy_budget/histograms.xml index e9e2a4e..9ccc7d9 100644 --- a/tools/metrics/histograms/metadata/privacy_budget/histograms.xml +++ b/tools/metrics/histograms/metadata/privacy_budget/histograms.xml
@@ -17,7 +17,7 @@ <histograms> <histogram name="PrivacyBudget.Identifiability.FinchConfigValidationResult" - enum="BooleanSuccess" expires_after="2024-04-28"> + enum="BooleanSuccess" expires_after="2024-10-28"> <owner>antoniosartori@chromium.org</owner> <owner>mkwst@chromium.org</owner> <summary> @@ -27,7 +27,7 @@ </histogram> <histogram name="PrivacyBudget.Identifiability.RecordedSample" - enum="PrivacyBudgetRecordedSample" expires_after="2024-05-17"> + enum="PrivacyBudgetRecordedSample" expires_after="2024-11-17"> <owner>antoniosartori@chromium.org</owner> <owner>mkwst@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/sharing/enums.xml b/tools/metrics/histograms/metadata/sharing/enums.xml new file mode 100644 index 0000000..e7489d3 --- /dev/null +++ b/tools/metrics/histograms/metadata/sharing/enums.xml
@@ -0,0 +1,88 @@ +<!-- +Copyright 2024 The Chromium Authors +Use of this source code is governed by a BSD-style license that can be +found in the LICENSE file. +--> + +<!-- + +This file describes the enumerations referenced by entries in histograms.xml for +this directory. Some enums may instead be listed in the central enums.xml file +at src/tools/metrics/histograms/enums.xml when multiple files use them. + +For best practices on writing enumerations descriptions, see +https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md#Enum-Histograms + +Please follow the instructions in the OWNERS file in this directory to find a +reviewer. If no OWNERS file exists, please consider signing up at +go/reviewing-metrics (Googlers only), as all subdirectories are expected to +have an OWNERS file. As a last resort you can send the CL to +chromium-metrics-reviews@google.com. +--> + +<histogram-configuration> + +<!-- Enum types --> + +<enums> + +<enum name="PageSummarySheetEvents"> + <int value="0" label="OPEN_SUMMARY_SHEET"> + Open summary sheet: user clicked the 'create summary' option on the share + sheet. This starts the summary sharing flow. + </int> + <int value="1" label="CLOSE_SHEET_WHILE_INITIALIZING"> + Dismiss/Close summary sheet while initializing: user dismissed or closed the + summary sheet before text started to load. This finishes the summary sharing + flow. + </int> + <int value="2" label="CLOSE_SHEET_WHILE_LOADING"> + Dismiss/Close summary sheet while loading: user dismissed or closed the + summary sheet while text was loading. This finishes the summary sharing + flow. + </int> + <int value="3" label="CLOSE_SHEET_ON_ERROR"> + Dismiss/Close summary sheet on error: user dismissed or closed the summary + sheet after loading failed. This finishes the summary sharing flow. + </int> + <int value="4" label="CLOSE_SHEET_AFTER_SUCCESS"> + Dismiss/Close summary sheet on success: user dismissed or closed the summary + sheet after loading succeeded. This finishes the summary sharing flow. + </int> + <int value="5" label="ADD_SUMMARY"> + Add summary: user clicked the 'add summary' button on the summary sheet, + share sheet will be re-opened with the summary attached. This finishes the + summary sharing flow. + </int> + <int value="6" label="REMOVE_SUMMARY"> + Remove summary: user clicked the 'remove summary' option on the share sheet. + This is only available after the user opened the summary sheet and then + clicked 'add summary' on it. This will re-open the share sheet without the + summary. + </int> + <int value="7" label="CLICK_POSITIVE_FEEDBACK"> + Provide positive feedback: user clicked the 'thumbs up' button on the + summary sheet. + </int> + <int value="8" label="CLICK_NEGATIVE_FEEDBACK"> + Provide negative feedback: user clicked the 'thumbs down' button on the + summary sheet. This will open another sheet with negative feedback types. + </int> + <int value="9" label="NEGATIVE_FEEDBACK_TYPE_SELECTED"> + Negative feedback type selected: user clicked 'submit' on the negative + feedback sheet. This will open the system feedback UI and finish the summary + sharing flow. + </int> + <int value="10" label="NEGATIVE_FEEDBACK_SHEET_DISMISSED"> + Negative feedback sheet dismissed: user clicked 'cancel' or dismissed the + negative feedback sheet. This will re-open the summary sheet. + </int> + <int value="11" label="CLICK_LEARN_MORE"> + Learn more clicked: user clicked 'learn more' link, which opens a help + center article. + </int> +</enum> + +</enums> + +</histogram-configuration>
diff --git a/tools/metrics/histograms/metadata/sharing/histograms.xml b/tools/metrics/histograms/metadata/sharing/histograms.xml index 03ea487..ba64478 100644 --- a/tools/metrics/histograms/metadata/sharing/histograms.xml +++ b/tools/metrics/histograms/metadata/sharing/histograms.xml
@@ -172,6 +172,17 @@ </summary> </histogram> +<histogram name="Sharing.AndroidPageSummary.SheetEvents" + enum="PageSummarySheetEvents" expires_after="2024-06-30"> + <owner>salg@google.com</owner> + <owner>ssid@google.com</owner> + <summary> + Records ocurrences of various UI events related to the page summary sharing + sheet (open sheet, dismiss sheet, send feedback, etc.). Recorded based on + user actions (See enum definitions for more details). + </summary> +</histogram> + <histogram name="Sharing.AnyShareStarted" enum="ShareSourceAndroid" expires_after="never"> <owner>dimich@chromium.org</owner>
diff --git a/tools/typescript/definitions/passwords_private.d.ts b/tools/typescript/definitions/passwords_private.d.ts index 32d2c36..159bf283 100644 --- a/tools/typescript/definitions/passwords_private.d.ts +++ b/tools/typescript/definitions/passwords_private.d.ts
@@ -231,7 +231,7 @@ export function switchBiometricAuthBeforeFillingState(): void; export function showAddShortcutDialog(): void; export function showExportedFileInShell(filePath: string): void; - export function changePasswordManagerPin(): void; + export function changePasswordManagerPin(): Promise<boolean>; export function isPasswordManagerPinAvailable(): Promise<boolean>; export const onSavedPasswordsListChanged:
diff --git a/ui/file_manager/file_manager/foreground/js/directory_contents.ts b/ui/file_manager/file_manager/foreground/js/directory_contents.ts index 3b863f5f..6e4206ab 100644 --- a/ui/file_manager/file_manager/foreground/js/directory_contents.ts +++ b/ui/file_manager/file_manager/foreground/js/directory_contents.ts
@@ -18,9 +18,10 @@ import {createTrashReaders, TRASH_CONFIG} from '../../common/js/trash.js'; import {FileErrorToDomError} from '../../common/js/util.js'; import {RootType, VolumeType} from '../../common/js/volume_manager_types.js'; +import {directoryContentSelector, fetchDirectoryContents} from '../../state/ducks/current_directory.js'; import {getDefaultSearchOptions} from '../../state/ducks/search.js'; -import {type FileKey, SearchLocation, type SearchOptions} from '../../state/state.js'; -import {getStore} from '../../state/store.js'; +import {type DirectoryContent, type FileKey, PropStatus, SearchLocation, type SearchOptions} from '../../state/state.js'; +import {getFileData, getStore, type Store} from '../../state/store.js'; import {ACTIONS_MODEL_METADATA_PREFETCH_PROPERTY_NAMES, CROSTINI_CONNECT_ERR, DLP_METADATA_PREFETCH_PROPERTY_NAMES, FILE_SELECTION_METADATA_PREFETCH_PROPERTY_NAMES, LIST_CONTAINER_METADATA_PREFETCH_PROPERTY_NAMES} from './constants.js'; import {FileListModel} from './file_list_model.js'; @@ -58,6 +59,13 @@ cancel() { this.canceled_ = true; } + + /** + * Whether the scanner pushes the entry directly to the store. + */ + isStoreBased(): boolean { + return false; + } } /** @@ -1217,8 +1225,8 @@ // called at most once. Remove such a limitation. this.scanner_ = this.scannerFactory_(); this.scanner_.scan( - this.onNewEntries_.bind(this, refresh), completionCallback, - errorCallback, invalidateCache); + this.onNewEntries_.bind(this, refresh, this.scanner_.isStoreBased()), + completionCallback, errorCallback, invalidateCache); } /** @@ -1278,7 +1286,7 @@ } this.prefetchMetadata(updatedList, true, () => { - this.onNewEntries_(true, addedList); + this.onNewEntries_(true, false, addedList); this.onScanFinished_(); this.onScanCompleted_(); }); @@ -1348,11 +1356,12 @@ /** * Called when some chunk of entries are read by scanner. * - * @param refresh True to refresh metadata, or false to use cached - * one. + * @param refresh True to refresh metadata, or false to use cached one. + * @param storeBased Whether the scan for `entries` was done in the store. * @param entries The list of the scanned entries. */ - private onNewEntries_(refresh: boolean, entries: UniversalEntry[]) { + private onNewEntries_( + refresh: boolean, storeBased: boolean, entries: UniversalEntry[]) { if (this.scanCanceled_) { return; } @@ -1378,7 +1387,7 @@ this.fileList_.push.apply(this.fileList_, entriesFiltered); const event = new CustomEvent('dir-contents-scan-updated', { detail: { - isStoreBased: false, + isStoreBased: storeBased, }, }); this.dispatchEvent(event); @@ -1432,3 +1441,102 @@ .then(callback); } } + +/** + * Scan entries using the Store and ActionsProducer to talk to the backend and + * propagate the state. + * + * This adapts the Store to the existing ContentScanner architecture. + */ +export class StoreScanner extends ContentScanner { + private store_: Store; + private entriesCallback_?: ScanResultCallback; + private successCallbcak_?: VoidCallback; + private errorCallback_?: ScanErrorCallback; + private unsubscribe_?: VoidCallback; + + constructor(private fileKey_: FileKey) { + super(); + this.store_ = getStore(); + } + + private onDirectoryContentUpdated_(dirContent?: DirectoryContent) { + if (!dirContent) { + return; + } + if (!(this.entriesCallback_ && this.errorCallback_ && + this.successCallbcak_)) { + return; + } + + if (dirContent.status === PropStatus.ERROR) { + // TODO(lucmult): Figure out the DOMError here. + this.errorCallback_({} as DOMError); + this.finalize_(); + return; + } + + if (dirContent.status === PropStatus.STARTED && + dirContent.keys.length > 0) { + const entries = this.getEntries_(dirContent.keys); + this.entriesCallback_(entries); + return; + } + + if (dirContent.status === PropStatus.SUCCESS) { + const entries = this.getEntries_(dirContent.keys); + this.entriesCallback_(entries); + this.successCallbcak_(); + this.finalize_(); + return; + } + } + + private getEntries_(keys: FileKey[]): UniversalEntry[] { + const state = this.store_.getState(); + const entries: UniversalEntry[] = []; + for (const k of keys) { + const entry = getFileData(state, k)?.entry; + if (!entry) { + console.debug(`Failed to find entry for ${k}`); + continue; + } + entries.push(entry); + } + return entries; + } + + override async scan( + entriesCallback: ScanResultCallback, successCallback: VoidCallback, + errorCallback: ScanErrorCallback, _invalidateCache: boolean = false) { + this.entriesCallback_ = entriesCallback; + this.errorCallback_ = errorCallback; + this.successCallbcak_ = successCallback; + // Start listening to the store. + this.unsubscribe_ = directoryContentSelector.subscribe( + this.onDirectoryContentUpdated_.bind(this)); + + // Dispatch action to scan in the store. + this.store_.dispatch(fetchDirectoryContents(this.fileKey_)); + } + + override cancel() { + super.cancel(); + this.finalize_(); + } + + private finalize_() { + // Usubscribe from the store. + if (this.unsubscribe_) { + this.unsubscribe_(); + } + this.unsubscribe_ = undefined; + this.successCallbcak_ = undefined; + this.errorCallback_ = undefined; + this.entriesCallback_ = undefined; + } + + override isStoreBased(): boolean { + return true; + } +}
diff --git a/ui/file_manager/file_manager/foreground/js/directory_model.ts b/ui/file_manager/file_manager/foreground/js/directory_model.ts index 09c0ce0c..3eae9f52 100644 --- a/ui/file_manager/file_manager/foreground/js/directory_model.ts +++ b/ui/file_manager/file_manager/foreground/js/directory_model.ts
@@ -26,7 +26,7 @@ import {CROSTINI_CONNECT_ERR, DLP_METADATA_PREFETCH_PROPERTY_NAMES, LIST_CONTAINER_METADATA_PREFETCH_PROPERTY_NAMES} from './constants.js'; import type {ContentScanner, DirContentsScanFailedEvent, DirContentsScanUpdatedEvent, FileFilter} from './directory_contents.js'; -import {CrostiniMounter, DirectoryContents, DirectoryContentScanner, DriveMetadataSearchContentScanner, EmptyContentScanner, FileListContext, GuestOsMounter, MediaViewContentScanner, RecentContentScanner, SearchV2ContentScanner, TrashContentScanner} from './directory_contents.js'; +import {CrostiniMounter, DirectoryContents, DirectoryContentScanner, DriveMetadataSearchContentScanner, EmptyContentScanner, FileListContext, GuestOsMounter, MediaViewContentScanner, RecentContentScanner, SearchV2ContentScanner, StoreScanner, TrashContentScanner} from './directory_contents.js'; import {FileListModel} from './file_list_model.js'; import {FileWatcher, type WatcherDirectoryChangedEvent} from './file_watcher.js'; import type {MetadataKey} from './metadata/metadata_item.js'; @@ -1242,6 +1242,7 @@ const {myFilesEntry} = getMyFiles(getStore().getState()); return myFilesEntry; } + async changeDirectoryFileData(fileData: FileData): Promise<boolean> { if (fileData.entry) { const result = await new Promise<boolean>(resolve => { @@ -1659,13 +1660,15 @@ createScannerFactory( fileKey: FileKey, entry?: DirectoryEntry|FilesAppEntry, query?: string, options?: SearchOptions): () => ContentScanner { - if (!entry) { + if (!entry && !!fileKey) { + // Store-based scanner, it doesn't use Entry. E.g: Materialized View. return () => { - console.debug(`TODO: Implement scanner for ${fileKey}`); - return new EmptyContentScanner(); + return new StoreScanner(fileKey); }; } + assert(entry); + const sanitizedQuery = (query || '').trimStart(); const locationInfo = this.volumeManager_.getLocationInfo(entry);
diff --git a/ui/file_manager/file_manager/foreground/js/scan_controller.ts b/ui/file_manager/file_manager/foreground/js/scan_controller.ts index 081ed77b..f288740 100644 --- a/ui/file_manager/file_manager/foreground/js/scan_controller.ts +++ b/ui/file_manager/file_manager/foreground/js/scan_controller.ts
@@ -2,14 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import type {FilesAppEntry} from '../../common/js/files_app_entry_types.js'; import {recordDirectoryListLoadWithTolerance, startInterval} from '../../common/js/metrics.js'; import {RootType, VolumeType} from '../../common/js/volume_manager_types.js'; import {updateDirectoryContent} from '../../state/ducks/current_directory.js'; import {PropStatus} from '../../state/state.js'; import {getStore, type Store} from '../../state/store.js'; -import type {DirectoryModel} from './directory_model.js'; +import type {CurDirScanUpdatedEvent, DirectoryModel} from './directory_model.js'; import type {FileSelectionHandler} from './file_selection.js'; import type {SpinnerController} from './spinner_controller.js'; import type {ListContainer} from './ui/list_container.js'; @@ -125,25 +124,26 @@ * Sends the scanned directory content to the Store. */ private updateStore_() { - const entries: Array<Entry|FilesAppEntry> = - this.directoryModel_.getFileList().slice(); + const entries = this.directoryModel_.getFileList().slice(); this.store_.dispatch( updateDirectoryContent({entries, status: PropStatus.SUCCESS})); } /** */ - private onScanUpdated_() { + private onScanUpdated_(e: CurDirScanUpdatedEvent) { if (!this.scanInProgress_) { console.warn('Scan-updated event received. But scan is not started.'); return; } - // Call this immediately (instead of debouncing it with - // `scanUpdatedTimer_`) so the current directory entries don't get - // accidentally removed from the store by `clearCachedEntries` in - // `state/reducers/all_entries.ts`. - this.updateStore_(); + // Call this immediately (instead of debouncing it with `scanUpdatedTimer_`) + // so the current directory entries don't get accidentally removed from the + // store by `clearCachedEntries()`, when the scan is store-based the entries + // are already in the store. + if (!e.detail.isStoreBased) { + this.updateStore_(); + } if (this.scanUpdatedTimer_) { return;
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html index e41e6466f..1ead16a 100644 --- a/ui/file_manager/file_manager/main.html +++ b/ui/file_manager/file_manager/main.html
@@ -8,6 +8,7 @@ <head> <title>$i18n{FILEMANAGER_APP_NAME}</title> <script src="chrome://file-manager/init_globals.js"></script> + <script type="module" src="chrome://file-manager/strings.m.js"></script> <meta charset="utf-8" name="google" value="notranslate"> <meta charset="utf-8" name="color-scheme" content="light dark">
diff --git a/ui/gfx/codec/jpeg_codec.cc b/ui/gfx/codec/jpeg_codec.cc index 3f814367..7a867df 100644 --- a/ui/gfx/codec/jpeg_codec.cc +++ b/ui/gfx/codec/jpeg_codec.cc
@@ -80,7 +80,24 @@ // Reject images that would exceed INT_MAX bytes. constexpr int kBytesPerPixel = 4; - return size.area() < (INT_MAX / kBytesPerPixel); + if (size.area() >= (INT_MAX / kBytesPerPixel)) { + return false; + } + + // The fuzzer is able to make astronomically large bitmaps (30000x30000) from + // very small inputs. Images this large can take several seconds to decode. In + // a build instrumented for fuzzing, this time can balloon to over a minute. + // To avoid timeouts, we limit the fuzzer to 16 million pixels. We don't + // reject very wide or very tall images, as long as the image is reasonably + // small on the other axis. +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + constexpr int kFuzzerPixelLimit = 4000 * 4000; + if (size.area() >= kFuzzerPixelLimit) { + return false; + } +#endif + + return true; } bool JPEGCodec::Decode(const unsigned char* input,
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.cc b/ui/views/controls/tabbed_pane/tabbed_pane.cc index 423c9ccf..e15e955 100644 --- a/ui/views/controls/tabbed_pane/tabbed_pane.cc +++ b/ui/views/controls/tabbed_pane/tabbed_pane.cc
@@ -10,7 +10,6 @@ #include "base/check_op.h" #include "base/i18n/rtl.h" -#include "base/notreached.h" #include "build/build_config.h" #include "cc/paint/paint_flags.h" #include "third_party/skia/include/core/SkPath.h" @@ -132,16 +131,10 @@ } gfx::Size TabbedPaneTab::CalculatePreferredSize() const { - NOTREACHED_NORETURN() << "Use CalculatePreferredSize(SizeBounds)"; -} - -gfx::Size TabbedPaneTab::CalculatePreferredSize( - const SizeBounds& available_size) const { int width = preferred_title_width_ + GetInsets().width(); if (tabbed_pane_->GetStyle() == TabbedPane::TabStripStyle::kHighlight && - tabbed_pane_->GetOrientation() == TabbedPane::Orientation::kVertical) { + tabbed_pane_->GetOrientation() == TabbedPane::Orientation::kVertical) width = std::max(width, 192); - } return gfx::Size(width, 32); } @@ -150,7 +143,7 @@ // LayoutManager::GetPreferredHeightForWidth by default, but this is not // consistent with the fixed height desired by CalculatePreferredSize, so we // override it and call it manually. - return CalculatePreferredSize(SizeBounds(w, {})).height(); + return CalculatePreferredSize().height(); } void TabbedPaneTab::GetAccessibleNodeData(ui::AXNodeData* data) {
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.h b/ui/views/controls/tabbed_pane/tabbed_pane.h index d0d33b2..48f164c 100644 --- a/ui/views/controls/tabbed_pane/tabbed_pane.h +++ b/ui/views/controls/tabbed_pane/tabbed_pane.h
@@ -176,9 +176,7 @@ void OnMouseEntered(const ui::MouseEvent& event) override; void OnMouseExited(const ui::MouseEvent& event) override; void OnGestureEvent(ui::GestureEvent* event) override; - gfx::Size CalculatePreferredSize() const final; - gfx::Size CalculatePreferredSize( - const SizeBounds& available_size) const override; + gfx::Size CalculatePreferredSize() const override; int GetHeightForWidth(int w) const override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override; bool HandleAccessibleAction(const ui::AXActionData& action_data) override;
diff --git a/ui/views/examples/multiline_example.cc b/ui/views/examples/multiline_example.cc index c0c3b890..af9f8a9 100644 --- a/ui/views/examples/multiline_example.cc +++ b/ui/views/examples/multiline_example.cc
@@ -86,27 +86,28 @@ render_text_->Draw(canvas); } - gfx::Size CalculatePreferredSize( - const SizeBounds& available_size) const override { - int w = available_size.width().value_or(0); - if (w == 0) { - // Turn off multiline mode to get the single-line text size, which is the - // preferred size for this view. - render_text_->SetMultiline(false); - gfx::Size size(render_text_->GetContentWidth(), - render_text_->GetStringSize().height()); - size.Enlarge(GetInsets().width(), GetInsets().height()); - render_text_->SetMultiline(true); - return size; - } + gfx::Size CalculatePreferredSize() const override { + // Turn off multiline mode to get the single-line text size, which is the + // preferred size for this view. + render_text_->SetMultiline(false); + gfx::Size size(render_text_->GetContentWidth(), + render_text_->GetStringSize().height()); + size.Enlarge(GetInsets().width(), GetInsets().height()); + render_text_->SetMultiline(true); + return size; + } + int GetHeightForWidth(int w) const override { + // TODO(ckocagil): Why does this happen? + if (w == 0) + return View::GetHeightForWidth(w); const gfx::Rect old_rect = render_text_->display_rect(); gfx::Rect rect = old_rect; rect.set_width(w - GetInsets().width()); render_text_->SetDisplayRect(rect); int height = render_text_->GetStringSize().height() + GetInsets().height(); render_text_->SetDisplayRect(old_rect); - return gfx::Size(w, height); + return height; } void OnThemeChanged() override {
diff --git a/ui/views/layout/layout_types.h b/ui/views/layout/layout_types.h index 152dc37..14e05150 100644 --- a/ui/views/layout/layout_types.h +++ b/ui/views/layout/layout_types.h
@@ -62,10 +62,6 @@ return is_bounded() ? std::min(this->value(), value) : value; } - constexpr int value_or(int defaule_value) const { - return is_bounded() ? value() : defaule_value; - } - void operator+=(const SizeBound& rhs); void operator-=(const SizeBound& rhs);
diff --git a/ui/views/test/test_views.cc b/ui/views/test/test_views.cc index 69ac753..c5dd24a8 100644 --- a/ui/views/test/test_views.cc +++ b/ui/views/test/test_views.cc
@@ -44,16 +44,14 @@ PreferredSizeChanged(); } -gfx::Size ProportionallySizedView::CalculatePreferredSize( - const SizeBounds& available_size) const { - if (available_size.width().is_bounded()) { - int w = available_size.width().value(); - return gfx::Size(w, w * factor_); - } else if (preferred_width_ >= 0) { - return gfx::Size(preferred_width_, preferred_width_ * factor_); - } else { - return View::CalculatePreferredSize(available_size); - } +int ProportionallySizedView::GetHeightForWidth(int w) const { + return w * factor_; +} + +gfx::Size ProportionallySizedView::CalculatePreferredSize() const { + if (preferred_width_ >= 0) + return gfx::Size(preferred_width_, GetHeightForWidth(preferred_width_)); + return View::CalculatePreferredSize(); } BEGIN_METADATA(ProportionallySizedView)
diff --git a/ui/views/test/test_views.h b/ui/views/test/test_views.h index 5f65e72..dfed1df 100644 --- a/ui/views/test/test_views.h +++ b/ui/views/test/test_views.h
@@ -61,8 +61,8 @@ void SetPreferredWidth(int width); - gfx::Size CalculatePreferredSize( - const SizeBounds& available_size) const override; + int GetHeightForWidth(int w) const override; + gfx::Size CalculatePreferredSize() const override; private: // The multiplicative factor between width and height, i.e.
diff --git a/ui/views/widget/widget_interactive_uitest.cc b/ui/views/widget/widget_interactive_uitest.cc index 9fbb726..e65f64e 100644 --- a/ui/views/widget/widget_interactive_uitest.cc +++ b/ui/views/widget/widget_interactive_uitest.cc
@@ -1443,7 +1443,8 @@ #if BUILDFLAG(ENABLE_DESKTOP_AURA) TEST_F(DesktopWidgetTestInteractive, - DoNotSynthesizeMouseMoveOnVisibilityChangeIfOccluded) { + // TODO(crbug.com/335767870): Re-enable this test + DISABLED_DoNotSynthesizeMouseMoveOnVisibilityChangeIfOccluded) { // Create a top-level widget. WidgetAutoclosePtr widget_below(CreateTopLevelPlatformDesktopWidget()); widget_below->SetBounds(gfx::Rect(300, 300));