diff --git a/AUTHORS b/AUTHORS index 49ddab2..86c4f7f0 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -1334,6 +1334,7 @@ wafuwafu13 <mariobaske@i.softbank.jp> Wojciech Bielawski <wojciech.bielawski@gmail.com> Wang Chen <wangchen20@iscas.ac.cn> +Wang Chen <unicornxw@gmail.com> Wang Weiwei <wangww@dingdao.com> Wangyang Dai <jludwy@gmail.com> Wanming Lin <wanming.lin@intel.com>
diff --git a/DEPS b/DEPS index d9ff744..46fa2bc 100644 --- a/DEPS +++ b/DEPS
@@ -300,19 +300,19 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'src_internal_revision': 'e03e8d1d7f7bd1869aff4f3d755d780810fcb21f', + 'src_internal_revision': 'ee9a494402f066aee426dc42b75d30cc71a18dbd', # 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': 'a226cfbd6cc7179e9ed165125d6861b99550a001', + 'skia_revision': '8a0152a423497497cc7425541947cf1bb3745a2e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '1a1dc7616f2c9fe00b8fffb056e678a428acf516', + 'v8_revision': '6013b6402ff6de4db468323ac6b7c69de83218f2', # 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': 'e7a9275be22d28c74049d397a87183d47a1d188f', + 'angle_revision': '6e40ce0071228c189506b986b6702b95ef0c2ac0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -391,7 +391,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': '59dd87f2f45f6d8659291fe1bff52540657566a9', + 'devtools_frontend_revision': 'bf4f2fcc886593af85cf7c2d5647d14ebccbbe51', # 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. @@ -479,7 +479,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. - 'libunwind_revision': 'cd144ced35285edaa064a91561969e5b22c219b1', + 'libunwind_revision': 'b5a43ecdac82a248f8a700a68c722b4d98708377', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -911,7 +911,7 @@ 'packages': [ { 'package': 'chromium/rts/model/linux-amd64', - 'version': 'qFXOotL3BRF2fhT8kz0P-RscghSPWuGF9_9_2b2xjUAC', + 'version': 'pgJa4nimCNU7g921DwcTZgWvtrtwVu6rkZhDfqjVLq0C', }, ], 'dep_type': 'cipd', @@ -922,7 +922,7 @@ 'packages': [ { 'package': 'chromium/rts/model/mac-amd64', - 'version': 'OyU9564VNQX3Yh8NwBC8iAhDU4gToLpsJxAgGK94c1MC', + 'version': 'gTuVXh_RZKUMB39uZY-Bu6PRx_fMNG_jRpiWeONhBhwC', }, ], 'dep_type': 'cipd', @@ -933,7 +933,7 @@ 'packages': [ { 'package': 'chromium/rts/model/windows-amd64', - 'version': 'ZTwDU5fQef0bjjHIFes5ZMRsn7uW89bAu7wNppEnhUoC', + 'version': 'LwcvneReAE8h5RWfbKv-flvZ0RcYiatwjJspxUbOZUwC', }, ], 'dep_type': 'cipd', @@ -1001,7 +1001,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'P3-Etm0wxlp5sUCCgNTJJBJWGVl8xyaQ6_Rwn7TmtHwC', + 'version': 'iYjHXTBxKD0S9CuLGLN6QESvNkURfGdqURQSUDrnai0C', }, ], 'condition': 'checkout_android', @@ -1207,7 +1207,7 @@ # Tools used when building Chrome for Chrome OS. This affects both the Simple # Chrome workflow, as well as the chromeos-chrome ebuild. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'e01cbdf84fb1dccb96a35c82bbe0cad642519d7e', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '1a51818385ec4ef833f9945ca5f248852f5cfaf0', 'condition': 'checkout_chromeos', }, @@ -1242,13 +1242,13 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'df2f11113c23d65c1fd7824b7ab3c55f7cfb9604', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '37d1312fcd44558402bebc2966b6b98babca5d7b', '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' + '@' + 'a4b757e5eae6a111eb772290e67cad21199b0a17', + 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '7b9cd2ab1fce7837fc5a40b816f3cd4f5ba5235a', 'condition': 'checkout_src_internal', }, @@ -1715,7 +1715,7 @@ Var('pdfium_git') + '/pdfium.git' + '@' + Var('pdfium_revision'), 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'bcbe569710dbd97b0d7d9e95d87e93be7d1f8065', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '55c4abdb8736d8618e0d6c1c0c6a7df5a41559a0', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -2025,7 +2025,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': '1YpDqTSySZ2wiWMd2YtGLNjqQ7O16Kd-w2aIxGs-mxEC', + 'version': 'U3w8ZDVd1zRC2BZDJJV71ryb9r5MHSTxIBmW4lnNyYMC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -2036,7 +2036,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'qFBi9r80SlowIX-MUdDoXWp0uK_A928fmBIKgR2dWJUC', + 'version': 'LcVQfWIBP6eUziUIUD3rSzXFvnUxu2Fg0M2E2IMzmCUC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -3995,7 +3995,7 @@ 'src/chrome/app/theme/default_100_percent/google_chrome': { 'url': Var('chrome_git') + '/chrome/theme/default_100_percent/google_chrome.git' + '@' + - '534ecab0aa3978f434d3fedc5f5b298265523482', + '6cae6834aee1c39513f0b2e22a6249466e79d407', 'condition': 'checkout_src_internal', }, @@ -4025,7 +4025,7 @@ 'src/chrome/browser/internal': { 'url': Var('chrome_git') + '/chrome/browser_internal.git' + '@' + - 'd3a55d714679c55a73ff96a7ea77493b326dae91', + '86edf3656689330827cd0bd118656e6be5ec88a4', 'condition': 'checkout_src_internal', }, @@ -4146,7 +4146,7 @@ 'src/components/optimization_guide/internal': { 'url': Var('chrome_git') + '/chrome/components/optimization_guide.git' + '@' + - '15a8ac31d8c154261e8e937c18a4fcf3a76ec22f', + '8d544b1e6c0adba47bb66f70bd7f8b92eed6d46d', 'condition': 'checkout_src_internal', },
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 0ec63376..29b4c2a 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -288,7 +288,8 @@ r'/RecordHistogram\.getHistogram(ValueCount|TotalCount|Samples)ForTesting\(', ( 'Raw histogram counts are easy to misuse; for example they don\'t reset ' - 'between batched tests. Use HistogramWatcher to check histogram records instead.', + 'between batched tests. Use HistogramWatcher to check histogram records ' + 'instead.', ), False, excluded_paths=( @@ -5005,6 +5006,10 @@ "correct_name": "Chrome", "incorrect_name": "Chromium", }, { + "filename_postfix": "google_chrome_strings.grd", + "correct_name": "Chrome", + "incorrect_name": "Chrome for Testing", + }, { "filename_postfix": "chromium_strings.grd", "correct_name": "Chromium", "incorrect_name": "Chrome", @@ -5023,6 +5028,9 @@ if "<message" in line or "<!--" in line or "-->" in line: continue if test_case["incorrect_name"] in line: + # Chrome for Testing is a special edge case: https://goo.gle/chrome-for-testing#bookmark=id.n1rat320av91 + if (test_case["correct_name"] == "Chromium" and line.count("Chrome") == line.count("Chrome for Testing")): + continue problems.append("Incorrect product name in %s:%d" % (f.LocalPath(), line_num))
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py index ea7797d..9d29a21 100755 --- a/PRESUBMIT_test.py +++ b/PRESUBMIT_test.py
@@ -2325,6 +2325,34 @@ self.assertTrue( 'chrome/app/google_chrome_strings.grd:2' in warnings[0].items[0]) + def testChromeForTestingInChromium(self): + mock_input_api = MockInputApi() + mock_input_api.files = [ + MockAffectedFile('chrome/app/chromium_strings.grd', [ + '<message name="Bar" desc="Welcome to Chrome">', + ' Welcome to Chrome for Testing!', + '</message>', + ]), + ] + warnings = PRESUBMIT.CheckCorrectProductNameInMessages( + mock_input_api, MockOutputApi()) + self.assertEqual(0, len(warnings)) + + def testChromeForTestingInChrome(self): + mock_input_api = MockInputApi() + mock_input_api.files = [ + MockAffectedFile('chrome/app/google_chrome_strings.grd', [ + '<message name="Bar" desc="Welcome to Chrome">', + ' Welcome to Chrome for Testing!', + '</message>', + ]), + ] + warnings = PRESUBMIT.CheckCorrectProductNameInMessages( + mock_input_api, MockOutputApi()) + self.assertEqual(1, len(warnings)) + self.assertTrue( + 'chrome/app/google_chrome_strings.grd:2' in warnings[0].items[0]) + def testMultipleInstances(self): mock_input_api = MockInputApi() mock_input_api.files = [
diff --git a/android_webview/browser/aw_autofill_client.cc b/android_webview/browser/aw_autofill_client.cc index 928a207..355a946 100644 --- a/android_webview/browser/aw_autofill_client.cc +++ b/android_webview/browser/aw_autofill_client.cc
@@ -24,6 +24,7 @@ #include "components/autofill/core/browser/autofill_download_manager.h" #include "components/autofill/core/browser/payments/legal_message_line.h" #include "components/autofill/core/browser/ui/autofill_popup_delegate.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" #include "components/autofill/core/browser/ui/suggestion.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/prefs/pref_registry_simple.h" @@ -358,7 +359,7 @@ content::SSLStatus::RAN_INSECURE_CONTENT); } -void AwAutofillClient::ExecuteCommand(autofill::Suggestion::FrontendId id) { +void AwAutofillClient::ExecuteCommand(autofill::PopupItemId popup_item_id) { NOTIMPLEMENTED(); } @@ -445,7 +446,7 @@ Java_AwAutofillClient_addToAutofillSuggestionArray( env, data_array, i, name, label, - base::to_underlying(suggestions[i].frontend_id.as_popup_item_id())); + base::to_underlying(suggestions[i].popup_item_id)); } ui::ViewAndroid* view_android = GetWebContents().GetNativeView(); if (!view_android)
diff --git a/android_webview/browser/aw_autofill_client.h b/android_webview/browser/aw_autofill_client.h index afd7ef2..105ea55 100644 --- a/android_webview/browser/aw_autofill_client.h +++ b/android_webview/browser/aw_autofill_client.h
@@ -16,6 +16,7 @@ #include "components/autofill/content/browser/content_autofill_client.h" #include "components/autofill/core/browser/autofill_trigger_source.h" #include "components/autofill/core/browser/payments/legal_message_line.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" #include "content/public/browser/web_contents_user_data.h" #include "ui/android/view_android.h" @@ -162,7 +163,7 @@ void DidFillOrPreviewField(const std::u16string& autofilled_value, const std::u16string& profile_full_name) override; bool IsContextSecure() const override; - void ExecuteCommand(autofill::Suggestion::FrontendId id) override; + void ExecuteCommand(autofill::PopupItemId popup_item_id) override; void OpenPromoCodeOfferDetailsURL(const GURL& url) override; autofill::FormInteractionsFlowId GetCurrentFormInteractionsFlowId() override;
diff --git a/android_webview/browser/aw_contents.cc b/android_webview/browser/aw_contents.cc index 5788c4b..cb48303 100644 --- a/android_webview/browser/aw_contents.cc +++ b/android_webview/browser/aw_contents.cc
@@ -59,6 +59,8 @@ #include "base/supports_user_data.h" #include "base/task/single_thread_task_runner.h" #include "base/threading/thread_restrictions.h" +#include "base/trace_event/trace_event.h" +#include "base/trace_event/typed_macros.h" #include "components/android_autofill/browser/android_autofill_manager.h" #include "components/android_autofill/browser/autofill_provider_android.h" #include "components/autofill/content/browser/content_autofill_driver.h" @@ -225,6 +227,8 @@ : content::WebContentsObserver(web_contents.get()), browser_view_renderer_(this, content::GetUIThreadTaskRunner({})), web_contents_(std::move(web_contents)) { + TRACE_EVENT_BEGIN("android_webview.timeline", "WebView Instance", + perfetto::Track::FromPointer(this)); base::subtle::NoBarrier_AtomicIncrement(&g_instance_count, 1); icon_helper_ = std::make_unique<IconHelper>(web_contents_.get()); icon_helper_->SetListener(this); @@ -368,6 +372,9 @@ WebContentsObserver::Observe(nullptr); AwBrowserProcess::GetInstance()->visibility_metrics_logger()->RemoveClient( this); + // Corresponds to "WebView Instance" in AwContents's constructor. + TRACE_EVENT_END("android_webview.timeline", + perfetto::Track::FromPointer(this)); } base::android::ScopedJavaLocalRef<jobject> AwContents::GetWebContents(
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java index e898572..1214e35 100644 --- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java +++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -130,6 +130,8 @@ "More robust heuristic for calling Invalidate"), Flag.baseFeature( VizFeatures.WEBVIEW_VULKAN_INTERMEDIATE_BUFFER, "For debugging vulkan"), + Flag.baseFeature(VizFeatures.ALLOW_UNDAMAGED_NONROOT_RENDER_PASS_TO_SKIP, + "Enable optimization for skipping undamaged nonroot render passes."), Flag.baseFeature( GpuFeatures.USE_GLES2_FOR_OOP_R, "Force Skia context to use es2 only."), Flag.baseFeature(AwFeatures.WEBVIEW_CONNECTIONLESS_SAFE_BROWSING,
diff --git a/android_webview/system_webview_apk_tmpl.gni b/android_webview/system_webview_apk_tmpl.gni index 3942af4..50bd7d02 100644 --- a/android_webview/system_webview_apk_tmpl.gni +++ b/android_webview/system_webview_apk_tmpl.gni
@@ -162,9 +162,6 @@ if (!_omit_dex) { product_config_java_packages = [ invoker.webview_product_config_java_package ] - if (allow_jni_multiplexing) { - enable_jni_multiplexing = true - } } if (webview_includes_weblayer) {
diff --git a/android_webview/tools/cts_config/webview_cts_gcs_path.json b/android_webview/tools/cts_config/webview_cts_gcs_path.json index 1cba621..fd2e56e 100644 --- a/android_webview/tools/cts_config/webview_cts_gcs_path.json +++ b/android_webview/tools/cts_config/webview_cts_gcs_path.json
@@ -86,6 +86,10 @@ { "match": "android.webkit.cts.WebViewClientTest#testOnSafeBrowsingHit", "_bug_id": "crbug.com/1300977" + }, + { + "match": "android.webkit.cts.WebViewTest#testLoadUrl", + "_bug_id": "crbug.com/1450170" } ] }, @@ -151,6 +155,10 @@ { "match": "android.webkit.cts.WebSettingsTest#testAppCacheEnabled", "_bug_id": "crbug.com/1246334" + }, + { + "match": "android.webkit.cts.WebViewTest#testLoadUrl", + "_bug_id": "crbug.com/1450170" } ] }, @@ -208,7 +216,13 @@ }, "test_runs": [ { - "apk": "android-cts/testcases/CtsWebkitTestCases.apk" + "apk": "android-cts/testcases/CtsWebkitTestCases.apk", + "excludes": [ + { + "match": "android.webkit.cts.WebViewTest#testLoadUrl", + "_bug_id": "crbug.com/1450170" + } + ] }, { "apk": "android-cts/testcases/CtsWebViewStartupApp.apk" @@ -276,6 +290,10 @@ { "match": "android.webkit.cts.WebViewClientTest#testOnSafeBrowsingHit", "_bug_id": "crbug.com/1245351" + }, + { + "match": "android.webkit.cts.WebViewTest#testLoadUrl", + "_bug_id": "crbug.com/1450170" } ] }, @@ -349,6 +367,10 @@ { "match": "android.webkit.cts.WebViewClientTest#testOnSafeBrowsingHitBackToSafety", "_bug_id": "crbug.com/1245351" + }, + { + "match": "android.webkit.cts.WebViewTest#testLoadUrl", + "_bug_id": "crbug.com/1450170" } ] }, @@ -437,6 +459,10 @@ { "match": "android.webkit.cts.WebViewClientTest#testOnSafeBrowsingHitBackToSafety", "_bug_id": "crbug.com/1245351" + }, + { + "match": "android.webkit.cts.WebViewTest#testLoadUrl", + "_bug_id": "crbug.com/1450170" } ] }, @@ -573,6 +599,10 @@ { "match": "android.webkit.cts.WebViewClientTest#testOnSafeBrowsingHitBackToSafety", "_bug_id": "crbug.com/1245351" + }, + { + "match": "android.webkit.cts.WebViewTest#testLoadUrl", + "_bug_id": "crbug.com/1450170" } ] }, @@ -744,6 +774,10 @@ { "match": "android.webkit.cts.WebViewTest#testSetNetworkAvailable", "_bug_id": "crbug.com/1368663" + }, + { + "match": "android.webkit.cts.WebViewTest#testLoadUrl", + "_bug_id": "crbug.com/1450170" } ] },
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 0efb848..da9dab4 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -606,9 +606,15 @@ <message name="IDS_ASH_STATUS_TRAY_CAST_PAUSE" desc="Label for a button in the cast notification to pause the current cast mirroring session to a Chromecast device"> Pause </message> + <message name="IDS_ASH_STATUS_TRAY_CAST_PAUSE_CASTING" desc="Label for a button in the system tray to pause the current cast mirroring session to a Chromecast device"> + Pause casting + </message> <message name="IDS_ASH_STATUS_TRAY_CAST_RESUME" desc="Label for a button in the cast notification to resume a paused cast mirroring session to a Chromecast device"> Resume </message> + <message name="IDS_ASH_STATUS_TRAY_CAST_RESUME_CASTING" desc="Label for a button in the system tray to resume a paused cast mirroring session to a Chromecast device"> + Resume casting + </message> <message name="IDS_ASH_STATUS_TRAY_QUIET_MODE_TOOLTIP" desc="The tooltip text for the status area icon to tell do-not-disturb mode is currently on."> Do Not Disturb is on </message>
diff --git a/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_CAST_PAUSE_CASTING.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_CAST_PAUSE_CASTING.png.sha1 new file mode 100644 index 0000000..87510852 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_CAST_PAUSE_CASTING.png.sha1
@@ -0,0 +1 @@ +c8647e60121c1b5a16205154492ba70f83d50d29 \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_CAST_RESUME_CASTING.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_CAST_RESUME_CASTING.png.sha1 new file mode 100644 index 0000000..fd0de7fe --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_CAST_RESUME_CASTING.png.sha1
@@ -0,0 +1 @@ +12ca3db87ee67fdfa25fd132901a7f491ef74f29 \ No newline at end of file
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 7a64b3d..ac21915 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -2453,7 +2453,7 @@ // on ChromeOS. BASE_FEATURE(kDeviceActiveClientChurnCohortCheckIn, "DeviceActiveClientChurnCohortCheckIn", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); // Enables or disables PSM CheckMembership for the churn cohort device active // pings on ChromeOS. @@ -2465,7 +2465,7 @@ // pings on ChromeOS. BASE_FEATURE(kDeviceActiveClientChurnObservationCheckIn, "DeviceActiveClientChurnObservationCheckIn", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); // Enables or disables PSM CheckMembership for the churn observation // device active pings on ChromeOS.
diff --git a/ash/resources/vector_icons/BUILD.gn b/ash/resources/vector_icons/BUILD.gn index 1861d26..996d54d 100644 --- a/ash/resources/vector_icons/BUILD.gn +++ b/ash/resources/vector_icons/BUILD.gn
@@ -269,6 +269,8 @@ "quick_settings_a11y_sticky_keys.icon", "quick_settings_cast.icon", "quick_settings_cast_connected.icon", + "quick_settings_circle_pause.icon", + "quick_settings_circle_play.icon", "quick_settings_circle_stop.icon", "quick_settings_left_arrow.icon", "quick_settings_managed.icon",
diff --git a/ash/resources/vector_icons/quick_settings_circle_pause.icon b/ash/resources/vector_icons/quick_settings_circle_pause.icon new file mode 100644 index 0000000..e9272e8 --- /dev/null +++ b/ash/resources/vector_icons/quick_settings_circle_pause.icon
@@ -0,0 +1,45 @@ +// 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. + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 7.5f, 13, +H_LINE_TO, 9, +V_LINE_TO, 7, +H_LINE_TO, 7.5f, +V_LINE_TO, 13, +CLOSE, +MOVE_TO, 11, 13, +H_LINE_TO, 12.5f, +V_LINE_TO, 7, +H_LINE_TO, 11, +V_LINE_TO, 13, +CLOSE, +MOVE_TO, 10, 18, +CUBIC_TO, 8.9f, 18, 7.87f, 17.79f, 6.9f, 17.38f, +CUBIC_TO, 5.92f, 16.96f, 5.07f, 16.39f, 4.33f, 15.67f, +CUBIC_TO, 3.61f, 14.93f, 3.04f, 14.08f, 2.63f, 13.1f, +CUBIC_TO, 2.21f, 12.13f, 2, 11.1f, 2, 10, +CUBIC_TO, 2, 8.89f, 2.21f, 7.85f, 2.63f, 6.9f, +CUBIC_TO, 3.04f, 5.92f, 3.61f, 5.08f, 4.33f, 4.35f, +CUBIC_TO, 5.07f, 3.62f, 5.92f, 3.04f, 6.9f, 2.63f, +CUBIC_TO, 7.87f, 2.21f, 8.9f, 2, 10, 2, +CUBIC_TO, 11.11f, 2, 12.15f, 2.21f, 13.1f, 2.63f, +CUBIC_TO, 14.08f, 3.04f, 14.92f, 3.62f, 15.65f, 4.35f, +CUBIC_TO, 16.38f, 5.08f, 16.96f, 5.92f, 17.38f, 6.9f, +CUBIC_TO, 17.79f, 7.85f, 18, 8.89f, 18, 10, +CUBIC_TO, 18, 11.1f, 17.79f, 12.13f, 17.38f, 13.1f, +CUBIC_TO, 16.96f, 14.08f, 16.38f, 14.93f, 15.65f, 15.67f, +CUBIC_TO, 14.92f, 16.39f, 14.08f, 16.96f, 13.1f, 17.38f, +CUBIC_TO, 12.15f, 17.79f, 11.11f, 18, 10, 18, +CLOSE, +MOVE_TO, 10, 16.5f, +CUBIC_TO, 11.81f, 16.5f, 13.34f, 15.87f, 14.6f, 14.6f, +CUBIC_TO, 15.87f, 13.34f, 16.5f, 11.81f, 16.5f, 10, +CUBIC_TO, 16.5f, 8.19f, 15.87f, 6.66f, 14.6f, 5.4f, +CUBIC_TO, 13.34f, 4.13f, 11.81f, 3.5f, 10, 3.5f, +CUBIC_TO, 8.19f, 3.5f, 6.66f, 4.13f, 5.4f, 5.4f, +CUBIC_TO, 4.13f, 6.66f, 3.5f, 8.19f, 3.5f, 10, +CUBIC_TO, 3.5f, 11.81f, 4.13f, 13.34f, 5.4f, 14.6f, +CUBIC_TO, 6.66f, 15.87f, 8.19f, 16.5f, 10, 16.5f, +CLOSE \ No newline at end of file
diff --git a/ash/resources/vector_icons/quick_settings_circle_play.icon b/ash/resources/vector_icons/quick_settings_circle_play.icon new file mode 100644 index 0000000..aefbbc6 --- /dev/null +++ b/ash/resources/vector_icons/quick_settings_circle_play.icon
@@ -0,0 +1,38 @@ +// 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. + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 8, 13.5f, +LINE_TO, 13.5f, 10, +LINE_TO, 8, 6.5f, +V_LINE_TO, 13.5f, +CLOSE, +MOVE_TO, 10, 18, +CUBIC_TO, 8.9f, 18, 7.87f, 17.79f, 6.9f, 17.38f, +CUBIC_TO, 5.92f, 16.96f, 5.07f, 16.39f, 4.33f, 15.67f, +CUBIC_TO, 3.61f, 14.93f, 3.04f, 14.08f, 2.63f, 13.1f, +CUBIC_TO, 2.21f, 12.13f, 2, 11.1f, 2, 10, +CUBIC_TO, 2, 8.89f, 2.21f, 7.85f, 2.63f, 6.9f, +CUBIC_TO, 3.04f, 5.92f, 3.61f, 5.08f, 4.33f, 4.35f, +CUBIC_TO, 5.07f, 3.62f, 5.92f, 3.04f, 6.9f, 2.63f, +CUBIC_TO, 7.87f, 2.21f, 8.9f, 2, 10, 2, +CUBIC_TO, 11.11f, 2, 12.15f, 2.21f, 13.1f, 2.63f, +CUBIC_TO, 14.08f, 3.04f, 14.92f, 3.62f, 15.65f, 4.35f, +CUBIC_TO, 16.38f, 5.08f, 16.96f, 5.92f, 17.38f, 6.9f, +CUBIC_TO, 17.79f, 7.85f, 18, 8.89f, 18, 10, +CUBIC_TO, 18, 11.1f, 17.79f, 12.13f, 17.38f, 13.1f, +CUBIC_TO, 16.96f, 14.08f, 16.38f, 14.93f, 15.65f, 15.67f, +CUBIC_TO, 14.92f, 16.39f, 14.08f, 16.96f, 13.1f, 17.38f, +CUBIC_TO, 12.15f, 17.79f, 11.11f, 18, 10, 18, +CLOSE, +MOVE_TO, 10, 16.5f, +CUBIC_TO, 11.81f, 16.5f, 13.34f, 15.87f, 14.6f, 14.6f, +CUBIC_TO, 15.87f, 13.34f, 16.5f, 11.81f, 16.5f, 10, +CUBIC_TO, 16.5f, 8.19f, 15.87f, 6.66f, 14.6f, 5.4f, +CUBIC_TO, 13.34f, 4.13f, 11.81f, 3.5f, 10, 3.5f, +CUBIC_TO, 8.19f, 3.5f, 6.66f, 4.13f, 5.4f, 5.4f, +CUBIC_TO, 4.13f, 6.66f, 3.5f, 8.19f, 3.5f, 10, +CUBIC_TO, 3.5f, 11.81f, 4.13f, 13.34f, 5.4f, 14.6f, +CUBIC_TO, 6.66f, 15.87f, 8.19f, 16.5f, 10, 16.5f, +CLOSE \ No newline at end of file
diff --git a/ash/system/cast/cast_detailed_view.cc b/ash/system/cast/cast_detailed_view.cc index 577511e..aceda3c 100644 --- a/ash/system/cast/cast_detailed_view.cc +++ b/ash/system/cast/cast_detailed_view.cc
@@ -35,11 +35,15 @@ #include "ui/views/border.h" #include "ui/views/controls/scroll_view.h" #include "ui/views/layout/box_layout.h" +#include "ui/views/view_class_properties.h" namespace ash { namespace { +// Extra spacing to add between cast stop buttons and the edge of the qs tray. +constexpr int kStopButtonExtraMargin = 4; + // Returns the correct vector icon for |icon_type|. Some types may be different // for branded builds. const gfx::VectorIcon& SinkIconTypeToIcon(SinkIconType icon_type) { @@ -65,6 +69,21 @@ return kSystemMenuCastGenericIcon; } +std::unique_ptr<views::View> MakeButtonContainer() { + std::unique_ptr<views::View> button_container = + std::make_unique<views::View>(); + views::BoxLayout* manager = + button_container->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal)); + manager->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kEnd); + manager->set_between_child_spacing(kTrayPopupLabelRightPadding); + button_container->SetProperty( + views::kMarginsKey, + gfx::Insets::TLBR(0, 0, 0, + kStopButtonExtraMargin + kQsExtraMarginsFromRightEdge)); + return button_container; +} + } // namespace CastDetailedView::CastDetailedView(DetailedViewDelegate* delegate) @@ -85,40 +104,18 @@ void CastDetailedView::OnDevicesUpdated( const std::vector<SinkAndRoute>& sinks_routes) { + sinks_and_routes_.clear(); // Add/update existing. for (const auto& device : sinks_routes) sinks_and_routes_.insert(std::make_pair(device.sink.id, device)); - // Remove non-existent sinks. Removing an element invalidates all existing - // iterators. - auto iter = sinks_and_routes_.begin(); - while (iter != sinks_and_routes_.end()) { - bool has_receiver = false; - for (auto& receiver : sinks_routes) { - if (iter->first == receiver.sink.id) - has_receiver = true; - } - - if (has_receiver) - ++iter; - else - iter = sinks_and_routes_.erase(iter); - } - // Update UI. UpdateReceiverListFromCachedData(); Layout(); } void CastDetailedView::UpdateReceiverListFromCachedData() { - // Remove all of the existing views. - view_to_sink_map_.clear(); - scroll_content()->RemoveAllChildViews(); - add_access_code_device_ = nullptr; - if (zero_state_view_) { - RemoveChildViewT(zero_state_view_.get()); - zero_state_view_ = nullptr; - } + RemoveAllViews(); // QsRevamp places items in a rounded container. const bool is_qs_revamp_enabled = features::IsQsRevampEnabled(); @@ -130,18 +127,7 @@ // Per product requirement, access code receiver should be shown before other // receivers. if (CastConfigController::Get()->AccessCodeCastingEnabled()) { - add_access_code_device_ = AddScrollListItem( - item_container, vector_icons::kKeyboardIcon, - l10n_util::GetStringUTF16( - IDS_ASH_STATUS_TRAY_CAST_ACCESS_CODE_CAST_CONNECT)); - if (chromeos::features::IsJellyEnabled()) { - // `views::ImageView` does not support changing the color, so set the - // image with an updated `ui::ImageModel`. - add_access_code_device_->icon()->SetImage(ui::ImageModel::FromVectorIcon( - vector_icons::kKeyboardIcon, cros_tokens::kCrosSysPrimary)); - add_access_code_device_->text_label()->SetEnabledColorId( - cros_tokens::kCrosSysPrimary); - } + AddAccessCodeCastButton(item_container); } // Add a view for each receiver. @@ -153,20 +139,10 @@ base::UTF8ToUTF16(sink.name)); view_to_sink_map_[container] = sink.id; - // Add a stop casting button if this machine ("local source") is casting to - // the device. See also CastNotificationController::OnDevicesUpdated(). + // Add receiver action buttons if this machine ("local source") is casting + // to the device. See also CastNotificationController::OnDevicesUpdated(). if (is_qs_revamp_enabled && !route.id.empty() && route.is_local_source) { - auto button = std::make_unique<PillButton>( - base::BindRepeating(&CastDetailedView::StopCasting, - base::Unretained(this), route.id), - l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAST_STOP_CASTING), - PillButton::kDefaultWithIconLeading, &kQuickSettingsCircleStopIcon); - button->SetBackgroundColorId(cros_tokens::kCrosSysErrorContainer); - button->SetIconColorId(cros_tokens::kCrosSysError); - button->SetButtonTextColorId(cros_tokens::kCrosSysError); - container->AddRightView( - button.release(), - views::CreateEmptyBorder(gfx::Insets::TLBR(0, 0, 0, 4))); + AddReceiverActionButtons(sink, route, container, item_container); } } @@ -221,6 +197,102 @@ CloseBubble(); // Deletes `this`. } +void CastDetailedView::FreezePressed(const std::string& route_id, + bool is_frozen) { + DCHECK(features::IsQsRevampEnabled()); + if (is_frozen) { + CastConfigController::Get()->UnfreezeRoute(route_id); + } else { + CastConfigController::Get()->FreezeRoute(route_id); + CloseBubble(); + } +} + +void CastDetailedView::RemoveAllViews() { + view_to_sink_map_.clear(); + sink_extra_views_map_.clear(); + scroll_content()->RemoveAllChildViews(); + add_access_code_device_ = nullptr; + if (zero_state_view_) { + RemoveChildViewT(zero_state_view_.get()); + zero_state_view_ = nullptr; + } +} + +void CastDetailedView::AddAccessCodeCastButton( + views::View* receiver_list_view) { + add_access_code_device_ = + AddScrollListItem(receiver_list_view, vector_icons::kKeyboardIcon, + l10n_util::GetStringUTF16( + IDS_ASH_STATUS_TRAY_CAST_ACCESS_CODE_CAST_CONNECT)); + if (chromeos::features::IsJellyEnabled()) { + // `views::ImageView` does not support changing the color, so set the + // image with an updated `ui::ImageModel`. + add_access_code_device_->icon()->SetImage(ui::ImageModel::FromVectorIcon( + vector_icons::kKeyboardIcon, cros_tokens::kCrosSysPrimary)); + add_access_code_device_->text_label()->SetEnabledColorId( + cros_tokens::kCrosSysPrimary); + } +} + +void CastDetailedView::AddReceiverActionButtons( + const CastSink& sink, + const CastRoute& route, + HoverHighlightView* receiver_view, + views::View* receiver_list_view) { + std::unique_ptr<PillButton> stop_button = CreateStopButton(route); + + // In the case that we want to show a pause/resume button, then we must + // put both buttons on a row below the cast sink. + if (route.freeze_info.can_freeze) { + std::unique_ptr<PillButton> freeze_button = CreateFreezeButton(route); + std::unique_ptr<views::View> button_container = MakeButtonContainer(); + std::vector<views::View*> extra_views; + extra_views.emplace_back( + button_container->AddChildView(std::move(freeze_button))); + extra_views.emplace_back( + button_container->AddChildView(std::move(stop_button))); + sink_extra_views_map_[sink.id] = extra_views; + + // Add the button container directly as a new row in the list of cast + // devices. Since the associated device was just added, the buttons will + // show up correctly below their associated device. + receiver_list_view->AddChildView(std::move(button_container)); + } else { + receiver_view->AddRightView(stop_button.release(), + views::CreateEmptyBorder(gfx::Insets::TLBR( + 0, 0, 0, kStopButtonExtraMargin))); + } +} + +std::unique_ptr<PillButton> CastDetailedView::CreateStopButton( + const CastRoute& route) { + std::unique_ptr<PillButton> stop_button = std::make_unique<PillButton>( + base::BindRepeating(&CastDetailedView::StopCasting, + base::Unretained(this), route.id), + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAST_STOP_CASTING), + PillButton::kDefaultWithIconLeading, &kQuickSettingsCircleStopIcon); + stop_button->SetBackgroundColorId(cros_tokens::kCrosSysErrorContainer); + stop_button->SetIconColorId(cros_tokens::kCrosSysError); + stop_button->SetButtonTextColorId(cros_tokens::kCrosSysError); + return stop_button; +} + +std::unique_ptr<PillButton> CastDetailedView::CreateFreezeButton( + const CastRoute& route) { + std::unique_ptr<PillButton> freeze_button = std::make_unique<PillButton>( + base::BindRepeating(&CastDetailedView::FreezePressed, + base::Unretained(this), route.id, + route.freeze_info.is_frozen), + route.freeze_info.is_frozen + ? l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAST_RESUME_CASTING) + : l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAST_PAUSE_CASTING), + PillButton::kSecondaryWithIconLeading, + route.freeze_info.is_frozen ? &kQuickSettingsCirclePlayIcon + : &kQuickSettingsCirclePauseIcon); + return freeze_button; +} + BEGIN_METADATA(CastDetailedView, TrayDetailedView) END_METADATA
diff --git a/ash/system/cast/cast_detailed_view.h b/ash/system/cast/cast_detailed_view.h index b8e21e19..4d1c7522 100644 --- a/ash/system/cast/cast_detailed_view.h +++ b/ash/system/cast/cast_detailed_view.h
@@ -22,6 +22,7 @@ namespace ash { class HoverHighlightView; +class PillButton; // This view displays a list of cast receivers that can be clicked on and casted // to. It is activated by clicking on the chevron inside of @@ -61,12 +62,38 @@ // Stops casting the route identified by `route_id`. void StopCasting(const std::string& route_id); + // Pauses or resumes the route given by `route_id`. + void FreezePressed(const std::string& route_id, bool is_frozen); + + // Remove all child views from CastDetailedView. + void RemoveAllViews(); + + // Adds a button which allows for adding a device using an access code. + void AddAccessCodeCastButton(views::View* receiver_list_view); + + // Adds buttons associated with a receiver so the user may perform route + // actions like stopping or pausing. + void AddReceiverActionButtons(const CastSink& sink, + const CastRoute& route, + HoverHighlightView* receiver_view, + views::View* receiver_list_view); + + // Creates a stop button which, when pressed, stops the associated `route`. + std::unique_ptr<PillButton> CreateStopButton(const CastRoute& route); + + // Creates a freeze button which, when pressed, pauses / resumes the + // associated `route`. + std::unique_ptr<PillButton> CreateFreezeButton(const CastRoute& route); + // A mapping from the sink id to the receiver/activity data. std::map<std::string, SinkAndRoute> sinks_and_routes_; // A mapping from the view pointer to the associated activity sink id. std::map<views::View*, std::string> view_to_sink_map_; + // A mapping of sink id to the associated extra views. + std::map<std::string, std::vector<views::View*>> sink_extra_views_map_; + // Special list item that, if clicked, launches the access code casting dialog raw_ptr<HoverHighlightView, ExperimentalAsh> add_access_code_device_ = nullptr;
diff --git a/ash/system/cast/cast_detailed_view_unittest.cc b/ash/system/cast/cast_detailed_view_unittest.cc index 88e821e..fb30dc4 100644 --- a/ash/system/cast/cast_detailed_view_unittest.cc +++ b/ash/system/cast/cast_detailed_view_unittest.cc
@@ -57,6 +57,10 @@ return views; } + std::vector<views::View*> GetExtraViewsForSink(const std::string& sink_id) { + return detailed_view_->sink_extra_views_map_[sink_id]; + } + views::View* GetZeroStateView() { return detailed_view_->zero_state_view_; } // Adds two simulated cast devices. @@ -226,4 +230,33 @@ EXPECT_FALSE(row->right_view()); } +TEST_F(CastDetailedViewTest, FreezeButton) { + // Set up a fake sink and route, as if this Chromebook is casting to the + // device. And, the route may be frozen. + std::vector<SinkAndRoute> devices; + SinkAndRoute device; + device.sink.id = "fake_sink_id_1"; + device.sink.name = "Sink Name 1"; + device.sink.sink_icon_type = SinkIconType::kCast; + device.route.id = "fake_route_id_1"; + device.route.title = "Title 1"; + // Simulate a local source (this Chromebook). + device.route.is_local_source = true; + device.route.freeze_info.can_freeze = true; + devices.push_back(device); + OnDevicesUpdated(devices); + + std::vector<views::View*> views = GetExtraViewsForSink("fake_sink_id_1"); + ASSERT_EQ(views.size(), 2u); + auto* freeze_button = views[0]; + EXPECT_TRUE(views::IsViewClass<PillButton>(freeze_button)); + EXPECT_EQ(freeze_button->GetTooltipText(gfx::Point()), u"Pause casting"); + + // Clicking on the button pauses casting. + LeftClickOn(freeze_button); + EXPECT_EQ(cast_config_.freeze_route_count(), 1u); + EXPECT_EQ(cast_config_.freeze_route_route_id(), "fake_route_id_1"); + EXPECT_EQ(delegate_->close_bubble_call_count(), 1u); +} + } // namespace ash
diff --git a/ash/system/human_presence/OWNERS b/ash/system/human_presence/OWNERS index 40600b67..35989f4 100644 --- a/ash/system/human_presence/OWNERS +++ b/ash/system/human_presence/OWNERS
@@ -1,5 +1,4 @@ # Primary OWNERS charleszhao@chromium.org -martis@chromium.org -# Backup OWNERS +# Backup OWNERS \ No newline at end of file
diff --git a/ash/system/input_device_settings/pref_handlers/keyboard_pref_handler_impl.cc b/ash/system/input_device_settings/pref_handlers/keyboard_pref_handler_impl.cc index 2597787..8b2f3e6 100644 --- a/ash/system/input_device_settings/pref_handlers/keyboard_pref_handler_impl.cc +++ b/ash/system/input_device_settings/pref_handlers/keyboard_pref_handler_impl.cc
@@ -213,13 +213,13 @@ ForceKeyboardSettingPersistence& force_persistence) { mojom::KeyboardSettingsPtr settings = mojom::KeyboardSettings::New(); - const auto* top_row_are_fkeys_preference = - prefs->GetUserPrefValue(prefs::kSendFunctionKeys); - settings->top_row_are_fkeys = - top_row_are_fkeys_preference - ? top_row_are_fkeys_preference->GetBool() - : GetDefaultTopRowAreFKeysValue(keyboard_policies, keyboard); - force_persistence.top_row_are_fkeys = top_row_are_fkeys_preference != nullptr; + // For the transition period, since the default behavior changed for external + // keyboards, the value from prefs must always be used even if the user did + // not explicitly configure it. Users expect their settings to remain + // consistent even if we think they may like the new default better. + settings->top_row_are_fkeys = prefs->GetBoolean(prefs::kSendFunctionKeys); + force_persistence.top_row_are_fkeys = + prefs->GetUserPrefValue(prefs::kSendFunctionKeys) != nullptr; settings->suppress_meta_fkey_rewrites = kDefaultSuppressMetaFKeyRewrites; // Do not persist as default should not be persisted.
diff --git a/ash/system/input_device_settings/pref_handlers/keyboard_pref_handler_unittest.cc b/ash/system/input_device_settings/pref_handlers/keyboard_pref_handler_unittest.cc index ba2d8cf..f8c7afa 100644 --- a/ash/system/input_device_settings/pref_handlers/keyboard_pref_handler_unittest.cc +++ b/ash/system/input_device_settings/pref_handlers/keyboard_pref_handler_unittest.cc
@@ -586,6 +586,30 @@ kDefaultSuppressMetaFKeyRewrites); } +TEST_F(KeyboardPrefHandlerTest, + KeyboardSendFunctionKeysTransitionPrefAlwaysConsistent) { + mojom::Keyboard keyboard; + keyboard.is_external = true; + keyboard.meta_key = mojom::MetaKey::kExternalMeta; + keyboard.device_key = kKeyboardKey1; + { + base::test::ScopedFeatureList disable_settings_split_feature_list; + disable_settings_split_feature_list.InitAndDisableFeature( + features::kInputDeviceSettingsSplit); + Shell::Get()->input_device_tracker()->OnKeyboardConnected(keyboard); + } + + // Initialize keyboard settings for the device and check that the global + // prefs were used as defaults even though the `kSendFunctionKeys` pref was + // never changed and it goes against the default since the keyboard is + // external. + mojom::KeyboardSettingsPtr settings = + CallInitializeKeyboardSettings(keyboard); + ASSERT_EQ(settings->top_row_are_fkeys, kGlobalSendFunctionKeys); + ASSERT_EQ(settings->suppress_meta_fkey_rewrites, + kDefaultSuppressMetaFKeyRewrites); +} + TEST_F(KeyboardPrefHandlerTest, ModifierRemappingsFromGlobalPrefs) { // Disable flag in this test since `InputDeviceTracker` only records // connected devices when the settings split flag is disabled.
diff --git a/ash/webui/personalization_app/README.md b/ash/webui/personalization_app/README.md index 89ba906..b431c32d 100644 --- a/ash/webui/personalization_app/README.md +++ b/ash/webui/personalization_app/README.md
@@ -97,10 +97,18 @@ * mojom handling logic * mojom handler unit tests +### Debugging tests +* The [browser test doc](https://www.chromium.org/developers/testing/browser-tests/#debugging) +has some useful information. +* Inject `debugger;` as a breakpoint. +* Run a specific test/test suite: `test("test name", () => ...) => test.only("test name"...)`. +* Debug flaky tests: Pass flags `--gtest_repeat=1000 --gtest_break_on_failure`. + ## Environment Setup ### VSCode - Follow [vscode setup](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/vscode.md). + - (Optional) Set up [code-server](go/vscode/remote_development_via_web) for remote development. - Create `tsconfig.json` using [helper script](https://chromium.googlesource.com/chromium/src/+/HEAD/ash/webui/personalization_app/tools/gen_tsconfig.py). Please follow the help doc in the header of the helper script. - Edit `${PATH_TO_CHROMIUM}/src/.git/info/exclude` and add these lines
diff --git a/ash/webui/print_management/resources/print_management.html b/ash/webui/print_management/resources/print_management.html index 51dcacd..5ab84ea 100644 --- a/ash/webui/print_management/resources/print_management.html +++ b/ash/webui/print_management/resources/print_management.html
@@ -167,11 +167,14 @@ </iron-list> </template> - <div id="ongoingEmptyState" hidden="[[ongoingPrintJobs.length]]"> + <div id="ongoingEmptyState" hidden="[[!shouldShowOngoingEmptyState( + ongoingPrintJobs.length, printJobs.length)]]"> [[i18n('noPrintJobInProgress')]] </div> - <printer-setup-info hidden$="[[!showSetupAssistance]]"></printer-setup-info> + <printer-setup-info hidden="[[!shouldShowSetupAssistance( + ongoingPrintJobs.length, printJobs.length)]]"> + </printer-setup-info> <template is="dom-if" if="[[printJobs.length]]" restamp> <div id="historyHeaderContainer" class="column-headers flex-center">
diff --git a/ash/webui/print_management/resources/print_management.ts b/ash/webui/print_management/resources/print_management.ts index 1827f5c3..557137e 100644 --- a/ash/webui/print_management/resources/print_management.ts +++ b/ash/webui/print_management/resources/print_management.ts
@@ -348,6 +348,18 @@ this.$.deleteIcon.classList.toggle( 'delete-disabled', this.shouldDisableClearAllButton); } + + /** Determine if printer setup UI should be shown. */ + private shouldShowSetupAssistance(): boolean { + return this.showSetupAssistance && this.ongoingPrintJobs.length === 0 && + this.printJobs.length === 0; + } + + /** Determine if ongoing jobs empty messaging should be shown. */ + private shouldShowOngoingEmptyState(): boolean { + return !this.shouldShowSetupAssistance() && + this.ongoingPrintJobs.length === 0; + } } customElements.define(PrintManagementElement.is, PrintManagementElement);
diff --git a/base/metrics/histogram_samples.h b/base/metrics/histogram_samples.h index 7f34093..3fe25047 100644 --- a/base/metrics/histogram_samples.h +++ b/base/metrics/histogram_samples.h
@@ -257,7 +257,7 @@ // external object. The callers guarantees the value will outlive this // instance. std::unique_ptr<Metadata> meta_owned_; - raw_ptr<Metadata> meta_; + raw_ptr<Metadata, LeakedDanglingUntriaged> meta_; }; class BASE_EXPORT SampleCountIterator {
diff --git a/base/metrics/persistent_memory_allocator.h b/base/metrics/persistent_memory_allocator.h index 806df91c..bd736dd 100644 --- a/base/metrics/persistent_memory_allocator.h +++ b/base/metrics/persistent_memory_allocator.h
@@ -900,7 +900,7 @@ // The underlying object that does the actual allocation of memory. Its // lifetime must exceed that of all DelayedPersistentAllocation objects // that use it. - const raw_ptr<PersistentMemoryAllocator> allocator_; + const raw_ptr<PersistentMemoryAllocator, LeakedDanglingUntriaged> allocator_; // The desired type and size of the allocated segment plus the offset // within it for the defined request. @@ -912,7 +912,8 @@ // stored once the allocation is complete. If multiple delayed allocations // share the same pointer then an allocation on one will amount to an // allocation for all. - const raw_ptr<volatile std::atomic<Reference>> reference_; + const raw_ptr<volatile std::atomic<Reference>, LeakedDanglingUntriaged> + reference_; // No DISALLOW_COPY_AND_ASSIGN as it's okay to copy/move these objects. };
diff --git a/base/metrics/persistent_sample_map.h b/base/metrics/persistent_sample_map.h index 21afc90..cd336a20 100644 --- a/base/metrics/persistent_sample_map.h +++ b/base/metrics/persistent_sample_map.h
@@ -98,13 +98,14 @@ // The allocator that manages histograms inside persistent memory. This is // owned externally and is expected to live beyond the life of this object. - raw_ptr<PersistentHistogramAllocator> allocator_; + raw_ptr<PersistentHistogramAllocator, LeakedDanglingUntriaged> allocator_; // The object that manages sample records inside persistent memory. This is // owned by the |allocator_| object (above) and so, like it, is expected to // live beyond the life of this object. This value is lazily-initialized on // first use via the GetRecords() accessor method. - raw_ptr<PersistentSampleMapRecords> records_ = nullptr; + raw_ptr<PersistentSampleMapRecords, LeakedDanglingUntriaged> records_ = + nullptr; }; } // namespace base
diff --git a/base/metrics/sample_vector.h b/base/metrics/sample_vector.h index 0160f59..0f22647f 100644 --- a/base/metrics/sample_vector.h +++ b/base/metrics/sample_vector.h
@@ -113,7 +113,7 @@ mutable std::atomic<HistogramBase::AtomicCount*> counts_{nullptr}; // Shares the same BucketRanges with Histogram object. - const raw_ptr<const BucketRanges> bucket_ranges_; + const raw_ptr<const BucketRanges, LeakedDanglingUntriaged> bucket_ranges_; }; // A sample vector that uses local memory for the counts array.
diff --git a/build/android/BUILD.gn b/build/android/BUILD.gn index bff6112..7341fb7ac 100644 --- a/build/android/BUILD.gn +++ b/build/android/BUILD.gn
@@ -71,7 +71,6 @@ } robolectric_binary("build_junit_tests") { # Test has no JNI, so skip JNI Generator step. - generate_final_jni = false resources_package = "org.chromium.build" sources = [ "junit/src/org/chromium/build/AndroidAssetsTest.java",
diff --git a/build/config/android/abi.gni b/build/config/android/abi.gni index 1101b4a..1aafbd0f 100644 --- a/build/config/android/abi.gni +++ b/build/config/android/abi.gni
@@ -88,7 +88,7 @@ assert(false, "Unknown target CPU: $target_cpu") } -# Do not define android_app_secondary_abi_cpu or android_app_secondary_abi for +# Do not define android_secondary_abi_cpu or android_app_secondary_abi for # target_cpu's that are 32-bit-only or 64-bit-only, as they are not used. The # presence of this variable may be used in conjunction with android_64bit_target_cpu # to identify target_cpu's that are 32-bit-only or 64-bit-only.
diff --git a/build/config/android/config.gni b/build/config/android/config.gni index 54e95d2..5714ed5 100644 --- a/build/config/android/config.gni +++ b/build/config/android/config.gni
@@ -283,12 +283,6 @@ # Reduce build time by using d8 incremental build. enable_incremental_d8 = true - # Use hashed symbol names to reduce JNI symbol overhead. - use_hashed_jni_names = !is_java_debug - - # Enables JNI multiplexing to reduce JNI native methods overhead. - allow_jni_multiplexing = false - # Enables trace event injection on Android views with bytecode rewriting. # This adds an additional step on android_app_bundle_module targets that # adds trace events to some methods in android.view.View subclasses.
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index d3427ebd..0a854267 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -4263,20 +4263,6 @@ } } } - - template("jni_sources_list") { - generated_file(target_name) { - forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "deps" ]) - outputs = [ invoker.output ] - data_keys = [ "jni_source_files" ] - rebase = root_build_dir - metadata = { - # This target is just collecting source files used - this is not a - # legitimate dependency. - shared_libraries_barrier = [] - } - } - } } # Create a zip archive corresponding to an application bundle module.
diff --git a/build/config/android/jni.gni b/build/config/android/jni.gni index 3d496ef..bcbf33e 100644 --- a/build/config/android/jni.gni +++ b/build/config/android/jni.gni
@@ -2,9 +2,201 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//build/config/android/rules.gni") +import("//build/config/android/config.gni") +import("//build/config/python.gni") import("//build/partitioned_shared_library.gni") +declare_args() { + # Enables JNI multiplexing to reduce JNI native methods overhead. + allow_jni_multiplexing = false + + # Use hashed symbol names to reduce JNI symbol overhead. + use_hashed_jni_names = !is_java_debug +} + +# Use a dedicated include dir so that files can #include headers from other +# toolchains without affecting non-JNI #includes. +if (target_os == "android") { + jni_headers_dir = "$root_build_dir/gen/jni_headers" +} else { + # Chrome OS builds cannot share gen/ directories because is_android=false + # within default_toolchain. + jni_headers_dir = "$root_gen_dir/jni_headers" +} + +template("jni_sources_list") { + generated_file(target_name) { + forward_variables_from(invoker, TESTONLY_AND_VISIBILITY + [ "deps" ]) + outputs = [ invoker.output ] + data_keys = [ "jni_source_files" ] + rebase = root_build_dir + metadata = { + # This target is just collecting source files used - this is not a + # legitimate dependency. + shared_libraries_barrier = [] + } + } +} + +# Declare a jni registration target. +# +# This target generates a srcjar containing a copy of GEN_JNI.java, which has +# the native methods of all dependent java files. It can also create a .h file +# for use with manual JNI registration. +# +# The script does not scan any generated sources (those within .srcjars, or +# within root_build_dir). This could be fixed by adding deps & logic to scan +# .srcjars, but isn't currently needed. +# +# See base/android/jni_generator/jni_registration_generator.py for more info +# about the format of the header file. +# +# Variables +# targets: List of .build_config.json supported targets to provide java sources. +# manual_jni_registration: Manually do JNI registration - required for feature +# splits which provide their own native library. (optional) +# file_exclusions: List of .java files that should be skipped. (optional) +# namespace: Registration functions will be wrapped into this. (optional) +# require_native_mocks: Enforce that any native calls using +# org.chromium.base.annotations.NativeMethods must have a mock set +# (optional). +# enable_native_mocks: Allow native calls using +# org.chromium.base.annotations.NativeMethods to be mocked in tests +# (optional). +# +# Example +# generate_jni_registration("chrome_jni_registration") { +# targets = [ ":chrome_public_apk" ] +# manual_jni_registration = false +# file_exclusions = [ +# "//path/to/Exception.java", +# ] +# } +template("generate_jni_registration") { + if (defined(invoker.native_deps)) { + _jni_sources_list = "$target_gen_dir/$target_name.jnisources" + _jni_sources_target = "${target_name}__jni_sources" + jni_sources_list(_jni_sources_target) { + forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) + deps = invoker.native_deps + output = _jni_sources_list + } + } + + action_with_pydeps(target_name) { + forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) + + script = "//base/android/jni_generator/jni_registration_generator.py" + inputs = [] + deps = [] + _srcjar_output = "$target_gen_dir/$target_name.srcjar" + outputs = [ _srcjar_output ] + depfile = "$target_gen_dir/$target_name.d" + + args = [ + "--srcjar-path", + rebase_path(_srcjar_output, root_build_dir), + "--depfile", + rebase_path(depfile, root_build_dir), + ] + + if (defined(_jni_sources_target)) { + inputs += [ _jni_sources_list ] + deps += [ ":$_jni_sources_target" ] + args += [ + "--native-sources-file", + rebase_path(_jni_sources_list, root_build_dir), + ] + } + foreach(_target, invoker.java_targets) { + # Due to robolectric, we can't import internal_rules.gni unconditionally, + # which means that build_config_target_suffix isn't always available, so + # we hardcode the value of it here. + deps += [ "${_target}__build_config_crbug_908819($default_toolchain)" ] + _build_config = + get_label_info("${_target}($default_toolchain)", "target_gen_dir") + + "/" + get_label_info("${_target}($default_toolchain)", "name") + + ".build_config.json" + _rebased_build_config = rebase_path(_build_config, root_build_dir) + inputs += [ _build_config ] + + args += [ + # This is a list of .sources files. + "--java-sources-files=@FileArg($_rebased_build_config:deps_info:jni_all_source)", + ] + } + + if (defined(invoker.include_testonly)) { + _include_testonly = invoker.include_testonly + } else { + _include_testonly = defined(testonly) && testonly + } + if (_include_testonly) { + args += [ "--include-test-only" ] + } + + if (use_hashed_jni_names) { + args += [ "--use-proxy-hash" ] + } + + if (defined(invoker.enable_native_mocks) && invoker.enable_native_mocks) { + args += [ "--enable-proxy-mocks" ] + + if (defined(invoker.require_native_mocks) && + invoker.require_native_mocks) { + args += [ "--require-mocks" ] + } + } + + if (defined(invoker.remove_uncalled_jni) && invoker.remove_uncalled_jni) { + args += [ "--remove-uncalled-methods" ] + } + if (defined(invoker.add_stubs_for_missing_jni) && + invoker.add_stubs_for_missing_jni) { + args += [ "--add-stubs-for-missing-native" ] + } + + _manual_jni_registration = defined(invoker.manual_jni_registration) && + invoker.manual_jni_registration + _enable_jni_multiplexing = defined(invoker.enable_jni_multiplexing) && + invoker.enable_jni_multiplexing + if (_manual_jni_registration) { + args += [ "--manual-jni-registration" ] + } + if (_enable_jni_multiplexing) { + args += [ "--enable-jni-multiplexing" ] + } + + if (_manual_jni_registration || _enable_jni_multiplexing) { + _subdir = rebase_path(target_gen_dir, root_gen_dir) + _jni_header_output = + "$jni_headers_dir/$_subdir/${target_name}_generated.h" + outputs += [ _jni_header_output ] + args += [ + "--header-path", + rebase_path(_jni_header_output, root_build_dir), + ] + + # This gives targets depending on this registration access to our generated header. + public_configs = [ "//build/config/android:jni_include_dir" ] + } + + if (defined(invoker.file_exclusions)) { + _rebase_file_exclusions = + rebase_path(invoker.file_exclusions, root_build_dir) + args += [ "--file-exclusions=$_rebase_file_exclusions" ] + } + + if (defined(invoker.namespace)) { + args += [ "--namespace=${invoker.namespace}" ] + } + + if (defined(invoker.module_name)) { + args += [ "--module-name=${invoker.module_name}" ] + } + } +} + # This is a wrapper around an underlying native target which inserts JNI # registration. #
diff --git a/build/config/android/linker_version_script.gni b/build/config/android/linker_version_script.gni index 864233c8..77d9983 100644 --- a/build/config/android/linker_version_script.gni +++ b/build/config/android/linker_version_script.gni
@@ -3,6 +3,7 @@ # found in the LICENSE file. import("//build/config/android/config.gni") +import("//build/config/android/jni.gni") import("//build/config/python.gni") # Generate a custom linker version script that can later be used with
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 0c6f5a3..05bc8ad 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -6,6 +6,7 @@ # Some projects (e.g. V8) do not have non-build directories DEPS'ed in. import("//build/config/android/config.gni") import("//build/config/android/copy_ex.gni") +import("//build/config/android/jni.gni") import("//build/config/clang/clang.gni") import("//build/config/compiler/compiler.gni") import("//build/config/coverage/coverage.gni") @@ -16,16 +17,6 @@ import("//build/toolchain/toolchain.gni") assert(is_android || is_robolectric) -# Use a dedicated include dir so that files can #include headers from other -# toolchains without affecting non-JNI #includes. -if (target_os == "android") { - jni_headers_dir = "$root_build_dir/gen/jni_headers" -} else { - # Chrome OS builds cannot share gen/ directories because is_android=false - # within default_toolchain. - jni_headers_dir = "$root_gen_dir/jni_headers" -} - if (target_cpu == "arm") { _sanitizer_arch = "arm" } else if (target_cpu == "arm64") { @@ -217,11 +208,11 @@ inputs += invoker.sources _input_args = rebase_path(invoker.sources, root_build_dir) _input_names = invoker.sources - if (!is_robolectric && use_hashed_jni_names) { + if (use_hashed_jni_names) { args += [ "--use_proxy_hash" ] } - if (!is_robolectric && defined(invoker.enable_jni_multiplexing) && + if (defined(invoker.enable_jni_multiplexing) && invoker.enable_jni_multiplexing) { args += [ "--enable_jni_multiplexing" ] } @@ -351,162 +342,6 @@ # non-robolectric things if (enable_java_templates && is_android) { - # Declare a jni registration target. - # - # This target generates a srcjar containing a copy of GEN_JNI.java, which has - # the native methods of all dependent java files. It can also create a .h file - # for use with manual JNI registration. - # - # The script does not scan any generated sources (those within .srcjars, or - # within root_build_dir). This could be fixed by adding deps & logic to scan - # .srcjars, but isn't currently needed. - # - # See base/android/jni_generator/jni_registration_generator.py for more info - # about the format of the header file. - # - # Variables - # targets: List of .build_config.json supported targets to provide java sources. - # manual_jni_registration: Manually do JNI registration - required for feature - # splits which provide their own native library. (optional) - # file_exclusions: List of .java files that should be skipped. (optional) - # namespace: Registration functions will be wrapped into this. (optional) - # require_native_mocks: Enforce that any native calls using - # org.chromium.base.annotations.NativeMethods must have a mock set - # (optional). - # enable_native_mocks: Allow native calls using - # org.chromium.base.annotations.NativeMethods to be mocked in tests - # (optional). - # - # Example - # generate_jni_registration("chrome_jni_registration") { - # targets = [ ":chrome_public_apk" ] - # manual_jni_registration = false - # file_exclusions = [ - # "//path/to/Exception.java", - # ] - # } - template("generate_jni_registration") { - if (defined(invoker.native_deps)) { - _jni_sources_list = "$target_gen_dir/$target_name.jnisources" - _jni_sources_target = "${target_name}__jni_sources" - jni_sources_list(_jni_sources_target) { - forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) - deps = invoker.native_deps - output = _jni_sources_list - } - } - - action_with_pydeps(target_name) { - forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) - - script = "//base/android/jni_generator/jni_registration_generator.py" - inputs = [] - deps = [] - _srcjar_output = "$target_gen_dir/$target_name.srcjar" - outputs = [ _srcjar_output ] - depfile = "$target_gen_dir/$target_name.d" - - args = [ - "--srcjar-path", - rebase_path(_srcjar_output, root_build_dir), - "--depfile", - rebase_path(depfile, root_build_dir), - ] - - if (defined(_jni_sources_target)) { - inputs += [ _jni_sources_list ] - deps += [ ":$_jni_sources_target" ] - args += [ - "--native-sources-file", - rebase_path(_jni_sources_list, root_build_dir), - ] - } - foreach(_target, invoker.java_targets) { - deps += [ "${_target}$build_config_target_suffix($default_toolchain)" ] - _build_config = - get_label_info("${_target}($default_toolchain)", "target_gen_dir") + - "/" + get_label_info("${_target}($default_toolchain)", "name") + - ".build_config.json" - _rebased_build_config = rebase_path(_build_config, root_build_dir) - inputs += [ _build_config ] - - args += [ - # This is a list of .sources files. - "--java-sources-files=@FileArg($_rebased_build_config:deps_info:jni_all_source)", - ] - } - - if (defined(invoker.include_testonly)) { - _include_testonly = invoker.include_testonly - } else { - _include_testonly = defined(testonly) && testonly - } - if (_include_testonly) { - args += [ "--include-test-only" ] - } - - if (use_hashed_jni_names) { - args += [ "--use-proxy-hash" ] - } - - if (defined(invoker.enable_native_mocks) && invoker.enable_native_mocks) { - args += [ "--enable-proxy-mocks" ] - - if (defined(invoker.require_native_mocks) && - invoker.require_native_mocks) { - args += [ "--require-mocks" ] - } - } - - if (defined(invoker.remove_uncalled_jni) && invoker.remove_uncalled_jni) { - args += [ "--remove-uncalled-methods" ] - } - if (defined(invoker.add_stubs_for_missing_jni) && - invoker.add_stubs_for_missing_jni) { - args += [ "--add-stubs-for-missing-native" ] - } - - _manual_jni_registration = defined(invoker.manual_jni_registration) && - invoker.manual_jni_registration - _enable_jni_multiplexing = defined(invoker.enable_jni_multiplexing) && - invoker.enable_jni_multiplexing - if (_manual_jni_registration) { - args += [ "--manual-jni-registration" ] - } - if (_enable_jni_multiplexing) { - args += [ "--enable-jni-multiplexing" ] - } - - if (_manual_jni_registration || _enable_jni_multiplexing) { - _subdir = rebase_path(target_gen_dir, root_gen_dir) - _jni_header_output = - "$jni_headers_dir/$_subdir/${target_name}_generated.h" - outputs += [ _jni_header_output ] - args += [ - "--header-path", - rebase_path(_jni_header_output, root_build_dir), - ] - - # This gives targets depending on this registration access to our generated header. - public_configs = [ "//build/config/android:jni_include_dir" ] - } - - if (defined(invoker.file_exclusions)) { - _rebase_file_exclusions = - rebase_path(invoker.file_exclusions, root_build_dir) - args += [ "--file-exclusions=$_rebase_file_exclusions" ] - } - - if (defined(invoker.namespace)) { - args += [ "--namespace=${invoker.namespace}" ] - } - - if (defined(invoker.module_name)) { - args += [ "--module-name=${invoker.module_name}" ] - } - } - } - # Declare a target for c-preprocessor-generated java files # # NOTE: For generating Java conterparts to enums prefer using the java_cpp_enum @@ -1577,21 +1412,17 @@ _generate_final_jni = !defined(invoker.generate_final_jni) || invoker.generate_final_jni if (_generate_final_jni) { - _jni_srcjar_target_name = "${target_name}__final_jni" - _outer_target_name = target_name - - generate_jni_registration(_jni_srcjar_target_name) { - enable_native_mocks = true - require_native_mocks = !defined(invoker.shared_libraries) - java_targets = [ ":$_outer_target_name" ] - } - + _jni_srcjar_deps = [] if (defined(invoker.shared_libraries)) { foreach(_dep, invoker.shared_libraries) { + _dep_no_toolchain = get_label_info(_dep, "label_no_toolchain") + _dep_toolchain = get_label_info(_dep, "toolchain") assert( - string_replace(_dep, robolectric_toolchain, "") != _dep, + _dep_toolchain == robolectric_toolchain, "$target_name has shared_libraries with incorrect toolchain. " + "Should contain (\$robolectric_toolchain) suffix: $_dep") + _jni_srcjar_deps += + [ "${_dep_no_toolchain}__jni_registration($_dep_toolchain)" ] } # Write shared library output files of all dependencies to a file. Those @@ -1604,6 +1435,16 @@ walk_keys = [ "shared_libraries_barrier" ] rebase = root_build_dir } + } else { + _outer_target_name = target_name + _jni_srcjar_target_name = "${target_name}__final_jni" + generate_jni_registration(_jni_srcjar_target_name) { + enable_native_mocks = true + require_native_mocks = true + java_targets = [ ":$_outer_target_name" ] + add_stubs_for_missing_jni = true + } + _jni_srcjar_deps = [ ":$_jni_srcjar_target_name" ] } _native_libraries_target_name = "${target_name}__native_libraries" write_native_libraries_java(_native_libraries_target_name) { @@ -1648,10 +1489,7 @@ "//build/android:build_config_for_testing_gen", ] if (_generate_final_jni) { - srcjar_deps += [ - ":$_jni_srcjar_target_name", - ":$_native_libraries_target_name", - ] + srcjar_deps += [ ":$_native_libraries_target_name" ] + _jni_srcjar_deps } }
diff --git a/build/config/clang/BUILD.gn b/build/config/clang/BUILD.gn index ed39cc6..ae371093f 100644 --- a/build/config/clang/BUILD.gn +++ b/build/config/clang/BUILD.gn
@@ -56,6 +56,15 @@ "raw-ptr-exclude-path=base/containers/span.h", ] } + + if (enable_check_raw_ref_fields) { + cflags += [ + "-Xclang", + "-plugin-arg-find-bad-constructs", + "-Xclang", + "check-raw-ref-fields", + ] + } } }
diff --git a/build/config/clang/clang.gni b/build/config/clang/clang.gni index 0de9792..0ff60e9 100644 --- a/build/config/clang/clang.gni +++ b/build/config/clang/clang.gni
@@ -18,6 +18,11 @@ build_with_chromium && !is_official_build && ((is_linux && !is_castos) || (is_android && !is_cast_android)) + # TODO(crbug.com/1446146): Merge with enable_check_raw_ptr_fields once both + # checks are activated on the same set of platforms. + enable_check_raw_ref_fields = + build_with_chromium && !is_official_build && is_linux && !is_castos + clang_base_path = default_clang_base_path # Specifies whether or not bitcode should be embedded during compilation.
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1 index eef0c6f..a6e3523 100644 --- a/build/fuchsia/linux_internal.sdk.sha1 +++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@ -12.20230520.1.1 +12.20230605.1.1
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 9eadf0a..6280b9a9 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -754,6 +754,7 @@ "//chrome/browser/commerce/merchant_viewer/android:java", "//chrome/browser/content_creation/notes/internal/android:java", "//chrome/browser/download/internal/android:java", + "//chrome/browser/mandatory_reauth/android/internal:java", "//chrome/browser/password_check:internal_java", "//chrome/browser/password_edit_dialog/android:java", "//chrome/browser/password_entry_edit/android/internal:java", @@ -2710,6 +2711,7 @@ "//chrome/browser/password_manager/android/pwd_migration:javatests", "//chrome/browser/subresource_filter:subresource_filter_javatests", "//chrome/browser/touch_to_fill/android:test_java", + "//chrome/browser/touch_to_fill/password_generation/android/internal:javatests", "//chrome/browser/touch_to_fill/payments/android/internal:javatests", "//chrome/browser/ui/android/fast_checkout/internal:javatests", "//chrome/browser/ui/android/omnibox:javatests", @@ -3271,6 +3273,7 @@ "java/src/org/chromium/chrome/browser/autofill/SaveUpdateAddressProfilePromptController.java", "java/src/org/chromium/chrome/browser/autofill/settings/AutofillPaymentMethodsDelegate.java", "java/src/org/chromium/chrome/browser/autofill/settings/AutofillProfileBridge.java", + "java/src/org/chromium/chrome/browser/autofill/settings/SettingsLauncherHelper.java", "java/src/org/chromium/chrome/browser/autofill/settings/VirtualCardEnrollmentFields.java", "java/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchBridge.java", "java/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTask.java", @@ -3485,6 +3488,7 @@ "//chrome/browser/image_descriptions:jni_headers", "//chrome/browser/incognito:jni_headers", "//chrome/browser/locale:jni_headers", + "//chrome/browser/mandatory_reauth/android:jni_headers", "//chrome/browser/preferences:jni_headers", "//chrome/browser/privacy:jni_headers", "//chrome/browser/profiles/android:jni_headers", @@ -3515,9 +3519,6 @@ chrome_common_shared_library(target_name) { sources = [ "../browser/android/chrome_entry_point.cc" ] deps = [] - if (allow_jni_multiplexing) { - enable_jni_multiplexing = true - } if (defined(invoker.deps)) { deps += invoker.deps } @@ -3617,9 +3618,6 @@ deps += [ "//weblayer:weblayer_lib" ] } - if (allow_jni_multiplexing) { - enable_jni_multiplexing = true - } if (android_64bit_target_cpu) { java_targets = [ "//chrome/android:monochrome_64_public_bundle" ] } else {
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index d10f2f7..918f57f 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -143,6 +143,7 @@ "java/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardEnrollmentDialog.java", "java/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardUnenrollmentDialog.java", "java/src/org/chromium/chrome/browser/autofill/settings/CreditCardNumberFormattingTextWatcher.java", + "java/src/org/chromium/chrome/browser/autofill/settings/SettingsLauncherHelper.java", "java/src/org/chromium/chrome/browser/autofill/settings/VirtualCardEnrollmentFields.java", "java/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchBridge.java", "java/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchProvider.java",
diff --git a/chrome/android/chrome_public_apk_tmpl.gni b/chrome/android/chrome_public_apk_tmpl.gni index 3f2270f1..06ea16b 100644 --- a/chrome/android/chrome_public_apk_tmpl.gni +++ b/chrome/android/chrome_public_apk_tmpl.gni
@@ -302,10 +302,6 @@ custom_assertion_handler = crash_reporting_assertion_handler } - if (allow_jni_multiplexing) { - enable_jni_multiplexing = true - } - # Include resource strings files only for supported locales. aapt_locale_allowlist = platform_pak_locales
diff --git a/chrome/android/expectations/lint-baseline.xml b/chrome/android/expectations/lint-baseline.xml index 4df8f95d..9a93c0af 100644 --- a/chrome/android/expectations/lint-baseline.xml +++ b/chrome/android/expectations/lint-baseline.xml
@@ -3704,17 +3704,6 @@ <issue id="WrongConstant" - message="Must be one of: DiscoverabilityAction.PERMISSION_ICON_SHOWN, DiscoverabilityAction.PAGE_INFO_OPENED, DiscoverabilityAction.PERMISSIONS_OPENED, DiscoverabilityAction.PERMISSION_CHANGED, DiscoverabilityAction.STORE_ICON_SHOWN, DiscoverabilityAction.PAGE_INFO_OPENED_FROM_STORE_ICON, DiscoverabilityAction.STORE_INFO_OPENED" - errorLine1=" DiscoverabilityAction.NUM_ENTRIES);" - errorLine2=" ~~~~~~~~~~~"> - <location - file="../../components/page_info/android/java/src/org/chromium/components/page_info/PageInfoDiscoverabilityMetrics.java" - line="48" - column="39"/> - </issue> - - <issue - id="WrongConstant" message="Must be one of: PasswordCheckUserAction.START_CHECK_AUTOMATICALLY, PasswordCheckUserAction.START_CHECK_MANUALLY, PasswordCheckUserAction.CANCEL_CHECK, PasswordCheckUserAction.CHANGE_PASSWORD, PasswordCheckUserAction.CHANGE_PASSWORD_MANUALLY, PasswordCheckUserAction.VIEW_PASSWORD_CLICK, PasswordCheckUserAction.VIEWED_PASSWORD, PasswordCheckUserAction.COPIED_PASSWORD, PasswordCheckUserAction.EDIT_PASSWORD_CLICK, PasswordCheckUserAction.EDITED_PASSWORD, PasswordCheckUserAction.DELETE_PASSWORD_CLICK, PasswordCheckUserAction.DELETED_PASSWORD" errorLine1=" userAction, PasswordCheckUserAction.COUNT);" errorLine2=" ~~~~~">
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 524d87f..6096e8f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -67,8 +67,6 @@ import org.chromium.chrome.browser.app.tabmodel.TabModelOrchestrator; import org.chromium.chrome.browser.app.tabmodel.TabWindowManagerSingleton; import org.chromium.chrome.browser.app.tabmodel.TabbedModeTabModelOrchestrator; -import org.chromium.chrome.browser.auxiliary_search.AuxiliarySearchController; -import org.chromium.chrome.browser.auxiliary_search.AuxiliarySearchControllerImpl; import org.chromium.chrome.browser.back_press.BackPressManager; import org.chromium.chrome.browser.back_press.MinimizeAppAndCloseTabBackPressHandler; import org.chromium.chrome.browser.back_press.MinimizeAppAndCloseTabBackPressHandler.MinimizeAppAndCloseTabType; @@ -329,10 +327,6 @@ * Keeps track of the pref for the last time since this activity was stopped. */ private ChromeInactivityTracker mInactivityTracker; - /** - * The controller for the auxiliary search. - */ - private AuxiliarySearchController mAuxiliarySearchController; // This is the cached value of mIntentHandler#shouldIgnoreIntent and shouldn't be read directly. // Use #shouldIgnoreIntent instead. @@ -1350,9 +1344,6 @@ mTabModelOrchestrator.setSkipSavingNonActiveNtps(skipSavingNonActiveNtps); } - mAuxiliarySearchController = new AuxiliarySearchControllerImpl( - Profile.getLastUsedRegularProfile(), mTabModelSelector); - mAuxiliarySearchController.register(this.getLifecycleDispatcher()); mInactivityTracker.register(this.getLifecycleDispatcher()); boolean isIntentWithEffect = false; boolean isMainIntentFromLauncher = false;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillProfileBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillProfileBridge.java index 6f25cb8..9de4971 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillProfileBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillProfileBridge.java
@@ -4,24 +4,16 @@ package org.chromium.chrome.browser.autofill.settings; -import android.app.Activity; - import androidx.annotation.IntDef; import androidx.annotation.VisibleForTesting; -import androidx.fragment.app.Fragment; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.NativeMethods; -import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.browser.autofill.editors.EditorProperties.DropdownKeyValue; -import org.chromium.chrome.browser.settings.SettingsLauncherImpl; -import org.chromium.components.browser_ui.settings.SettingsLauncher; -import org.chromium.content_public.browser.WebContents; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.lang.ref.WeakReference; import java.text.Collator; import java.util.ArrayList; import java.util.Collections; @@ -209,26 +201,6 @@ } } - @CalledByNative - private static void showAutofillProfileSettings(WebContents webContents) { - RecordUserAction.record("AutofillAddressesViewed"); - showSettingSubpage(webContents, AutofillProfilesFragment.class); - } - - @CalledByNative - private static void showAutofillCreditCardSettings(WebContents webContents) { - RecordUserAction.record("AutofillCreditCardsViewed"); - showSettingSubpage(webContents, AutofillPaymentMethodsFragment.class); - } - - private static void showSettingSubpage( - WebContents webContents, Class<? extends Fragment> fragment) { - WeakReference<Activity> currentActivity = - webContents.getTopLevelNativeWindow().getActivity(); - SettingsLauncher settingsLauncher = new SettingsLauncherImpl(); - settingsLauncher.launchSettingsActivity(currentActivity.get(), fragment); - } - @NativeMethods @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) public interface Natives {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/SettingsLauncherHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/SettingsLauncherHelper.java new file mode 100644 index 0000000..0f39d29 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/SettingsLauncherHelper.java
@@ -0,0 +1,39 @@ +// 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.chrome.browser.autofill.settings; + +import android.content.Context; + +import androidx.fragment.app.Fragment; + +import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.metrics.RecordUserAction; +import org.chromium.chrome.browser.settings.SettingsLauncherImpl; +import org.chromium.components.browser_ui.settings.SettingsLauncher; +import org.chromium.content_public.browser.WebContents; + +/** Launches autofill settings subpages. */ +public class SettingsLauncherHelper { + @CalledByNative + private static void showAutofillProfileSettings(WebContents webContents) { + RecordUserAction.record("AutofillAddressesViewed"); + showSettingSubpage(webContents, AutofillProfilesFragment.class); + } + + @CalledByNative + private static void showAutofillCreditCardSettings(WebContents webContents) { + RecordUserAction.record("AutofillCreditCardsViewed"); + showSettingSubpage(webContents, AutofillPaymentMethodsFragment.class); + } + + private static void showSettingSubpage( + WebContents webContents, Class<? extends Fragment> fragment) { + Context context = webContents.getTopLevelNativeWindow().getActivity().get(); + if (context != null) { + SettingsLauncher settingsLauncher = new SettingsLauncherImpl(); + settingsLauncher.launchSettingsActivity(context, fragment); + } + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/AddToBookmarksToolbarButtonController.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/AddToBookmarksToolbarButtonController.java index 0ff490e..1acd0a9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/AddToBookmarksToolbarButtonController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/AddToBookmarksToolbarButtonController.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.bookmarks; import android.content.Context; +import android.content.res.Configuration; import android.content.res.Resources; import android.view.View; @@ -15,6 +16,8 @@ import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.Supplier; import org.chromium.chrome.R; +import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; +import org.chromium.chrome.browser.lifecycle.ConfigurationChangedObserver; import org.chromium.chrome.browser.tab.CurrentTabObserver; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; @@ -25,20 +28,25 @@ import org.chromium.components.feature_engagement.EventConstants; import org.chromium.components.feature_engagement.FeatureConstants; import org.chromium.components.feature_engagement.Tracker; +import org.chromium.ui.base.DeviceFormFactor; import java.util.Objects; /** * Defines a toolbar button to add the current web page to bookmarks. */ -public class AddToBookmarksToolbarButtonController extends BaseButtonDataProvider { +public class AddToBookmarksToolbarButtonController + extends BaseButtonDataProvider implements ConfigurationChangedObserver { + private final ActivityLifecycleDispatcher mActivityLifecycleDispatcher; private final Supplier<TabBookmarker> mTabBookmarkerSupplier; private final Supplier<Tracker> mTrackerSupplier; private final ObservableSupplier<BookmarkModel> mBookmarkModelSupplier; private final ButtonSpec mFilledButtonSpec; private final ButtonSpec mEmptyButtonSpec; + private final Context mContext; private CurrentTabObserver mCurrentTabObserver; private BookmarkModel mObservedBookmarkModel; + private boolean mIsTablet; private final Callback<BookmarkModel> mBookmarkModelSupplierObserver = new Callback<BookmarkModel>() { @@ -72,8 +80,8 @@ * changes and checking if the current tab is bookmarked. */ public AddToBookmarksToolbarButtonController(ObservableSupplier<Tab> activeTabSupplier, - Context context, Supplier<TabBookmarker> tabBookmarkerSupplier, - Supplier<Tracker> trackerSupplier, + Context context, ActivityLifecycleDispatcher activityLifecycleDispatcher, + Supplier<TabBookmarker> tabBookmarkerSupplier, Supplier<Tracker> trackerSupplier, ObservableSupplier<BookmarkModel> bookmarkModelSupplier) { // By default use the empty star drawable with an "Add to bookmarks" description. super(activeTabSupplier, /* modalDialogManager = */ null, @@ -81,10 +89,13 @@ context.getString(R.string.accessibility_menu_bookmark), /* actionChipLabelResId = */ Resources.ID_NULL, /* supportsTinting = */ true, /* iphCommandBuilder = */ null, AdaptiveToolbarButtonVariant.ADD_TO_BOOKMARKS); + mActivityLifecycleDispatcher = activityLifecycleDispatcher; mTabBookmarkerSupplier = tabBookmarkerSupplier; mTrackerSupplier = trackerSupplier; + mContext = context; mBookmarkModelSupplier = bookmarkModelSupplier; + mActivityLifecycleDispatcher.register(this); mBookmarkModelSupplier.addObserver(mBookmarkModelSupplierObserver); mCurrentTabObserver = new CurrentTabObserver(activeTabSupplier, new EmptyTabObserver() { @Override @@ -100,6 +111,8 @@ context.getString(R.string.menu_edit_bookmark), true, /* iphCommandBuilder= */ null, AdaptiveToolbarButtonVariant.ADD_TO_BOOKMARKS, /* actionChipLabelResId = */ Resources.ID_NULL); + + mIsTablet = DeviceFormFactor.isNonMultiDisplayContextOnTablet(mContext); } private void refreshBookmarkIcon() { @@ -119,6 +132,13 @@ } @Override + protected boolean shouldShowButton(Tab tab) { + if (mIsTablet) return false; + + return super.shouldShowButton(tab); + } + + @Override protected IPHCommandBuilder getIphCommandBuilder(Tab tab) { return new IPHCommandBuilder(tab.getContext().getResources(), FeatureConstants @@ -129,6 +149,17 @@ } @Override + public void onConfigurationChanged(Configuration configuration) { + boolean isTablet = DeviceFormFactor.isNonMultiDisplayContextOnTablet(mContext); + if (mIsTablet == isTablet) { + return; + } + mIsTablet = isTablet; + + mButtonData.setCanShow(shouldShowButton(mActiveTabSupplier.get())); + } + + @Override public void onClick(View view) { if (!mTabBookmarkerSupplier.hasValue() || !mActiveTabSupplier.hasValue()) return; @@ -157,6 +188,10 @@ mCurrentTabObserver = null; } + if (mActivityLifecycleDispatcher != null) { + mActivityLifecycleDispatcher.unregister(this); + } + super.destroy(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java index 62b097b4..5670e8f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
@@ -1156,7 +1156,8 @@ mActivityTabProvider, trackerSupplier); AddToBookmarksToolbarButtonController addToBookmarksToolbarButtonController = new AddToBookmarksToolbarButtonController(mActivityTabProvider, mActivity, - mTabBookmarkerSupplier, trackerSupplier, mBookmarkModelSupplier); + mActivityLifecycleDispatcher, mTabBookmarkerSupplier, trackerSupplier, + mBookmarkModelSupplier); AdaptiveToolbarButtonController adaptiveToolbarButtonController = new AdaptiveToolbarButtonController(mActivity, new SettingsLauncherImpl(), mActivityLifecycleDispatcher, new AdaptiveButtonActionMenuCoordinator(),
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/AddToBookmarksToolbarButtonControllerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/AddToBookmarksToolbarButtonControllerUnitTest.java index fdb527c..5555826 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/AddToBookmarksToolbarButtonControllerUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/AddToBookmarksToolbarButtonControllerUnitTest.java
@@ -8,6 +8,9 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.Activity; +import android.content.res.Configuration; +import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Looper; @@ -21,8 +24,10 @@ import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; import org.robolectric.Shadows; import org.robolectric.annotation.Config; @@ -32,6 +37,8 @@ import org.chromium.base.test.util.Features.EnableFeatures; import org.chromium.base.test.util.UserActionTester; import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.init.ActivityLifecycleDispatcherImpl; +import org.chromium.chrome.browser.lifecycle.ConfigurationChangedObserver; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabObserver; import org.chromium.chrome.browser.toolbar.ButtonData; @@ -59,6 +66,11 @@ private TabBookmarker mTabBookmarker; @Mock private BookmarkModel mBookmarkModel; + @Mock + private ActivityLifecycleDispatcherImpl mActivityLifecycleDispatcher; + @Captor + private ArgumentCaptor<ConfigurationChangedObserver> mConfigurationChangedObserver; + private ObservableSupplierImpl<Tab> mTabSupplier; private ObservableSupplierImpl<BookmarkModel> mBookmarkModelSupplier; @@ -82,18 +94,73 @@ mActionTester.tearDown(); } + /** Sets device qualifiers and notifies the activity about configuration change. */ + private void applyQualifiers(Activity activity, String qualifiers) { + RuntimeEnvironment.setQualifiers(qualifiers); + Configuration configuration = Resources.getSystem().getConfiguration(); + // ChromeTabbedActivity takes care of calling onConfigurationChanged on + // ActivityLifecycleDispatcher, but this is a TestActivity so we do it manually. + activity.onConfigurationChanged(configuration); + mConfigurationChangedObserver.getValue().onConfigurationChanged(configuration); + } + + private AddToBookmarksToolbarButtonController createController(Activity activity) { + AddToBookmarksToolbarButtonController addToBookmarksToolbarButtonController = + new AddToBookmarksToolbarButtonController(mTabSupplier, activity, + mActivityLifecycleDispatcher, + () -> mTabBookmarker, () -> mTracker, mBookmarkModelSupplier); + verify(mActivityLifecycleDispatcher).register(mConfigurationChangedObserver.capture()); + return addToBookmarksToolbarButtonController; + } + @Test - public void testButtonData() { + @Config(qualifiers = "w390dp-h820dp-land") + public void testButtonData_shownOnPhone() { mActivityScenarioRule.getScenario().onActivity(activity -> { when(mTab.getContext()).thenReturn(activity); AddToBookmarksToolbarButtonController addToBookmarksToolbarButtonController = - new AddToBookmarksToolbarButtonController(mTabSupplier, activity, - () -> mTabBookmarker, () -> mTracker, mBookmarkModelSupplier); + createController(activity); ButtonData buttonData = addToBookmarksToolbarButtonController.get(mTab); Assert.assertTrue(buttonData.canShow()); Assert.assertTrue(buttonData.isEnabled()); Assert.assertNotNull(buttonData.getButtonSpec()); + + applyQualifiers(activity, "+port"); + + Assert.assertTrue(addToBookmarksToolbarButtonController.get(mTab).canShow()); + }); + } + + @Test + @Config(qualifiers = "w600dp-h820dp") + public void testButtonData_notShownOnTablet() { + mActivityScenarioRule.getScenario().onActivity(activity -> { + when(mTab.getContext()).thenReturn(activity); + AddToBookmarksToolbarButtonController addToBookmarksToolbarButtonController = + createController(activity); + ButtonData buttonData = addToBookmarksToolbarButtonController.get(mTab); + + Assert.assertFalse(buttonData.canShow()); + applyQualifiers(activity, "+land"); + + Assert.assertFalse(buttonData.canShow()); + }); + } + + @Test + @Config(qualifiers = "w600dp-h820dp") + public void testButtonData_visibilityChangesOnScreenSizeUpdate() { + mActivityScenarioRule.getScenario().onActivity(activity -> { + when(mTab.getContext()).thenReturn(activity); + AddToBookmarksToolbarButtonController addToBookmarksToolbarButtonController = + createController(activity); + ButtonData buttonData = addToBookmarksToolbarButtonController.get(mTab); + + Assert.assertFalse(buttonData.canShow()); + applyQualifiers(activity, "w390dp-h820dp"); + + Assert.assertTrue(buttonData.canShow()); }); } @@ -102,8 +169,7 @@ mActivityScenarioRule.getScenario().onActivity(activity -> { when(mTab.getContext()).thenReturn(activity); AddToBookmarksToolbarButtonController addToBookmarksToolbarButtonController = - new AddToBookmarksToolbarButtonController(mTabSupplier, activity, - () -> mTabBookmarker, () -> mTracker, mBookmarkModelSupplier); + createController(activity); addToBookmarksToolbarButtonController.onClick(null); Assert.assertEquals( @@ -124,8 +190,7 @@ when(mBookmarkModel.hasBookmarkIdForTab(mTab)).thenReturn(false); when(mBookmarkModel.hasBookmarkIdForTab(anotherTab)).thenReturn(true); AddToBookmarksToolbarButtonController addToBookmarksToolbarButtonController = - new AddToBookmarksToolbarButtonController(mTabSupplier, activity, - () -> mTabBookmarker, () -> mTracker, mBookmarkModelSupplier); + createController(activity); ButtonDataObserver mockButtonObserver = mock(ButtonDataObserver.class); addToBookmarksToolbarButtonController.addObserver(mockButtonObserver); @@ -158,8 +223,7 @@ // Set the current tab as not bookmarked. when(mBookmarkModel.hasBookmarkIdForTab(mTab)).thenReturn(false); AddToBookmarksToolbarButtonController addToBookmarksToolbarButtonController = - new AddToBookmarksToolbarButtonController(mTabSupplier, activity, - () -> mTabBookmarker, () -> mTracker, mBookmarkModelSupplier); + createController(activity); // If an ObservableSupplier already has a value then its change callback will be called // immediately as a separate task, idle the main looper to ensure all Observable @@ -201,8 +265,7 @@ // Set the current tab as not bookmarked. when(mBookmarkModel.hasBookmarkIdForTab(mTab)).thenReturn(false); AddToBookmarksToolbarButtonController addToBookmarksToolbarButtonController = - new AddToBookmarksToolbarButtonController(mTabSupplier, activity, - () -> mTabBookmarker, () -> mTracker, mBookmarkModelSupplier); + createController(activity); // If an ObservableSupplier already has a value then its change callback will be called // immediately as a separate task, idle the main looper to ensure all Observable
diff --git a/chrome/app/PRESUBMIT.py b/chrome/app/PRESUBMIT.py index 6bf4324..df98e69 100644 --- a/chrome/app/PRESUBMIT.py +++ b/chrome/app/PRESUBMIT.py
@@ -24,14 +24,15 @@ filename_filter = lambda x: x.LocalPath().endswith(('.grd', '.grdp')) for f, line_num, line in input_api.RightHandSideLines(filename_filter): - if 'PRODUCT_NAME' in line: + if ('PRODUCT_NAME' in line and 'name="IDS_PRODUCT_NAME"' not in line and + 'name="IDS_SHORT_PRODUCT_NAME"' not in line): problems.append('%s:%d' % (f.LocalPath(), line_num)) if problems: return [output_api.PresubmitPromptWarning( - "Don't use PRODUCT_NAME placeholders in string resources. Instead, add " - "separate strings to google_chrome_strings.grd and " - "chromium_strings.grd. See http://goo.gl/6614MQ for more information." + "Don't use PRODUCT_NAME placeholders in string resources. Instead, " + "add separate strings to google_chrome_strings.grd and " + "chromium_strings.grd. See http://goo.gl/6614MQ for more information. " "Problems with this check? Contact dubroy@chromium.org.", items=problems)] return []
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index d5cc68c..1fbc396 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd
@@ -276,12 +276,31 @@ <part file="settings_chromium_strings.grdp" /> </if> - <message name="IDS_PRODUCT_NAME" desc="The Chrome application name"> - Chromium - </message> - <message name="IDS_SHORT_PRODUCT_NAME" desc="The Chrome application short name."> - Chromium - </message> + <!-- + Even though Google Chrome for Testing is a separate brand, there is + no separate file for it. Instead, we use the same file as Chromium, with + a few select overrides for the most prominent end-user strings. + + Rationale: https://goo.gle/chrome-for-testing#bookmark=id.n1rat320av91 + --> + <if expr="_is_chrome_for_testing_branded"> + <then> + <message name="IDS_PRODUCT_NAME" desc="The Chrome for Testing application name" translateable="false"> + Google Chrome for Testing + </message> + <message name="IDS_SHORT_PRODUCT_NAME" desc="The Chrome for Testing application short name." translateable="false"> + Chrome for Testing + </message> + </then> + <else> + <message name="IDS_PRODUCT_NAME" desc="The Chromium application name"> + Chromium + </message> + <message name="IDS_SHORT_PRODUCT_NAME" desc="The Chromium application short name."> + Chromium + </message> + </else> + </if> <if expr="is_win"> <message name="IDS_SXS_SHORTCUT_NAME" desc="Unused in Chromium builds" translateable="false"> </message> @@ -799,17 +818,35 @@ </message> <if expr="use_titlecase and not chromeos_ash"> - <message name="IDS_ABOUT" desc="In Title Case: The text label of the About Chrome menu item"> - About &Chromium - </message> + <if expr="_is_chrome_for_testing_branded"> + <then> + <message name="IDS_ABOUT" desc="In Title Case: The text label of the About Chrome for Testing menu item"> + About &Google Chrome for Testing + </message> + </then> + <else> + <message name="IDS_ABOUT" desc="In Title Case: The text label of the About Chrome menu item"> + About &Chromium + </message> + </else> + </if> <message name="IDS_RELAUNCH_TO_UPDATE" desc="In Title Case: The text label of the relaunch to update Chrome menu item"> Relaunch to Update &Chromium </message> </if> <if expr="not use_titlecase and not chromeos_ash"> - <message name="IDS_ABOUT" desc="The text label of the About Chrome menu item"> - About &Chromium - </message> + <if expr="_is_chrome_for_testing_branded"> + <then> + <message name="IDS_ABOUT" desc="The text label of the About Chrome for Testing menu item"> + About &Google Chrome for Testing + </message> + </then> + <else> + <message name="IDS_ABOUT" desc="The text label of the About Chrome menu item"> + About &Chromium + </message> + </else> + </if> <message name="IDS_RELAUNCH_TO_UPDATE" desc="The text label of the relaunch to update Chrome menu item"> Relaunch to update &Chromium </message>
diff --git a/chrome/app/settings_chromium_strings.grdp b/chrome/app/settings_chromium_strings.grdp index 115b0d2..4fe3b8c7e 100644 --- a/chrome/app/settings_chromium_strings.grdp +++ b/chrome/app/settings_chromium_strings.grdp
@@ -8,12 +8,24 @@ </message> </if> <!-- About Page --> - <message name="IDS_SETTINGS_ABOUT_PROGRAM" desc="Menu title for the About Chromium page."> - About Chromium - </message> - <message name="IDS_SETTINGS_GET_HELP_USING_CHROME" desc="Text of the button which takes the user to the Chrome help page."> - Get help with Chromium - </message> + <if expr="_is_chrome_for_testing_branded"> + <then> + <message name="IDS_SETTINGS_ABOUT_PROGRAM" desc="Menu title for the About Chrome for Testing page."> + About Chrome for Testing + </message> + <message name="IDS_SETTINGS_GET_HELP_USING_CHROME" desc="Text of the button which takes the user to the Chrome for Testing help page."> + Get help with Chrome for Testing + </message> + </then> + <else> + <message name="IDS_SETTINGS_ABOUT_PROGRAM" desc="Menu title for the About Chromium page."> + About Chromium + </message> + <message name="IDS_SETTINGS_GET_HELP_USING_CHROME" desc="Text of the button which takes the user to the Chrome help page."> + Get help with Chromium + </message> + </else> + </if> <if expr="not chromeos_ash"> <message name="IDS_SETTINGS_UPGRADE_UPDATING" desc="Status label: Updating Chromium"> Updating Chromium @@ -88,9 +100,18 @@ <message name="IDS_SETTINGS_DEFAULT_BROWSER_ERROR" desc="The text displayed when Chrome cannot determine or set the default browser"> Chromium cannot determine or set the default browser </message> - <message name="IDS_SETTINGS_DEFAULT_BROWSER_SECONDARY" desc="The text displayed when Chromium is installed in side-by-side mode, which does not support setting as the default browser."> - This is a secondary installation of Chromium, and cannot be made your default browser. - </message> + <if expr="_is_chrome_for_testing_branded"> + <then> + <message name="IDS_SETTINGS_DEFAULT_BROWSER_SECONDARY" desc="The text displayed when Chrome for Testing is installed in side-by-side mode, which does not support setting as the default browser."> + Google Chrome for Testing cannot be made your default browser. + </message> + </then> + <else> + <message name="IDS_SETTINGS_DEFAULT_BROWSER_SECONDARY" desc="The text displayed when Chromium is installed in side-by-side mode, which does not support setting as the default browser."> + This is a secondary installation of Chromium, and cannot be made your default browser. + </message> + </else> + </if> </if> <!-- Privacy Page -->
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index ad806e2..5c981e6 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1034,6 +1034,8 @@ "page_load_metrics/observers/service_worker_page_load_metrics_observer.h", "page_load_metrics/observers/signed_exchange_page_load_metrics_observer.cc", "page_load_metrics/observers/signed_exchange_page_load_metrics_observer.h", + "page_load_metrics/observers/tab_strip_page_load_metrics_observer.cc", + "page_load_metrics/observers/tab_strip_page_load_metrics_observer.h", "page_load_metrics/observers/third_party_metrics_observer.cc", "page_load_metrics/observers/third_party_metrics_observer.h", "page_load_metrics/observers/translate_page_load_metrics_observer.cc", @@ -2761,6 +2763,8 @@ "android/preferences/autofill/autofill_payment_methods_delegate.h", "android/preferences/autofill/autofill_profile_bridge.cc", "android/preferences/autofill/autofill_profile_bridge.h", + "android/preferences/autofill/settings_launcher_helper.cc", + "android/preferences/autofill/settings_launcher_helper.h", "android/preferences/browser_prefs_android.cc", "android/preferences/browser_prefs_android.h", "android/preferences/clipboard_android.cc", @@ -3013,6 +3017,8 @@ "lookalikes/safety_tip_infobar_delegate_android.h", "lookalikes/safety_tip_message_delegate_android.cc", "lookalikes/safety_tip_message_delegate_android.h", + "mandatory_reauth/android/mandatory_reauth_opt_in_view_android.cc", + "mandatory_reauth/android/mandatory_reauth_opt_in_view_android.h", "media/android/cdm/media_drm_origin_id_manager.cc", "media/android/cdm/media_drm_origin_id_manager.h", "media/android/cdm/media_drm_origin_id_manager_factory.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 60f1554..e1f2fa7 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -4791,16 +4791,6 @@ flag_descriptions::kDesktopPWAsDetailedInstallDialogName, flag_descriptions::kDesktopPWAsDetailedInstallDialogDescription, kOsAll, FEATURE_VALUE_TYPE(webapps::features::kDesktopPWAsDetailedInstallDialog)}, - {"enable-skip-service-worker-check-install-only", - flag_descriptions::kSkipServiceWorkerCheckInstallOnlyName, - flag_descriptions::kSkipServiceWorkerCheckInstallOnlyDescription, - kOsDesktop, - FEATURE_VALUE_TYPE(webapps::features::kSkipServiceWorkerCheckInstallOnly)}, - {"enable-skip-service-worker-check-install-for-promotion", - flag_descriptions::kSkipServiceWorkerForInstallPromptName, - flag_descriptions::kSkipServiceWorkerForInstallPromptDescription, - kOsDesktop, - FEATURE_VALUE_TYPE(webapps::features::kSkipServiceWorkerForInstallPrompt)}, {"record-web-app-debug-info", flag_descriptions::kRecordWebAppDebugInfoName, flag_descriptions::kRecordWebAppDebugInfoDescription, kOsDesktop, FEATURE_VALUE_TYPE(features::kRecordWebAppDebugInfo)}, @@ -10391,6 +10381,10 @@ FEATURE_VALUE_TYPE(features::kCrosWebAppShortcutUiUpdate)}, #endif // !BUILDFLAG(IS_CHROMEOS_ASH) + {"use-gpu-scheduler-dfs", flag_descriptions::kUseGpuSchedulerDfsName, + flag_descriptions::kUseGpuSchedulerDfsDescription, kOsAll, + FEATURE_VALUE_TYPE(features::kUseGpuSchedulerDfs)}, + // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host.cc b/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host.cc index 7373ba0..9ff26201 100644 --- a/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host.cc +++ b/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host.cc
@@ -25,6 +25,7 @@ #include "media/base/media_switches.h" #include "media/mojo/mojom/speech_recognition_result.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" +#include "ui/base/l10n/l10n_util.h" namespace captions { @@ -53,6 +54,8 @@ prefs_ = Profile::FromBrowserContext(GetWebContents()->GetBrowserContext()) ->GetPrefs(); context_ = CaptionBubbleContextBrowser::Create(web_contents); + + source_language_ = prefs_->GetString(prefs::kLiveCaptionLanguageCode); } LiveCaptionSpeechRecognitionHost::~LiveCaptionSpeechRecognitionHost() { @@ -71,13 +74,13 @@ } if (base::FeatureList::IsEnabled(media::kLiveTranslate) && - prefs_->GetBoolean(prefs::kLiveTranslateEnabled)) { - std::string source_language = - prefs_->GetString(prefs::kLiveCaptionLanguageCode); - std::string target_language = - prefs_->GetString(prefs::kLiveTranslateTargetLanguageCode); + prefs_->GetBoolean(prefs::kLiveTranslateEnabled) && + l10n_util::GetLanguage( + prefs_->GetString(prefs::kLiveTranslateTargetLanguageCode)) != + l10n_util::GetLanguage(source_language_)) { GetLiveTranslateController()->GetTranslation( - result, source_language, target_language, + result, source_language_, + prefs_->GetString(prefs::kLiveTranslateTargetLanguageCode), base::BindOnce(&LiveCaptionSpeechRecognitionHost::OnTranslationCallback, weak_factory_.GetWeakPtr())); std::move(reply).Run(!stop_transcriptions_); @@ -93,7 +96,13 @@ if (!live_caption_controller) return; - live_caption_controller->OnLanguageIdentificationEvent(std::move(event)); + if (event->asr_switch_result == + media::mojom::AsrSwitchResult::kSwitchSucceeded) { + source_language_ = event->language; + } + + live_caption_controller->OnLanguageIdentificationEvent(context_.get(), + std::move(event)); } void LiveCaptionSpeechRecognitionHost::OnSpeechRecognitionError() {
diff --git a/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host.h b/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host.h index 63bcb204..47549dac 100644 --- a/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host.h +++ b/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host.h
@@ -93,6 +93,9 @@ // should stop. bool stop_transcriptions_ = false; + // The source language code of the audio stream. + std::string source_language_; + // The user preferences containing the target and source language codes. raw_ptr<PrefService> prefs_;
diff --git a/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host_browsertest.cc b/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host_browsertest.cc index c1d8e3b..69f52c59 100644 --- a/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host_browsertest.cc +++ b/chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host_browsertest.cc
@@ -100,10 +100,11 @@ void OnLanguageIdentificationEvent( content::RenderFrameHost* frame_host, const std::string& language, - const media::mojom::ConfidenceLevel confidence_level) { + const media::mojom::ConfidenceLevel confidence_level, + const media::mojom::AsrSwitchResult asr_switch_result) { remotes_[frame_host]->OnLanguageIdentificationEvent( - media::mojom::LanguageIdentificationEvent::New(language, - confidence_level)); + media::mojom::LanguageIdentificationEvent::New( + language, confidence_level, asr_switch_result)); } void OnSpeechRecognitionError(content::RenderFrameHost* frame_host) { @@ -204,7 +205,8 @@ SetLiveCaptionEnabled(true); OnLanguageIdentificationEvent( - frame_host, "en-US", media::mojom::ConfidenceLevel::kHighlyConfident); + frame_host, "en-US", media::mojom::ConfidenceLevel::kHighlyConfident, + media::mojom::AsrSwitchResult::kSwitchSucceeded); } IN_PROC_BROWSER_TEST_F(LiveCaptionSpeechRecognitionHostTest, @@ -253,14 +255,11 @@ SetLiveCaptionEnabled(true); SetLiveTranslateEnabled(true); - // Dispatching the speech recognition should be successful, but the - // widget should remain hidden because the test does not fetch real - // translations. OnSpeechRecognitionRecognitionEvent( frame_host, "Elephants can live over 90 years in captivity.", /* expected_success= */ true); base::RunLoop().RunUntilIdle(); - ExpectIsWidgetVisible(false); + ExpectIsWidgetVisible(true); } } // namespace captions
diff --git a/chrome/browser/android/preferences/autofill/autofill_profile_bridge.cc b/chrome/browser/android/preferences/autofill/autofill_profile_bridge.cc index 20418bb5..fb9c52e7 100644 --- a/chrome/browser/android/preferences/autofill/autofill_profile_bridge.cc +++ b/chrome/browser/android/preferences/autofill/autofill_profile_bridge.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/android/preferences/autofill/autofill_profile_bridge.h" -#include "base/android/jni_android.h" #include "base/android/jni_array.h" #include "base/android/jni_string.h" #include "base/android/scoped_java_ref.h" @@ -14,7 +13,6 @@ #include "chrome/browser/browser_process.h" #include "components/autofill/core/browser/autofill_address_util.h" #include "components/autofill/core/browser/geo/autofill_country.h" -#include "content/public/browser/web_contents.h" #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_field.h" #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_metadata.h" #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_ui.h" @@ -158,14 +156,4 @@ return ConvertUTF8ToJavaString(env, best_language_tag); } -void ShowAutofillProfileSettings(content::WebContents* web_contents) { - Java_AutofillProfileBridge_showAutofillProfileSettings( - base::android::AttachCurrentThread(), web_contents->GetJavaWebContents()); -} - -void ShowAutofillCreditCardSettings(content::WebContents* web_contents) { - Java_AutofillProfileBridge_showAutofillCreditCardSettings( - base::android::AttachCurrentThread(), web_contents->GetJavaWebContents()); -} - } // namespace autofill
diff --git a/chrome/browser/android/preferences/autofill/autofill_profile_bridge.h b/chrome/browser/android/preferences/autofill/autofill_profile_bridge.h index 8cc5c8b..1303930 100644 --- a/chrome/browser/android/preferences/autofill/autofill_profile_bridge.h +++ b/chrome/browser/android/preferences/autofill/autofill_profile_bridge.h
@@ -5,10 +5,6 @@ #ifndef CHROME_BROWSER_ANDROID_PREFERENCES_AUTOFILL_AUTOFILL_PROFILE_BRIDGE_H_ #define CHROME_BROWSER_ANDROID_PREFERENCES_AUTOFILL_AUTOFILL_PROFILE_BRIDGE_H_ -namespace content { -class WebContents; -} - namespace autofill { // Specifies which rules are to be used for address validation. @@ -21,12 +17,6 @@ kAccount = 1 }; -// Opens the autofill settings page for profiles. -void ShowAutofillProfileSettings(content::WebContents* web_contents); - -// Opens the autofill settings page for credit cards. -void ShowAutofillCreditCardSettings(content::WebContents* web_contents); - } // namespace autofill #endif // CHROME_BROWSER_ANDROID_PREFERENCES_AUTOFILL_AUTOFILL_PROFILE_BRIDGE_H_
diff --git a/chrome/browser/android/preferences/autofill/settings_launcher_helper.cc b/chrome/browser/android/preferences/autofill/settings_launcher_helper.cc new file mode 100644 index 0000000..61cfebb --- /dev/null +++ b/chrome/browser/android/preferences/autofill/settings_launcher_helper.cc
@@ -0,0 +1,23 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/android/preferences/autofill/settings_launcher_helper.h" + +#include "base/android/jni_android.h" +#include "chrome/android/chrome_jni_headers/SettingsLauncherHelper_jni.h" +#include "content/public/browser/web_contents.h" + +namespace autofill { + +void ShowAutofillProfileSettings(content::WebContents* web_contents) { + Java_SettingsLauncherHelper_showAutofillProfileSettings( + base::android::AttachCurrentThread(), web_contents->GetJavaWebContents()); +} + +void ShowAutofillCreditCardSettings(content::WebContents* web_contents) { + Java_SettingsLauncherHelper_showAutofillCreditCardSettings( + base::android::AttachCurrentThread(), web_contents->GetJavaWebContents()); +} + +} // namespace autofill
diff --git a/chrome/browser/android/preferences/autofill/settings_launcher_helper.h b/chrome/browser/android/preferences/autofill/settings_launcher_helper.h new file mode 100644 index 0000000..ef04fbd --- /dev/null +++ b/chrome/browser/android/preferences/autofill/settings_launcher_helper.h
@@ -0,0 +1,22 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ANDROID_PREFERENCES_AUTOFILL_SETTINGS_LAUNCHER_HELPER_H_ +#define CHROME_BROWSER_ANDROID_PREFERENCES_AUTOFILL_SETTINGS_LAUNCHER_HELPER_H_ + +namespace content { +class WebContents; +} + +namespace autofill { + +// Opens the autofill settings page for profiles. +void ShowAutofillProfileSettings(content::WebContents* web_contents); + +// Opens the autofill settings page for credit cards. +void ShowAutofillCreditCardSettings(content::WebContents* web_contents); + +} // namespace autofill + +#endif // CHROME_BROWSER_ANDROID_PREFERENCES_AUTOFILL_SETTINGS_LAUNCHER_HELPER_H_
diff --git a/chrome/browser/android/webapk/webapk_update_data_fetcher.cc b/chrome/browser/android/webapk/webapk_update_data_fetcher.cc index 973de80..b4b5ddd 100644 --- a/chrome/browser/android/webapk/webapk_update_data_fetcher.cc +++ b/chrome/browser/android/webapk/webapk_update_data_fetcher.cc
@@ -146,8 +146,8 @@ params.valid_manifest = true; params.prefer_maskable_icon = webapps::WebappsIconUtils::DoesAndroidSupportMaskableIcons(); - params.has_worker = !webapps::features::SkipInstallServiceWorkerCheck(); - params.wait_for_worker = !webapps::features::SkipInstallServiceWorkerCheck(); + params.has_worker = false; + params.wait_for_worker = false; params.valid_primary_icon = true; params.valid_splash_icon = true; webapps::InstallableManager* installable_manager =
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc index 0e6b5de..097dacc1 100644 --- a/chrome/browser/apps/guest_view/web_view_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -2817,6 +2817,22 @@ EXPECT_TRUE(content::NavigateToURLFromRenderer(guest2, coop_url)); } +// This test creates a situation where we have two unattached webviews which +// have an opener relationship, and ensures that we can shutdown safely. See +// https://crbug.com/1450397. +IN_PROC_BROWSER_TEST_P(WebViewNewWindowTest, DestroyOpenerBeforeAttachment) { + TestHelper("testDestroyOpenerBeforeAttachment", "web_view/newwindow", + NEEDS_TEST_SERVER); + GetGuestViewManager()->WaitForNumGuestsCreated(2); + + content::RenderProcessHost* embedder_rph = + GetEmbedderWebContents()->GetPrimaryMainFrame()->GetProcess(); + content::RenderProcessHostWatcher kill_observer( + embedder_rph, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + EXPECT_TRUE(embedder_rph->Shutdown(content::RESULT_CODE_KILLED)); + kill_observer.Wait(); +} + IN_PROC_BROWSER_TEST_F(WebViewTest, ContextMenuInspectElement) { LoadAppWithGuest("web_view/context_menus/basic"); content::RenderFrameHost* guest_rfh = GetGuestRenderFrameHost();
diff --git a/chrome/browser/ash/app_list/arc/arc_app_list_prefs.cc b/chrome/browser/ash/app_list/arc/arc_app_list_prefs.cc index 9892129..b2e2c47f 100644 --- a/chrome/browser/ash/app_list/arc/arc_app_list_prefs.cc +++ b/chrome/browser/ash/app_list/arc/arc_app_list_prefs.cc
@@ -2250,7 +2250,7 @@ const std::string* app_package_name = app.second.GetDict().FindString(kPackageName); if (!app_package_name) { - NOTREACHED(); + LOG(ERROR) << "App is malformed: " << app.first; continue; } if (*app_package_name != package_name) {
diff --git a/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc b/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc index 9154ee14..9d67b64 100644 --- a/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc +++ b/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc
@@ -495,7 +495,7 @@ enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepError); enrollment_ui_.ExpectErrorMessage( IDS_ENTERPRISE_ENROLLMENT_MISSING_LICENSES_ERROR, /*can_retry=*/true); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); } @@ -513,7 +513,7 @@ enrollment_ui_.ExpectErrorMessage( IDS_ENTERPRISE_ENROLLMENT_MISSING_LICENSES_ERROR_MEETS, /*can_retry=*/true); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); } @@ -529,7 +529,7 @@ enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepError); enrollment_ui_.ExpectErrorMessage( IDS_ENTERPRISE_ENROLLMENT_AUTH_ACCOUNT_ERROR, /*can_retry=*/true); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); } @@ -546,7 +546,7 @@ enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepError); enrollment_ui_.ExpectErrorMessage( IDS_ENTERPRISE_ENROLLMENT_ACCOUNT_ERROR_MEETS, /*can_retry=*/true); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); } @@ -564,7 +564,7 @@ enrollment_ui_.ExpectErrorMessage( IDS_POLICY_DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER, /*can_retry=*/true); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); } @@ -580,7 +580,7 @@ enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepError); enrollment_ui_.ExpectErrorMessage( IDS_ENTERPRISE_ENROLLMENT_DOMAIN_MISMATCH_ERROR, /*can_retry=*/true); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); } @@ -597,7 +597,7 @@ // TODO (antrim, rsorokin): find out why it makes sense to retry here? enrollment_ui_.ExpectErrorMessage( IDS_POLICY_DM_STATUS_SERVICE_DEVICE_ID_CONFLICT, /*can_retry=*/true); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); } @@ -613,7 +613,7 @@ enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepError); enrollment_ui_.ExpectErrorMessage( IDS_POLICY_DM_STATUS_SERVICE_ACTIVATION_PENDING, /*can_retry=*/true); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); } @@ -630,7 +630,7 @@ enrollment_ui_.ExpectErrorMessage( IDS_ENTERPRISE_ENROLLMENT_CONSUMER_ACCOUNT_WITH_PACKAGED_LICENSE, /*can_retry=*/true); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); } @@ -646,7 +646,7 @@ enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepError); enrollment_ui_.ExpectErrorMessage(IDS_POLICY_DM_STATUS_TEMPORARY_UNAVAILABLE, /*can_retry=*/true); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); } @@ -663,7 +663,7 @@ enrollment_ui_.ExpectErrorMessage( IDS_ENTERPRISE_ENROLLMENT_ENTERPRISE_ACCOUNT_IS_NOT_ELIGIBLE_TO_ENROLL, /*can_retry=*/true); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); } @@ -679,7 +679,7 @@ enrollment_ui_.ExpectErrorMessage( IDS_ENTERPRISE_ENROLLMENT_ENTERPRISE_TOS_HAS_NOT_BEEN_ACCEPTED, /*can_retry=*/true); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); } @@ -697,7 +697,7 @@ enrollment_ui_.ExpectErrorMessage( IDS_ENTERPRISE_ENROLLMENT_ENTERPRISE_TOS_HAS_NOT_BEEN_ACCEPTED_MEETS, /*can_retry=*/true); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); } @@ -713,7 +713,7 @@ enrollment_ui_.ExpectErrorMessage( IDS_ENTERPRISE_ENROLLMENT_ILLEGAL_ACCOUNT_FOR_PACKAGED_EDU_LICENSE, /*can_retry=*/true); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); } @@ -728,7 +728,7 @@ enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepError); enrollment_ui_.ExpectErrorMessage(IDS_POLICY_DM_STATUS_HTTP_STATUS_ERROR, /*can_retry=*/true); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); } @@ -769,7 +769,7 @@ /*can_retry=*/true); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); } // Error during enrollment : Error 418: PACKAGED_DEVICE_KIOSK_DISALLOWED. @@ -784,7 +784,7 @@ enrollment_ui_.ExpectErrorMessage( IDS_ENTERPRISE_ENROLLMENT_INVALID_PACKAGED_DEVICE_FOR_KIOSK, /*can_retry=*/true); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); } @@ -803,7 +803,7 @@ /*can_retry=*/true); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); } // Error during enrollment : Error fetching policy : 903 - deprovisioned. @@ -819,7 +819,7 @@ /*can_retry=*/true); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); } // No state keys on the server. Auto enrollment check should proceed to login. @@ -1069,7 +1069,7 @@ enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepError); enrollment_ui_.ExpectErrorMessage( IDS_ENTERPRISE_ENROLLMENT_STATUS_LOCK_WRONG_USER, true); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); } IN_PROC_BROWSER_TEST_F(InitialEnrollmentTest, EnrollmentForced) { @@ -1304,7 +1304,7 @@ enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepError); enrollment_ui_.ExpectErrorMessage( IDS_ENTERPRISE_ENROLLMENT_MISSING_LICENSES_ERROR, /*can_retry=*/true); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); } @@ -1335,7 +1335,7 @@ enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepError); enrollment_ui_.ExpectErrorMessage( IDS_ENTERPRISE_ENROLLMENT_MISSING_LICENSES_ERROR, /*can_retry=*/true); - enrollment_ui_.RetryAfterError(); + enrollment_ui_.RetryAndWaitForSigninStep(); EXPECT_FALSE(StartupUtils::IsDeviceRegistered()); EXPECT_FALSE(InstallAttributes::Get()->IsEnterpriseManaged()); }
diff --git a/chrome/browser/ash/login/enrollment/enrollment_screen.cc b/chrome/browser/ash/login/enrollment/enrollment_screen.cc index dc9fc16..68e59cd 100644 --- a/chrome/browser/ash/login/enrollment/enrollment_screen.cc +++ b/chrome/browser/ash/login/enrollment/enrollment_screen.cc
@@ -323,8 +323,14 @@ scoped_network_observation_.Observe(network_state_informer_.get()); } is_rollback_flow_ = IsRollbackFlow(*context()); - if (view_) + if (view_) { + // Reset the view when the screen is shown for the first time or after a + // retry. Notably, the ShowImpl is not invoked after network error overlay + // is dismissed, which prevents the view from resetting when enrollment has + // already been completed. + view_->ResetEnrollmentScreen(); view_->SetEnrollmentController(this); + } // Block enrollment on liveboot (OS isn't installed yet and this is trial // flow). if (switches::IsOsInstallAllowed()) { @@ -815,6 +821,11 @@ UpdateStateInternal(reason, false); } +void EnrollmentScreen::SetNetworkStateForTesting(const NetworkState* state) { + CHECK_IS_TEST(); + network_state_informer_->DefaultNetworkChanged(state); +} + // TODO(rsorokin): This function is mostly copied from SigninScreenHandler and // should be refactored in the future. void EnrollmentScreen::UpdateStateInternal(NetworkError::ErrorReason reason,
diff --git a/chrome/browser/ash/login/enrollment/enrollment_screen.h b/chrome/browser/ash/login/enrollment/enrollment_screen.h index 99eb95f..cb94bee0 100644 --- a/chrome/browser/ash/login/enrollment/enrollment_screen.h +++ b/chrome/browser/ash/login/enrollment/enrollment_screen.h
@@ -124,6 +124,9 @@ weak_ptr_factory_.GetWeakPtr()); } + // Changes network state. Useful for simulating network issues in tests. + void SetNetworkStateForTesting(const NetworkState* state); + protected: // BaseScreen: bool MaybeSkip(WizardContext& context) override;
diff --git a/chrome/browser/ash/login/enrollment/enrollment_screen_browsertest.cc b/chrome/browser/ash/login/enrollment/enrollment_screen_browsertest.cc index 425c4a9..66df70c7 100644 --- a/chrome/browser/ash/login/enrollment/enrollment_screen_browsertest.cc +++ b/chrome/browser/ash/login/enrollment/enrollment_screen_browsertest.cc
@@ -24,6 +24,7 @@ #include "chrome/browser/ash/login/wizard_controller.h" #include "chrome/browser/ash/policy/enrollment/enrollment_config.h" #include "chrome/browser/ash/policy/enrollment/enrollment_status.h" +#include "chrome/browser/ui/webui/ash/login/error_screen_handler.h" #include "chrome/browser/ui/webui/ash/login/tpm_error_screen_handler.h" #include "chrome/common/chrome_paths.h" #include "chromeos/dbus/tpm_manager/fake_tpm_manager_client.h" @@ -102,6 +103,15 @@ return enrollment_screen; } + policy::EnrollmentConfig CreateConfig( + policy::EnrollmentConfig::Mode mode, + policy::EnrollmentConfig::AuthMechanism auth_mechanism) { + policy::EnrollmentConfig config; + config.mode = mode; + config.auth_mechanism = auth_mechanism; + return config; + } + test::EnrollmentUIMixin enrollment_ui_{&mixin_host_}; test::EnrollmentHelperMixin enrollment_helper_{&mixin_host_}; }; @@ -466,6 +476,55 @@ EXPECT_TRUE(StartupUtils::IsDeviceRegistered()); } +IN_PROC_BROWSER_TEST_F(EnrollmentScreenTest, + SuccessStepPreservedAfterNetworkErrorScreen) { + WizardContext context; + enrollment_helper_.ExpectAttestationEnrollmentSuccess(); + enrollment_helper_.DisableAttributePromptUpdate(); + enrollment_screen()->SetEnrollmentConfig( + CreateConfig(policy::EnrollmentConfig::MODE_ATTESTATION_SERVER_FORCED, + policy::EnrollmentConfig::AUTH_MECHANISM_BEST_AVAILABLE)); + enrollment_screen()->Show(&context); + enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepSuccess); + + enrollment_screen()->SetNetworkStateForTesting(nullptr); + OobeScreenWaiter(ErrorScreenView::kScreenId).Wait(); + enrollment_screen()->SetNetworkStateForTesting( + NetworkHandler::Get()->network_state_handler()->DefaultNetwork()); + OobeScreenWaiter(EnrollmentScreenView::kScreenId).Wait(); + + enrollment_ui_.ExpectStepVisibility(true, test::ui::kEnrollmentStepSuccess); +} + +IN_PROC_BROWSER_TEST_F(EnrollmentScreenTest, + ShowsWorkingStepOnAttestationFlow) { + WizardContext context; + enrollment_screen()->SetEnrollmentConfig( + CreateConfig(policy::EnrollmentConfig::MODE_ATTESTATION_SERVER_FORCED, + policy::EnrollmentConfig::AUTH_MECHANISM_ATTESTATION)); + + enrollment_screen()->Show(&context); + enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepWorking); +} + +IN_PROC_BROWSER_TEST_F(EnrollmentScreenTest, + ShowsWorkingStepAfterAttestationRetry) { + WizardContext context; + enrollment_helper_.ExpectAttestationEnrollmentError( + policy::EnrollmentStatus::ForRegistrationError( + policy::DeviceManagementStatus::DM_STATUS_SERVICE_DEVICE_NOT_FOUND)); + enrollment_helper_.SetupClearAuth(); + enrollment_screen()->SetEnrollmentConfig( + CreateConfig(policy::EnrollmentConfig::MODE_ATTESTATION_SERVER_FORCED, + policy::EnrollmentConfig::AUTH_MECHANISM_ATTESTATION)); + enrollment_screen()->Show(&context); + enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepError); + + enrollment_helper_.VerifyAndClear(); + enrollment_ui_.RetryAfterError(); + enrollment_ui_.WaitForStep(test::ui::kEnrollmentStepWorking); +} + struct EnrollmentErrorScreenTestParams { policy::EnrollmentConfig::Mode enrollment_mode; policy::EnrollmentConfig::AuthMechanism enrollment_auth_mechanism;
diff --git a/chrome/browser/ash/login/enrollment/enrollment_screen_view.h b/chrome/browser/ash/login/enrollment/enrollment_screen_view.h index 932cf5b..63414866 100644 --- a/chrome/browser/ash/login/enrollment/enrollment_screen_view.h +++ b/chrome/browser/ash/login/enrollment/enrollment_screen_view.h
@@ -89,6 +89,9 @@ // Reloads the signin screen. virtual void ReloadSigninScreen() = 0; + // Resets shown enrollment screen. + virtual void ResetEnrollmentScreen() = 0; + // Shows error related to user account eligibility. virtual void ShowUserError(const std::string& email) = 0;
diff --git a/chrome/browser/ash/login/enrollment/mock_enrollment_screen.h b/chrome/browser/ash/login/enrollment/mock_enrollment_screen.h index 3bd3dabd..3e93a54a 100644 --- a/chrome/browser/ash/login/enrollment/mock_enrollment_screen.h +++ b/chrome/browser/ash/login/enrollment/mock_enrollment_screen.h
@@ -48,6 +48,7 @@ MOCK_METHOD(void, MockUnbind, ()); MOCK_METHOD(void, ShowSigninScreen, ()); MOCK_METHOD(void, ReloadSigninScreen, ()); + MOCK_METHOD(void, ResetEnrollmentScreen, ()); MOCK_METHOD(void, ShowUserError, (const std::string& email)); MOCK_METHOD(void, ShowEnrollmentDuringTrialNotAllowedError, ()); MOCK_METHOD(void, ShowSkipConfirmationDialog, ());
diff --git a/chrome/browser/ash/login/test/enrollment_helper_mixin.cc b/chrome/browser/ash/login/test/enrollment_helper_mixin.cc index 729a1da7..65cf7529 100644 --- a/chrome/browser/ash/login/test/enrollment_helper_mixin.cc +++ b/chrome/browser/ash/login/test/enrollment_helper_mixin.cc
@@ -62,6 +62,10 @@ EnrollmentLauncher::SetEnrollmentHelperMock(std::move(mock)); } +void EnrollmentHelperMixin::VerifyAndClear() { + testing::Mock::VerifyAndClear(mock_); +} + void EnrollmentHelperMixin::ExpectNoEnrollment() { EXPECT_CALL(*mock_, Setup(_, _, _)).Times(0); }
diff --git a/chrome/browser/ash/login/test/enrollment_helper_mixin.h b/chrome/browser/ash/login/test/enrollment_helper_mixin.h index b649224b..4fdd73d 100644 --- a/chrome/browser/ash/login/test/enrollment_helper_mixin.h +++ b/chrome/browser/ash/login/test/enrollment_helper_mixin.h
@@ -36,9 +36,14 @@ ~EnrollmentHelperMixin() override; - // Resets mock (to be used in tests that retry enrollment. + // Re-creates mock. Useful in tests that retry enrollment with different auth + // mechanism, which causes original mock to be destroyed by EnrollmentScreen. void ResetMock(); + // Verifies mock expectations and clears them. Useful in tests that retry + // enrollment with the same auth mechanism. + void VerifyAndClear(); + // Sets up expectation of no enrollment attempt. void ExpectNoEnrollment();
diff --git a/chrome/browser/ash/login/test/enrollment_ui_mixin.cc b/chrome/browser/ash/login/test/enrollment_ui_mixin.cc index f74d31c..4576d0a 100644 --- a/chrome/browser/ash/login/test/enrollment_ui_mixin.cc +++ b/chrome/browser/ash/login/test/enrollment_ui_mixin.cc
@@ -103,6 +103,10 @@ void EnrollmentUIMixin::RetryAfterError() { OobeJS().ClickOnPath(kEnrollmentErrorRetryButtonPath); +} + +void EnrollmentUIMixin::RetryAndWaitForSigninStep() { + RetryAfterError(); WaitForStep(ui::kEnrollmentStepSignin); }
diff --git a/chrome/browser/ash/login/test/enrollment_ui_mixin.h b/chrome/browser/ash/login/test/enrollment_ui_mixin.h index c427385..fb21151a 100644 --- a/chrome/browser/ash/login/test/enrollment_ui_mixin.h +++ b/chrome/browser/ash/login/test/enrollment_ui_mixin.h
@@ -63,6 +63,7 @@ void ExpectErrorMessage(int error_message_id, bool can_retry); void RetryAfterError(); + void RetryAndWaitForSigninStep(); void CancelAfterError(); // Fills out the UI with device attribute information and submits it.
diff --git a/chrome/browser/ash/web_applications/diagnostics_system_web_app_info.cc b/chrome/browser/ash/web_applications/diagnostics_system_web_app_info.cc index 44b0707..61fc7d0 100644 --- a/chrome/browser/ash/web_applications/diagnostics_system_web_app_info.cc +++ b/chrome/browser/ash/web_applications/diagnostics_system_web_app_info.cc
@@ -13,7 +13,9 @@ #include "chrome/browser/ui/webui/ash/diagnostics_dialog.h" #include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h" #include "chrome/browser/web_applications/web_app_install_info.h" +#include "chromeos/strings/grit/chromeos_strings.h" #include "third_party/blink/public/mojom/manifest/display_mode.mojom.h" +#include "ui/base/l10n/l10n_util.h" #include "url/gurl.h" std::unique_ptr<WebAppInstallInfo> @@ -23,8 +25,7 @@ info->start_url = GURL(ash::kChromeUIDiagnosticsAppUrl); info->scope = GURL(ash::kChromeUIDiagnosticsAppUrl); - // TODO(jimmyxgong): Update the title with finalized i18n copy. - info->title = u"Diagnostics"; + info->title = l10n_util::GetStringUTF16(IDS_DIAGNOSTICS_TITLE); web_app::CreateIconInfoForSystemWebApp( info->start_url, {{"app_icon_192.png", 192, IDR_ASH_DIAGNOSTICS_APP_APP_ICON_192_PNG}},
diff --git a/chrome/browser/autofill/address_accessory_controller_impl.cc b/chrome/browser/autofill/address_accessory_controller_impl.cc index 8dc18d22..bd3c0de 100644 --- a/chrome/browser/autofill/address_accessory_controller_impl.cc +++ b/chrome/browser/autofill/address_accessory_controller_impl.cc
@@ -10,7 +10,7 @@ #include "base/ranges/algorithm.h" #include "base/strings/utf_string_conversions.h" #include "base/trace_event/trace_event.h" -#include "chrome/browser/android/preferences/autofill/autofill_profile_bridge.h" +#include "chrome/browser/android/preferences/autofill/settings_launcher_helper.h" #include "chrome/browser/autofill/manual_filling_controller.h" #include "chrome/browser/autofill/manual_filling_utils.h" #include "chrome/browser/autofill/personal_data_manager_factory.h"
diff --git a/chrome/browser/autofill/credit_card_accessory_controller_impl.cc b/chrome/browser/autofill/credit_card_accessory_controller_impl.cc index 745a587..d184fb9 100644 --- a/chrome/browser/autofill/credit_card_accessory_controller_impl.cc +++ b/chrome/browser/autofill/credit_card_accessory_controller_impl.cc
@@ -15,7 +15,7 @@ #include "base/ranges/algorithm.h" #include "base/strings/utf_string_conversions.h" #include "base/trace_event/trace_event.h" -#include "chrome/browser/android/preferences/autofill/autofill_profile_bridge.h" +#include "chrome/browser/android/preferences/autofill/settings_launcher_helper.h" #include "chrome/browser/autofill/manual_filling_controller.h" #include "chrome/browser/autofill/manual_filling_utils.h" #include "chrome/browser/autofill/personal_data_manager_factory.h"
diff --git a/chrome/browser/autofill/mock_autofill_popup_controller.h b/chrome/browser/autofill/mock_autofill_popup_controller.h index 74c6bb85..c735d66 100644 --- a/chrome/browser/autofill/mock_autofill_popup_controller.h +++ b/chrome/browser/autofill/mock_autofill_popup_controller.h
@@ -14,6 +14,7 @@ #include "base/time/time.h" #include "build/build_config.h" #include "chrome/browser/ui/autofill/autofill_popup_controller.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" #include "components/autofill/core/browser/ui/suggestion.h" #include "testing/gmock/include/gmock/gmock.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -85,7 +86,7 @@ MOCK_METHOD(void, SelectSuggestion, (absl::optional<size_t>), (override)); MOCK_METHOD(PopupType, GetPopupType, (), (const override)); - void set_suggestions(const std::vector<Suggestion::FrontendId>& ids) { + void set_suggestions(const std::vector<PopupItemId>& ids) { for (const auto& id : ids) { // Accessibility requires all focusable AutofillPopupItemView to have // ui::AXNodeData with non-empty names. We specify dummy values and labels
diff --git a/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java b/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java index 178e7e1..ef700c1 100644 --- a/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java +++ b/chrome/browser/banners/android/java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java
@@ -1210,29 +1210,6 @@ @Test @MediumTest @Feature({"AppBanners"}) - @Features.EnableFeatures({ChromeFeatureList.INSTALLABLE_AMBIENT_BADGE_INFOBAR, - ChromeFeatureList.SKIP_SERVICE_WORKER_FOR_INSTALL_PROMPT}) - public void - testAmbientBadgeDoesNotAppearWhenNoServiceWorker() throws Exception { - String webBannerUrl = WebappTestPage.getNonServiceWorkerUrlWithAction( - mTestServer, "call_stashed_prompt_on_click"); - resetEngagementForUrl(webBannerUrl, 10); - navigateToUrlAndWaitForBannerManager(mTabbedActivityTestRule, webBannerUrl); - - // As the page doesn't have service worker, we do not expect to - // see an ambient badge. - Tab tab = mTabbedActivityTestRule.getActivity().getActivityTab(); - waitForBadgeStatus(tab, AmbientBadgeState.PENDING_WORKER); - checkAmbientBadgePromptNotExist(mTabbedActivityTestRule); - - // Tap to trigger beforeinstallprompt.prompt, we expect to see the modal banner. - tapAndWaitForModalBanner(tab); - } - - @Test - @MediumTest - @Feature({"AppBanners"}) - @Features.EnableFeatures({ChromeFeatureList.SKIP_SERVICE_WORKER_FOR_INSTALL_PROMPT}) public void testAmbientBadgeAppearWithServiceWorkerPage() throws Exception { String webBannerUrl = WebappTestPage.getServiceWorkerUrlWithAction( mTestServer, "call_stashed_prompt_on_click");
diff --git a/chrome/browser/banners/app_banner_manager_browsertest.cc b/chrome/browser/banners/app_banner_manager_browsertest.cc index c97dfee6..be26474b 100644 --- a/chrome/browser/banners/app_banner_manager_browsertest.cc +++ b/chrome/browser/banners/app_banner_manager_browsertest.cc
@@ -101,10 +101,6 @@ on_banner_prompt_reply_ = std::move(on_banner_prompt_reply); } - void SetWaitForServiceWorker(bool wait_for_worker) { - wait_for_worker_ = wait_for_worker; - } - bool IsAppFullyInstalledForSiteUrl(const GURL& site_url) const override { return false; } @@ -172,19 +168,6 @@ } } - InstallableParams ParamsToPerformInstallableWebAppCheck() override { - InstallableParams params = - AppBannerManager::ParamsToPerformInstallableWebAppCheck(); - params.wait_for_worker = wait_for_worker_; - return params; - } - - InstallableParams ParamsToPerformWorkerCheck() override { - InstallableParams params = AppBannerManager::ParamsToPerformWorkerCheck(); - params.wait_for_worker = wait_for_worker_; - return params; - } - void OnBannerPromptReply( mojo::Remote<blink::mojom::AppBannerController> controller, blink::mojom::AppBannerPromptReply reply) override { @@ -227,8 +210,6 @@ std::unique_ptr<bool> banner_shown_; std::unique_ptr<WebappInstallSource> install_source_; - bool wait_for_worker_ = true; - base::WeakPtrFactory<AppBannerManagerTest> weak_factory_{this}; }; @@ -287,7 +268,6 @@ EXPECT_TRUE(manager->state() == State::COMPLETE || manager->state() == State::PENDING_PROMPT_CANCELED || manager->state() == State::PENDING_PROMPT_NOT_CANCELED || - manager->state() == State::PENDING_WORKER || manager->state() == State::INACTIVE); // If in incognito, ensure that nothing is recorded. @@ -871,73 +851,6 @@ std::unique_ptr<InstallableData> failure_data_; }; -class AppBannerManagerBrowserTestWithFailableInstallableManager - : public AppBannerManagerBrowserTest { - public: - AppBannerManagerBrowserTestWithFailableInstallableManager() = default; - ~AppBannerManagerBrowserTestWithFailableInstallableManager() override = - default; - - void SetUpOnMainThread() override { - // Manually inject the FailingInstallableManager as a "InstallableManager" - // WebContentsUserData. We can't directly call ::CreateForWebContents due to - // typing issues since FailingInstallableManager doesn't directly inherit - // from WebContentsUserData. - browser()->tab_strip_model()->GetActiveWebContents()->SetUserData( - FailingInstallableManager::UserDataKey(), - base::WrapUnique(new FailingInstallableManager( - browser()->tab_strip_model()->GetActiveWebContents()))); - installable_manager_ = static_cast<FailingInstallableManager*>( - browser()->tab_strip_model()->GetActiveWebContents()->GetUserData( - FailingInstallableManager::UserDataKey())); - - AppBannerManagerBrowserTest::SetUpOnMainThread(); - } - - protected: - raw_ptr<FailingInstallableManager, DanglingUntriaged> installable_manager_ = - nullptr; -}; - -IN_PROC_BROWSER_TEST_F( - AppBannerManagerBrowserTestWithFailableInstallableManager, - AppBannerManagerRetriesPipeline) { - std::unique_ptr<AppBannerManagerTest> manager( - CreateAppBannerManager(browser())); - - site_engagement::SiteEngagementService* service = - site_engagement::SiteEngagementService::Get(browser()->profile()); - GURL test_url = GetBannerURLWithAction("stash_event"); - service->ResetBaseScoreForURL(test_url, 10); - - blink::mojom::Manifest manifest; - std::vector<Screenshot> screenshots; - installable_manager_->FailNext(base::WrapUnique( - new InstallableData({MANIFEST_URL_CHANGED}, GURL::EmptyGURL(), manifest, - GURL::EmptyGURL(), nullptr, false, GURL::EmptyGURL(), - nullptr, false, screenshots, false, false))); - - // The page should record one failure of MANIFEST_URL_CHANGED, but it should - // still successfully get to the PENDING_PROMPT state of the pipeline, as it - // should retry the call to GetData on the InstallableManager. - RunBannerTest(browser(), manager.get(), test_url, MANIFEST_URL_CHANGED); - EXPECT_EQ(manager->state(), - AppBannerManager::State::PENDING_PROMPT_NOT_CANCELED); - - { - base::HistogramTester histograms; - // Now let the page call prompt with a gesture. The banner should be shown. - TriggerBannerFlow( - browser(), manager.get(), - base::BindOnce(&AppBannerManagerBrowserTest::ExecuteScript, browser(), - "callStashedPrompt();", true /* with_gesture */), - true /* expected_will_show */, State::COMPLETE); - - histograms.ExpectUniqueSample(kInstallableStatusCodeHistogram, - SHOWING_WEB_APP_BANNER, 1); - } -} - class AppBannerManagerMPArchBrowserTest : public AppBannerManagerBrowserTest { public: AppBannerManagerMPArchBrowserTest() = default; @@ -1063,36 +976,9 @@ EXPECT_EQ(manager->state(), AppBannerManager::State::INACTIVE); } -enum class ServiceWorkerCriteriaType { - kDisabled, - kSkipForInstalls, - kNoForBeforeInstalls -}; - -class AppBannerServiceWorkerCriteriaTest - : public AppBannerManagerBrowserTest, - public testing::WithParamInterface<ServiceWorkerCriteriaType> { +class AppBannerServiceWorkerCriteriaTest : public AppBannerManagerBrowserTest { public: - AppBannerServiceWorkerCriteriaTest() { - switch (GetParam()) { - case ServiceWorkerCriteriaType::kDisabled: - scoped_feature_list_.InitWithFeatures( - {}, {features::kSkipServiceWorkerCheckInstallOnly, - features::kSkipServiceWorkerForInstallPrompt}); - break; - case ServiceWorkerCriteriaType::kSkipForInstalls: - scoped_feature_list_.InitWithFeatures( - {features::kSkipServiceWorkerCheckInstallOnly}, - {features::kSkipServiceWorkerForInstallPrompt}); - break; - case ServiceWorkerCriteriaType::kNoForBeforeInstalls: - scoped_feature_list_.InitWithFeatures( - {features::kSkipServiceWorkerCheckInstallOnly, - features::kSkipServiceWorkerForInstallPrompt}, - {}); - break; - } - } + AppBannerServiceWorkerCriteriaTest() = default; ~AppBannerServiceWorkerCriteriaTest() override = default; AppBannerServiceWorkerCriteriaTest( @@ -1107,28 +993,12 @@ void CheckInstallableResult( AppBannerManager::InstallableWebAppCheckResult result, AppBannerManager::InstallableWebAppCheckResult expected_control_result) { - switch (GetParam()) { - case ServiceWorkerCriteriaType::kDisabled: - EXPECT_EQ(result, expected_control_result); - break; - case ServiceWorkerCriteriaType::kSkipForInstalls: - EXPECT_EQ( - result, - AppBannerManager::InstallableWebAppCheckResult::kYes_ByUserRequest); - break; - case ServiceWorkerCriteriaType::kNoForBeforeInstalls: - EXPECT_EQ( - result, - AppBannerManager::InstallableWebAppCheckResult::kYes_Promotable); - break; - } + EXPECT_EQ(result, + AppBannerManager::InstallableWebAppCheckResult::kYes_Promotable); } - - private: - base::test::ScopedFeatureList scoped_feature_list_; }; -IN_PROC_BROWSER_TEST_P(AppBannerServiceWorkerCriteriaTest, ShowBanner) { +IN_PROC_BROWSER_TEST_F(AppBannerServiceWorkerCriteriaTest, ShowBanner) { std::unique_ptr<AppBannerManagerTest> manager( CreateAppBannerManager(browser())); RunBannerTest( @@ -1141,96 +1011,51 @@ AppBannerManager::InstallableWebAppCheckResult::kYes_Promotable); } -IN_PROC_BROWSER_TEST_P(AppBannerServiceWorkerCriteriaTest, NoServiceWorker) { +IN_PROC_BROWSER_TEST_F(AppBannerServiceWorkerCriteriaTest, NoServiceWorker) { std::unique_ptr<AppBannerManagerTest> manager( CreateAppBannerManager(browser())); - // Set not wait for service worker so it will not timeout. - manager->SetWaitForServiceWorker(false); - - absl::optional<InstallableStatusCode> expected_code; - if (GetParam() != ServiceWorkerCriteriaType::kNoForBeforeInstalls) - expected_code = NO_MATCHING_SERVICE_WORKER; RunBannerTest(browser(), manager.get(), embedded_test_server()->GetURL( "/banners/manifest_no_service_worker.html"), - expected_code); + /*expected_code_for_histogram=*/absl::nullopt); - if (GetParam() == ServiceWorkerCriteriaType::kNoForBeforeInstalls) { - EXPECT_EQ(manager->state(), - AppBannerManager::State::PENDING_PROMPT_NOT_CANCELED); - } else { - EXPECT_EQ(manager->state(), AppBannerManager::State::COMPLETE); - } - + EXPECT_EQ(manager->state(), + AppBannerManager::State::PENDING_PROMPT_NOT_CANCELED); CheckInstallableResult(manager->GetInstallableWebAppCheckResultForTesting(), AppBannerManager::InstallableWebAppCheckResult::kNo); } -IN_PROC_BROWSER_TEST_P(AppBannerServiceWorkerCriteriaTest, NoFetchHandler) { +IN_PROC_BROWSER_TEST_F(AppBannerServiceWorkerCriteriaTest, NoFetchHandler) { std::unique_ptr<AppBannerManagerTest> manager( CreateAppBannerManager(browser())); - absl::optional<InstallableStatusCode> expected_code; - if (GetParam() != ServiceWorkerCriteriaType::kNoForBeforeInstalls) - expected_code = NOT_OFFLINE_CAPABLE; - RunBannerTest(browser(), manager.get(), embedded_test_server()->GetURL( "/banners/no_sw_fetch_handler_test_page.html"), - expected_code); + /*expected_code_for_histogram=*/absl::nullopt); - if (GetParam() == ServiceWorkerCriteriaType::kNoForBeforeInstalls) { - EXPECT_EQ(manager->state(), - AppBannerManager::State::PENDING_PROMPT_NOT_CANCELED); - } else { - EXPECT_EQ(manager->state(), AppBannerManager::State::COMPLETE); - } + EXPECT_EQ(manager->state(), + AppBannerManager::State::PENDING_PROMPT_NOT_CANCELED); CheckInstallableResult(manager->GetInstallableWebAppCheckResultForTesting(), AppBannerManager::InstallableWebAppCheckResult::kNo); } -class PendingWorkerAppBannerManager : public AppBannerManagerTest { - public: - explicit PendingWorkerAppBannerManager(content::WebContents* web_contents) - : AppBannerManagerTest(web_contents) {} - - PendingWorkerAppBannerManager(const PendingWorkerAppBannerManager&) = delete; - PendingWorkerAppBannerManager& operator=( - const PendingWorkerAppBannerManager&) = delete; - - ~PendingWorkerAppBannerManager() override = default; - - protected: - void UpdateState(AppBannerManager::State state) override { - AppBannerManagerTest::UpdateState(state); - if (state == AppBannerManager::State::PENDING_WORKER) { - if (on_done_) - base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, std::move(on_done_)); - } - } -}; - -IN_PROC_BROWSER_TEST_P(AppBannerServiceWorkerCriteriaTest, +IN_PROC_BROWSER_TEST_F(AppBannerServiceWorkerCriteriaTest, PendingServiceWorker) { content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - std::unique_ptr<PendingWorkerAppBannerManager> manager = - std::make_unique<PendingWorkerAppBannerManager>(web_contents); + std::unique_ptr<AppBannerManagerTest> manager = + std::make_unique<AppBannerManagerTest>(web_contents); RunBannerTest(browser(), manager.get(), embedded_test_server()->GetURL( "/banners/manifest_no_service_worker.html"), absl::nullopt); - if (GetParam() == ServiceWorkerCriteriaType::kNoForBeforeInstalls) { - EXPECT_EQ(manager->state(), - AppBannerManager::State::PENDING_PROMPT_NOT_CANCELED); - } else { - EXPECT_EQ(manager->state(), AppBannerManager::State::PENDING_WORKER); - } + EXPECT_EQ(manager->state(), + AppBannerManager::State::PENDING_PROMPT_NOT_CANCELED); CheckInstallableResult( manager->GetInstallableWebAppCheckResultForTesting(), @@ -1239,12 +1064,5 @@ EXPECT_EQ(manager->GetAppName(), u"Manifest test app"); } -INSTANTIATE_TEST_SUITE_P( - All, - AppBannerServiceWorkerCriteriaTest, - testing::Values(ServiceWorkerCriteriaType::kDisabled, - ServiceWorkerCriteriaType::kSkipForInstalls, - ServiceWorkerCriteriaType::kNoForBeforeInstalls)); - } // namespace } // namespace webapps
diff --git a/chrome/browser/banners/test_app_banner_manager_desktop.cc b/chrome/browser/banners/test_app_banner_manager_desktop.cc index de33e9d..f26e695 100644 --- a/chrome/browser/banners/test_app_banner_manager_desktop.cc +++ b/chrome/browser/banners/test_app_banner_manager_desktop.cc
@@ -110,23 +110,6 @@ SetInstallable(result.NoBlockingErrors()); } -void TestAppBannerManagerDesktop::PerformServiceWorkerCheck() { - waiting_for_worker_ = true; - AppBannerManagerDesktop::PerformServiceWorkerCheck(); -} - -void TestAppBannerManagerDesktop::OnDidPerformWorkerCheck( - const InstallableData& result) { - debug_log_.Append("OnDidPerformWorkerCheck"); - AppBannerManagerDesktop::OnDidPerformWorkerCheck(result); - - DCHECK(waiting_for_worker_); - waiting_for_worker_ = false; - if (promotable_quit_closure_) { - std::move(promotable_quit_closure_).Run(); - } -} - void TestAppBannerManagerDesktop::ResetCurrentPageData() { debug_log_.Append("ResetCurrentPageData"); AppBannerManagerDesktop::ResetCurrentPageData();
diff --git a/chrome/browser/banners/test_app_banner_manager_desktop.h b/chrome/browser/banners/test_app_banner_manager_desktop.h index 79a487c..3e570911 100644 --- a/chrome/browser/banners/test_app_banner_manager_desktop.h +++ b/chrome/browser/banners/test_app_banner_manager_desktop.h
@@ -55,8 +55,6 @@ void OnDidGetManifest(const InstallableData& result) override; void OnDidPerformInstallableWebAppCheck( const InstallableData& result) override; - void PerformServiceWorkerCheck() override; - void OnDidPerformWorkerCheck(const InstallableData& result) override; void ResetCurrentPageData() override; // AppBannerManagerDesktop:
diff --git a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/PageInfoStoreInfoController.java b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/PageInfoStoreInfoController.java index c9f1181..25102194 100644 --- a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/PageInfoStoreInfoController.java +++ b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/PageInfoStoreInfoController.java
@@ -17,8 +17,6 @@ import org.chromium.chrome.tab_ui.R; import org.chromium.components.commerce.core.ShoppingService.MerchantInfo; import org.chromium.components.page_info.PageInfoAction; -import org.chromium.components.page_info.PageInfoDiscoverabilityMetrics; -import org.chromium.components.page_info.PageInfoDiscoverabilityMetrics.DiscoverabilityAction; import org.chromium.components.page_info.PageInfoMainController; import org.chromium.components.page_info.PageInfoRowView; import org.chromium.components.page_info.PageInfoSubpageController; @@ -42,8 +40,6 @@ private final Context mContext; private final boolean mPageInfoOpenedFromStoreIcon; private final WebContents mWebContents; - private final PageInfoDiscoverabilityMetrics mDiscoverabilityMetrics = - new PageInfoDiscoverabilityMetrics(); private final MerchantTrustMetrics mMetrics = new MerchantTrustMetrics(); public PageInfoStoreInfoController(PageInfoMainController mainController, @@ -86,10 +82,6 @@ rowParams.rowTint = R.color.iph_highlight_blue; } rowParams.clickCallback = () -> { - if (mPageInfoOpenedFromStoreIcon) { - mDiscoverabilityMetrics.recordDiscoverabilityAction( - DiscoverabilityAction.STORE_INFO_OPENED); - } mMainController.recordAction(PageInfoAction.PAGE_INFO_STORE_INFO_CLICKED); mMainController.dismiss(); mMetrics.recordUkmOnRowClicked(mWebContents); @@ -133,4 +125,4 @@ @Override public void updateRowIfNeeded() {} -} \ No newline at end of file +}
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 9c405cb..b57e8ba 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -4737,7 +4737,7 @@ { "name": "iph-price-notifications-while-browsing", "owners": [ "danieltwhite", "ajuma" ], - "expiry_milestone": 114 + "expiry_milestone": 118 }, { "name": "isolate-origins", @@ -7464,6 +7464,11 @@ "expiry_milestone": -1 }, { + "name": "use-gpu-scheduler-dfs", + "owners": [ "vikassoni", "sunnyps" ], + "expiry_milestone": 125 + }, + { "name": "use-hdr-transfer-function", "owners": [ "mcasas", "chromeos-gfx@google.com" ], "expiry_milestone": 125 @@ -7832,6 +7837,11 @@ "expiry_milestone": 111 }, { + "name": "whats-new-ios-m116", + "owners": [ "cheickcisse@google.com", "bling-flags@google.com" ], + "expiry_milestone": 122 + }, + { "name": "wifi-connect-mac-address-randomization", "owners": [ "jsiuda", "chromeos-wifi-team" ], "expiry_milestone": 130
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 00c7743..596bcff 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -986,18 +986,6 @@ "Enable PWAs with screenshots to show a detailed install dialog during " "installation"; -const char kSkipServiceWorkerCheckInstallOnlyName[] = - "Skip service worker check for PWA installs"; -const char kSkipServiceWorkerCheckInstallOnlyDescription[] = - "Allows PWAs to be installed without a service worker."; - -const char kSkipServiceWorkerForInstallPromptName[] = - "Promote PWA installation without a service worker"; -const char kSkipServiceWorkerForInstallPromptDescription[] = - "Allows PWAs that can be installed without a service worker to be " - "promoted. Requires #enable-skip-service-worker-check-install-only flag to " - "also be enabled."; - const char kEnablePreinstalledWebAppDuplicationFixerName[] = "Enable the app deduplication fix for migrated preinstalled web apps"; const char kEnablePreinstalledWebAppDuplicationFixerDescription[] = @@ -3534,6 +3522,11 @@ const char kWebSQLAccessDescription[] = "The WebSQL API is enabled by default, but can be disabled here."; +const char kUseGpuSchedulerDfsName[] = "Use new gpu scheduler."; +const char kUseGpuSchedulerDfsDescription[] = + "Enables using the new gpu " + "scheduler called GpuSchedulerDfs."; + const char kUseIDNA2008NonTransitionalName[] = "Enable IDNA 2008 Non-Transitional Mode"; const char kUseIDNA2008NonTransitionalDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 7f160329..82a6ef66 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -564,12 +564,6 @@ extern const char kDesktopPWAsDetailedInstallDialogName[]; extern const char kDesktopPWAsDetailedInstallDialogDescription[]; -extern const char kSkipServiceWorkerCheckInstallOnlyName[]; -extern const char kSkipServiceWorkerCheckInstallOnlyDescription[]; - -extern const char kSkipServiceWorkerForInstallPromptName[]; -extern const char kSkipServiceWorkerForInstallPromptDescription[]; - extern const char kDeviceForceScheduledRebootName[]; extern const char kDeviceForceScheduledRebootDescription[]; @@ -2036,6 +2030,9 @@ extern const char kWebSQLAccessName[]; extern const char kWebSQLAccessDescription[]; +extern const char kUseGpuSchedulerDfsName[]; +extern const char kUseGpuSchedulerDfsDescription[]; + extern const char kUseIDNA2008NonTransitionalName[]; extern const char kUseIDNA2008NonTransitionalDescription[];
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index 4ace63e0..e856e1e 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -401,8 +401,6 @@ public static final String SHARED_HIGHLIGHTING_AMP = "SharedHighlightingAmp"; public static final String SHOPPING_LIST = "ShoppingList"; public static final String SHOW_SCROLLABLE_MVT_ON_NTP_ANDROID = "ShowScrollableMVTOnNTPAndroid"; - public static final String SKIP_SERVICE_WORKER_FOR_INSTALL_PROMPT = - "SkipServiceWorkerForInstallPromot"; public static final String SMART_SUGGESTION_FOR_LARGE_DOWNLOADS = "SmartSuggestionForLargeDownloads"; public static final String SPARE_TAB = "SpareTab";
diff --git a/chrome/browser/mandatory_reauth/android/BUILD.gn b/chrome/browser/mandatory_reauth/android/BUILD.gn new file mode 100644 index 0000000..ff1a46a --- /dev/null +++ b/chrome/browser/mandatory_reauth/android/BUILD.gn
@@ -0,0 +1,9 @@ +# 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. + +import("//build/config/android/rules.gni") + +generate_jni("jni_headers") { + sources = [ "internal/java/src/org/chromium/chrome/browser/mandatory_reauth/MandatoryReauthOptInBottomSheetViewBridge.java" ] +}
diff --git a/chrome/browser/mandatory_reauth/android/internal/BUILD.gn b/chrome/browser/mandatory_reauth/android/internal/BUILD.gn new file mode 100644 index 0000000..5aafefca --- /dev/null +++ b/chrome/browser/mandatory_reauth/android/internal/BUILD.gn
@@ -0,0 +1,11 @@ +# 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. + +import("//build/config/android/rules.gni") + +android_library("java") { + deps = [ "//base:jni_java" ] + sources = [ "java/src/org/chromium/chrome/browser/mandatory_reauth/MandatoryReauthOptInBottomSheetViewBridge.java" ] + resources_package = "org.chromium.chrome.browser.mandatory_reauth" +}
diff --git a/chrome/browser/mandatory_reauth/android/internal/java/src/org/chromium/chrome/browser/mandatory_reauth/MandatoryReauthOptInBottomSheetViewBridge.java b/chrome/browser/mandatory_reauth/android/internal/java/src/org/chromium/chrome/browser/mandatory_reauth/MandatoryReauthOptInBottomSheetViewBridge.java new file mode 100644 index 0000000..e20931f --- /dev/null +++ b/chrome/browser/mandatory_reauth/android/internal/java/src/org/chromium/chrome/browser/mandatory_reauth/MandatoryReauthOptInBottomSheetViewBridge.java
@@ -0,0 +1,37 @@ +// 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.chrome.browser.mandatory_reauth; + +import org.chromium.base.annotations.CalledByNative; +import org.chromium.base.annotations.JNINamespace; + +/** + * Java bridge to delegate calls from native MandatoryReauthOptInViewAndroid. Facilitates creating + * the Mandatory Reauth opt-in bottom sheet. + */ +@JNINamespace("autofill") +public class MandatoryReauthOptInBottomSheetViewBridge { + private MandatoryReauthOptInBottomSheetViewBridge() {} + + /** + * Creates an instance of a {@link MandatoryReauthOptInBottomSheetViewBridge}. + */ + @CalledByNative + private static MandatoryReauthOptInBottomSheetViewBridge create() { + return new MandatoryReauthOptInBottomSheetViewBridge(); + } + + /** + * Create and show the view. + */ + @CalledByNative + private void show() {} + + /** + * Lets the native controller dismiss the view. + */ + @CalledByNative + private void close() {} +}
diff --git a/chrome/browser/mandatory_reauth/android/mandatory_reauth_opt_in_view_android.cc b/chrome/browser/mandatory_reauth/android/mandatory_reauth_opt_in_view_android.cc new file mode 100644 index 0000000..61d97c4 --- /dev/null +++ b/chrome/browser/mandatory_reauth/android/mandatory_reauth_opt_in_view_android.cc
@@ -0,0 +1,40 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/mandatory_reauth/android/mandatory_reauth_opt_in_view_android.h" + +#include <jni.h> + +#include "chrome/browser/mandatory_reauth/android/jni_headers/MandatoryReauthOptInBottomSheetViewBridge_jni.h" + +namespace autofill { + +std::unique_ptr<MandatoryReauthOptInViewAndroid> +MandatoryReauthOptInViewAndroid::CreateAndShow() { + std::unique_ptr<MandatoryReauthOptInViewAndroid> view = + std::make_unique<MandatoryReauthOptInViewAndroid>(); + view->Show(); + return view; +} + +MandatoryReauthOptInViewAndroid::MandatoryReauthOptInViewAndroid() = default; + +MandatoryReauthOptInViewAndroid::~MandatoryReauthOptInViewAndroid() = default; + +void MandatoryReauthOptInViewAndroid::Show() { + JNIEnv* env = base::android::AttachCurrentThread(); + java_bridge_.Reset( + Java_MandatoryReauthOptInBottomSheetViewBridge_create(env)); + CHECK(java_bridge_); + Java_MandatoryReauthOptInBottomSheetViewBridge_show(env, java_bridge_); +} + +void MandatoryReauthOptInViewAndroid::Hide() { + if (java_bridge_) { + Java_MandatoryReauthOptInBottomSheetViewBridge_close( + base::android::AttachCurrentThread(), java_bridge_); + } +} + +} // namespace autofill
diff --git a/chrome/browser/mandatory_reauth/android/mandatory_reauth_opt_in_view_android.h b/chrome/browser/mandatory_reauth/android/mandatory_reauth_opt_in_view_android.h new file mode 100644 index 0000000..3cb4dcd --- /dev/null +++ b/chrome/browser/mandatory_reauth/android/mandatory_reauth_opt_in_view_android.h
@@ -0,0 +1,39 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_MANDATORY_REAUTH_ANDROID_MANDATORY_REAUTH_OPT_IN_VIEW_ANDROID_H_ +#define CHROME_BROWSER_MANDATORY_REAUTH_ANDROID_MANDATORY_REAUTH_OPT_IN_VIEW_ANDROID_H_ + +#include "base/android/scoped_java_ref.h" +#include "chrome/browser/ui/autofill/autofill_bubble_base.h" + +namespace autofill { + +// The native class responsible for managing the Android view to show the +// Mandatory Reauth opt-in prompt. +class MandatoryReauthOptInViewAndroid final : public AutofillBubbleBase { + public: + // Factory function for creating and showing the view. + static std::unique_ptr<MandatoryReauthOptInViewAndroid> CreateAndShow(); + + MandatoryReauthOptInViewAndroid(); + ~MandatoryReauthOptInViewAndroid(); + MandatoryReauthOptInViewAndroid(const MandatoryReauthOptInViewAndroid&) = + delete; + MandatoryReauthOptInViewAndroid& operator=( + const MandatoryReauthOptInViewAndroid&) = delete; + + // AutofillBubbleBase: + void Hide() override; + + private: + void Show(); + + // This class's corresponding java object. + base::android::ScopedJavaGlobalRef<jobject> java_bridge_; +}; + +} // namespace autofill + +#endif // CHROME_BROWSER_MANDATORY_REAUTH_ANDROID_MANDATORY_REAUTH_OPT_IN_VIEW_ANDROID_H_
diff --git a/chrome/browser/page_load_metrics/integration_tests/layout_instability_browsertest.cc b/chrome/browser/page_load_metrics/integration_tests/layout_instability_browsertest.cc index 00d6e7e..3093106 100644 --- a/chrome/browser/page_load_metrics/integration_tests/layout_instability_browsertest.cc +++ b/chrome/browser/page_load_metrics/integration_tests/layout_instability_browsertest.cc
@@ -73,14 +73,14 @@ expectations.Append(std::move(d)); } - // It compares the trace data of layout shift events with |expectations| and - // computes a score that's used to check the UKM and UMA values below. - double final_score = CheckTraceData(expectations, *StopTracingAndAnalyze()); - waiter->Wait(); // Finish session. ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("about:blank"))); + // It compares the trace data of layout shift events with |expectations| and + // computes a score that's used to check the UKM and UMA values below. + double final_score = CheckTraceData(expectations, *StopTracingAndAnalyze()); + // We can only verify the layout shift metrics here in UKM and UMA if layout // shift only happens in the main frame. For layout shift happens in the // sub-frame, it needs to apply a sub-frame weighting factor. @@ -280,24 +280,12 @@ CheckUKMAndUMAMetricsWithValues(totalCls, cls); } -// TODO(crbug.com/1407011): Flaky on linux. -#if BUILDFLAG(IS_LINUX) -#define MAYBE_Sources_Enclosure DISABLED_Sources_Enclosure -#else -#define MAYBE_Sources_Enclosure Sources_Enclosure -#endif -IN_PROC_BROWSER_TEST_F(LayoutInstabilityTest, MAYBE_Sources_Enclosure) { +IN_PROC_BROWSER_TEST_F(LayoutInstabilityTest, Sources_Enclosure) { RunWPT("sources-enclosure.html", ShiftFrame::LayoutShiftOnlyInMainFrame, /*num_layout_shifts=*/2); } -// TODO(crbug.com/1407011): Flaky on linux. -#if BUILDFLAG(IS_LINUX) -#define MAYBE_Sources_MaxImpact DISABLED_Sources_MaxImpact -#else -#define MAYBE_Sources_MaxImpact Sources_MaxImpact -#endif -IN_PROC_BROWSER_TEST_F(LayoutInstabilityTest, MAYBE_Sources_MaxImpact) { +IN_PROC_BROWSER_TEST_F(LayoutInstabilityTest, Sources_MaxImpact) { RunWPT("sources-maximpact.html"); }
diff --git a/chrome/browser/page_load_metrics/observers/tab_strip_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/tab_strip_page_load_metrics_observer.cc new file mode 100644 index 0000000..18205882 --- /dev/null +++ b/chrome/browser/page_load_metrics/observers/tab_strip_page_load_metrics_observer.cc
@@ -0,0 +1,133 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/page_load_metrics/observers/tab_strip_page_load_metrics_observer.h" + +#include "base/metrics/histogram_functions.h" +#include "base/time/time.h" +#include "base/time/time_delta_from_string.h" + +#if BUILDFLAG(IS_ANDROID) +#include "chrome/browser/ui/android/tab_model/tab_model.h" +#include "chrome/browser/ui/android/tab_model/tab_model_list.h" +#else // BUILDFLAG(IS_ANDROID) +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#endif // BUILDFLAG(IS_ANDROID) + +#include "components/page_load_metrics/browser/metrics_web_contents_observer.h" + +namespace internal { + +const char kTabsActiveAbsolutePosition[] = "Tabs.Active.AbsolutePosition"; +const char kTabsActiveRelativePosition[] = "Tabs.Active.RelativePosition"; +const char kTabsPageLoadTimeSinceActive[] = "Tabs.PageLoad.TimeSinceActive"; +const char kTabsPageLoadTimeSinceCreated[] = "Tabs.PageLoad.TimeSinceCreated"; + +} // namespace internal + +namespace { + +// TODO(crbug/1450633): Create an iterator abstraction that could be reused +// in other places we need to iterate across tabs for both Android and desktop. +std::vector<std::vector<content::WebContents*>> GetAllWebContents() { + std::vector<std::vector<content::WebContents*>> all_web_contents = {}; +#if BUILDFLAG(IS_ANDROID) + for (const TabModel* model : TabModelList::models()) { + std::vector<content::WebContents*> web_contents_for_tab_strip = {}; + for (int i = 0; i < model->GetTabCount(); ++i) { +#else // BUILDFLAG(IS_ANDROID) + for (auto* browser : *BrowserList::GetInstance()) { + std::vector<content::WebContents*> web_contents_for_tab_strip = {}; + TabStripModel* model = browser->tab_strip_model(); + for (int i = 0; i < model->count(); ++i) { +#endif // BUILDFLAG(IS_ANDROID) + web_contents_for_tab_strip.push_back(model->GetWebContentsAt(i)); + } + all_web_contents.push_back(web_contents_for_tab_strip); + } + return all_web_contents; +} + +void RecordTimeDeltaHistogram(const char histogram_name[], + base::TimeDelta value) { + base::UmaHistogramCustomTimes(histogram_name, value, base::TimeDelta(), + base::Days(14), 50); +} + +} // namespace + +TabStripPageLoadMetricsObserver::TabStripPageLoadMetricsObserver( + content::WebContents* web_contents) { + web_contents_ = web_contents; +} + +TabStripPageLoadMetricsObserver::~TabStripPageLoadMetricsObserver() = default; + +page_load_metrics::PageLoadMetricsObserver::ObservePolicy +TabStripPageLoadMetricsObserver::OnStart( + content::NavigationHandle* navigation_handle, + const GURL& currently_committed_url, + bool started_in_foreground) { + if (!started_in_foreground) { + return CONTINUE_OBSERVING; + } + base::TimeTicks now = base::TimeTicks::Now(); + std::vector<std::vector<content::WebContents*>> all_web_contents = + GetAllWebContents(); + for (std::vector<content::WebContents*> tab_strip_web_contents : + all_web_contents) { + for (content::WebContents* web_contents : tab_strip_web_contents) { + if (web_contents) { + base::TimeTicks last_active = web_contents->GetLastActiveTime(); + page_load_metrics::MetricsWebContentsObserver* + metrics_web_contents_observer = + page_load_metrics::MetricsWebContentsObserver::FromWebContents( + web_contents); + base::TimeTicks created = metrics_web_contents_observer->GetCreated(); + RecordTimeDeltaHistogram(internal::kTabsPageLoadTimeSinceActive, + now - last_active); + RecordTimeDeltaHistogram(internal::kTabsPageLoadTimeSinceCreated, + now - created); + } + } + } + return CONTINUE_OBSERVING; +} + +page_load_metrics::PageLoadMetricsObserver::ObservePolicy +TabStripPageLoadMetricsObserver::OnPrerenderStart( + content::NavigationHandle* navigation_handle, + const GURL& currently_committed_url) { + return CONTINUE_OBSERVING; +} + +page_load_metrics::PageLoadMetricsObserver::ObservePolicy +TabStripPageLoadMetricsObserver::OnFencedFramesStart( + content::NavigationHandle* navigation_handle, + const GURL& currently_committed_url) { + return STOP_OBSERVING; +} + +page_load_metrics::PageLoadMetricsObserver::ObservePolicy +TabStripPageLoadMetricsObserver::OnShown() { + std::vector<std::vector<content::WebContents*>> all_web_contents = + GetAllWebContents(); + for (std::vector<content::WebContents*> tab_strip_web_contents : + all_web_contents) { + const int count = tab_strip_web_contents.size(); + for (int i = 0; i < count; i++) { + if (tab_strip_web_contents.at(i) == web_contents_.get()) { + const int absolute_sequence = i + 1; + base::UmaHistogramCounts1000(internal::kTabsActiveAbsolutePosition, + absolute_sequence); + base::UmaHistogramPercentage(internal::kTabsActiveRelativePosition, + absolute_sequence * 100 / count); + break; + } + } + } + return CONTINUE_OBSERVING; +}
diff --git a/chrome/browser/page_load_metrics/observers/tab_strip_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/tab_strip_page_load_metrics_observer.h new file mode 100644 index 0000000..23ef02d6 --- /dev/null +++ b/chrome/browser/page_load_metrics/observers/tab_strip_page_load_metrics_observer.h
@@ -0,0 +1,49 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_TAB_STRIP_PAGE_LOAD_METRICS_OBSERVER_H_ +#define CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_TAB_STRIP_PAGE_LOAD_METRICS_OBSERVER_H_ + +#include "components/page_load_metrics/browser/page_load_metrics_observer.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/web_contents.h" + +namespace internal { + +extern const char kTabsActiveAbsolutePosition[]; +extern const char kTabsActiveRelativePosition[]; +extern const char kTabsPageLoadTimeSinceActive[]; +extern const char kTabsPageLoadTimeSinceCreated[]; + +} // namespace internal + +// Observer responsible for notifying the tab strip of the status of a page +// load. This information is used to log UMA metrics at a page load level. +class TabStripPageLoadMetricsObserver + : public page_load_metrics::PageLoadMetricsObserver { + public: + explicit TabStripPageLoadMetricsObserver(content::WebContents* web_contents); + ~TabStripPageLoadMetricsObserver() override; + + TabStripPageLoadMetricsObserver(const TabStripPageLoadMetricsObserver&) = + delete; + TabStripPageLoadMetricsObserver& operator=( + const TabStripPageLoadMetricsObserver&) = delete; + + // page_load_metrics::PageLoadMetricsObserver + ObservePolicy OnStart(content::NavigationHandle* navigation_handle, + const GURL& currently_committed_url, + bool started_in_foreground) override; + ObservePolicy OnPrerenderStart(content::NavigationHandle* navigation_handle, + const GURL& currently_committed_url) override; + ObservePolicy OnFencedFramesStart( + content::NavigationHandle* navigation_handle, + const GURL& currently_committed_url) override; + ObservePolicy OnShown() override; + + private: + raw_ptr<content::WebContents> web_contents_ = nullptr; +}; + +#endif // CHROME_BROWSER_PAGE_LOAD_METRICS_OBSERVERS_TAB_STRIP_PAGE_LOAD_METRICS_OBSERVER_H_
diff --git a/chrome/browser/page_load_metrics/observers/tab_strip_page_load_metrics_observer_browsertest.cc b/chrome/browser/page_load_metrics/observers/tab_strip_page_load_metrics_observer_browsertest.cc new file mode 100644 index 0000000..df76c5e --- /dev/null +++ b/chrome/browser/page_load_metrics/observers/tab_strip_page_load_metrics_observer_browsertest.cc
@@ -0,0 +1,79 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/page_load_metrics/observers/tab_strip_page_load_metrics_observer.h" + +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/test/browser_test.h" +#include "ui/base/window_open_disposition.h" + +class TabStripPageLoadMetricsObserverTest : public InProcessBrowserTest { + protected: + void StartHttpsServer(net::EmbeddedTestServer::ServerCertificate cert) { + https_test_server_ = std::make_unique<net::EmbeddedTestServer>( + net::EmbeddedTestServer::TYPE_HTTPS); + https_test_server_->SetSSLConfig(cert); + https_test_server_->ServeFilesFromSourceDirectory(GetChromeTestDataDir()); + ASSERT_TRUE(https_test_server_->Start()); + } + + net::EmbeddedTestServer* https_test_server() { + return https_test_server_.get(); + } + + private: + std::unique_ptr<net::EmbeddedTestServer> https_test_server_; +}; + +IN_PROC_BROWSER_TEST_F(TabStripPageLoadMetricsObserverTest, + RecordPageLoadMetrics) { + base::HistogramTester histogram_tester; + StartHttpsServer(net::EmbeddedTestServer::CERT_OK); + GURL url = https_test_server()->GetURL("/simple.html"); + + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); + + ui_test_utils::NavigateToURLWithDisposition( + browser(), url, WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); + + histogram_tester.ExpectTotalCount(internal::kTabsPageLoadTimeSinceActive, 2); + histogram_tester.ExpectTotalCount(internal::kTabsPageLoadTimeSinceCreated, 2); +} + +IN_PROC_BROWSER_TEST_F(TabStripPageLoadMetricsObserverTest, + RecordActiveMetrics) { + base::HistogramTester histogram_tester; + StartHttpsServer(net::EmbeddedTestServer::CERT_OK); + GURL url = https_test_server()->GetURL("/simple.html"); + + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); + + ui_test_utils::NavigateToURLWithDisposition( + browser(), url, WindowOpenDisposition::NEW_BACKGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); + + ui_test_utils::NavigateToURLWithDisposition( + browser(), url, WindowOpenDisposition::NEW_BACKGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); + + ui_test_utils::NavigateToURLWithDisposition( + browser(), url, WindowOpenDisposition::NEW_BACKGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); + + ui_test_utils::NavigateToURLWithDisposition( + browser(), url, WindowOpenDisposition::NEW_BACKGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); + + browser()->tab_strip_model()->ActivateTabAt( + 2, TabStripUserGestureDetails( + TabStripUserGestureDetails::GestureType::kOther)); + + histogram_tester.ExpectUniqueSample(internal::kTabsActiveAbsolutePosition, 3, + 1); + histogram_tester.ExpectUniqueSample(internal::kTabsActiveRelativePosition, 60, + 1); +}
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc b/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc index acba34ae..7a189cb 100644 --- a/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc +++ b/chrome/browser/page_load_metrics/page_load_metrics_initialize.cc
@@ -34,6 +34,7 @@ #include "chrome/browser/page_load_metrics/observers/security_state_page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/observers/service_worker_page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/observers/signed_exchange_page_load_metrics_observer.h" +#include "chrome/browser/page_load_metrics/observers/tab_strip_page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/observers/third_party_metrics_observer.h" #include "chrome/browser/page_load_metrics/observers/translate_page_load_metrics_observer.h" #include "chrome/browser/page_load_metrics/page_load_metrics_memory_tracker_factory.h" @@ -172,6 +173,8 @@ tracker->AddObserver(std::move(loading_predictor_observer)); tracker->AddObserver( std::make_unique<LocalNetworkRequestsPageLoadMetricsObserver>()); + tracker->AddObserver( + std::make_unique<TabStripPageLoadMetricsObserver>(web_contents())); } tracker->AddObserver( std::make_unique<OmniboxSuggestionUsedMetricsObserver>());
diff --git a/chrome/browser/password_manager/android/password_generation_controller_impl.cc b/chrome/browser/password_manager/android/password_generation_controller_impl.cc index 26143f9b..589bd12 100644 --- a/chrome/browser/password_manager/android/password_generation_controller_impl.cc +++ b/chrome/browser/password_manager/android/password_generation_controller_impl.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/autofill/manual_filling_controller.h" #include "chrome/browser/password_manager/android/password_accessory_controller.h" #include "chrome/browser/password_manager/android/password_generation_dialog_view_interface.h" +#include "chrome/browser/password_manager/android/password_infobar_utils.h" #include "chrome/browser/password_manager/chrome_password_manager_client.h" #include "chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge_impl.h" #include "chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.h" @@ -305,7 +306,16 @@ touch_to_fill_generation_controller_ = create_touch_to_fill_generation_controller_.Run(); - if (!touch_to_fill_generation_controller_->ShowTouchToFill()) { + std::u16string generated_password = + active_frame_driver_->GetPasswordGenerationHelper()->GeneratePassword( + GetWebContents().GetLastCommittedURL().DeprecatedGetOriginAsURL(), + generation_element_data_->form_signature, + generation_element_data_->field_signature, + generation_element_data_->max_password_length); + std::string account = + password_manager::GetDisplayableAccountName(&GetWebContents()); + if (!touch_to_fill_generation_controller_->ShowTouchToFill( + std::move(generated_password), std::move(account))) { return false; }
diff --git a/chrome/browser/password_manager/android/password_infobar_utils.cc b/chrome/browser/password_manager/android/password_infobar_utils.cc index e3245b8..b0e3c8a 100644 --- a/chrome/browser/password_manager/android/password_infobar_utils.cc +++ b/chrome/browser/password_manager/android/password_infobar_utils.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/password_manager/android/password_infobar_utils.h" +#include "chrome/browser/flags/android/chrome_feature_list.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/sync/sync_service_factory.h" @@ -11,6 +12,7 @@ #include "components/password_manager/core/browser/password_bubble_experiment.h" #include "components/signin/public/identity_manager/account_info.h" #include "components/signin/public/identity_manager/identity_manager.h" +#include "content/public/browser/web_contents.h" namespace password_manager { @@ -28,4 +30,21 @@ return identity_manager->FindExtendedAccountInfoByAccountId(account_id); } +std::string GetDisplayableAccountName(content::WebContents* web_contents) { + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + absl::optional<AccountInfo> account_info = + password_manager::GetAccountInfoForPasswordMessages(profile); + if (!account_info.has_value()) { + return ""; + } + if (!base::FeatureList::IsEnabled( + chrome::android::kHideNonDisplayableAccountEmail)) { + return account_info.value().email; + } + return account_info->CanHaveEmailAddressDisplayed() + ? account_info.value().email + : account_info.value().full_name; +} + } // namespace password_manager
diff --git a/chrome/browser/password_manager/android/password_infobar_utils.h b/chrome/browser/password_manager/android/password_infobar_utils.h index 0b5a182c..6b723444 100644 --- a/chrome/browser/password_manager/android/password_infobar_utils.h +++ b/chrome/browser/password_manager/android/password_infobar_utils.h
@@ -6,13 +6,19 @@ #define CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_PASSWORD_INFOBAR_UTILS_H_ #include "components/signin/public/identity_manager/account_info.h" +#include "content/public/browser/web_contents.h" class Profile; +namespace content { +class WebContents; +} namespace password_manager { AccountInfo GetAccountInfoForPasswordMessages(Profile* profile); +std::string GetDisplayableAccountName(content::WebContents* web_contents); + } // namespace password_manager #endif // CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_PASSWORD_INFOBAR_UTILS_H_
diff --git a/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningMediator.java b/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningMediator.java index b524ad4..c730b13e 100644 --- a/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningMediator.java +++ b/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningMediator.java
@@ -37,7 +37,7 @@ @Override public void onAcknowledge(BottomSheetController bottomSheetController) { - bottomSheetController.collapseSheet(true); + mModel.set(VISIBLE, false); } @Override @@ -53,6 +53,6 @@ @Override public void onCancel(BottomSheetController bottomSheetController) { - bottomSheetController.collapseSheet(true); + mModel.set(VISIBLE, false); } }
diff --git a/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningMediatorTest.java b/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningMediatorTest.java index e3aaefd..97d409d 100644 --- a/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningMediatorTest.java +++ b/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningMediatorTest.java
@@ -8,7 +8,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.verify; import static org.chromium.chrome.browser.pwd_migration.PasswordMigrationWarningProperties.CURRENT_SCREEN; import static org.chromium.chrome.browser.pwd_migration.PasswordMigrationWarningProperties.DISMISS_HANDLER; @@ -90,14 +89,14 @@ } @Test - public void testOnAcknowledgeCollapsesTheSheet() { + public void testOnAcknowledgeHidesTheSheet() { mMediator.onAcknowledge(mBottomSheetController); - verify(mBottomSheetController).collapseSheet(true); + assertFalse(mModel.get(VISIBLE)); } @Test - public void testOnCancelCollapsesTheSheet() { + public void testOnCancelHidesTheSheet() { mMediator.onCancel(mBottomSheetController); - verify(mBottomSheetController).collapseSheet(true); + assertFalse(mModel.get(VISIBLE)); } }
diff --git a/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningViewTest.java b/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningViewTest.java index 3b1f1179d5..3b171cf 100644 --- a/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningViewTest.java +++ b/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningViewTest.java
@@ -22,6 +22,7 @@ import androidx.test.filters.MediumTest; import org.junit.Before; +import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -44,12 +45,17 @@ import org.chromium.components.browser_ui.widget.RadioButtonWithDescription; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; +import org.chromium.ui.test.util.DisableAnimationsTestRule; /** Tests for {@link PasswordMigrationWarningView} */ @RunWith(ChromeJUnit4ClassRunner.class) @Batch(Batch.PER_CLASS) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) public class PasswordMigrationWarningViewTest { + @ClassRule + public static DisableAnimationsTestRule sDisableAnimationsRule = + new DisableAnimationsTestRule(); + @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS); @Rule
diff --git a/chrome/browser/password_manager/android/save_update_password_message_delegate.cc b/chrome/browser/password_manager/android/save_update_password_message_delegate.cc index c739ba5..88a399a3 100644 --- a/chrome/browser/password_manager/android/save_update_password_message_delegate.cc +++ b/chrome/browser/password_manager/android/save_update_password_message_delegate.cc
@@ -93,6 +93,18 @@ return string_version == 2 || string_version == 3; } +void TryToShowPasswordMigrationWarning( + base::RepeatingCallback<void(gfx::NativeWindow)> callback, + raw_ptr<content::WebContents> web_contents) { + if (base::FeatureList::IsEnabled( + password_manager::features:: + kUnifiedPasswordManagerLocalPasswordsMigrationWarning)) { + // TODO(crbug.com/1439853): Check if the bottom sheet was shown a month ago + // or more. + callback.Run(web_contents->GetTopLevelNativeWindow()); + } +} + } // namespace SaveUpdatePasswordMessageDelegate::SaveUpdatePasswordMessageDelegate() @@ -415,15 +427,6 @@ void SaveUpdatePasswordMessageDelegate::HandleSaveButtonClicked() { passwords_state_.form_manager()->Save(); - - if (base::FeatureList::IsEnabled( - password_manager::features:: - kUnifiedPasswordManagerLocalPasswordsMigrationWarning)) { - // TODO(crbug.com/439853): Check if the bottom sheet was shown a month ago - // or more. - create_migration_warning_callback_.Run( - web_contents_->GetTopLevelNativeWindow()); - } } void SaveUpdatePasswordMessageDelegate::HandleNeverSaveClicked() { @@ -482,6 +485,9 @@ RecordSaveUpdateUIDismissalReason( GetSaveUpdatePasswordMessageDismissReason(dismiss_reason)); } + + TryToShowPasswordMigrationWarning(create_migration_warning_callback_, + web_contents_); ClearState(); } @@ -521,6 +527,9 @@ GetPasswordEditDialogDismissReason(dialog_accepted)); } + TryToShowPasswordMigrationWarning(create_migration_warning_callback_, + web_contents_); + password_edit_dialog_.reset(); ClearState(); }
diff --git a/chrome/browser/password_manager/android/save_update_password_message_delegate_unittest.cc b/chrome/browser/password_manager/android/save_update_password_message_delegate_unittest.cc index bbe044f..9f9ddcf 100644 --- a/chrome/browser/password_manager/android/save_update_password_message_delegate_unittest.cc +++ b/chrome/browser/password_manager/android/save_update_password_message_delegate_unittest.cc
@@ -51,6 +51,7 @@ using password_manager::PasswordFormMetricsRecorder; using ::testing::_; using ::testing::ElementsAre; +using ::testing::Eq; using ::testing::Return; using ::testing::ReturnRef; @@ -609,8 +610,8 @@ password_manager::metrics_util::CLICKED_ACCEPT, 1); } -// Tests that local password migration warning will show when the user clicks -// "Save" button. +// Tests that the local password migration warning will show when the user +// clicks the "Save" button. TEST_F(SaveUpdatePasswordMessageDelegateTest, TriggerLocalPasswordMigrationWarning_OnSaveClicked) { base::test::ScopedFeatureList scoped_feature_state; @@ -628,6 +629,146 @@ EXPECT_EQ(nullptr, GetMessageWrapper()); } +TEST_F(SaveUpdatePasswordMessageDelegateTest, + TriggerLocalPasswordMigrationWarning_OnSavePasswordDialogAccepted) { + base::test::ScopedFeatureList scoped_feature_state; + scoped_feature_state.InitAndEnableFeature( + password_manager::features:: + kUnifiedPasswordManagerLocalPasswordsMigrationWarning); + auto form_manager = + CreateFormManager(GURL(kDefaultUrl), empty_best_matches()); + MockPasswordFormManagerForUI* form_manager_pointer = form_manager.get(); + MockPasswordEditDialog* mock_dialog = PreparePasswordEditDialog(); + + EnqueueMessage(std::move(form_manager), /*user_signed_in=*/false, + /*update_password=*/false); + EXPECT_NE(nullptr, GetMessageWrapper()); + EXPECT_CALL(*mock_dialog, ShowPasswordEditDialog); + EXPECT_CALL(GetMigrationWarningCallback(), Run(_)).Times(0); + TriggerPasswordEditDialog(/*update_password=*/false); + + EXPECT_EQ(nullptr, GetMessageWrapper()); + EXPECT_CALL(*form_manager_pointer, Save()); + TriggerDialogAcceptedCallback(/*username=*/kUsername, + /*password=*/kPassword); + EXPECT_CALL(GetMigrationWarningCallback(), Run(_)); + TriggerDialogDismissedCallback(/*dialog_accepted=*/true); +} + +// Tests that the local password migration warning will show when the user +// dismisses the save password message. +TEST_F(SaveUpdatePasswordMessageDelegateTest, + TriggerLocalPasswordMigrationWarning_OnSaveMessageDismissed) { + base::test::ScopedFeatureList scoped_feature_state; + scoped_feature_state.InitAndEnableFeature( + password_manager::features:: + kUnifiedPasswordManagerLocalPasswordsMigrationWarning); + auto form_manager = + CreateFormManager(GURL(kDefaultUrl), empty_best_matches()); + EnqueueMessage(std::move(form_manager), /*user_signed_in=*/true, + /*update_password=*/false); + EXPECT_NE(nullptr, GetMessageWrapper()); + EXPECT_CALL(GetMigrationWarningCallback(), Run(_)); + DismissMessage(messages::DismissReason::GESTURE); + EXPECT_EQ(nullptr, GetMessageWrapper()); +} + +// Tests that the local password migration warning will show when the user +// accepts the update password message in case when there is no confirmation +// dialog. +TEST_F(SaveUpdatePasswordMessageDelegateTest, + TriggerLocalPasswordMigrationWarning_OnUpdatePasswordWithSingleForm) { + base::test::ScopedFeatureList scoped_feature_state; + scoped_feature_state.InitAndEnableFeature( + password_manager::features:: + kUnifiedPasswordManagerLocalPasswordsMigrationWarning); + SetPendingCredentials(kUsername, kPassword); + PasswordForm password_form = CreatePasswordForm(kUsername, kPassword); + std::vector<const PasswordForm*> single_form_best_matches = {&password_form}; + auto form_manager = + CreateFormManager(GURL(kDefaultUrl), &single_form_best_matches); + EXPECT_CALL(*form_manager, Save()); + EnqueueMessage(std::move(form_manager), /*user_signed_in=*/true, + /*update_password=*/true); + EXPECT_NE(nullptr, GetMessageWrapper()); + EXPECT_CALL(GetMigrationWarningCallback(), Run(_)); + TriggerActionClick(); + EXPECT_EQ(nullptr, GetMessageWrapper()); +} + +// Tests that the local password migration warning will show when the user +// dismisses the update password message. +TEST_F(SaveUpdatePasswordMessageDelegateTest, + TriggerLocalPasswordMigrationWarning_OnUpdatePasswordMessageDismissed) { + base::test::ScopedFeatureList scoped_feature_state; + scoped_feature_state.InitAndEnableFeature( + password_manager::features:: + kUnifiedPasswordManagerLocalPasswordsMigrationWarning); + SetPendingCredentials(kUsername, kPassword); + PasswordForm password_form = CreatePasswordForm(kUsername, kPassword); + std::vector<const PasswordForm*> single_form_best_matches = {&password_form}; + auto form_manager = + CreateFormManager(GURL(kDefaultUrl), &single_form_best_matches); + EnqueueMessage(std::move(form_manager), /*user_signed_in=*/true, + /*update_password=*/true); + EXPECT_NE(nullptr, GetMessageWrapper()); + EXPECT_CALL(GetMigrationWarningCallback(), Run(_)); + DismissMessage(messages::DismissReason::GESTURE); + EXPECT_EQ(nullptr, GetMessageWrapper()); +} + +// Tests that the local password migration warning will show when the user +// accepts the update password message and the confirmation dialog. +TEST_F(SaveUpdatePasswordMessageDelegateTest, + TriggerLocalPasswordMigrationWarning_OnUpdatePasswordDialogAccepted) { + base::test::ScopedFeatureList scoped_feature_state; + scoped_feature_state.InitAndEnableFeature( + password_manager::features:: + kUnifiedPasswordManagerLocalPasswordsMigrationWarning); + SetPendingCredentials(kUsername, kPassword); + auto form_manager = + CreateFormManager(GURL(kDefaultUrl), two_forms_best_matches()); + MockPasswordEditDialog* mock_dialog = PreparePasswordEditDialog(); + EXPECT_CALL( + *mock_dialog, + ShowPasswordEditDialog( + ElementsAre(std::u16string(kUsername), std::u16string(kUsername2)), + Eq(kUsername), Eq(kPassword), Eq(kAccountEmail))); + EnqueueMessage(std::move(form_manager), /*user_signed_in=*/true, + /*update_password=*/true); + EXPECT_CALL(GetMigrationWarningCallback(), Run(_)).Times(0); + TriggerActionClick(); + TriggerDialogAcceptedCallback(/*username=*/kUsername, + /*password=*/kPassword); + EXPECT_CALL(GetMigrationWarningCallback(), Run(_)); + TriggerDialogDismissedCallback(/*dialog_accepted=*/true); +} + +// Tests that the local password migration warning will show when the user +// accepts the update password message and cancels the confirmation dialog. +TEST_F(SaveUpdatePasswordMessageDelegateTest, + TriggerLocalPasswordMigrationWarning_OnUpdatePasswordDialogCanceled) { + base::test::ScopedFeatureList scoped_feature_state; + scoped_feature_state.InitAndEnableFeature( + password_manager::features:: + kUnifiedPasswordManagerLocalPasswordsMigrationWarning); + SetPendingCredentials(kUsername, kPassword); + auto form_manager = + CreateFormManager(GURL(kDefaultUrl), two_forms_best_matches()); + MockPasswordEditDialog* mock_dialog = PreparePasswordEditDialog(); + EXPECT_CALL( + *mock_dialog, + ShowPasswordEditDialog( + ElementsAre(std::u16string(kUsername), std::u16string(kUsername2)), + Eq(kUsername), Eq(kPassword), Eq(kAccountEmail))); + EnqueueMessage(std::move(form_manager), /*user_signed_in=*/true, + /*update_password=*/true); + EXPECT_CALL(GetMigrationWarningCallback(), Run(_)).Times(0); + TriggerActionClick(); + EXPECT_CALL(GetMigrationWarningCallback(), Run(_)); + TriggerDialogDismissedCallback(/*dialog_accepted=*/false); +} + // Tests that password form is not saved and metrics recorded correctly when the // user dismisses the message. TEST_F(SaveUpdatePasswordMessageDelegateTest, DontSaveOnDismiss) {
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc index ef3a17f..801df69 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -417,8 +417,10 @@ } auto* webauthn_delegate = GetWebAuthnCredentialsDelegateForDriver(driver); std::vector<password_manager::PasskeyCredential> passkeys; + bool should_show_hybrid_option = false; if (webauthn_delegate && webauthn_delegate->GetPasskeys().has_value()) { passkeys = *webauthn_delegate->GetPasskeys(); + should_show_hybrid_option = webauthn_delegate->IsAndroidHybridAvailable(); } GetOrCreateTouchToFillController()->Show( credential_cache_ @@ -428,7 +430,9 @@ passkeys, std::make_unique<TouchToFillControllerAutofillDelegate>( this, GetDeviceAuthenticator(), driver->AsWeakPtr(), - submission_readiness)); + submission_readiness, + TouchToFillControllerAutofillDelegate::ShowHybridOption( + should_show_hybrid_option))); } #endif
diff --git a/chrome/browser/password_manager/chrome_webauthn_credentials_delegate.cc b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate.cc index 58efe9f..5a50cb0 100644 --- a/chrome/browser/password_manager/chrome_webauthn_credentials_delegate.cc +++ b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate.cc
@@ -98,3 +98,21 @@ std::move(retrieve_passkeys_callback_).Run(); } } + +#if BUILDFLAG(IS_ANDROID) +void ChromeWebAuthnCredentialsDelegate::ShowAndroidHybridSignIn() { + if (WebAuthnRequestDelegateAndroid* delegate = + WebAuthnRequestDelegateAndroid::GetRequestDelegate(web_contents_)) { + delegate->ShowHybridSignIn(); + } +} + +bool ChromeWebAuthnCredentialsDelegate::IsAndroidHybridAvailable() const { + return android_hybrid_available_.value(); +} + +void ChromeWebAuthnCredentialsDelegate::SetAndroidHybridAvailable( + AndroidHybridAvailable available) { + android_hybrid_available_ = available; +} +#endif
diff --git a/chrome/browser/password_manager/chrome_webauthn_credentials_delegate.h b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate.h index fad1650..a100a46 100644 --- a/chrome/browser/password_manager/chrome_webauthn_credentials_delegate.h +++ b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate.h
@@ -8,6 +8,8 @@ #include "base/functional/callback.h" #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" +#include "base/types/strong_alias.h" +#include "build/build_config.h" #include "components/password_manager/core/browser/passkey_credential.h" #include "components/password_manager/core/browser/webauthn_credentials_delegate.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -20,6 +22,9 @@ class ChromeWebAuthnCredentialsDelegate : public password_manager::WebAuthnCredentialsDelegate { public: + using AndroidHybridAvailable = + base::StrongAlias<struct AndroidHybridAvailableTag, bool>; + explicit ChromeWebAuthnCredentialsDelegate( content::WebContents* web_contents); ~ChromeWebAuthnCredentialsDelegate() override; @@ -45,6 +50,16 @@ // WebAuthn options should no longer show up on the autofill popup. void NotifyWebAuthnRequestAborted(); +#if BUILDFLAG(IS_ANDROID) + // password_manager::WebAuthnCredentialsDelegate: + void ShowAndroidHybridSignIn() override; + bool IsAndroidHybridAvailable() const override; + + // Sets the hybrid availability flag, which can be queried through + // `IsAndroidHybridAvailable()`. + void SetAndroidHybridAvailable(AndroidHybridAvailable available); +#endif + protected: const raw_ptr<content::WebContents> web_contents_; @@ -57,6 +72,11 @@ base::OnceClosure retrieve_passkeys_callback_; +#if BUILDFLAG(IS_ANDROID) + AndroidHybridAvailable android_hybrid_available_ = + AndroidHybridAvailable(false); +#endif + base::WeakPtrFactory<ChromeWebAuthnCredentialsDelegate> weak_ptr_factory_{ this}; };
diff --git a/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc index 76448c7..d72a9635 100644 --- a/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc +++ b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate_unittest.cc
@@ -239,3 +239,12 @@ EXPECT_TRUE(callback.was_called()); EXPECT_FALSE(credentials_delegate_->GetPasskeys()); } + +#if BUILDFLAG(IS_ANDROID) +TEST_F(ChromeWebAuthnCredentialsDelegateTest, AndroidHybridAvailability) { + EXPECT_FALSE(credentials_delegate_->IsAndroidHybridAvailable()); + credentials_delegate_->SetAndroidHybridAvailable( + ChromeWebAuthnCredentialsDelegate::AndroidHybridAvailable(true)); + EXPECT_TRUE(credentials_delegate_->IsAndroidHybridAvailable()); +} +#endif // BUILDFLAG(IS_ANDROID)
diff --git a/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/v4/PrivacySandboxDialogNoticeRestrictedV4.java b/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/v4/PrivacySandboxDialogNoticeRestrictedV4.java index 0d3ca427..6ae54df 100644 --- a/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/v4/PrivacySandboxDialogNoticeRestrictedV4.java +++ b/chrome/browser/privacy_sandbox/android/java/src/org/chromium/chrome/browser/privacy_sandbox/v4/PrivacySandboxDialogNoticeRestrictedV4.java
@@ -64,7 +64,7 @@ @Override public void show() { - PrivacySandboxBridge.promptActionOccurred(PromptAction.NOTICE_SHOWN); + PrivacySandboxBridge.promptActionOccurred(PromptAction.RESTRICTED_NOTICE_SHOWN); super.show(); } @@ -80,7 +80,8 @@ dismiss(); mSettingsLauncher.launchSettingsActivity(getContext(), AdMeasurementFragmentV4.class); } else if (id == R.id.more_button) { - PrivacySandboxBridge.promptActionOccurred(PromptAction.NOTICE_MORE_BUTTON_CLICKED); + PrivacySandboxBridge.promptActionOccurred( + PromptAction.RESTRICTED_NOTICE_MORE_BUTTON_CLICKED); if (mScrollView.canScrollVertically(ScrollView.FOCUS_DOWN)) { mScrollView.post(() -> { mScrollView.pageScroll(ScrollView.FOCUS_DOWN); }); } else {
diff --git a/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxDialogTest.java b/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxDialogTest.java index 54e3b78..09d2db8 100644 --- a/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxDialogTest.java +++ b/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxDialogTest.java
@@ -159,10 +159,13 @@ assertEquals("Last dialog action", PromptAction.CONSENT_MORE_BUTTON_CLICKED, (int) mFakePrivacySandboxBridge.getLastPromptAction()); } else if (promptType == PromptType.M1_NOTICE_EEA - || promptType == PromptType.M1_NOTICE_ROW - || promptType == PromptType.M1_NOTICE_RESTRICTED) { + || promptType == PromptType.M1_NOTICE_ROW) { assertEquals("Last dialog action", PromptAction.NOTICE_MORE_BUTTON_CLICKED, (int) mFakePrivacySandboxBridge.getLastPromptAction()); + } else if (promptType == PromptType.M1_NOTICE_RESTRICTED) { + assertEquals("Last dialog action", + PromptAction.RESTRICTED_NOTICE_MORE_BUTTON_CLICKED, + (int) mFakePrivacySandboxBridge.getLastPromptAction()); } } catch (PerformException e) { return; @@ -530,7 +533,7 @@ launchDialog(); // Verify that the restricted notice is shown onViewWaiting(withId(R.id.privacy_sandbox_notice_title)); - assertEquals("Last dialog action", PromptAction.NOTICE_SHOWN, + assertEquals("Last dialog action", PromptAction.RESTRICTED_NOTICE_SHOWN, (int) mFakePrivacySandboxBridge.getLastPromptAction()); // Ack the notice and verify it worked correctly. tryClickOn(withId(R.id.ack_button));
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_service.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_service.cc index 70f278a..7f4d7138 100644 --- a/chrome/browser/privacy_sandbox/privacy_sandbox_service.cc +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_service.cc
@@ -1745,6 +1745,21 @@ "Settings.PrivacySandbox.RestrictedNotice.OpenedSettings")); break; } + case (PromptAction::kRestrictedNoticeShown): { + base::RecordAction(base::UserMetricsAction( + "Settings.PrivacySandbox.RestrictedNotice.Shown")); + break; + } + case (PromptAction::kRestrictedNoticeClosedNoInteraction): { + base::RecordAction(base::UserMetricsAction( + "Settings.PrivacySandbox.RestrictedNotice.ClosedNoInteraction")); + break; + } + case (PromptAction::kRestrictedNoticeMoreButtonClicked): { + base::RecordAction(base::UserMetricsAction( + "Settings.PrivacySandbox.RestrictedNotice.MoreButtonClicked")); + break; + } } }
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_service.h b/chrome/browser/privacy_sandbox/privacy_sandbox_service.h index c72ab5c..46665fb7 100644 --- a/chrome/browser/privacy_sandbox/privacy_sandbox_service.h +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_service.h
@@ -97,13 +97,14 @@ kConsentMoreButtonClicked = 14, kNoticeMoreButtonClicked = 15, - // Restricted notice interactions, including only the interactions that - // complete - // the notice, using the `kNoticeXxx` for all other interactions. + // Restricted notice interactions kRestrictedNoticeAcknowledge = 16, kRestrictedNoticeOpenSettings = 17, + kRestrictedNoticeShown = 18, + kRestrictedNoticeClosedNoInteraction = 19, + kRestrictedNoticeMoreButtonClicked = 20, - kMaxValue = kRestrictedNoticeOpenSettings, + kMaxValue = kRestrictedNoticeMoreButtonClicked, }; // TODO(crbug.com/1378703): Integrate this when handling Notice and Consent
diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_service_unittest.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_service_unittest.cc index 1d27f96..49c3808 100644 --- a/chrome/browser/privacy_sandbox/privacy_sandbox_service_unittest.cc +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_service_unittest.cc
@@ -1199,11 +1199,6 @@ "Settings.PrivacySandbox.Notice.OpenedSettings")); privacy_sandbox_service()->PromptActionOccurred( - PrivacySandboxService::PromptAction::kRestrictedNoticeOpenSettings); - EXPECT_EQ(1, user_action_tester.GetActionCount( - "Settings.PrivacySandbox.RestrictedNotice.OpenedSettings")); - - privacy_sandbox_service()->PromptActionOccurred( PrivacySandboxService::PromptAction::kNoticeAcknowledge); EXPECT_EQ(1, user_action_tester.GetActionCount( "Settings.PrivacySandbox.Notice.Acknowledged")); @@ -1272,6 +1267,34 @@ PrivacySandboxService::PromptAction::kNoticeMoreButtonClicked); EXPECT_EQ(1, user_action_tester.GetActionCount( "Settings.PrivacySandbox.Notice.MoreButtonClicked")); + + privacy_sandbox_service()->PromptActionOccurred( + PrivacySandboxService::PromptAction::kRestrictedNoticeOpenSettings); + EXPECT_EQ(1, user_action_tester.GetActionCount( + "Settings.PrivacySandbox.RestrictedNotice.OpenedSettings")); + + privacy_sandbox_service()->PromptActionOccurred( + PrivacySandboxService::PromptAction::kRestrictedNoticeAcknowledge); + EXPECT_EQ(1, user_action_tester.GetActionCount( + "Settings.PrivacySandbox.RestrictedNotice.Acknowledged")); + + privacy_sandbox_service()->PromptActionOccurred( + PrivacySandboxService::PromptAction::kRestrictedNoticeShown); + EXPECT_EQ(1, user_action_tester.GetActionCount( + "Settings.PrivacySandbox.RestrictedNotice.Shown")); + + privacy_sandbox_service()->PromptActionOccurred( + PrivacySandboxService::PromptAction:: + kRestrictedNoticeClosedNoInteraction); + EXPECT_EQ( + 1, user_action_tester.GetActionCount( + "Settings.PrivacySandbox.RestrictedNotice.ClosedNoInteraction")); + + privacy_sandbox_service()->PromptActionOccurred( + PrivacySandboxService::PromptAction::kRestrictedNoticeMoreButtonClicked); + EXPECT_EQ(1, + user_action_tester.GetActionCount( + "Settings.PrivacySandbox.RestrictedNotice.MoreButtonClicked")); } #if !BUILDFLAG(IS_ANDROID)
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc index 80acbb14..92dec1c2 100644 --- a/chrome/browser/profiles/profile_manager.cc +++ b/chrome/browser/profiles/profile_manager.cc
@@ -933,9 +933,12 @@ // adding an entry to ProfileAttributesStorage. Creating a new // ProfileAttributesEntry consistently before writing the profile folder to // disk would resolve this. + // The TaskPriority should be `USER_BLOCKING` because `CreateProfileAsync` + // will eventually open a new browser window or navigates to the sign-in page, + // either of which will block the user's interaction. base::ThreadPool::PostTask( FROM_HERE, - {base::MayBlock(), base::TaskPriority::BEST_EFFORT, + {base::MayBlock(), base::TaskPriority::USER_BLOCKING, base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, base::BindOnce(&NukeProfileFromDisk, new_path, base::BindOnce(&ProfileManager::CreateProfileAsync,
diff --git a/chrome/browser/resources/chromeos/login/screens/oobe/enterprise_enrollment.js b/chrome/browser/resources/chromeos/login/screens/oobe/enterprise_enrollment.js index c5e5930..e440c9f 100644 --- a/chrome/browser/resources/chromeos/login/screens/oobe/enterprise_enrollment.js +++ b/chrome/browser/resources/chromeos/login/screens/oobe/enterprise_enrollment.js
@@ -348,9 +348,11 @@ } invokePolymerMethod(this.$['step-ad-join'], 'onBeforeShow'); - this.showStep( - this.isAutoEnroll_ ? OobeTypes.EnrollmentStep.WORKING : - OobeTypes.EnrollmentStep.LOADING); + if (!this.uiStep) { + this.showStep( + this.isAutoEnroll_ ? OobeTypes.EnrollmentStep.WORKING : + OobeTypes.EnrollmentStep.LOADING); + } } /**
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_browser_proxy.ts b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_browser_proxy.ts index 6eab420..81c2b30 100644 --- a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_browser_proxy.ts +++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_browser_proxy.ts
@@ -29,6 +29,9 @@ NOTICE_MORE_BUTTON_CLICKED = 15, RESTRICTED_NOTICE_ACKNOWLEDGE = 16, RESTRICTED_NOTICE_OPEN_SETTINGS = 17, + RESTRICTED_NOTICE_SHOWN = 18, + RESTRICTED_NOTICE_CLOSED_NO_INTERACTION = 19, + RESTRICTED_NOTICE_MORE_BUTTON_CLICKED = 20, } export class PrivacySandboxDialogBrowserProxy {
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_mixin.ts b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_mixin.ts index deecd51..d3a8828a 100644 --- a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_mixin.ts +++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_mixin.ts
@@ -83,6 +83,12 @@ PrivacySandboxPromptAction.NOTICE_MORE_BUTTON_CLICKED); } + onRestrictedNoticeMoreClicked() { + this.onMoreClicked_(); + this.promptActionOccurred( + PrivacySandboxPromptAction.RESTRICTED_NOTICE_MORE_BUTTON_CLICKED); + } + promptActionOccurred(action: PrivacySandboxPromptAction) { PrivacySandboxDialogBrowserProxy.getInstance().promptActionOccurred( action);
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.html b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.html index 53aa564..0c28653 100644 --- a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.html +++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.html
@@ -29,7 +29,7 @@ </div> </div> <div id="showMoreOverlay" hidden="[[wasScrolledToBottom]]"> - <cr-button id="moreButton" on-click="onNoticeMoreClicked" + <cr-button id="moreButton" on-click="onRestrictedNoticeMoreClicked" class="action-button" aria-hidden="true" tabindex="-1"> $i18n{m1DialogMoreButton} <iron-icon icon="cr:expand-more"></iron-icon>
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.ts b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.ts index acff955..64f8638 100644 --- a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.ts +++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_notice_restricted_dialog_app.ts
@@ -36,7 +36,7 @@ this.updateScrollableContents(); this.maybeShowMoreButton().then( () => this.promptActionOccurred( - PrivacySandboxPromptAction.NOTICE_SHOWN)); + PrivacySandboxPromptAction.RESTRICTED_NOTICE_SHOWN)); }); }
diff --git a/chrome/browser/resources/settings/chromeos/main_page_mixin.ts b/chrome/browser/resources/settings/chromeos/main_page_mixin.ts index 23d7d89..0ca4898 100644 --- a/chrome/browser/resources/settings/chromeos/main_page_mixin.ts +++ b/chrome/browser/resources/settings/chromeos/main_page_mixin.ts
@@ -74,6 +74,11 @@ [RouteState.ROOT, ALL_STATES], ]); +/** + * The route for the first page listed in the Settings menu. + */ +const FIRST_PAGE_ROUTE: Route = Router.getInstance().routes.INTERNET; + export interface MainPageMixinInterface extends RouteObserverMixinInterface { containsRoute(route: Route|undefined): boolean; querySection(section: string): HTMLElement|null; @@ -99,6 +104,10 @@ return castExists(hostEl ? hostEl.parentElement : document.body); } + private get isMainPageContainer(): boolean { + return this.tagName === 'MAIN-PAGE-CONTAINER'; + } + /** * Method to be overridden by users of MainPageMixin. * @return Whether the given route is part of |this| page. @@ -130,8 +139,7 @@ const waitFn = beforeNextRender.bind(null, this); return new Promise(resolve => { - if (this.tagName === 'MAIN-PAGE-CONTAINER' && - isAdvancedRoute(route)) { + if (this.isMainPageContainer && isAdvancedRoute(route)) { this.dispatchCustomEvent_('hide-container'); waitFn(async () => { await this.loadAdvancedPage(); @@ -280,7 +288,13 @@ return; case RouteState.ROOT: - // TODO(b/282961146) Activate first top-level page (Network) + // Do not activate the Network page if the host element is + // the About page since it does not contain that page. + // TODO(b/282961146) Investigate removing MainPageMixin from + // the About page so this check can be removed. + if (isRevampWayfindingEnabled() && this.isMainPageContainer) { + this.activatePage(FIRST_PAGE_ROUTE); + } return; // Nothing to do here for the DIALOG case.
diff --git a/chrome/browser/resources/waffle/app.html b/chrome/browser/resources/waffle/app.html index 259b9d8..6fb92b8 100644 --- a/chrome/browser/resources/waffle/app.html +++ b/chrome/browser/resources/waffle/app.html
@@ -5,4 +5,3 @@ </style> <h1>$i18n{title}</h1> -<button on-click="onCloseClick_">$i18n{closeButtonTitle}</button>
diff --git a/chrome/browser/resources/waffle/app.ts b/chrome/browser/resources/waffle/app.ts index 19d25f8..98da622 100644 --- a/chrome/browser/resources/waffle/app.ts +++ b/chrome/browser/resources/waffle/app.ts
@@ -5,7 +5,7 @@ import './strings.m.js'; import 'chrome://resources/cr_elements/cr_shared_vars.css.js'; -import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {afterNextRender, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './app.html.js'; import {WaffleBrowserProxy} from './browser_proxy.js'; @@ -19,8 +19,12 @@ return getTemplate(); } - private onCloseClick_() { - WaffleBrowserProxy.getInstance().handler.closeClicked(); + override connectedCallback() { + super.connectedCallback(); + + afterNextRender(this, () => { + WaffleBrowserProxy.getInstance().handler.displayDialog(); + }); } }
diff --git a/chrome/browser/resources/waffle/waffle.html b/chrome/browser/resources/waffle/waffle.html index 2e244ea..0fd0106 100644 --- a/chrome/browser/resources/waffle/waffle.html +++ b/chrome/browser/resources/waffle/waffle.html
@@ -6,9 +6,9 @@ <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> <style> body { - height: 100vh; + height: 100%; margin: 0; - width: 100vw; + width: 100%; } @media (prefers-color-scheme: dark) { body {
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service.cc b/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service.cc index 53d062b7..1903a642 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service.cc
@@ -96,12 +96,16 @@ "Connector for scanning." trigger: "If the OnFileAttachedEnterpriseConnector, " - "OnFileDownloadedEnterpriseConnector or " - "OnBulkDataEntryEnterpriseConnector policy is set, a request is made to " - "scan a file attached to Chrome, a file downloaded by Chrome or " - "data pasted in Chrome respectively." + "OnFileDownloadedEnterpriseConnector, " + "OnFileTransferEnterpriseConnector, " + "OnBulkDataEntryEnterpriseConnector or OnPrintEnterpriseConnector " + "policy is set, a request is made to scan a file attached to " + "Chrome, a file downloaded by Chrome, a file transfered from a " + "ChromeOS file system, data pasted in " + "Chrome or data printed from Chrome respectively." data: - "The uploaded or downloaded file, or pasted data." + "The uploaded/downloaded/transfered file, pasted data or printed " + "data." destination: GOOGLE_OWNED_SERVICE } policy { @@ -119,6 +123,12 @@ OnBulkDataEntryEnterpriseConnector { OnBulkDataEntryEnterpriseConnector: "[]" } + OnFileTransferEnterpriseConnector { + OnFileTransferEnterpriseConnector: "[]" + } + OnPrintEnterpriseConnector { + OnPrintEnterpriseConnector: "[]" + } } } )");
diff --git a/chrome/browser/touch_to_fill/android/internal/java/res/layout/touch_to_fill_footer_item.xml b/chrome/browser/touch_to_fill/android/internal/java/res/layout/touch_to_fill_footer_item.xml index 1ebd654..6dcb25e7 100644 --- a/chrome/browser/touch_to_fill/android/internal/java/res/layout/touch_to_fill_footer_item.xml +++ b/chrome/browser/touch_to_fill/android/internal/java/res/layout/touch_to_fill_footer_item.xml
@@ -22,6 +22,19 @@ android:layout_marginBottom="@dimen/ttf_buttons_vertical_margin"/> <TextView + android:id="@+id/touch_to_fill_sheet_use_passkeys_other_device" + android:text="@string/touch_to_fill_use_device_passkey" + android:layout_width="match_parent" + android:layout_height="@dimen/ttf_buttons_height" + android:paddingHorizontal="@dimen/ttf_sheet_padding" + android:minHeight="48dp" + android:gravity="center_vertical|start" + android:textAppearance="@style/TextAppearance.TextLarge.Primary" + android:background="?android:attr/selectableItemBackground" + android:textDirection="locale" + android:textAlignment="viewStart"/> + + <TextView android:id="@+id/touch_to_fill_sheet_manage_passwords" android:layout_width="match_parent" android:layout_height="@dimen/ttf_buttons_height"
diff --git a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillBridge.java b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillBridge.java index d4cf335b..050cc36 100644 --- a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillBridge.java +++ b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillBridge.java
@@ -76,10 +76,11 @@ @CalledByNative private void showCredentials(GURL url, boolean isOriginSecure, WebAuthnCredential[] webAuthnCredentials, Credential[] credentials, - boolean submitCredential, boolean managePasskeysHidesPasswords) { + boolean submitCredential, boolean managePasskeysHidesPasswords, + boolean showHybridPasskeyOption) { mTouchToFillComponent.showCredentials(url, isOriginSecure, Arrays.asList(webAuthnCredentials), Arrays.asList(credentials), submitCredential, - managePasskeysHidesPasswords); + managePasskeysHidesPasswords, showHybridPasskeyOption); } @Override @@ -95,6 +96,13 @@ } @Override + public void onHybridSignInSelected() { + if (mNativeView != 0) { + TouchToFillBridgeJni.get().onHybridSignInSelected(mNativeView); + } + } + + @Override public void onCredentialSelected(Credential credential) { if (mNativeView != 0) { TouchToFillBridgeJni.get().onCredentialSelected(mNativeView, credential); @@ -114,6 +122,7 @@ void onWebAuthnCredentialSelected( long nativeTouchToFillViewImpl, WebAuthnCredential credential); void onManagePasswordsSelected(long nativeTouchToFillViewImpl, boolean passkeysShown); + void onHybridSignInSelected(long nativeTouchToFillViewImpl); void onDismiss(long nativeTouchToFillViewImpl); } }
diff --git a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillCoordinator.java b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillCoordinator.java index 98f33ca..c5a5710 100644 --- a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillCoordinator.java +++ b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillCoordinator.java
@@ -46,9 +46,10 @@ @Override public void showCredentials(GURL url, boolean isOriginSecure, List<WebAuthnCredential> webAuthnCredentials, List<Credential> credentials, - boolean triggerSubmission, boolean managePasskeysHidesPasswords) { + boolean triggerSubmission, boolean managePasskeysHidesPasswords, + boolean showHybridPasskeyOption) { mMediator.showCredentials(url, isOriginSecure, webAuthnCredentials, credentials, - triggerSubmission, managePasskeysHidesPasswords); + triggerSubmission, managePasskeysHidesPasswords, showHybridPasskeyOption); } /**
diff --git a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillMediator.java b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillMediator.java index bff8343..80c4006 100644 --- a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillMediator.java +++ b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillMediator.java
@@ -10,7 +10,9 @@ import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CredentialProperties.ON_CLICK_LISTENER; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CredentialProperties.SHOW_SUBMIT_BUTTON; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FooterProperties.MANAGE_BUTTON_TEXT; +import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FooterProperties.ON_CLICK_HYBRID; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FooterProperties.ON_CLICK_MANAGE; +import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FooterProperties.SHOW_HYBRID; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.FORMATTED_URL; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.IMAGE_DRAWABLE_ID; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.ORIGIN_SECURE; @@ -87,7 +89,8 @@ void showCredentials(GURL url, boolean isOriginSecure, List<WebAuthnCredential> webAuthnCredentials, List<Credential> credentials, - boolean triggerSubmission, boolean managePasskeysHidesPasswords) { + boolean triggerSubmission, boolean managePasskeysHidesPasswords, + boolean showHybridPasskeyOption) { assert credentials != null; mManagePasskeysHidesPasswords = managePasskeysHidesPasswords; @@ -133,6 +136,8 @@ .with(ON_CLICK_MANAGE, this::onManagePasswordSelected) .with(MANAGE_BUTTON_TEXT, getManageButtonText(credentials, webAuthnCredentials)) + .with(ON_CLICK_HYBRID, this::onHybridSignInSelected) + .with(SHOW_HYBRID, showHybridPasskeyOption) .build())); mBottomSheetFocusHelper.registerForOneTimeUse(); @@ -254,6 +259,13 @@ mDelegate.onManagePasswordsSelected(passkeysShown); } + private void onHybridSignInSelected() { + mModel.set(VISIBLE, false); + RecordHistogram.recordEnumeratedHistogram( + UMA_TOUCH_TO_FILL_USER_ACTION, UserAction.SELECT_HYBRID, UserAction.MAX_VALUE + 1); + mDelegate.onHybridSignInSelected(); + } + /** * @param credentials The available credentials. Show the confirmation for a lone credential. * @return True if a confirmation button should be shown at the end of the bottom sheet.
diff --git a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillProperties.java b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillProperties.java index c1ab90f3..afaf1ee 100644 --- a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillProperties.java +++ b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillProperties.java
@@ -134,8 +134,13 @@ new PropertyModel.WritableObjectPropertyKey<>("on_click_manage"); static final PropertyModel.WritableObjectPropertyKey<String> MANAGE_BUTTON_TEXT = new PropertyModel.WritableObjectPropertyKey<>("manage_button_text"); + static final PropertyModel.WritableObjectPropertyKey<Runnable> ON_CLICK_HYBRID = + new PropertyModel.WritableObjectPropertyKey<>("on_click_hybrid"); + static final PropertyModel.WritableBooleanPropertyKey SHOW_HYBRID = + new PropertyModel.WritableBooleanPropertyKey("show_hybrid"); - static final PropertyKey[] ALL_KEYS = {ON_CLICK_MANAGE, MANAGE_BUTTON_TEXT}; + static final PropertyKey[] ALL_KEYS = { + ON_CLICK_MANAGE, MANAGE_BUTTON_TEXT, ON_CLICK_HYBRID, SHOW_HYBRID}; private FooterProperties() {} }
diff --git a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewBinder.java b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewBinder.java index 34e1372..4fd36f3 100644 --- a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewBinder.java +++ b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewBinder.java
@@ -12,7 +12,9 @@ import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CredentialProperties.SHOW_SUBMIT_BUTTON; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.DISMISS_HANDLER; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FooterProperties.MANAGE_BUTTON_TEXT; +import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FooterProperties.ON_CLICK_HYBRID; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FooterProperties.ON_CLICK_MANAGE; +import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FooterProperties.SHOW_HYBRID; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.FORMATTED_URL; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.IMAGE_DRAWABLE_ID; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.ORIGIN_SECURE; @@ -310,6 +312,12 @@ if (key == ON_CLICK_MANAGE) { view.findViewById(R.id.touch_to_fill_sheet_manage_passwords) .setOnClickListener((v) -> model.get(ON_CLICK_MANAGE).run()); + } else if (key == ON_CLICK_HYBRID) { + view.findViewById(R.id.touch_to_fill_sheet_use_passkeys_other_device) + .setOnClickListener((v) -> model.get(ON_CLICK_HYBRID).run()); + } else if (key == SHOW_HYBRID) { + view.findViewById(R.id.touch_to_fill_sheet_use_passkeys_other_device) + .setVisibility(model.get(SHOW_HYBRID) ? View.VISIBLE : View.GONE); } else if (key == MANAGE_BUTTON_TEXT) { TextView managePasswordsView = view.findViewById(R.id.touch_to_fill_sheet_manage_passwords);
diff --git a/chrome/browser/touch_to_fill/android/internal/java/strings/android_touch_to_fill_strings.grd b/chrome/browser/touch_to_fill/android/internal/java/strings/android_touch_to_fill_strings.grd index d5eb346..79f59d0e 100644 --- a/chrome/browser/touch_to_fill/android/internal/java/strings/android_touch_to_fill_strings.grd +++ b/chrome/browser/touch_to_fill/android/internal/java/strings/android_touch_to_fill_strings.grd
@@ -232,6 +232,9 @@ <message name="IDS_TOUCH_TO_FILL_PASSKEY_CREDENTIAL_ACCESSIBILITY_DESCRIPTION" desc="Content description for a passkey credential item on the sheet list. This is not visually displayed, but is audibly read by screen readers for accessibility purposes."> Passkey for <ph name="USERNAME">%1$s<ex>John.Doe@example.com</ex></ph>, use your screen lock. </message> + <message name="IDS_TOUCH_TO_FILL_USE_DEVICE_PASSKEY" desc="Title of a button at the end of a touch to fill sheet that will use a different device’s passkey. This string also exists for desktop password manager and translations should match. See IDS_PASSWORD_MANAGER_USE_DEVICE_PASSKEY in components/password_manager_strings.grdp."> + Use a passkey on a different device + </message> </messages> </release> </grit>
diff --git a/chrome/browser/touch_to_fill/android/internal/java/strings/android_touch_to_fill_strings_grd/IDS_TOUCH_TO_FILL_USE_DEVICE_PASSKEY.png.sha1 b/chrome/browser/touch_to_fill/android/internal/java/strings/android_touch_to_fill_strings_grd/IDS_TOUCH_TO_FILL_USE_DEVICE_PASSKEY.png.sha1 new file mode 100644 index 0000000..09e21af --- /dev/null +++ b/chrome/browser/touch_to_fill/android/internal/java/strings/android_touch_to_fill_strings_grd/IDS_TOUCH_TO_FILL_USE_DEVICE_PASSKEY.png.sha1
@@ -0,0 +1 @@ +452dbb6ffe46f729da35bf3f5c97aa3e7a9852aa \ No newline at end of file
diff --git a/chrome/browser/touch_to_fill/android/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillComponent.java b/chrome/browser/touch_to_fill/android/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillComponent.java index a77aeeb..1e661e8 100644 --- a/chrome/browser/touch_to_fill/android/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillComponent.java +++ b/chrome/browser/touch_to_fill/android/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillComponent.java
@@ -32,14 +32,15 @@ * TODO(crbug.com/1013134): Deduplicate the Java and C++ enum. */ @IntDef({UserAction.SELECT_CREDENTIAL, UserAction.DISMISS, UserAction.SELECT_MANAGE_PASSWORDS, - UserAction.SELECT_WEBAUTHN_CREDENTIAL, UserAction.MAX_VALUE}) + UserAction.SELECT_WEBAUTHN_CREDENTIAL, UserAction.SELECT_HYBRID, UserAction.MAX_VALUE}) @Retention(RetentionPolicy.SOURCE) @interface UserAction { int SELECT_CREDENTIAL = 0; int DISMISS = 1; int SELECT_MANAGE_PASSWORDS = 2; int SELECT_WEBAUTHN_CREDENTIAL = 3; - int MAX_VALUE = SELECT_WEBAUTHN_CREDENTIAL; + int SELECT_HYBRID = 4; + int MAX_VALUE = SELECT_HYBRID; } /** @@ -71,6 +72,11 @@ * @param passkeysShown True when the sheet contained passkey credentials. */ void onManagePasswordsSelected(boolean passkeysShown); + + /** + * Called when the user selects 'Use a Passkey on a Different Device'. + */ + void onHybridSignInSelected(); } /** @@ -94,8 +100,11 @@ * after filling. * @param managePasskeysHidesPasswords A {@link boolean} that indicates whether managing * passkeys will show a screen that does not provide password management. + * @param showHybridPasskeyOption A {@link boolean} that indicates whether the footer should + * display an option to initiate hybrid sign-in. */ void showCredentials(GURL url, boolean isOriginSecure, List<WebAuthnCredential> webauthnCredentials, List<Credential> credentials, - boolean triggerSubmission, boolean managePasskeysHidesPasswords); + boolean triggerSubmission, boolean managePasskeysHidesPasswords, + boolean showHybridPasskeyOption); }
diff --git a/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillIntegrationTest.java b/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillIntegrationTest.java index 92ffb62e..a6d58d4 100644 --- a/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillIntegrationTest.java +++ b/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillIntegrationTest.java
@@ -111,7 +111,7 @@ runOnUiThreadBlocking(() -> { mTouchToFill.showCredentials(sExampleUrl, true, Collections.emptyList(), Collections.singletonList(sAna), /*submitCredential=*/false, - /*managePasskeysHidesPasswords=*/false); + /*managePasskeysHidesPasswords=*/false, /*showHybridPasskeyOption=*/false); }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); @@ -128,7 +128,7 @@ runOnUiThreadBlocking(() -> { mTouchToFill.showCredentials(sExampleUrl, true, Collections.singletonList(sCam), Collections.singletonList(sAna), /*submitCredential=*/false, - /*managePasskeysHidesPasswords=*/false); + /*managePasskeysHidesPasswords=*/false, /*showHybridPasskeyOption=*/false); }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); @@ -145,7 +145,7 @@ runOnUiThreadBlocking(() -> { mTouchToFill.showCredentials(sExampleUrl, true, Collections.emptyList(), Collections.singletonList(sAna), /*submitCredential=*/false, - /*managePasskeysHidesPasswords=*/false); + /*managePasskeysHidesPasswords=*/false, /*showHybridPasskeyOption=*/false); }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); @@ -162,7 +162,7 @@ runOnUiThreadBlocking(() -> { mTouchToFill.showCredentials(sExampleUrl, true, Collections.emptyList(), Arrays.asList(sAna, sBob), /*submitCredential=*/false, - /*managePasskeysHidesPasswords=*/false); + /*managePasskeysHidesPasswords=*/false, /*showHybridPasskeyOption=*/false); }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); @@ -178,13 +178,13 @@ runOnUiThreadBlocking(() -> { mTouchToFill.showCredentials(sExampleUrl, true, Collections.emptyList(), Collections.singletonList(sAna), /*submitCredential=*/false, - /*managePasskeysHidesPasswords=*/false); + /*managePasskeysHidesPasswords=*/false, /*showHybridPasskeyOption=*/false); }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); BottomSheetTestSupport sheetSupport = new BottomSheetTestSupport(mBottomSheetController); - // Swipe the sheet up to it's full state in order to see the 'Manage Passwords' button. + // Swipe the sheet up to its full state in order to see the 'Manage Passwords' button. runOnUiThreadBlocking(() -> { sheetSupport.setSheetState(SheetState.FULL, false); }); pollUiThread(() -> getManagePasswordsButton() != null); @@ -196,6 +196,29 @@ @Test @MediumTest + public void testClickingHybridButtonTriggersCallback() { + runOnUiThreadBlocking(() -> { + mTouchToFill.showCredentials(sExampleUrl, true, Collections.emptyList(), + Collections.singletonList(sAna), /*submitCredential=*/false, + /*managePasskeysHidesPasswords=*/false, /*showHybridPasskeyOption=*/true); + }); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); + + BottomSheetTestSupport sheetSupport = new BottomSheetTestSupport(mBottomSheetController); + + // Swipe the sheet up to its full state in order to see the 'Use a Passkey on a Different + // Device' button. + runOnUiThreadBlocking(() -> { sheetSupport.setSheetState(SheetState.FULL, false); }); + + pollUiThread(() -> getHybridSignInButton() != null); + TouchCommon.singleClickView(getHybridSignInButton()); + waitForEvent(mMockBridge).onHybridSignInSelected(); + verify(mMockBridge, never()).onDismissed(); + verify(mMockBridge, never()).onCredentialSelected(any()); + } + + @Test + @MediumTest @SuppressLint("SetTextI18n") public void testDismissedIfUnableToShow() throws Exception { BottomSheetContent otherBottomSheetContent = runOnUiThreadBlocking(() -> { @@ -261,7 +284,7 @@ runOnUiThreadBlocking(() -> { mTouchToFill.showCredentials(sExampleUrl, true, Collections.emptyList(), Arrays.asList(sAna, sBob), /*submitCredential=*/false, - /*managePasskeysHidesPasswords=*/false); + /*managePasskeysHidesPasswords=*/false, /*showHybridPasskeyOption=*/false); }); waitForEvent(mMockBridge).onDismissed(); verify(mMockBridge, never()).onCredentialSelected(any()); @@ -282,6 +305,11 @@ R.id.touch_to_fill_sheet_manage_passwords); } + private TextView getHybridSignInButton() { + return mActivityTestRule.getActivity().findViewById( + R.id.touch_to_fill_sheet_use_passkeys_other_device); + } + public static <T> T waitForEvent(T mock) { return verify(mock, timeout(ScalableTimeout.scaleTimeout(CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL)));
diff --git a/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java b/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java index 0300fae..6793ae6f 100644 --- a/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java +++ b/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java
@@ -22,7 +22,9 @@ import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CredentialProperties.ON_CLICK_LISTENER; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CredentialProperties.SHOW_SUBMIT_BUTTON; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FooterProperties.MANAGE_BUTTON_TEXT; +import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FooterProperties.ON_CLICK_HYBRID; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FooterProperties.ON_CLICK_MANAGE; +import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FooterProperties.SHOW_HYBRID; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.FORMATTED_URL; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.IMAGE_DRAWABLE_ID; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.ORIGIN_SECURE; @@ -94,6 +96,7 @@ private static final Credential NIK = new Credential("Nik", "***", "Nik", "group.xyz", GetLoginMatchType.AFFILIATED, 0); private final AtomicBoolean mManageButtonClicked = new AtomicBoolean(false); + private final AtomicBoolean mHybridButtonClicked = new AtomicBoolean(false); @Mock private Callback<Integer> mDismissHandler; @@ -132,7 +135,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { mModel.get(SHEET_ITEMS) .addAll(asList(buildCredentialItem(ANA), buildConfirmationButton(ANA, true), - buildFooterItem())); + buildFooterItem(false))); mModel.set(VISIBLE, true); }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); @@ -161,7 +164,7 @@ .with(IMAGE_DRAWABLE_ID, mResourceProvider.getHeaderImageDrawableId()) .build()), - buildFooterItem())); + buildFooterItem(false))); mModel.set(VISIBLE, true); }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); @@ -189,7 +192,7 @@ .with(IMAGE_DRAWABLE_ID, mResourceProvider.getHeaderImageDrawableId()) .build()), - buildFooterItem())); + buildFooterItem(false))); mModel.set(VISIBLE, true); }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); @@ -213,7 +216,7 @@ .with(IMAGE_DRAWABLE_ID, mResourceProvider.getHeaderImageDrawableId()) .build()), - buildFooterItem())); + buildFooterItem(false))); mModel.set(VISIBLE, true); }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); @@ -236,7 +239,7 @@ .with(IMAGE_DRAWABLE_ID, mResourceProvider.getHeaderImageDrawableId()) .build()), - buildFooterItem())); + buildFooterItem(false))); mModel.set(VISIBLE, true); }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); @@ -260,7 +263,7 @@ .with(IMAGE_DRAWABLE_ID, mResourceProvider.getHeaderImageDrawableId()) .build()), - buildFooterItem())); + buildFooterItem(false))); mModel.set(VISIBLE, true); }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); @@ -284,7 +287,7 @@ .with(IMAGE_DRAWABLE_ID, mResourceProvider.getHeaderImageDrawableId()) .build()), - buildFooterItem())); + buildFooterItem(false))); mModel.set(VISIBLE, true); }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); @@ -336,7 +339,8 @@ @MediumTest public void testCredentialsAreClickable() { TestThreadUtils.runOnUiThreadBlocking(() -> { - mModel.get(SHEET_ITEMS).addAll(asList(buildCredentialItem(ANA), buildFooterItem())); + mModel.get(SHEET_ITEMS) + .addAll(asList(buildCredentialItem(ANA), buildFooterItem(false))); mModel.set(VISIBLE, true); }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); @@ -354,7 +358,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { mModel.get(SHEET_ITEMS) .addAll(asList(buildCredentialItem(ANA), buildConfirmationButton(ANA, false), - buildFooterItem())); + buildFooterItem(false))); mModel.set(VISIBLE, true); }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); @@ -374,7 +378,8 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { mModel.get(SHEET_ITEMS) .addAll(asList(buildCredentialItem(ANA), - buildConfirmationButton(ANA, showSubmitButton), buildFooterItem())); + buildConfirmationButton(ANA, showSubmitButton), + buildFooterItem(false))); mModel.set(VISIBLE, true); }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); @@ -391,7 +396,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { mModel.get(SHEET_ITEMS) .addAll(asList(buildCredentialItem(ANA), buildConfirmationButton(ANA, true), - buildFooterItem())); + buildFooterItem(false))); mModel.set(VISIBLE, true); }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); @@ -408,7 +413,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { mModel.get(SHEET_ITEMS) .addAll(asList(buildCredentialItem(ANA), buildConfirmationButton(ANA, true), - buildFooterItem())); + buildFooterItem(false))); mModel.set(VISIBLE, true); }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); @@ -430,7 +435,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { mModel.get(SHEET_ITEMS) .addAll(asList(buildCredentialItem(ANA), buildConfirmationButton(ANA, true), - buildFooterItem())); + buildFooterItem(false))); mModel.set(VISIBLE, true); }); BottomSheetTestSupport.waitForOpen(mBottomSheetController); @@ -445,7 +450,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { mModel.get(SHEET_ITEMS) .addAll(asList(buildCredentialItem(ANA), buildConfirmationButton(ANA, true), - buildFooterItem())); + buildFooterItem(false))); mModel.set(VISIBLE, true); }); @@ -463,7 +468,7 @@ public void testPasskeyCredentialAccessibilityDescription() { TestThreadUtils.runOnUiThreadBlocking(() -> { mModel.get(SHEET_ITEMS) - .addAll(asList(buildWebAuthnCredentialItem(CAM), buildFooterItem())); + .addAll(asList(buildWebAuthnCredentialItem(CAM), buildFooterItem(false))); mModel.set(VISIBLE, true); }); @@ -504,7 +509,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { mModel.get(SHEET_ITEMS) .addAll(asList(buildCredentialItem(ANA), buildConfirmationButton(ANA, true), - buildFooterItem())); + buildFooterItem(false))); mModel.set(VISIBLE, true); }); @@ -538,6 +543,55 @@ assertFalse(recyclerView.isLayoutSuppressed()); } + @Test + @MediumTest + @EnableFeatures({ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ANDROID}) + public void testHybridPropertyShowsHybridButton() { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mModel.get(SHEET_ITEMS) + .addAll(asList( + new MVCListAdapter.ListItem(TouchToFillProperties.ItemType.HEADER, + new PropertyModel.Builder(HeaderProperties.ALL_KEYS) + .with(TITLE, + getActivity().getString( + R.string.touch_to_fill_sheet_uniform_title)) + .with(FORMATTED_URL, "www.example.org") + .with(ORIGIN_SECURE, true) + .with(IMAGE_DRAWABLE_ID, + mResourceProvider.getHeaderImageDrawableId()) + .build()), + buildFooterItem(true))); + mModel.set(VISIBLE, true); + }); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); + TextView hybridButtonText = mTouchToFillView.getContentView().findViewById( + R.id.touch_to_fill_sheet_use_passkeys_other_device); + + assertThat(hybridButtonText.getText(), + is(getActivity().getString(R.string.touch_to_fill_use_device_passkey))); + } + + @Test + @MediumTest + public void testHybridButtonIsClickable() { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mModel.get(SHEET_ITEMS) + .addAll(asList(buildCredentialItem(ANA), buildConfirmationButton(ANA, true), + buildFooterItem(true))); + mModel.set(VISIBLE, true); + }); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); + + TestThreadUtils.runOnUiThreadBlocking( + () -> mSheetTestSupport.setSheetState(SheetState.FULL, false)); + + TextView hybridButton = mTouchToFillView.getContentView().findViewById( + R.id.touch_to_fill_sheet_use_passkeys_other_device); + TouchCommon.singleClickView(hybridButton); + + pollUiThread(mHybridButtonClicked::get); + } + private ChromeActivity getActivity() { return mActivityTestRule.getActivity(); } @@ -598,13 +652,15 @@ .build()); } - private MVCListAdapter.ListItem buildFooterItem() { + private MVCListAdapter.ListItem buildFooterItem(boolean showHybrid) { return new MVCListAdapter.ListItem(TouchToFillProperties.ItemType.FOOTER, new PropertyModel.Builder(FooterProperties.ALL_KEYS) .with(MANAGE_BUTTON_TEXT, mActivityTestRule.getActivity().getString( R.string.manage_passwords_and_passkeys)) .with(ON_CLICK_MANAGE, () -> mManageButtonClicked.set(true)) + .with(SHOW_HYBRID, showHybrid) + .with(ON_CLICK_HYBRID, () -> mHybridButtonClicked.set(true)) .build()); } }
diff --git a/chrome/browser/touch_to_fill/android/junit/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillControllerTest.java b/chrome/browser/touch_to_fill/android/junit/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillControllerTest.java index e1c469dc..fdfee2be6 100644 --- a/chrome/browser/touch_to_fill/android/junit/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillControllerTest.java +++ b/chrome/browser/touch_to_fill/android/junit/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillControllerTest.java
@@ -23,7 +23,9 @@ import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CredentialProperties.SHOW_SUBMIT_BUTTON; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.DISMISS_HANDLER; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FooterProperties.MANAGE_BUTTON_TEXT; +import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FooterProperties.ON_CLICK_HYBRID; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FooterProperties.ON_CLICK_MANAGE; +import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FooterProperties.SHOW_HYBRID; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.FORMATTED_URL; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.IMAGE_DRAWABLE_ID; import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.HeaderProperties.ORIGIN_SECURE; @@ -151,7 +153,8 @@ @EnableFeatures({ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ANDROID}) public void testShowCredentialsWithMultipleEntries() { mMediator.showCredentials(TEST_URL, true, Collections.emptyList(), Arrays.asList(ANA, CARL), - /*submitCredential=*/true, /*managePasskeysHidesPasswords=*/false); + /*submitCredential=*/true, /*managePasskeysHidesPasswords=*/false, + /*showHybridPasskeyOption=*/false); ListModel<MVCListAdapter.ListItem> itemList = mModel.get(SHEET_ITEMS); assertThat(itemList.size(), is(4)); // Header + 2 credentials + footer. assertThat(itemList.get(itemList.size() - 1).model.get(MANAGE_BUTTON_TEXT), @@ -182,7 +185,8 @@ @EnableFeatures({ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ANDROID}) public void testShowCredentialsWithSingleEntry() { mMediator.showCredentials(TEST_URL, true, Collections.emptyList(), Arrays.asList(ANA), - /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/false); + /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/false, + /*showHybridPasskeyOption=*/false); ListModel<MVCListAdapter.ListItem> itemList = mModel.get(SHEET_ITEMS); assertThat(itemList.size(), is(4)); // Header + 1 credential + Button + Footer. assertThat(itemList.get(itemList.size() - 1).model.get(MANAGE_BUTTON_TEXT), @@ -208,7 +212,8 @@ @EnableFeatures({ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ANDROID}) public void testShowCredentialsWithSingleWebAuthnEntry() { mMediator.showCredentials(TEST_URL, true, Arrays.asList(DINO), Collections.emptyList(), - /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/false); + /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/false, + /*showHybridPasskeyOption=*/false); ListModel<MVCListAdapter.ListItem> itemList = mModel.get(SHEET_ITEMS); assertThat(itemList.size(), is(4)); // Header + 1 credential + Button + Footer. assertThat(itemList.get(itemList.size() - 1).model.get(MANAGE_BUTTON_TEXT), @@ -230,7 +235,8 @@ @EnableFeatures({ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ANDROID}) public void testShowCredentialsWithWebAuthnAndPasswordEntries() { mMediator.showCredentials(TEST_URL, true, Arrays.asList(DINO), Arrays.asList(ANA), - /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/false); + /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/false, + /*showHybridPasskeyOption=*/false); ListModel<MVCListAdapter.ListItem> itemList = mModel.get(SHEET_ITEMS); // Header + 1 webauthn credential + 1 password credential + Footer. assertThat(itemList.size(), is(4)); @@ -255,7 +261,8 @@ @EnableFeatures({ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ANDROID}) public void testShowCredentialsToSubmit() { mMediator.showCredentials(TEST_URL, true, Collections.emptyList(), Arrays.asList(ANA), - /*submitCredential=*/true, /*managePasskeysHidesPasswords=*/false); + /*submitCredential=*/true, /*managePasskeysHidesPasswords=*/false, + /*showHybridPasskeyOption=*/false); ListModel<MVCListAdapter.ListItem> itemList = mModel.get(SHEET_ITEMS); assertThat(itemList.size(), is(4)); // Header + 1 credential + Button + Footer. assertThat(itemList.get(itemList.size() - 1).model.get(MANAGE_BUTTON_TEXT), @@ -273,7 +280,7 @@ public void testShowCredentialsSetsCredentialListAndRequestsFavicons() { mMediator.showCredentials(TEST_URL, true, Collections.emptyList(), Arrays.asList(ANA, CARL, BOB), /*submitCredential=*/false, - /*managePasskeysHidesPasswords=*/false); + /*managePasskeysHidesPasswords=*/false, /*showHybridPasskeyOption=*/false); ListModel<MVCListAdapter.ListItem> itemList = mModel.get(SHEET_ITEMS); assertThat(itemList.size(), is(5)); // Header + 3 Credentials + Footer. assertThat(itemList.get(1).type, is(ItemType.CREDENTIAL)); @@ -299,7 +306,7 @@ public void testFetchFaviconUpdatesModel() { mMediator.showCredentials(TEST_URL, true, Collections.emptyList(), Collections.singletonList(CARL), /*submitCredential=*/false, - /*managePasskeysHidesPasswords=*/false); + /*managePasskeysHidesPasswords=*/false, /*showHybridPasskeyOption=*/false); ListModel<MVCListAdapter.ListItem> itemList = mModel.get(SHEET_ITEMS); assertThat(itemList.size(), is(4)); // Header + Credential + Continue Button + Footer. assertThat(itemList.get(1).type, is(ItemType.CREDENTIAL)); @@ -327,7 +334,8 @@ @EnableFeatures({ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ANDROID}) public void testShowCredentialsFormatPslOrigins() { mMediator.showCredentials(TEST_URL, true, Collections.emptyList(), Arrays.asList(ANA, BOB), - /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/false); + /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/false, + /*showHybridPasskeyOption=*/false); assertThat(mModel.get(SHEET_ITEMS).size(), is(4)); // Header + 2 Credentials + Footer. assertThat(mModel.get(SHEET_ITEMS).get(1).type, is(ItemType.CREDENTIAL)); assertThat(mModel.get(SHEET_ITEMS).get(1).model.get(FORMATTED_ORIGIN), @@ -342,7 +350,7 @@ public void testClearsCredentialListWhenShowingAgain() { mMediator.showCredentials(TEST_URL, true, Collections.emptyList(), Collections.singletonList(ANA), /*submitCredential=*/false, - /*managePasskeysHidesPasswords=*/false); + /*managePasskeysHidesPasswords=*/false, /*showHybridPasskeyOption=*/false); ListModel<MVCListAdapter.ListItem> itemList = mModel.get(SHEET_ITEMS); assertThat(itemList.size(), is(4)); // Header + Credential + Continue Button + Footer. assertThat(itemList.get(1).type, is(ItemType.CREDENTIAL)); @@ -352,7 +360,7 @@ // Showing the sheet a second time should replace all changed credentials. mMediator.showCredentials(TEST_URL, true, Collections.emptyList(), Collections.singletonList(BOB), /*submitCredential=*/false, - /*managePasskeysHidesPasswords=*/false); + /*managePasskeysHidesPasswords=*/false, /*showHybridPasskeyOption=*/false); itemList = mModel.get(SHEET_ITEMS); assertThat(itemList.size(), is(4)); // Header + Credential + Continue Button + Footer. assertThat(itemList.get(1).type, is(ItemType.CREDENTIAL)); @@ -365,7 +373,7 @@ public void testShowCredentialsSetsVisibile() { mMediator.showCredentials(TEST_URL, true, Collections.emptyList(), Arrays.asList(ANA, CARL, BOB), /*submitCredential=*/false, - /*managePasskeysHidesPasswords=*/false); + /*managePasskeysHidesPasswords=*/false, /*showHybridPasskeyOption=*/false); assertThat(mModel.get(VISIBLE), is(true)); } @@ -373,7 +381,8 @@ @EnableFeatures({ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ANDROID}) public void testCallsCallbackAndHidesOnSelectingItemDoesNotRecordIndexForSingleCredential() { mMediator.showCredentials(TEST_URL, true, Collections.emptyList(), Arrays.asList(ANA), - /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/false); + /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/false, + /*showHybridPasskeyOption=*/false); assertThat(mModel.get(VISIBLE), is(true)); assertNotNull(mModel.get(SHEET_ITEMS).get(1).model.get(ON_CLICK_LISTENER)); @@ -393,7 +402,8 @@ @EnableFeatures({ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ANDROID}) public void testCallsCallbackAndHidesOnSelectingItem() { mMediator.showCredentials(TEST_URL, true, Collections.emptyList(), Arrays.asList(ANA, CARL), - /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/false); + /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/false, + /*showHybridPasskeyOption=*/false); assertThat(mModel.get(VISIBLE), is(true)); assertNotNull(mModel.get(SHEET_ITEMS).get(1).model.get(ON_CLICK_LISTENER)); @@ -413,7 +423,8 @@ @EnableFeatures({ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ANDROID}) public void testCallsDelegateAndHidesOnDismiss() { mMediator.showCredentials(TEST_URL, true, Collections.emptyList(), Arrays.asList(ANA, CARL), - /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/false); + /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/false, + /*showHybridPasskeyOption=*/false); mMediator.onDismissed(BottomSheetController.StateChangeReason.BACK_PRESS); verify(mMockDelegate).onDismissed(); assertThat(mModel.get(VISIBLE), is(false)); @@ -431,7 +442,7 @@ public void testHidesWhenSelectingManagePasswords() { mMediator.showCredentials(TEST_URL, true, Collections.emptyList(), Arrays.asList(ANA, CARL, BOB), /*submitCredential=*/false, - /*managePasskeysHidesPasswords=*/false); + /*managePasskeysHidesPasswords=*/false, /*showHybridPasskeyOption=*/false); ListModel<MVCListAdapter.ListItem> itemList = mModel.get(SHEET_ITEMS); assertThat( itemList.get(itemList.size() - 1).model.get(ON_CLICK_MANAGE), is(notNullValue())); @@ -448,7 +459,8 @@ @EnableFeatures({ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ANDROID}) public void testManagePasswordsWithPasskeysShown() { mMediator.showCredentials(TEST_URL, true, Arrays.asList(DINO), Collections.emptyList(), - /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/true); + /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/true, + /*showHybridPasskeyOption=*/false); ListModel<MVCListAdapter.ListItem> itemList = mModel.get(SHEET_ITEMS); assertThat( itemList.get(itemList.size() - 1).model.get(ON_CLICK_MANAGE), is(notNullValue())); @@ -460,7 +472,8 @@ @EnableFeatures({ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ANDROID}) public void testManagePasskeysButtonTitleWhenPasswordsHidden() { mMediator.showCredentials(TEST_URL, true, Arrays.asList(DINO), Arrays.asList(ANA), - /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/true); + /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/true, + /*showHybridPasskeyOption=*/false); ListModel<MVCListAdapter.ListItem> itemList = mModel.get(SHEET_ITEMS); // Header + 1 webauthn credential + 1 password credential + Footer. assertThat(itemList.size(), is(4)); @@ -470,13 +483,42 @@ @Test @EnableFeatures({ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ANDROID}) - public void testAddsTheBottomSheetHeperToObserveTheSheet() { + public void testAddsTheBottomSheetHelperToObserveTheSheet() { mMediator.showCredentials(TEST_URL, true, Arrays.asList(DINO), Arrays.asList(ANA), - /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/true); + /*submitCredential=*/false, /*managePasskeysHidesPasswords=*/true, + /*showHybridPasskeyOption=*/false); verify(mMockFocusHelper).registerForOneTimeUse(); } + @Test + @EnableFeatures({ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ANDROID}) + public void testHybridPasskeysShown() { + mMediator.showCredentials(TEST_URL, true, Collections.emptyList(), + Arrays.asList(ANA, CARL, BOB), /*submitCredential=*/false, + /*managePasskeysHidesPasswords=*/false, /*showHybridPasskeyOption=*/true); + ListModel<MVCListAdapter.ListItem> itemList = mModel.get(SHEET_ITEMS); + assertThat(itemList.get(itemList.size() - 1).model.get(SHOW_HYBRID), is(true)); + } + + @Test + @EnableFeatures({ChromeFeatureList.UNIFIED_PASSWORD_MANAGER_ANDROID}) + public void testHidesWhenSelectingHybridSignin() { + mMediator.showCredentials(TEST_URL, true, Collections.emptyList(), + Arrays.asList(ANA, CARL, BOB), /*submitCredential=*/false, + /*managePasskeysHidesPasswords=*/false, /*showHybridPasskeyOption=*/true); + ListModel<MVCListAdapter.ListItem> itemList = mModel.get(SHEET_ITEMS); + assertThat( + itemList.get(itemList.size() - 1).model.get(ON_CLICK_HYBRID), is(notNullValue())); + itemList.get(itemList.size() - 1).model.get(ON_CLICK_HYBRID).run(); + verify(mMockDelegate).onHybridSignInSelected(); + assertThat(mModel.get(VISIBLE), is(false)); + assertThat(RecordHistogram.getHistogramValueCountForTesting( + TouchToFillMediator.UMA_TOUCH_TO_FILL_USER_ACTION, + UserAction.SELECT_HYBRID), + is(1)); + } + /** * Helper to verify formatted URLs. The real implementation calls {@link UrlFormatter}. It's not * useful to actually reimplement the formatter, so just modify the string in a trivial way.
diff --git a/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.cc b/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.cc index 8df7d30..de9547c 100644 --- a/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.cc +++ b/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.cc
@@ -94,8 +94,7 @@ IsOriginSecure is_origin_secure, base::span<const password_manager::UiCredential> credentials, base::span<const PasskeyCredential> passkey_credentials, - bool trigger_submission, - bool can_manage_passwords_when_passkeys_present) { + int flags) { if (!RecreateJavaObject()) { // It's possible that the constructor cannot access the bottom sheet clank // component. That case may be temporary but we can't let users in a waiting @@ -137,7 +136,9 @@ Java_TouchToFillBridge_showCredentials( env, java_object_internal_, url::GURLAndroid::FromNativeGURL(env, url), is_origin_secure.value(), passkey_array, credential_array, - trigger_submission, !can_manage_passwords_when_passkeys_present); + !!(flags & TouchToFillView::kTriggerSubmission), + !(flags & TouchToFillView::kCanManagePasswordsWhenPasskeysPresent), + !!(flags & TouchToFillView::kShouldShowHybridOption)); } void TouchToFillViewImpl::OnCredentialSelected(const UiCredential& credential) { @@ -166,6 +167,10 @@ controller_->OnManagePasswordsSelected(passkeys_shown); } +void TouchToFillViewImpl::OnHybridSignInSelected(JNIEnv* env) { + controller_->OnHybridSignInSelected(); +} + void TouchToFillViewImpl::OnDismiss(JNIEnv* env) { OnDismiss(); }
diff --git a/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.h b/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.h index 725a900..62629e2 100644 --- a/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.h +++ b/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.h
@@ -34,8 +34,7 @@ IsOriginSecure is_origin_secure, base::span<const password_manager::UiCredential> credentials, base::span<const password_manager::PasskeyCredential> passkey_credentials, - bool trigger_submission, - bool can_manage_passwords_when_passkeys_present) override; + int flags) override; void OnCredentialSelected( const password_manager::UiCredential& credential) override; void OnDismiss() override; @@ -47,6 +46,7 @@ JNIEnv* env, const base::android::JavaParamRef<jobject>& credential); void OnManagePasswordsSelected(JNIEnv* env, jboolean passkeys_shown); + void OnHybridSignInSelected(JNIEnv* env); void OnDismiss(JNIEnv* env); private:
diff --git a/chrome/browser/touch_to_fill/password_generation/android/fake_touch_to_fill_password_generation_bridge.cc b/chrome/browser/touch_to_fill/password_generation/android/fake_touch_to_fill_password_generation_bridge.cc index bf747b6..dcd2f7f 100644 --- a/chrome/browser/touch_to_fill/password_generation/android/fake_touch_to_fill_password_generation_bridge.cc +++ b/chrome/browser/touch_to_fill/password_generation/android/fake_touch_to_fill_password_generation_bridge.cc
@@ -13,7 +13,9 @@ bool FakeTouchToFillPasswordGenerationBridge::Show( content::WebContents* web_contents, - base::WeakPtr<TouchToFillPasswordGenerationDelegate> delegate) { + base::WeakPtr<TouchToFillPasswordGenerationDelegate> delegate, + std::u16string password, + std::string account) { delegate_ = delegate; return true; }
diff --git a/chrome/browser/touch_to_fill/password_generation/android/fake_touch_to_fill_password_generation_bridge.h b/chrome/browser/touch_to_fill/password_generation/android/fake_touch_to_fill_password_generation_bridge.h index 16a3451..4cfe6e6 100644 --- a/chrome/browser/touch_to_fill/password_generation/android/fake_touch_to_fill_password_generation_bridge.h +++ b/chrome/browser/touch_to_fill/password_generation/android/fake_touch_to_fill_password_generation_bridge.h
@@ -15,9 +15,10 @@ FakeTouchToFillPasswordGenerationBridge(); ~FakeTouchToFillPasswordGenerationBridge() override; - bool Show( - content::WebContents* web_contents, - base::WeakPtr<TouchToFillPasswordGenerationDelegate> delegate) override; + bool Show(content::WebContents* web_contents, + base::WeakPtr<TouchToFillPasswordGenerationDelegate> delegate, + std::u16string password, + std::string account) override; void Hide() override; void OnDismissed(JNIEnv* env) override;
diff --git a/chrome/browser/touch_to_fill/password_generation/android/internal/BUILD.gn b/chrome/browser/touch_to_fill/password_generation/android/internal/BUILD.gn index 3d31eb47..23af4bb 100644 --- a/chrome/browser/touch_to_fill/password_generation/android/internal/BUILD.gn +++ b/chrome/browser/touch_to_fill/password_generation/android/internal/BUILD.gn
@@ -11,10 +11,12 @@ "//base:jni_java", "//chrome/browser/autofill/android:java", "//chrome/browser/password_manager/android:password_manager_resource_provider_java", + "//chrome/browser/sync/android:java", "//chrome/browser/touch_to_fill/common/android:java", "//chrome/browser/touch_to_fill/common/android:java_resources", "//chrome/browser/ui/android/strings:ui_strings_grd", "//components/browser_ui/bottomsheet/android:java", + "//components/signin/public/android:java", "//third_party/androidx:androidx_annotation_annotation_java", "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//third_party/androidx:androidx_recyclerview_recyclerview_java", @@ -24,7 +26,9 @@ sources = [ "java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationBridge.java", "java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationCoordinator.java", + "java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationProperties.java", "java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationView.java", + "java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationViewBinder.java", ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] @@ -49,9 +53,41 @@ "//base:base_java", "//base:base_java_test_support", "//base:base_junit_test_support", + "//chrome/browser/sync/android:java", "//chrome/test/android:chrome_java_unit_test_support", "//components/browser_ui/bottomsheet/android:java", + "//components/signin/public/android:java", "//third_party/junit", "//third_party/mockito:mockito_java", ] } + +android_library("javatests") { + testonly = true + resources_package = + "org.chromium.chrome.browser.touch_to_fill.password_generation" + + sources = [ "java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationRenderTest.java" ] + + deps = [ + ":java", + ":java_resources", + "//base:base_java", + "//base:base_java_test_support", + "//chrome/android:chrome_java", + "//chrome/browser/flags:java", + "//chrome/browser/sync/android:java", + "//chrome/browser/ui/android/night_mode:night_mode_java_test_support", + "//chrome/test/android:chrome_java_integration_test_support", + "//components/browser_ui/bottomsheet/android:java", + "//components/browser_ui/bottomsheet/android:java_resources", + "//components/browser_ui/bottomsheet/android/test:java", + "//components/signin/public/android:java", + "//content/public/test/android:content_java_test_support", + "//third_party/androidx:androidx_test_runner_java", + "//third_party/junit:junit", + "//third_party/mockito:mockito_java", + "//ui/android:ui_java_test_support", + "//ui/android:ui_no_recycler_view_java", + ] +}
diff --git a/chrome/browser/touch_to_fill/password_generation/android/internal/java/res/layout/touch_to_fill_password_generation.xml b/chrome/browser/touch_to_fill/password_generation/android/internal/java/res/layout/touch_to_fill_password_generation.xml index 6d740c38..940c695b 100644 --- a/chrome/browser/touch_to_fill/password_generation/android/internal/java/res/layout/touch_to_fill_password_generation.xml +++ b/chrome/browser/touch_to_fill/password_generation/android/internal/java/res/layout/touch_to_fill_password_generation.xml
@@ -44,6 +44,7 @@ android:layout_height="52dp" android:layout_marginHorizontal="@dimen/ttf_sheet_padding" android:layout_marginBottom="24dp" + android:gravity="center" android:background="@drawable/touch_to_fill_credential_background_modern_rounded_all" android:singleLine="true" android:textAppearance="@style/TextAppearance.TextMedium.Primary" />
diff --git a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationBridge.java b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationBridge.java index 59b980a..c62fb384 100644 --- a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationBridge.java +++ b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationBridge.java
@@ -38,8 +38,8 @@ } @CalledByNative - public boolean show() { - return mCoordinator.show(); + public boolean show(String generatedPassword, String account) { + return mCoordinator.show(generatedPassword, account); } @CalledByNative
diff --git a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationCoordinator.java b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationCoordinator.java index b5c3a36..6ba194de 100644 --- a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationCoordinator.java +++ b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationCoordinator.java
@@ -4,14 +4,17 @@ package org.chromium.chrome.browser.touch_to_fill.password_generation; -import android.content.Context; +import static org.chromium.chrome.browser.touch_to_fill.password_generation.TouchToFillPasswordGenerationProperties.ACCOUNT_EMAIL; +import static org.chromium.chrome.browser.touch_to_fill.password_generation.TouchToFillPasswordGenerationProperties.GENERATED_PASSWORD; -import androidx.annotation.VisibleForTesting; +import android.content.Context; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.StateChangeReason; import org.chromium.components.browser_ui.bottomsheet.BottomSheetObserver; import org.chromium.components.browser_ui.bottomsheet.EmptyBottomSheetObserver; +import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.modelutil.PropertyModelChangeProcessor; /** * Coordinates the password generation bottom sheet functionality. It shows the bottom sheet, fills @@ -44,7 +47,14 @@ /** * Displays the bottom sheet. */ - public boolean show() { + public boolean show(String generatedPassword, String account) { + PropertyModel model = + new PropertyModel.Builder(TouchToFillPasswordGenerationProperties.ALL_KEYS) + .with(ACCOUNT_EMAIL, account) + .with(GENERATED_PASSWORD, generatedPassword) + .build(); + setUpModelChangeProcessors(model, mTouchToFillPasswordGenerationView); + mBottomSheetController.addObserver(mBottomSheetObserver); if (mBottomSheetController.requestShowContent(mTouchToFillPasswordGenerationView, true)) { return true; @@ -63,8 +73,15 @@ mTouchToFillPasswordGenerationDelegate.onDismissed(); } - @VisibleForTesting - TouchToFillPasswordGenerationView getViewForTesting() { - return mTouchToFillPasswordGenerationView; + /** + * Connects the given model with the given view using Model Change Processors. + * @param model A {@link PropertyModel} built with {@link + * TouchToFillPasswordGenerationProperties}. + * @param view A {@link TouchToFillPasswordGenerationView}. + */ + private static void setUpModelChangeProcessors( + PropertyModel model, TouchToFillPasswordGenerationView view) { + PropertyModelChangeProcessor.create( + model, view, TouchToFillPasswordGenerationViewBinder::bindView); } }
diff --git a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationModuleTest.java b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationModuleTest.java index ed6f3b7..4834fc6f 100644 --- a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationModuleTest.java +++ b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationModuleTest.java
@@ -50,6 +50,8 @@ private TouchToFillPasswordGenerationBridge.Natives mBridgeJniMock; private static final long sDummyNativePointer = 1; + private static final String sTestEmailAddress = "test@email.com"; + private static final String sGeneratedPassword = "Strong generated password"; @Before public void setUp() { @@ -67,7 +69,7 @@ @Test public void showsAndHidesBottomSheet() { - mBridge.show(); + mBridge.show(sGeneratedPassword, sTestEmailAddress); verify(mBottomSheetController).requestShowContent(any(), anyBoolean()); verify(mBottomSheetController).addObserver(any()); @@ -78,7 +80,7 @@ @Test public void testBottomSheetForceHide() { - mBridge.show(); + mBridge.show(sGeneratedPassword, sTestEmailAddress); verify(mBottomSheetController).requestShowContent(any(), anyBoolean()); mBridge.hide();
diff --git a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationProperties.java b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationProperties.java new file mode 100644 index 0000000..0443c574 --- /dev/null +++ b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationProperties.java
@@ -0,0 +1,22 @@ +// 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.chrome.browser.touch_to_fill.password_generation; + +import org.chromium.ui.modelutil.PropertyKey; +import org.chromium.ui.modelutil.PropertyModel.ReadableObjectPropertyKey; + +/** + * Properties defined here reflect the visible state of the TouchToFillPasswordGeneration + * component. + */ +class TouchToFillPasswordGenerationProperties { + public static final ReadableObjectPropertyKey<String> ACCOUNT_EMAIL = + new ReadableObjectPropertyKey<>(); + public static final ReadableObjectPropertyKey<String> GENERATED_PASSWORD = + new ReadableObjectPropertyKey<>(); + + public static final PropertyKey[] ALL_KEYS = + new PropertyKey[] {ACCOUNT_EMAIL, GENERATED_PASSWORD}; +}
diff --git a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationRenderTest.java b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationRenderTest.java new file mode 100644 index 0000000..3c6a019 --- /dev/null +++ b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationRenderTest.java
@@ -0,0 +1,121 @@ +// 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.chrome.browser.touch_to_fill.password_generation; + +import static org.chromium.base.test.util.ApplicationTestUtils.finishActivity; +import static org.chromium.chrome.browser.night_mode.ChromeNightModeTestUtils.tearDownNightModeAfterChromeActivityDestroyed; +import static org.chromium.content_public.browser.test.util.TestThreadUtils.runOnUiThreadBlocking; +import static org.chromium.ui.base.LocalizationUtils.setRtlForTesting; + +import android.view.View; + +import androidx.test.filters.MediumTest; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.mockito.quality.Strictness; + +import org.chromium.base.test.params.ParameterAnnotations; +import org.chromium.base.test.params.ParameterSet; +import org.chromium.base.test.params.ParameterizedRunner; +import org.chromium.base.test.util.Batch; +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.Feature; +import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.browser.night_mode.ChromeNightModeTestUtils; +import org.chromium.chrome.test.ChromeTabbedActivityTestRule; +import org.chromium.chrome.test.util.ChromeRenderTestRule; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetTestSupport; +import org.chromium.ui.test.util.RenderTestRule.Component; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +/** + * These tests render screenshots of touch to fill for credit cards sheet and compare them to a gold + * standard. + */ +@RunWith(ParameterizedRunner.class) +@Batch(Batch.PER_CLASS) +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +public class TouchToFillPasswordGenerationRenderTest { + @ParameterAnnotations.ClassParameter + private static List<ParameterSet> sClassParams = + Arrays.asList(new ParameterSet().value(false, false).name("Default"), + new ParameterSet().value(false, true).name("RTL"), + new ParameterSet().value(true, false).name("NightMode")); + + public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS); + + @Rule + public final ChromeRenderTestRule mRenderTestRule = + ChromeRenderTestRule.Builder.withPublicCorpus() + .setRevision(0) + .setBugComponent(Component.UI_BROWSER_AUTOFILL) + .build(); + + @Mock + private TouchToFillPasswordGenerationCoordinator.Delegate mDelegateMock; + + private BottomSheetController mBottomSheetController; + private TouchToFillPasswordGenerationCoordinator mCoordinator; + private static final String sGeneratedPassword = "Strong generated password"; + private static final String sTestEmailAddress = "test@email.com"; + + public TouchToFillPasswordGenerationRenderTest(boolean nightModeEnabled, boolean useRtlLayout) { + setRtlForTesting(useRtlLayout); + ChromeNightModeTestUtils.setUpNightModeForChromeActivity(nightModeEnabled); + mRenderTestRule.setNightModeEnabled(nightModeEnabled); + mRenderTestRule.setVariantPrefix(useRtlLayout ? "RTL" : "LTR"); + } + + @Before + public void setUp() throws InterruptedException { + MockitoAnnotations.openMocks(this); + mActivityTestRule.startMainActivityOnBlankPage(); + mActivityTestRule.waitForActivityCompletelyLoaded(); + mBottomSheetController = mActivityTestRule.getActivity() + .getRootUiCoordinatorForTesting() + .getBottomSheetController(); + runOnUiThreadBlocking(() -> { + mCoordinator = new TouchToFillPasswordGenerationCoordinator( + mActivityTestRule.getActivity(), mBottomSheetController, mDelegateMock); + }); + } + + @After + public void tearDown() { + setRtlForTesting(false); + try { + finishActivity(mActivityTestRule.getActivity()); + } catch (Exception e) { + // Activity was already closed (e.g. due to last test tearing down the suite). + } + runOnUiThreadBlocking(() -> tearDownNightModeAfterChromeActivityDestroyed()); + } + + @Test + @MediumTest + @Feature({"RenderTest"}) + public void testShowsOneCard() throws IOException { + runOnUiThreadBlocking(() -> { mCoordinator.show(sGeneratedPassword, sTestEmailAddress); }); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); + + View bottomSheetView = mActivityTestRule.getActivity().findViewById(R.id.bottom_sheet); + mRenderTestRule.render(bottomSheetView, "touch_to_fill_password_generation_bottom_sheet"); + } +}
diff --git a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationView.java b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationView.java index c5506192..fcd49f8 100644 --- a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationView.java +++ b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationView.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.touch_to_fill.password_generation; import android.content.Context; +import android.graphics.Typeface; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; @@ -22,8 +23,10 @@ */ class TouchToFillPasswordGenerationView implements BottomSheetContent { private final View mContent; + private final Context mContext; TouchToFillPasswordGenerationView(Context context) { + mContext = context; mContent = LayoutInflater.from(context).inflate( R.layout.touch_to_fill_password_generation, null); ImageView sheetHeaderImage = mContent.findViewById(R.id.touch_to_fill_sheet_header_image); @@ -36,6 +39,22 @@ "elisa.becket@gmail.com")); } + void setSheetSubtitle(String accountEmail) { + TextView sheetSubtitleView = mContent.findViewById(R.id.touch_to_fill_sheet_subtitle); + String sheetSubtitle = accountEmail.isEmpty() + ? mContext.getString(R.string.password_generation_bottom_sheet_subtitle_no_account) + : String.format( + mContext.getString(R.string.password_generation_bottom_sheet_subtitle), + accountEmail); + sheetSubtitleView.setText(sheetSubtitle); + } + + void setGeneratedPassword(String generatedPassword) { + TextView passwordView = mContent.findViewById(R.id.password); + passwordView.setTypeface(Typeface.MONOSPACE); + passwordView.setText(generatedPassword); + } + @Override public View getContentView() { return mContent;
diff --git a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationViewBinder.java b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationViewBinder.java new file mode 100644 index 0000000..59dd4a2 --- /dev/null +++ b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationViewBinder.java
@@ -0,0 +1,32 @@ +// 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.chrome.browser.touch_to_fill.password_generation; + +import static org.chromium.chrome.browser.touch_to_fill.password_generation.TouchToFillPasswordGenerationProperties.ACCOUNT_EMAIL; +import static org.chromium.chrome.browser.touch_to_fill.password_generation.TouchToFillPasswordGenerationProperties.GENERATED_PASSWORD; + +import org.chromium.ui.modelutil.PropertyKey; +import org.chromium.ui.modelutil.PropertyModel; + +/** + * Maps the {@link TouchToFillPasswordGenerationProperties} model properties to the {@link + * TouchToFillPasswordGenerationView}. + */ +class TouchToFillPasswordGenerationViewBinder { + /** + * Called whenever a property in the given model changes. It updates the given view accordingly. + * @param model The observed {@link PropertyModel}. Its data need to be reflected in the view. + * @param view The {@link TouchToFillPasswordGenerationView} to update. + * @param propertyKey The {@link PropertyKey} which changed. + */ + static void bindView( + PropertyModel model, TouchToFillPasswordGenerationView view, PropertyKey propertyKey) { + if (propertyKey == ACCOUNT_EMAIL) { + view.setSheetSubtitle(model.get(ACCOUNT_EMAIL)); + } else if (propertyKey == GENERATED_PASSWORD) { + view.setGeneratedPassword(model.get(GENERATED_PASSWORD)); + } + } +}
diff --git a/chrome/browser/touch_to_fill/password_generation/android/mock_touch_to_fill_password_generation_bridge.h b/chrome/browser/touch_to_fill/password_generation/android/mock_touch_to_fill_password_generation_bridge.h index 4828727..af70568 100644 --- a/chrome/browser/touch_to_fill/password_generation/android/mock_touch_to_fill_password_generation_bridge.h +++ b/chrome/browser/touch_to_fill/password_generation/android/mock_touch_to_fill_password_generation_bridge.h
@@ -19,7 +19,9 @@ MOCK_METHOD(bool, Show, (content::WebContents*, - base::WeakPtr<TouchToFillPasswordGenerationDelegate>), + base::WeakPtr<TouchToFillPasswordGenerationDelegate>, + std::u16string, + std::string), (override)); MOCK_METHOD(void, Hide, (), (override)); MOCK_METHOD(void, OnDismissed, (JNIEnv * env), (override));
diff --git a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge.h b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge.h index 31b5c3da..4c3e114 100644 --- a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge.h +++ b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_TOUCH_TO_FILL_PASSWORD_GENERATION_ANDROID_TOUCH_TO_FILL_PASSWORD_GENERATION_BRIDGE_H_ #include <jni.h> +#include <string> #include "content/public/browser/web_contents.h" @@ -17,7 +18,9 @@ virtual bool Show( content::WebContents* web_contents, - base::WeakPtr<TouchToFillPasswordGenerationDelegate> delegate_) = 0; + base::WeakPtr<TouchToFillPasswordGenerationDelegate> delegate_, + std::u16string password, + std::string account) = 0; virtual void Hide() = 0; virtual void OnDismissed(JNIEnv* env) = 0; };
diff --git a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge_impl.cc b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge_impl.cc index b356f89..2e908c1b 100644 --- a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge_impl.cc +++ b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge_impl.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge_impl.h" +#include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" #include "base/check.h" #include "chrome/browser/touch_to_fill/password_generation/android/jni_headers/TouchToFillPasswordGenerationBridge_jni.h" #include "components/password_manager/core/common/password_manager_features.h" @@ -22,7 +24,9 @@ bool TouchToFillPasswordGenerationBridgeImpl::Show( content::WebContents* web_contents, - base::WeakPtr<TouchToFillPasswordGenerationDelegate> delegate) { + base::WeakPtr<TouchToFillPasswordGenerationDelegate> delegate, + std::u16string password, + std::string account) { if (!web_contents->GetNativeView() || !web_contents->GetNativeView()->GetWindowAndroid()) { return false; @@ -35,8 +39,14 @@ web_contents->GetNativeView()->GetWindowAndroid()->GetJavaObject(), reinterpret_cast<intptr_t>(this))); - return Java_TouchToFillPasswordGenerationBridge_show( - base::android::AttachCurrentThread(), java_object_); + JNIEnv* env = base::android::AttachCurrentThread(); + base::android::ScopedJavaLocalRef<jstring> j_password = + base::android::ConvertUTF16ToJavaString(env, password); + base::android::ScopedJavaLocalRef<jstring> j_account = + base::android::ConvertUTF8ToJavaString(env, account); + + return Java_TouchToFillPasswordGenerationBridge_show(env, java_object_, + j_password, j_account); } void TouchToFillPasswordGenerationBridgeImpl::Hide() {
diff --git a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge_impl.h b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge_impl.h index 86f38810..4595283c 100644 --- a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge_impl.h +++ b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge_impl.h
@@ -21,9 +21,10 @@ const TouchToFillPasswordGenerationBridgeImpl&) = delete; ~TouchToFillPasswordGenerationBridgeImpl() override; - bool Show( - content::WebContents* web_contents, - base::WeakPtr<TouchToFillPasswordGenerationDelegate> delegate) override; + bool Show(content::WebContents* web_contents, + base::WeakPtr<TouchToFillPasswordGenerationDelegate> delegate, + std::u16string password, + std::string account) override; void Hide() override;
diff --git a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.cc b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.cc index ffd9203..852078e 100644 --- a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.cc +++ b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.cc
@@ -6,10 +6,12 @@ #include <algorithm> #include <memory> +#include <string> #include "base/check.h" #include "base/feature_list.h" #include "base/memory/ptr_util.h" #include "base/memory/weak_ptr.h" +#include "base/strings/utf_string_conversions.h" #include "chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge.h" #include "chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.h" #include "components/password_manager/content/browser/content_password_manager_driver.h" @@ -44,8 +46,12 @@ }); } -bool TouchToFillPasswordGenerationController::ShowTouchToFill() { - if (!bridge_->Show(web_contents_, base::AsWeakPtr(this))) { +bool TouchToFillPasswordGenerationController::ShowTouchToFill( + std::u16string generated_password, + std::string account_display_name) { + if (!bridge_->Show(web_contents_, base::AsWeakPtr(this), + std::move(generated_password), + std::move(account_display_name))) { return false; }
diff --git a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.h b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.h index e2ebe082..61839cd 100644 --- a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.h +++ b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_TOUCH_TO_FILL_PASSWORD_GENERATION_ANDROID_TOUCH_TO_FILL_PASSWORD_GENERATION_CONTROLLER_H_ #define CHROME_BROWSER_TOUCH_TO_FILL_PASSWORD_GENERATION_ANDROID_TOUCH_TO_FILL_PASSWORD_GENERATION_CONTROLLER_H_ +#include <string> #include "base/allocator/partition_allocator/pointers/raw_ptr.h" #include "base/functional/callback_forward.h" #include "chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge.h" @@ -38,7 +39,8 @@ ~TouchToFillPasswordGenerationController() override; // Shows the password generation bottom sheet. - bool ShowTouchToFill(); + bool ShowTouchToFill(std::u16string generated_password, + std::string account_display_name); void OnDismissed() override;
diff --git a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller_unittest.cc b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller_unittest.cc index e0ca2de..12b7ebe 100644 --- a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller_unittest.cc +++ b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller_unittest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include <memory> +#include <string> #include "base/functional/callback_forward.h" #include "base/memory/weak_ptr.h" @@ -19,6 +20,9 @@ #include "ui/base/ime/mojom/text_input_state.mojom.h" #include "ui/base/ime/text_input_type.h" +using testing::_; +using testing::Eq; + class TouchToFillPasswordGenerationControllerTest : public ChromeRenderViewHostTestHarness { public: @@ -35,6 +39,8 @@ } base::MockCallback<base::OnceCallback<void()>> on_dismissed_callback_; + const std::u16string test_generated_password_ = u"Strong generated password"; + const std::string test_user_account_ = "test@email.com"; private: std::unique_ptr<password_manager::ContentPasswordManagerDriver> @@ -51,7 +57,7 @@ password_mananger_driver(), web_contents(), std::move(bridge), on_dismissed_callback_.Get()); EXPECT_CALL(*bridge_ptr, Show); - controller->ShowTouchToFill(); + controller->ShowTouchToFill(test_generated_password_, test_user_account_); ui::mojom::TextInputStatePtr initial_state = ui::mojom::TextInputState::New(); initial_state->type = ui::TEXT_INPUT_TYPE_PASSWORD; @@ -81,7 +87,7 @@ std::make_unique<MockTouchToFillPasswordGenerationBridge>(), on_dismissed_callback_.Get()); - controller->ShowTouchToFill(); + controller->ShowTouchToFill(test_generated_password_, test_user_account_); EXPECT_CALL(on_dismissed_callback_, Run); controller->OnDismissed(); @@ -95,8 +101,9 @@ password_mananger_driver(), web_contents(), std::move(bridge), on_dismissed_callback_.Get()); - EXPECT_CALL(*bridge_ptr, Show); - controller->ShowTouchToFill(); + EXPECT_CALL(*bridge_ptr, + Show(_, _, Eq(test_generated_password_), Eq(test_user_account_))); + controller->ShowTouchToFill(test_generated_password_, test_user_account_); EXPECT_CALL(*bridge_ptr, Hide); controller.reset();
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_controller.cc b/chrome/browser/touch_to_fill/touch_to_fill_controller.cc index 25665ed..d66ff22 100644 --- a/chrome/browser/touch_to_fill/touch_to_fill_controller.cc +++ b/chrome/browser/touch_to_fill/touch_to_fill_controller.cc
@@ -69,14 +69,23 @@ if (!view_) view_ = TouchToFillViewFactory::Create(this); + int flags = TouchToFillView::kNone; + if (delegate_->ShouldTriggerSubmission()) { + flags |= TouchToFillView::kTriggerSubmission; + } + if (password_manager_launcher::CanManagePasswordsWhenPasskeysPresent()) { + flags |= TouchToFillView::kCanManagePasswordsWhenPasskeysPresent; + } + if (delegate_->ShouldShowHybridOption()) { + flags |= TouchToFillView::kShouldShowHybridOption; + } + GURL url = delegate_->GetFrameUrl(); view_->Show( url, TouchToFillView::IsOriginSecure( network::IsOriginPotentiallyTrustworthy(url::Origin::Create(url))), - SortCredentials(credentials), passkey_credentials, - delegate_->ShouldTriggerSubmission(), - password_manager_launcher::CanManagePasswordsWhenPasskeysPresent()); + SortCredentials(credentials), passkey_credentials, flags); touch_to_fill_state_ = TouchToFillState::kIsShowing; } @@ -106,6 +115,12 @@ base::Unretained(this))); } +void TouchToFillController::OnHybridSignInSelected() { + view_.reset(); + delegate_->OnHybridSignInSelected(base::BindOnce( + &TouchToFillController::ActionCompleted, base::Unretained(this))); +} + void TouchToFillController::OnDismiss() { view_.reset(); // Unretained is safe here because TouchToFillController owns the delegate.
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_controller.h b/chrome/browser/touch_to_fill/touch_to_fill_controller.h index 6752d90..8604421 100644 --- a/chrome/browser/touch_to_fill/touch_to_fill_controller.h +++ b/chrome/browser/touch_to_fill/touch_to_fill_controller.h
@@ -50,6 +50,10 @@ // password management screen is displayed. void OnManagePasswordsSelected(bool passkeys_shown); + // Informs the controller that the user has tapped the "Use Passkey on a + // Different Device" option, which initiates hybrid passkey sign-in. + void OnHybridSignInSelected(); + // Informs the controller that the user has dismissed the sheet. No-op if // invoked repeatedly. void OnDismiss();
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate.cc b/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate.cc index d323335..7811d8b 100644 --- a/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate.cc +++ b/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate.cc
@@ -66,21 +66,25 @@ password_manager::PasswordManagerClient* password_client, scoped_refptr<device_reauth::DeviceAuthenticator> authenticator, base::WeakPtr<password_manager::PasswordManagerDriver> driver, - autofill::mojom::SubmissionReadinessState submission_readiness) + autofill::mojom::SubmissionReadinessState submission_readiness, + ShowHybridOption should_show_hybrid_option) : password_client_(password_client), authenticator_(std::move(authenticator)), driver_(std::move(driver)), - submission_readiness_(submission_readiness) {} + submission_readiness_(submission_readiness), + should_show_hybrid_option_(should_show_hybrid_option) {} TouchToFillControllerAutofillDelegate::TouchToFillControllerAutofillDelegate( ChromePasswordManagerClient* password_client, scoped_refptr<device_reauth::DeviceAuthenticator> authenticator, base::WeakPtr<password_manager::PasswordManagerDriver> driver, - autofill::mojom::SubmissionReadinessState submission_readiness) + autofill::mojom::SubmissionReadinessState submission_readiness, + ShowHybridOption should_show_hybrid_option) : password_client_(password_client), authenticator_(std::move(authenticator)), driver_(driver), submission_readiness_(submission_readiness), + should_show_hybrid_option_(should_show_hybrid_option), source_id_(password_client->web_contents() ->GetPrimaryMainFrame() ->GetPageUkmSourceId()) {} @@ -177,6 +181,21 @@ std::move(action_complete).Run(); } +void TouchToFillControllerAutofillDelegate::OnHybridSignInSelected( + base::OnceClosure action_complete) { + if (!driver_) { + return; + } + + password_client_->GetWebAuthnCredentialsDelegateForDriver(driver_.get()) + ->ShowAndroidHybridSignIn(); + + CleanUpDriverAndReportOutcome(TouchToFillOutcome::kHybridSignInSelected, + /*show_virtual_keyboard=*/false); + + std::move(action_complete).Run(); +} + void TouchToFillControllerAutofillDelegate::OnDismiss( base::OnceClosure action_complete) { if (!driver_) @@ -198,6 +217,10 @@ return trigger_submission_; } +bool TouchToFillControllerAutofillDelegate::ShouldShowHybridOption() { + return should_show_hybrid_option_.value(); +} + gfx::NativeView TouchToFillControllerAutofillDelegate::GetNativeView() { // It is not a |ChromePasswordManagerClient| only in // TouchToFillControllerTest.
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate.h b/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate.h index 1fcdb8b..2befee0 100644 --- a/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate.h +++ b/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate.h
@@ -11,6 +11,7 @@ #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/types/pass_key.h" +#include "base/types/strong_alias.h" #include "chrome/browser/touch_to_fill/touch_to_fill_controller_delegate.h" #include "components/autofill/core/common/mojom/autofill_types.mojom.h" #include "components/device_reauth/device_authenticator.h" @@ -32,6 +33,8 @@ class TouchToFillControllerAutofillDelegate : public TouchToFillControllerDelegate { public: + using ShowHybridOption = base::StrongAlias<struct ShowHybridOptionTag, bool>; + // The action a user took when interacting with the Touch To Fill sheet. // // These values are persisted to logs. Entries should not be renumbered and @@ -45,6 +48,7 @@ kDismissed = 1, kSelectedManagePasswords = 2, kSelectedPasskeyCredential = 3, + kSelectedHybrid = 4, }; // The final outcome that closes the Touch To Fill sheet. @@ -58,7 +62,8 @@ kReauthenticationFailed = 2, kManagePasswordsSelected = 3, kPasskeyCredentialSelected = 4, - kMaxValue = kPasskeyCredentialSelected, + kHybridSignInSelected = 5, + kMaxValue = kHybridSignInSelected, }; // No-op constructor for tests. @@ -67,13 +72,15 @@ password_manager::PasswordManagerClient* password_client, scoped_refptr<device_reauth::DeviceAuthenticator> authenticator, base::WeakPtr<password_manager::PasswordManagerDriver> driver, - autofill::mojom::SubmissionReadinessState submission_readiness); + autofill::mojom::SubmissionReadinessState submission_readiness, + ShowHybridOption should_show_hybrid_option); TouchToFillControllerAutofillDelegate( ChromePasswordManagerClient* password_client, scoped_refptr<device_reauth::DeviceAuthenticator> authenticator, base::WeakPtr<password_manager::PasswordManagerDriver> driver, - autofill::mojom::SubmissionReadinessState submission_readiness); + autofill::mojom::SubmissionReadinessState submission_readiness, + ShowHybridOption should_show_hybrid_option); TouchToFillControllerAutofillDelegate( const TouchToFillControllerAutofillDelegate&) = delete; TouchToFillControllerAutofillDelegate& operator=( @@ -91,9 +98,11 @@ base::OnceClosure action_completed) override; void OnManagePasswordsSelected(bool passkeys_shown, base::OnceClosure action_completed) override; + void OnHybridSignInSelected(base::OnceClosure action_completed) override; void OnDismiss(base::OnceClosure action_completed) override; const GURL& GetFrameUrl() override; bool ShouldTriggerSubmission() override; + bool ShouldShowHybridOption() override; gfx::NativeView GetNativeView() override; private: @@ -132,6 +141,9 @@ // filled in. bool trigger_submission_ = false; + // Whether the controller should show an option for passkey hybrid sign-in. + ShowHybridOption should_show_hybrid_option_ = ShowHybridOption(false); + ukm::SourceId source_id_ = ukm::kInvalidSourceId; };
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate_unittest.cc b/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate_unittest.cc index 979cfc0..4f39d88 100644 --- a/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate_unittest.cc +++ b/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate_unittest.cc
@@ -94,8 +94,7 @@ IsOriginSecure, base::span<const UiCredential>, base::span<const PasskeyCredential>, - bool, - bool), + int), (override)); MOCK_METHOD(void, OnCredentialSelected, (const UiCredential&)); MOCK_METHOD(void, OnDismiss, ()); @@ -167,10 +166,13 @@ std::unique_ptr<TouchToFillControllerAutofillDelegate> MakeTouchToFillControllerDelegate( - autofill::mojom::SubmissionReadinessState submission_readiness) { + autofill::mojom::SubmissionReadinessState submission_readiness, + TouchToFillControllerAutofillDelegate::ShowHybridOption + should_show_hybrid_option) { return std::make_unique<TouchToFillControllerAutofillDelegate>( base::PassKey<TouchToFillControllerAutofillTest>(), &client_, - authenticator_, driver().AsWeakPtr(), submission_readiness); + authenticator_, driver().AsWeakPtr(), submission_readiness, + should_show_hybrid_option); } password_manager::MockWebAuthnCredentialsDelegate* @@ -211,12 +213,12 @@ Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), ElementsAreArray(credentials), ElementsAreArray(std::vector<PasskeyCredential>()), - /*trigger_submission=*/false, - /*can_manage_passwords_when_passkeys_present*/ false)); + TouchToFillView::kNone)); touch_to_fill_controller().Show( credentials, {}, MakeTouchToFillControllerDelegate( - autofill::mojom::SubmissionReadinessState::kNoInformation)); + autofill::mojom::SubmissionReadinessState::kNoInformation, + TouchToFillControllerAutofillDelegate::ShowHybridOption(false))); // Test that we correctly log the absence of an Android credential. EXPECT_CALL(driver(), FillSuggestion(std::u16string(u"alice"), @@ -255,12 +257,12 @@ Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), ElementsAreArray(credentials), ElementsAreArray(std::vector<PasskeyCredential>()), - /*trigger_submission=*/true, - /*can_manage_passwords_when_passkeys_present*/ false)); + TouchToFillView::kTriggerSubmission)); touch_to_fill_controller().Show( credentials, {}, MakeTouchToFillControllerDelegate( - autofill::mojom::SubmissionReadinessState::kTwoFields)); + autofill::mojom::SubmissionReadinessState::kTwoFields, + TouchToFillControllerAutofillDelegate::ShowHybridOption(false))); EXPECT_CALL(driver(), FillSuggestion(std::u16string(u"alice"), std::u16string(u"p4ssw0rd"))); @@ -285,12 +287,12 @@ Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), ElementsAreArray(credentials), ElementsAreArray(std::vector<PasskeyCredential>()), - /*trigger_submission=*/false, - /*can_manage_passwords_when_passkeys_present*/ false)); + TouchToFillView::kNone)); touch_to_fill_controller().Show( credentials, {}, MakeTouchToFillControllerDelegate( - autofill::mojom::SubmissionReadinessState::kNoInformation)); + autofill::mojom::SubmissionReadinessState::kNoInformation, + TouchToFillControllerAutofillDelegate::ShowHybridOption(false))); EXPECT_CALL(driver(), FillSuggestion(std::u16string(u"alice"), std::u16string(u"p4ssw0rd"))); @@ -319,12 +321,12 @@ Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), ElementsAreArray(credentials), ElementsAreArray(std::vector<PasskeyCredential>()), - /*trigger_submission=*/true, - /*can_manage_passwords_when_passkeys_present*/ false)); + TouchToFillView::kTriggerSubmission)); touch_to_fill_controller().Show( credentials, {}, MakeTouchToFillControllerDelegate( - autofill::mojom::SubmissionReadinessState::kTwoFields)); + autofill::mojom::SubmissionReadinessState::kTwoFields, + TouchToFillControllerAutofillDelegate::ShowHybridOption(false))); // The user picks the credential with an empty username, submission should not // be triggered. @@ -352,12 +354,12 @@ Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), ElementsAreArray(credentials), ElementsAreArray(std::vector<PasskeyCredential>()), - /*trigger_submission=*/false, - /*can_manage_passwords_when_passkeys_present*/ false)); + TouchToFillView::kNone)); touch_to_fill_controller().Show( credentials, {}, MakeTouchToFillControllerDelegate( - autofill::mojom::SubmissionReadinessState::kTwoFields)); + autofill::mojom::SubmissionReadinessState::kTwoFields, + TouchToFillControllerAutofillDelegate::ShowHybridOption(false))); // Filling doesn't trigger submission. EXPECT_CALL(driver(), TriggerFormSubmission()).Times(0); @@ -373,16 +375,15 @@ UiCredential credentials[] = { MakeUiCredential({.username = "alice", .password = "p4ssw0rd"})}; - EXPECT_CALL(view(), - Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), - ElementsAreArray(credentials), - ElementsAreArray(std::vector<PasskeyCredential>()), - /*trigger_submission=*/false, - /*can_manage_passwords_when_passkeys_present*/ false)); + EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), + ElementsAreArray(credentials), + ElementsAreArray(std::vector<PasskeyCredential>()), + TouchToFillView::kNone)); touch_to_fill_controller().Show( credentials, {}, MakeTouchToFillControllerDelegate( - autofill::mojom::SubmissionReadinessState::kNoInformation)); + autofill::mojom::SubmissionReadinessState::kNoInformation, + TouchToFillControllerAutofillDelegate::ShowHybridOption(false))); // Test that we correctly log the absence of an Android credential. EXPECT_CALL(driver(), FillSuggestion(std::u16string(u"alice"), @@ -412,16 +413,15 @@ UiCredential credentials[] = { MakeUiCredential({.username = "alice", .password = "p4ssw0rd"})}; - EXPECT_CALL(view(), - Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), - ElementsAreArray(credentials), - ElementsAreArray(std::vector<PasskeyCredential>()), - /*trigger_submission=*/true, - /*can_manage_passwords_when_passkeys_present*/ false)); + EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), + ElementsAreArray(credentials), + ElementsAreArray(std::vector<PasskeyCredential>()), + TouchToFillView::kTriggerSubmission)); touch_to_fill_controller().Show( credentials, {}, MakeTouchToFillControllerDelegate( - autofill::mojom::SubmissionReadinessState::kTwoFields)); + autofill::mojom::SubmissionReadinessState::kTwoFields, + TouchToFillControllerAutofillDelegate::ShowHybridOption(false))); EXPECT_CALL(driver(), FillSuggestion(std::u16string(u"alice"), std::u16string(u"p4ssw0rd"))); @@ -445,16 +445,15 @@ UiCredential credentials[] = { MakeUiCredential({.username = "alice", .password = "p4ssw0rd"})}; - EXPECT_CALL(view(), - Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), - ElementsAreArray(credentials), - ElementsAreArray(std::vector<PasskeyCredential>()), - /*trigger_submission=*/false, - /*can_manage_passwords_when_passkeys_present*/ false)); + EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), + ElementsAreArray(credentials), + ElementsAreArray(std::vector<PasskeyCredential>()), + TouchToFillView::kNone)); touch_to_fill_controller().Show( credentials, {}, MakeTouchToFillControllerDelegate( - autofill::mojom::SubmissionReadinessState::kNoInformation)); + autofill::mojom::SubmissionReadinessState::kNoInformation, + TouchToFillControllerAutofillDelegate::ShowHybridOption(false))); EXPECT_CALL(driver(), FillSuggestion(_, _)).Times(0); EXPECT_CALL(driver(), @@ -480,7 +479,8 @@ touch_to_fill_controller().Show( {}, {}, MakeTouchToFillControllerDelegate( - autofill::mojom::SubmissionReadinessState::kNoInformation)); + autofill::mojom::SubmissionReadinessState::kNoInformation, + TouchToFillControllerAutofillDelegate::ShowHybridOption(false))); histogram_tester().ExpectUniqueSample( "PasswordManager.TouchToFill.NumCredentialsShown", 0, 1); } @@ -492,16 +492,15 @@ UiCredential credentials[] = { MakeUiCredential({.username = "alice", .password = "p4ssw0rd"})}; - EXPECT_CALL(view(), - Show(Eq(GURL("http://example.com")), IsOriginSecure(false), - ElementsAreArray(credentials), - ElementsAreArray(std::vector<PasskeyCredential>()), - /*trigger_submission=*/false, - /*can_manage_passwords_when_passkeys_present*/ false)); + EXPECT_CALL(view(), Show(Eq(GURL("http://example.com")), + IsOriginSecure(false), ElementsAreArray(credentials), + ElementsAreArray(std::vector<PasskeyCredential>()), + TouchToFillView::kNone)); touch_to_fill_controller().Show( credentials, {}, MakeTouchToFillControllerDelegate( - autofill::mojom::SubmissionReadinessState::kNoInformation)); + autofill::mojom::SubmissionReadinessState::kNoInformation, + TouchToFillControllerAutofillDelegate::ShowHybridOption(false))); } TEST_F(TouchToFillControllerAutofillTest, Show_And_Fill_Android_Credential) { @@ -521,16 +520,15 @@ }), }; - EXPECT_CALL(view(), - Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), - ElementsAreArray(credentials), - ElementsAreArray(std::vector<PasskeyCredential>()), - /*trigger_submission=*/false, - /*can_manage_passwords_when_passkeys_present*/ false)); + EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), + ElementsAreArray(credentials), + ElementsAreArray(std::vector<PasskeyCredential>()), + TouchToFillView::kNone)); touch_to_fill_controller().Show( credentials, {}, MakeTouchToFillControllerDelegate( - autofill::mojom::SubmissionReadinessState::kNoInformation)); + autofill::mojom::SubmissionReadinessState::kNoInformation, + TouchToFillControllerAutofillDelegate::ShowHybridOption(false))); // Test that we correctly log the presence of an Android credential. EXPECT_CALL(driver(), FillSuggestion(std::u16string(u"bob"), @@ -580,32 +578,30 @@ }); UiCredential credentials[] = {alice, bob, charlie, david}; - EXPECT_CALL(view(), - Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), - testing::ElementsAre(charlie, alice, bob, david), - ElementsAreArray(std::vector<PasskeyCredential>()), - /*trigger_submission=*/false, - /*can_manage_passwords_when_passkeys_present*/ false)); + EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), + testing::ElementsAre(charlie, alice, bob, david), + ElementsAreArray(std::vector<PasskeyCredential>()), + TouchToFillView::kNone)); touch_to_fill_controller().Show( credentials, {}, MakeTouchToFillControllerDelegate( - autofill::mojom::SubmissionReadinessState::kNoInformation)); + autofill::mojom::SubmissionReadinessState::kNoInformation, + TouchToFillControllerAutofillDelegate::ShowHybridOption(false))); } TEST_F(TouchToFillControllerAutofillTest, Dismiss) { UiCredential credentials[] = { MakeUiCredential({.username = "alice", .password = "p4ssw0rd"})}; - EXPECT_CALL(view(), - Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), - ElementsAreArray(credentials), - ElementsAreArray(std::vector<PasskeyCredential>()), - /*trigger_submission=*/false, - /*can_manage_passwords_when_passkeys_present*/ false)); + EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), + ElementsAreArray(credentials), + ElementsAreArray(std::vector<PasskeyCredential>()), + TouchToFillView::kNone)); touch_to_fill_controller().Show( credentials, {}, MakeTouchToFillControllerDelegate( - autofill::mojom::SubmissionReadinessState::kNoInformation)); + autofill::mojom::SubmissionReadinessState::kNoInformation, + TouchToFillControllerAutofillDelegate::ShowHybridOption(false))); EXPECT_CALL(driver(), KeyboardReplacingSurfaceClosed(ToShowVirtualKeyboard(true))); @@ -636,12 +632,12 @@ Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), ElementsAreArray(credentials), ElementsAreArray(std::vector<PasskeyCredential>()), - /*trigger_submission=*/false, - /*can_manage_passwords_when_passkeys_present*/ false)); + TouchToFillView::kNone)); touch_to_fill_controller().Show( credentials, {}, MakeTouchToFillControllerDelegate( - autofill::mojom::SubmissionReadinessState::kNoInformation)); + autofill::mojom::SubmissionReadinessState::kNoInformation, + TouchToFillControllerAutofillDelegate::ShowHybridOption(false))); EXPECT_CALL(driver(), KeyboardReplacingSurfaceClosed(ToShowVirtualKeyboard(false))); @@ -670,16 +666,15 @@ UiCredential credentials[] = { MakeUiCredential({.username = "alice", .password = "p4ssw0rd"})}; - EXPECT_CALL(view(), - Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), - ElementsAreArray(credentials), - ElementsAreArray(std::vector<PasskeyCredential>()), - /*trigger_submission=*/false, - /*can_manage_passwords_when_passkeys_present*/ false)); + EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), + ElementsAreArray(credentials), + ElementsAreArray(std::vector<PasskeyCredential>()), + TouchToFillView::kNone)); touch_to_fill_controller().Show( credentials, {}, MakeTouchToFillControllerDelegate( - autofill::mojom::SubmissionReadinessState::kNoInformation)); + autofill::mojom::SubmissionReadinessState::kNoInformation, + TouchToFillControllerAutofillDelegate::ShowHybridOption(false))); EXPECT_CALL(*authenticator(), CanAuthenticateWithBiometrics) .WillOnce(Return(true)); @@ -708,13 +703,12 @@ EXPECT_CALL(*weak_view, Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), ElementsAreArray(std::vector<UiCredential>()), - ElementsAreArray(credentials), - /*trigger_submission=*/false, - /*can_manage_passwords_when_passkeys_present*/ false)); + ElementsAreArray(credentials), TouchToFillView::kNone)); touch_to_fill_controller().Show( {}, credentials, MakeTouchToFillControllerDelegate( - autofill::mojom::SubmissionReadinessState::kNoInformation)); + autofill::mojom::SubmissionReadinessState::kNoInformation, + TouchToFillControllerAutofillDelegate::ShowHybridOption(false))); EXPECT_CALL(*webauthn_credentials_delegate(), SelectPasskey(base::Base64Encode(credential.credential_id()))); @@ -730,6 +724,29 @@ 1); } +TEST_F(TouchToFillControllerAutofillTest, ShowAndSelectHybrid) { + UiCredential credentials[] = { + MakeUiCredential({.username = "alice", .password = "p4ssw0rd"})}; + + EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), + ElementsAreArray(credentials), + ElementsAreArray(std::vector<PasskeyCredential>()), + TouchToFillView::kShouldShowHybridOption)); + touch_to_fill_controller().Show( + credentials, {}, + MakeTouchToFillControllerDelegate( + autofill::mojom::SubmissionReadinessState::kNoInformation, + TouchToFillControllerAutofillDelegate::ShowHybridOption(true))); + + EXPECT_CALL(*webauthn_credentials_delegate(), ShowAndroidHybridSignIn()); + touch_to_fill_controller().OnHybridSignInSelected(); + histogram_tester().ExpectUniqueSample( + "PasswordManager.TouchToFill.Outcome", + TouchToFillControllerAutofillDelegate::TouchToFillOutcome:: + kHybridSignInSelected, + 1); +} + class TouchToFillControllerAutofillTestWithSubmissionReadinessVariationTest : public TouchToFillControllerAutofillTest, public testing::WithParamInterface<SubmissionReadinessState> {}; @@ -744,25 +761,28 @@ // If there is no field after the password and both username and password // fields are there, then submit the form. - bool submission_expected = - submission_readiness == SubmissionReadinessState::kEmptyFields || + int show_flags = TouchToFillView::kNone; + if (submission_readiness == SubmissionReadinessState::kEmptyFields || submission_readiness == SubmissionReadinessState::kMoreThanTwoFields || - submission_readiness == SubmissionReadinessState::kTwoFields; - EXPECT_CALL(view(), - Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), - ElementsAreArray(credentials), - ElementsAreArray(std::vector<PasskeyCredential>()), - /*trigger_submission=*/submission_expected, - /*can_manage_passwords_when_passkeys_present*/ false)); + submission_readiness == SubmissionReadinessState::kTwoFields) { + show_flags |= TouchToFillView::kTriggerSubmission; + } + EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), + ElementsAreArray(credentials), + ElementsAreArray(std::vector<PasskeyCredential>()), + show_flags)); touch_to_fill_controller().Show( - credentials, {}, MakeTouchToFillControllerDelegate(submission_readiness)); + credentials, {}, + MakeTouchToFillControllerDelegate( + submission_readiness, + TouchToFillControllerAutofillDelegate::ShowHybridOption(false))); EXPECT_CALL(driver(), KeyboardReplacingSurfaceClosed(ToShowVirtualKeyboard(false))); EXPECT_CALL(driver(), FillSuggestion(credential.username(), credential.password())); EXPECT_CALL(driver(), TriggerFormSubmission()) - .Times(submission_expected ? 1 : 0); + .Times((show_flags & TouchToFillView::kTriggerSubmission) ? 1 : 0); touch_to_fill_controller().OnCredentialSelected(credential); } @@ -776,14 +796,15 @@ UiCredential credentials[] = { MakeUiCredential({.username = "alice", .password = "p4ssw0rd"})}; - EXPECT_CALL(view(), - Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), - ElementsAreArray(credentials), - ElementsAreArray(std::vector<PasskeyCredential>()), - /*trigger_submission=*/_, - /*can_manage_passwords_when_passkeys_present*/ false)); + EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), + ElementsAreArray(credentials), + ElementsAreArray(std::vector<PasskeyCredential>()), + /*flags=*/_)); touch_to_fill_controller().Show( - credentials, {}, MakeTouchToFillControllerDelegate(submission_readiness)); + credentials, {}, + MakeTouchToFillControllerDelegate( + submission_readiness, + TouchToFillControllerAutofillDelegate::ShowHybridOption(false))); EXPECT_CALL(driver(), KeyboardReplacingSurfaceClosed(ToShowVirtualKeyboard(true)));
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_controller_delegate.h b/chrome/browser/touch_to_fill/touch_to_fill_controller_delegate.h index ed6c076..ec56cd3 100644 --- a/chrome/browser/touch_to_fill/touch_to_fill_controller_delegate.h +++ b/chrome/browser/touch_to_fill/touch_to_fill_controller_delegate.h
@@ -47,6 +47,8 @@ bool passkeys_shown, base::OnceClosure action_completed) = 0; + virtual void OnHybridSignInSelected(base::OnceClosure action_completed) = 0; + // Informs the controller that the user has dismissed the sheet. No-op if // invoked repeatedly. virtual void OnDismiss(base::OnceClosure action_completed) = 0; @@ -59,6 +61,10 @@ // a password credential. virtual bool ShouldTriggerSubmission() = 0; + // Indicates whether the view should display an option to activate hybrid + // sign-in for passkeys. + virtual bool ShouldShowHybridOption() = 0; + // The web page view containing the focused field. virtual gfx::NativeView GetNativeView() = 0; };
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_controller_webauthn_delegate.cc b/chrome/browser/touch_to_fill/touch_to_fill_controller_webauthn_delegate.cc index 48722f3..a8f5e07 100644 --- a/chrome/browser/touch_to_fill/touch_to_fill_controller_webauthn_delegate.cc +++ b/chrome/browser/touch_to_fill/touch_to_fill_controller_webauthn_delegate.cc
@@ -19,8 +19,10 @@ #include "url/gurl.h" TouchToFillControllerWebAuthnDelegate::TouchToFillControllerWebAuthnDelegate( - WebAuthnRequestDelegateAndroid* request_delegate) - : request_delegate_(request_delegate) {} + WebAuthnRequestDelegateAndroid* request_delegate, + bool should_show_hybrid_option) + : request_delegate_(request_delegate), + should_show_hybrid_option_(should_show_hybrid_option) {} TouchToFillControllerWebAuthnDelegate:: ~TouchToFillControllerWebAuthnDelegate() = default; @@ -52,6 +54,12 @@ OnDismiss(std::move(action_complete)); } +void TouchToFillControllerWebAuthnDelegate::OnHybridSignInSelected( + base::OnceClosure action_complete) { + request_delegate_->ShowHybridSignIn(); + std::move(action_complete).Run(); +} + void TouchToFillControllerWebAuthnDelegate::OnDismiss( base::OnceClosure action_complete) { request_delegate_->OnWebAuthnAccountSelected(std::vector<uint8_t>()); @@ -66,6 +74,10 @@ return false; } +bool TouchToFillControllerWebAuthnDelegate::ShouldShowHybridOption() { + return should_show_hybrid_option_; +} + gfx::NativeView TouchToFillControllerWebAuthnDelegate::GetNativeView() { return request_delegate_->web_contents()->GetNativeView(); }
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_controller_webauthn_delegate.h b/chrome/browser/touch_to_fill/touch_to_fill_controller_webauthn_delegate.h index e0854e2..221a8b36 100644 --- a/chrome/browser/touch_to_fill/touch_to_fill_controller_webauthn_delegate.h +++ b/chrome/browser/touch_to_fill/touch_to_fill_controller_webauthn_delegate.h
@@ -27,7 +27,8 @@ : public TouchToFillControllerDelegate { public: explicit TouchToFillControllerWebAuthnDelegate( - WebAuthnRequestDelegateAndroid* delegate); + WebAuthnRequestDelegateAndroid* delegate, + bool should_show_hybrid_option); TouchToFillControllerWebAuthnDelegate( const TouchToFillControllerWebAuthnDelegate&) = delete; @@ -47,14 +48,18 @@ base::OnceClosure action_completed) override; void OnManagePasswordsSelected(bool passkeys_shown, base::OnceClosure action_completed) override; + void OnHybridSignInSelected(base::OnceClosure action_completed) override; void OnDismiss(base::OnceClosure action_completed) override; const GURL& GetFrameUrl() override; bool ShouldTriggerSubmission() override; + bool ShouldShowHybridOption() override; gfx::NativeView GetNativeView() override; private: // Raw pointer to the request delegate that owns this. raw_ptr<WebAuthnRequestDelegateAndroid> request_delegate_ = nullptr; + + bool should_show_hybrid_option_; }; #endif // CHROME_BROWSER_TOUCH_TO_FILL_TOUCH_TO_FILL_CONTROLLER_WEBAUTHN_DELEGATE_H_
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_controller_webauthn_delegate_unittest.cc b/chrome/browser/touch_to_fill/touch_to_fill_controller_webauthn_delegate_unittest.cc index 7e3f440b..7863854 100644 --- a/chrome/browser/touch_to_fill/touch_to_fill_controller_webauthn_delegate_unittest.cc +++ b/chrome/browser/touch_to_fill/touch_to_fill_controller_webauthn_delegate_unittest.cc
@@ -61,6 +61,7 @@ OnWebAuthnAccountSelected, (const std::vector<uint8_t>& id), (override)); + MOCK_METHOD(void, ShowHybridSignIn, (), (override)); }; struct MockTouchToFillView : public TouchToFillView { @@ -70,8 +71,7 @@ IsOriginSecure, base::span<const UiCredential>, base::span<const PasskeyCredential>, - bool, - bool), + int), (override)); MOCK_METHOD(void, OnCredentialSelected, (const UiCredential&)); MOCK_METHOD(void, OnDismiss, ()); @@ -122,9 +122,9 @@ } std::unique_ptr<TouchToFillControllerWebAuthnDelegate> - MakeTouchToFillControllerDelegate() { + MakeTouchToFillControllerDelegate(bool should_show_hybrid_option) { return std::make_unique<TouchToFillControllerWebAuthnDelegate>( - request_delegate_.get()); + request_delegate_.get(), should_show_hybrid_option); } private: @@ -140,11 +140,10 @@ EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), ElementsAreArray(std::vector<UiCredential>()), - ElementsAreArray(credentials), - /*trigger_submission=*/false, - /*can_manage_passwords_when_passkeys_present*/ false)); - touch_to_fill_controller().Show({}, credentials, - MakeTouchToFillControllerDelegate()); + ElementsAreArray(credentials), TouchToFillView::kNone)); + touch_to_fill_controller().Show( + {}, credentials, + MakeTouchToFillControllerDelegate(/*should_show_hybrid_option=*/false)); EXPECT_CALL(request_delegate(), OnWebAuthnAccountSelected(kCredentialId1)); touch_to_fill_controller().OnPasskeyCredentialSelected(credentials[0]); @@ -157,11 +156,10 @@ EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), ElementsAreArray(std::vector<UiCredential>()), - ElementsAreArray(credentials), - /*trigger_submission=*/false, - /*can_manage_passwords_when_passkeys_present*/ false)); - touch_to_fill_controller().Show({}, credentials, - MakeTouchToFillControllerDelegate()); + ElementsAreArray(credentials), TouchToFillView::kNone)); + touch_to_fill_controller().Show( + {}, credentials, + MakeTouchToFillControllerDelegate(/*should_show_hybrid_option=*/false)); EXPECT_CALL(request_delegate(), OnWebAuthnAccountSelected(kCredentialId2)); touch_to_fill_controller().OnPasskeyCredentialSelected(credentials[1]); @@ -173,15 +171,28 @@ EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), ElementsAreArray(std::vector<UiCredential>()), - ElementsAreArray(credentials), - /*trigger_submission=*/false, - /*can_manage_passwords_when_passkeys_present*/ false)); - touch_to_fill_controller().Show({}, credentials, - MakeTouchToFillControllerDelegate()); + ElementsAreArray(credentials), TouchToFillView::kNone)); + touch_to_fill_controller().Show( + {}, credentials, + MakeTouchToFillControllerDelegate(/*should_show_hybrid_option=*/false)); EXPECT_CALL(request_delegate(), OnWebAuthnAccountSelected(std::vector<uint8_t>())); touch_to_fill_controller().Close(); } +TEST_F(TouchToFillControllerWebAuthnTest, ShowAndSelectHybrid) { + std::vector<PasskeyCredential> credentials({CreatePasskey()}); + + EXPECT_CALL(view(), Show(Eq(GURL(kExampleCom)), IsOriginSecure(true), + ElementsAreArray(std::vector<UiCredential>()), + ElementsAreArray(credentials), + TouchToFillView::kShouldShowHybridOption)); + touch_to_fill_controller().Show( + {}, credentials, + MakeTouchToFillControllerDelegate(/*should_show_hybrid_option=*/true)); + EXPECT_CALL(request_delegate(), ShowHybridSignIn()); + touch_to_fill_controller().OnHybridSignInSelected(); +} + } // namespace
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_view.h b/chrome/browser/touch_to_fill/touch_to_fill_view.h index a47176e..edab15c9 100644 --- a/chrome/browser/touch_to_fill/touch_to_fill_view.h +++ b/chrome/browser/touch_to_fill/touch_to_fill_view.h
@@ -21,6 +21,21 @@ public: using IsOriginSecure = base::StrongAlias<class IsOriginSecureTag, bool>; + enum ShowFlags { + kNone = 0, + + // Indicates whether Touch To Fill will submit a form after filling. + kTriggerSubmission = 1 << 0, + + // Indicates whether selecting the 'manage' button with passkeys available + // will show a screen that also allows management of passwords. + kCanManagePasswordsWhenPasskeysPresent = 1 << 1, + + // Indicates whether the footer should contain a button that invokes hybrid + // passkey sign-in. + kShouldShowHybridOption = 1 << 2, + }; + TouchToFillView() = default; TouchToFillView(const TouchToFillView&) = delete; TouchToFillView& operator=(const TouchToFillView&) = delete; @@ -29,18 +44,15 @@ // Instructs Touch To Fill to show the provided `credentials` to the user. // `formatted_url` contains a human friendly version of the current origin. // `is_origin_secure` indicates whether the current frame origin is secure. - // `trigger_submission` indicates whether Touch To Fill will submit a form - // after filling. `can_manage_passwords_when_passkeys_present` indicates - // whether selecting the 'manage' button with passkeys available will show a - // screen that also allows management of passwords. After user interaction - // either OnCredentialSelected() or OnDismiss() gets invoked. + // `flags` is a combination of bits that affect the behaviors listed in the + // `ShowFlags` enum. After user interaction either OnCredentialSelected() or + // OnDismiss() gets invoked. virtual void Show( const GURL& url, IsOriginSecure is_origin_secure, base::span<const password_manager::UiCredential> credentials, base::span<const password_manager::PasskeyCredential> passkey_credentials, - bool trigger_submission, - bool can_manage_passwords_when_passkeys_present) = 0; + int flags) = 0; // Invoked in case the user chooses an entry from the credential list // presented to them.
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index f4515b8..0eb77add 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -825,6 +825,10 @@ if (enable_waffle_desktop) { deps += [ "//chrome/browser/ui/webui/waffle:mojo_bindings" ] sources += [ + "views/waffle/waffle_dialog_view.cc", + "views/waffle/waffle_dialog_view.h", + "waffle/waffle_tab_helper.cc", + "waffle/waffle_tab_helper.h", "webui/waffle/waffle_handler.cc", "webui/waffle/waffle_handler.h", "webui/waffle/waffle_ui.cc", @@ -4749,6 +4753,8 @@ "views/device_chooser_content_view.h", "views/devtools_process_observer.cc", "views/devtools_process_observer.h", + "views/download/bubble/download_bubble_contents_view.cc", + "views/download/bubble/download_bubble_contents_view.h", "views/download/bubble/download_bubble_partial_view.cc", "views/download/bubble/download_bubble_partial_view.h", "views/download/bubble/download_bubble_row_list_view.cc",
diff --git a/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view.cc b/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view.cc index b10dca36..0c74148 100644 --- a/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view.cc +++ b/chrome/browser/ui/android/autofill/autofill_keyboard_accessory_view.cc
@@ -103,7 +103,7 @@ Java_AutofillKeyboardAccessoryViewBridge_addToAutofillSuggestionArray( env, data_array, position++, ConvertUTF16ToJavaString(env, label), ConvertUTF16ToJavaString(env, sublabel), android_icon_id, - suggestion.frontend_id.as_popup_item_id(), + base::to_underlying(suggestion.popup_item_id), controller_->GetRemovalConfirmationText(i, nullptr, nullptr), ConvertUTF8ToJavaString(env, suggestion.feature_for_iph), url::GURLAndroid::FromNativeGURL(env, suggestion.custom_icon_url));
diff --git a/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc b/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc index 70d36cb..fc48312 100644 --- a/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc +++ b/chrome/browser/ui/android/autofill/autofill_popup_view_android.cc
@@ -133,10 +133,10 @@ bool is_deletable = controller_->GetRemovalConfirmationText(i, nullptr, nullptr); bool is_label_multiline = - suggestion.frontend_id == + suggestion.popup_item_id == PopupItemId::kInsecureContextPaymentDisabledMessage || - suggestion.frontend_id == PopupItemId::kCreditCardSigninPromo || - suggestion.frontend_id == PopupItemId::kMixedFormMessage; + suggestion.popup_item_id == PopupItemId::kCreditCardSigninPromo || + suggestion.popup_item_id == PopupItemId::kMixedFormMessage; Java_AutofillPopupBridge_addToAutofillSuggestionArray( env, java_object_, data_array, i, @@ -145,8 +145,9 @@ base::android::ConvertUTF16ToJavaString(env, sublabel), base::android::ConvertUTF16ToJavaString(env, secondary_sublabel), base::android::ConvertUTF16ToJavaString(env, item_tag), android_icon_id, - suggestion.is_icon_at_start, suggestion.frontend_id.as_popup_item_id(), - is_deletable, is_label_multiline, /*isLabelBold*/ false, + suggestion.is_icon_at_start, + base::to_underlying(suggestion.popup_item_id), is_deletable, + is_label_multiline, /*isLabelBold*/ false, url::GURLAndroid::FromNativeGURL(env, suggestion.custom_icon_url)); }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java index 79b36bef..ef62880 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/status/StatusMediator.java
@@ -39,8 +39,6 @@ import org.chromium.components.content_settings.ContentSettingValues; import org.chromium.components.content_settings.ContentSettingsType; import org.chromium.components.page_info.PageInfoController; -import org.chromium.components.page_info.PageInfoDiscoverabilityMetrics; -import org.chromium.components.page_info.PageInfoDiscoverabilityMetrics.DiscoverabilityAction; import org.chromium.components.permissions.PermissionDialogController; import org.chromium.components.search_engines.TemplateUrlService; import org.chromium.components.search_engines.TemplateUrlService.TemplateUrlServiceObserver; @@ -95,8 +93,6 @@ @ContentSettingsType private int mLastPermission = ContentSettingsType.DEFAULT; private final PageInfoIPHController mPageInfoIPHController; - private final PageInfoDiscoverabilityMetrics mDiscoverabilityMetrics = - new PageInfoDiscoverabilityMetrics(); private final WindowAndroid mWindowAndroid; private boolean mUrlBarTextIsSearch = true; @@ -637,9 +633,6 @@ mModel.set(StatusProperties.STATUS_ICON_RESOURCE, permissionIconResource); Runnable finishIconAnimation = () -> updateLocationBarIcon(IconTransitionType.ROTATE); mPermissionTaskHandler.postDelayed(finishIconAnimation, mPermissionIconDisplayTimeoutMs); - - mDiscoverabilityMetrics.recordDiscoverabilityAction( - DiscoverabilityAction.PERMISSION_ICON_SHOWN); } private void startIPH() { @@ -676,7 +669,6 @@ updateLocationBarIcon(IconTransitionType.ROTATE); }, mPermissionIconDisplayTimeoutMs); mIsStoreIconShowing = true; - mDiscoverabilityMetrics.recordDiscoverabilityAction(DiscoverabilityAction.STORE_ICON_SHOWN); } // Reset all customized icons' status to avoid different icons' conflicts. @@ -698,13 +690,6 @@ /** Notifies that the page info was opened. */ void onPageInfoOpened() { - if (mLastPermission != ContentSettingsType.DEFAULT) { - mDiscoverabilityMetrics.recordDiscoverabilityAction( - DiscoverabilityAction.PAGE_INFO_OPENED); - } else if (mIsStoreIconShowing) { - mDiscoverabilityMetrics.recordDiscoverabilityAction( - DiscoverabilityAction.PAGE_INFO_OPENED_FROM_STORE_ICON); - } resetCustomIconsStatus(); updateLocationBarIcon(IconTransitionType.CROSSFADE); }
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index 9a16b3f..9ee5c30 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -5782,6 +5782,9 @@ <message name="IDS_PASSWORD_GENERATION_BOTTOM_SHEET_SUBTITLE" desc="The subtitle for the password generation bottom sheet."> You won’t need to remember this password. It will be saved to Google Password Manager for <ph name="USERNAME">%1$s<ex>elisa.becket@gmail.com</ex></ph>. </message> + <message name="IDS_PASSWORD_GENERATION_BOTTOM_SHEET_SUBTITLE_NO_ACCOUNT" desc="The subtitle for the password generation bottom sheet."> + You won’t need to remember this password. It will be saved to Google Password Manager. + </message> <message name="IDS_PASSWORD_GENERATION_BOTTOM_SHEET_USE_PASSWORD_BUTTON" desc="Appears on the button, which reflects the user agreement to user the generated strong password."> Use password </message>
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PASSWORD_GENERATION_BOTTOM_SHEET_SUBTITLE_NO_ACCOUNT.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PASSWORD_GENERATION_BOTTOM_SHEET_SUBTITLE_NO_ACCOUNT.png.sha1 new file mode 100644 index 0000000..fb2a73f --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PASSWORD_GENERATION_BOTTOM_SHEET_SUBTITLE_NO_ACCOUNT.png.sha1
@@ -0,0 +1 @@ +39e3d78d8976187fb813d0f47b38ba7c342ec4a4 \ No newline at end of file
diff --git a/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.cc b/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.cc index b11a932..fcd7f38c 100644 --- a/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.cc +++ b/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.cc
@@ -78,7 +78,7 @@ front_element_ = absl::nullopt; for (int i = 0; i < GetLineCount(); ++i) { const Suggestion& suggestion = controller_->GetSuggestionAt(i); - if (suggestion.frontend_id != PopupItemId::kClearForm) { + if (suggestion.popup_item_id != PopupItemId::kClearForm) { labels_.push_back(CreateLabel(suggestion)); continue; }
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 fbcf7fd..d1442ea 100644 --- a/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter_unittest.cc +++ b/chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter_unittest.cc
@@ -13,6 +13,7 @@ #include "base/logging.h" #include "base/memory/raw_ptr.h" #include "base/strings/utf_string_conversions.h" +#include "base/types/cxx23_to_underlying.h" #include "build/build_config.h" #include "chrome/browser/autofill/mock_autofill_popup_controller.h" #include "chrome/browser/ui/autofill/autofill_keyboard_accessory_adapter.h" @@ -99,8 +100,9 @@ // Matcher returning true if suggestions have equal members. MATCHER_P(equalsSuggestion, other, "") { - if (arg.frontend_id != other.frontend_id) { - *result_listener << "has frontend_id " << arg.frontend_id; + if (arg.popup_item_id != other.popup_item_id) { + *result_listener << "has popup_item_id " + << base::to_underlying(arg.popup_item_id); return false; } if (arg.main_text != other.main_text) {
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc index 66b0843..1489094a 100644 --- a/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc +++ b/chrome/browser/ui/autofill/autofill_popup_controller_impl.cc
@@ -173,7 +173,7 @@ // Remove all the old data list values, which should always be at the top of // the list if they are present. while (!suggestions_.empty() && - suggestions_[0].frontend_id == PopupItemId::kDatalistEntry) { + suggestions_[0].popup_item_id == PopupItemId::kDatalistEntry) { suggestions_.erase(suggestions_.begin()); } @@ -181,7 +181,7 @@ // is one). if (values.empty()) { if (!suggestions_.empty() && - suggestions_[0].frontend_id == PopupItemId::kSeparator) { + suggestions_[0].popup_item_id == PopupItemId::kSeparator) { suggestions_.erase(suggestions_.begin()); } @@ -196,7 +196,7 @@ // Add a separator if there are any other values. if (!suggestions_.empty() && - suggestions_[0].frontend_id != PopupItemId::kSeparator) { + suggestions_[0].popup_item_id != PopupItemId::kSeparator) { suggestions_.insert(suggestions_.begin(), Suggestion(PopupItemId::kSeparator)); } @@ -207,7 +207,7 @@ suggestions_[i].main_text = Suggestion::Text(values[i], Suggestion::Text::IsPrimary(true)); suggestions_[i].labels = {{Suggestion::Text(labels[i])}}; - suggestions_[i].frontend_id = PopupItemId::kDatalistEntry; + suggestions_[i].popup_item_id = PopupItemId::kDatalistEntry; } OnSuggestionsChanged(); @@ -318,7 +318,7 @@ #endif if (web_contents_ && - suggestion.frontend_id == PopupItemId::kVirtualCreditCardEntry) { + suggestion.popup_item_id == PopupItemId::kVirtualCreditCardEntry) { feature_engagement::TrackerFactory::GetForBrowserContext( web_contents_->GetBrowserContext()) ->NotifyEvent("autofill_virtual_card_suggestion_accepted"); @@ -397,7 +397,7 @@ std::u16string* body) { return delegate_->GetDeletionConfirmationText( suggestions_[list_index].main_text.value, - suggestions_[list_index].frontend_id, + suggestions_[list_index].popup_item_id, suggestions_[list_index].GetPayload<Suggestion::BackendId>(), title, body); } @@ -415,7 +415,7 @@ return false; if (!delegate_->RemoveSuggestion( suggestions_[list_index].main_text.value, - suggestions_[list_index].frontend_id, + suggestions_[list_index].popup_item_id, suggestions_[list_index].GetPayload<Suggestion::BackendId>())) { return false; } @@ -442,7 +442,7 @@ if (index) { DCHECK_LT(*index, suggestions_.size()); - if (!CanAccept(GetSuggestionAt(*index).frontend_id.as_popup_item_id())) { + if (!CanAccept(GetSuggestionAt(*index).popup_item_id)) { index = absl::nullopt; } } @@ -462,9 +462,9 @@ if (suggestions_.empty()) { return false; } - Suggestion::FrontendId id = suggestions_[0].frontend_id; - return base::Contains(kItemsTriggeringFieldFilling, id) || - id == PopupItemId::kScanCreditCard; + PopupItemId popup_item_id = suggestions_[0].popup_item_id; + return base::Contains(kItemsTriggeringFieldFilling, popup_item_id) || + popup_item_id == PopupItemId::kScanCreditCard; } void AutofillPopupControllerImpl::SetSuggestions(
diff --git a/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc b/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc index 1160deb..759252d8 100644 --- a/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc +++ b/chrome/browser/ui/autofill/autofill_popup_controller_unittest.cc
@@ -108,7 +108,7 @@ void DidSelectSuggestion(const Suggestion& suggestion) override {} bool RemoveSuggestion(const std::u16string& value, - Suggestion::FrontendId frontend_id, + PopupItemId popup_item_id, Suggestion::BackendId backend_id) override { return true; } @@ -225,12 +225,13 @@ autofill_manager(), autofill_driver()); } - // Shows empty suggestions with the frontend ids passed as `ids`. - void ShowSuggestions(const std::vector<Suggestion::FrontendId>& ids) { + // Shows empty suggestions with the popup_item_id ids passed as + // `popup_item_ids`. + void ShowSuggestions(const std::vector<PopupItemId>& popup_item_ids) { std::vector<Suggestion> suggestions; - suggestions.reserve(ids.size()); - for (Suggestion::FrontendId id : ids) { - suggestions.emplace_back("", "", "", id); + suggestions.reserve(popup_item_ids.size()); + for (PopupItemId popup_item_id : popup_item_ids) { + suggestions.emplace_back("", "", "", popup_item_id); } popup_controller().Show(std::move(suggestions), AutoselectFirstSuggestion(false)); @@ -292,8 +293,7 @@ }; TEST_F(AutofillPopupControllerUnitTest, RemoveSuggestion) { - ShowSuggestions({Suggestion::FrontendId(PopupItemId::kAddressEntry), - Suggestion::FrontendId(PopupItemId::kAddressEntry), + ShowSuggestions({PopupItemId::kAddressEntry, PopupItemId::kAddressEntry, PopupItemId::kAutofillOptions}); // Generate a popup, so it can be hidden later. It doesn't matter what the @@ -314,7 +314,7 @@ } TEST_F(AutofillPopupControllerUnitTest, UpdateDataListValues) { - ShowSuggestions({Suggestion::FrontendId(PopupItemId::kAddressEntry)}); + ShowSuggestions({PopupItemId::kAddressEntry}); // Add one data list entry. std::u16string value1 = u"data list value 1"; @@ -334,19 +334,19 @@ EXPECT_EQ(label1, result0.labels[0][0].value); EXPECT_EQ(std::u16string(), result0.additional_label); EXPECT_EQ(label1, popup_controller().GetSuggestionLabelsAt(0)[0][0].value); - EXPECT_EQ(PopupItemId::kDatalistEntry, result0.frontend_id); + EXPECT_EQ(PopupItemId::kDatalistEntry, result0.popup_item_id); Suggestion result1 = popup_controller().GetSuggestionAt(1); EXPECT_EQ(std::u16string(), result1.main_text.value); EXPECT_TRUE(result1.labels.empty()); EXPECT_EQ(std::u16string(), result1.additional_label); - EXPECT_EQ(PopupItemId::kSeparator, result1.frontend_id); + EXPECT_EQ(PopupItemId::kSeparator, result1.popup_item_id); Suggestion result2 = popup_controller().GetSuggestionAt(2); EXPECT_EQ(std::u16string(), result2.main_text.value); EXPECT_TRUE(result2.labels.empty()); EXPECT_EQ(std::u16string(), result2.additional_label); - EXPECT_EQ(PopupItemId::kAddressEntry, result2.frontend_id.as_popup_item_id()); + EXPECT_EQ(PopupItemId::kAddressEntry, result2.popup_item_id); // Add two data list entries (which should replace the current one). std::u16string value2 = u"data list value 2"; @@ -373,16 +373,15 @@ EXPECT_EQ(std::u16string(), popup_controller().GetSuggestionAt(1).additional_label); EXPECT_EQ(PopupItemId::kSeparator, - popup_controller().GetSuggestionAt(2).frontend_id); + popup_controller().GetSuggestionAt(2).popup_item_id); // Clear all data list values. data_list_values.clear(); popup_controller().UpdateDataListValues(data_list_values, data_list_labels); ASSERT_EQ(1, popup_controller().GetLineCount()); - EXPECT_EQ( - PopupItemId::kAddressEntry, - popup_controller().GetSuggestionAt(0).frontend_id.as_popup_item_id()); + EXPECT_EQ(PopupItemId::kAddressEntry, + popup_controller().GetSuggestionAt(0).popup_item_id); } TEST_F(AutofillPopupControllerUnitTest, PopupsWithOnlyDataLists) { @@ -405,7 +404,7 @@ EXPECT_EQ(std::u16string(), popup_controller().GetSuggestionAt(0).additional_label); EXPECT_EQ(PopupItemId::kDatalistEntry, - popup_controller().GetSuggestionAt(0).frontend_id); + popup_controller().GetSuggestionAt(0).popup_item_id); // Clear datalist values and check that the popup becomes hidden. EXPECT_CALL(popup_controller(), Hide(PopupHidingReason::kNoSuggestions)); @@ -527,7 +526,7 @@ // This is a regression test for crbug.com/521133 to ensure that we don't crash // when suggestions updates race with user selections. TEST_F(AutofillPopupControllerUnitTest, SelectInvalidSuggestion) { - ShowSuggestions({Suggestion::FrontendId(PopupItemId::kAddressEntry)}); + ShowSuggestions({PopupItemId::kAddressEntry}); EXPECT_CALL(*delegate(), DidAcceptSuggestion).Times(0); @@ -536,7 +535,7 @@ } TEST_F(AutofillPopupControllerUnitTest, AcceptSuggestionRespectsTimeout) { - ShowSuggestions({Suggestion::FrontendId(PopupItemId::kAddressEntry)}); + ShowSuggestions({PopupItemId::kAddressEntry}); // Calls before the threshold are ignored. EXPECT_CALL(*delegate(), DidAcceptSuggestion).Times(0); @@ -550,7 +549,7 @@ } TEST_F(AutofillPopupControllerUnitTest, AcceptSuggestionWithoutThreshold) { - ShowSuggestions({Suggestion::FrontendId(PopupItemId::kAddressEntry)}); + ShowSuggestions({PopupItemId::kAddressEntry}); // Calls are accepted immediately. EXPECT_CALL(*delegate(), DidAcceptSuggestion).Times(1); @@ -559,7 +558,7 @@ TEST_F(AutofillPopupControllerUnitTest, AcceptSuggestionTimeoutIsUpdatedOnPopupMove) { - ShowSuggestions({Suggestion::FrontendId(PopupItemId::kAddressEntry)}); + ShowSuggestions({PopupItemId::kAddressEntry}); // Calls before the threshold are ignored. EXPECT_CALL(*delegate(), DidAcceptSuggestion).Times(0); @@ -570,7 +569,7 @@ task_environment()->FastForwardBy(base::Milliseconds(400)); // Show the suggestions again (simulating, e.g., a click somewhere slightly // different). - ShowSuggestions({Suggestion::FrontendId(PopupItemId::kAddressEntry)}); + ShowSuggestions({PopupItemId::kAddressEntry}); EXPECT_CALL(*delegate(), DidAcceptSuggestion).Times(0); popup_controller().AcceptSuggestion(0); @@ -677,7 +676,7 @@ // Test for successfully firing controls changed event for popup show/hide. TEST_F(AutofillPopupControllerAccessibilityUnitTest, FireControlsChangedEventDuringShowAndHide) { - ShowSuggestions({Suggestion::FrontendId(PopupItemId::kAddressEntry)}); + ShowSuggestions({PopupItemId::kAddressEntry}); // Manually fire the event for popup show since setting the test view results // in the fire controls changed event not being sent. popup_controller().FireControlsChangedEvent(true); @@ -695,7 +694,7 @@ EXPECT_CALL(mock_ax_platform_node_delegate_, GetFromTreeIDAndNodeID) .WillOnce(Return(nullptr)); - ShowSuggestions({Suggestion::FrontendId(PopupItemId::kAddressEntry)}); + ShowSuggestions({PopupItemId::kAddressEntry}); // Manually fire the event for popup show since setting the test view results // in the fire controls changed event not being sent. popup_controller().FireControlsChangedEvent(true); @@ -710,7 +709,7 @@ EXPECT_CALL(*autofill_popup_view_, GetAxUniqueId) .WillOnce(testing::Return(absl::nullopt)); - ShowSuggestions({Suggestion::FrontendId(PopupItemId::kAddressEntry)}); + ShowSuggestions({PopupItemId::kAddressEntry}); // Manually fire the event for popup show since setting the test view results // in the fire controls changed event not being sent. popup_controller().FireControlsChangedEvent(true);
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index 36ebcfa..a448113 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -102,7 +102,7 @@ #include "url/origin.h" #if BUILDFLAG(IS_ANDROID) -#include "chrome/browser/android/preferences/autofill/autofill_profile_bridge.h" +#include "chrome/browser/android/preferences/autofill/settings_launcher_helper.h" #include "chrome/browser/android/signin/signin_bridge.h" #include "chrome/browser/android/tab_android.h" #include "chrome/browser/flags/android/chrome_feature_list.h" @@ -1079,9 +1079,9 @@ security_level != security_state::DANGEROUS; } -void ChromeAutofillClient::ExecuteCommand(Suggestion::FrontendId id) { +void ChromeAutofillClient::ExecuteCommand(PopupItemId popup_item_id) { #if BUILDFLAG(IS_ANDROID) - if (id.as_popup_item_id() == PopupItemId::kCreditCardSigninPromo) { + if (popup_item_id == PopupItemId::kCreditCardSigninPromo) { auto* window = web_contents()->GetNativeView()->GetWindowAndroid(); if (window) { SigninBridge::LaunchSigninActivity(
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h index d0261f7..65a0777 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.h +++ b/chrome/browser/ui/autofill/chrome_autofill_client.h
@@ -25,6 +25,7 @@ #include "components/autofill/core/browser/payments/legal_message_line.h" #include "components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.h" #include "components/autofill/core/browser/ui/payments/card_unmask_prompt_options.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" #include "components/signin/public/identity_manager/account_info.h" #include "content/public/browser/visibility.h" #include "content/public/browser/web_contents_observer.h" @@ -251,7 +252,7 @@ void DidFillOrPreviewField(const std::u16string& autofilled_value, const std::u16string& profile_full_name) override; bool IsContextSecure() const override; - void ExecuteCommand(Suggestion::FrontendId id) override; + void ExecuteCommand(PopupItemId popup_item_id) override; void OpenPromoCodeOfferDetailsURL(const GURL& url) override; LogManager* GetLogManager() const override; FormInteractionsFlowId GetCurrentFormInteractionsFlowId() override;
diff --git a/chrome/browser/ui/autofill/payments/autofill_snackbar_controller_impl.cc b/chrome/browser/ui/autofill/payments/autofill_snackbar_controller_impl.cc index 42fe3c1e..800d0077 100644 --- a/chrome/browser/ui/autofill/payments/autofill_snackbar_controller_impl.cc +++ b/chrome/browser/ui/autofill/payments/autofill_snackbar_controller_impl.cc
@@ -6,7 +6,7 @@ #include <string> #include "base/metrics/histogram_functions.h" #include "build/build_config.h" -#include "chrome/browser/android/preferences/autofill/autofill_profile_bridge.h" +#include "chrome/browser/android/preferences/autofill/settings_launcher_helper.h" #include "chrome/browser/autofill/manual_filling_controller.h" #include "chrome/browser/autofill/manual_filling_controller_impl.h" #include "chrome/browser/ui/android/autofill/snackbar/autofill_snackbar_view_android.h" @@ -27,20 +27,17 @@ void AutofillSnackbarControllerImpl::Show( AutofillSnackbarType autofill_snackbar_type) { CHECK_NE(autofill_snackbar_type, AutofillSnackbarType::kUnspecified); - autofill_snackbar_type_ = autofill_snackbar_type; - if (!autofill_snackbar_view_) { - autofill_snackbar_view_ = AutofillSnackbarView::Create(this); + if (autofill_snackbar_view_) { + // A snackbar is already showing. Ignore the new request. + return; } + autofill_snackbar_type_ = autofill_snackbar_type; + autofill_snackbar_view_ = AutofillSnackbarView::Create(this); autofill_snackbar_view_->Show(); base::UmaHistogramBoolean( "Autofill.Snackbar." + GetSnackbarTypeForLogging() + ".Shown", true); } -void AutofillSnackbarControllerImpl::SetViewForTesting( - AutofillSnackbarView* view) { - autofill_snackbar_view_ = view; -} - void AutofillSnackbarControllerImpl::OnActionClicked() { switch (autofill_snackbar_type_) { case AutofillSnackbarType::kVirtualCard:
diff --git a/chrome/browser/ui/autofill/payments/autofill_snackbar_controller_impl.h b/chrome/browser/ui/autofill/payments/autofill_snackbar_controller_impl.h index b51db632..e886ef0 100644 --- a/chrome/browser/ui/autofill/payments/autofill_snackbar_controller_impl.h +++ b/chrome/browser/ui/autofill/payments/autofill_snackbar_controller_impl.h
@@ -27,7 +27,6 @@ // Show the snackbar. void Show(AutofillSnackbarType autofill_snackbar_type); - void SetViewForTesting(AutofillSnackbarView* view); // AutofillSnackbarController: void OnActionClicked() override;
diff --git a/chrome/browser/ui/autofill/payments/autofill_snackbar_controller_impl_unittest.cc b/chrome/browser/ui/autofill/payments/autofill_snackbar_controller_impl_unittest.cc index 71c052dd..b7284388 100644 --- a/chrome/browser/ui/autofill/payments/autofill_snackbar_controller_impl_unittest.cc +++ b/chrome/browser/ui/autofill/payments/autofill_snackbar_controller_impl_unittest.cc
@@ -20,13 +20,6 @@ namespace autofill { -class MockAutofillSnackbarView : public AutofillSnackbarView { - public: - MockAutofillSnackbarView() = default; - void Show() override {} - void Dismiss() override {} -}; - class AutofillSnackbarControllerImplTest : public ChromeRenderViewHostTestHarness { public: @@ -34,7 +27,6 @@ void SetUp() override { ChromeRenderViewHostTestHarness::SetUp(); - controller()->SetViewForTesting(new MockAutofillSnackbarView()); ManualFillingControllerImpl::CreateForWebContentsForTesting( web_contents(), mock_pwd_controller_.AsWeakPtr(), mock_address_controller_.AsWeakPtr(), mock_cc_controller_.AsWeakPtr(), @@ -65,8 +57,6 @@ "Autofill.Snackbar.VirtualCard.ActionClicked", 1, 0); controller()->OnDismissed(); - // Reset the mock view. - controller()->SetViewForTesting(new MockAutofillSnackbarView()); controller()->Show(AutofillSnackbarType::kVirtualCard); controller()->OnActionClicked(); // Verify that the count for both Shown and ActionClicked is incremented. @@ -76,6 +66,25 @@ "Autofill.Snackbar.VirtualCard.ActionClicked", 1, 1); } +TEST_F(AutofillSnackbarControllerImplTest, + AttemptToShowDialogWhileAlreadyShowing) { + base::HistogramTester histogram_tester; + controller()->Show(AutofillSnackbarType::kVirtualCard); + // Verify that the count for Shown is incremented and ActionClicked hasn't + // changed. + histogram_tester.ExpectUniqueSample("Autofill.Snackbar.VirtualCard.Shown", 1, + 1); + histogram_tester.ExpectUniqueSample( + "Autofill.Snackbar.VirtualCard.ActionClicked", 1, 0); + + // Attempt to show another dialog without dismissing the previous one. + controller()->Show(AutofillSnackbarType::kVirtualCard); + + // Verify that the count for both Shown is not incremented. + histogram_tester.ExpectUniqueSample("Autofill.Snackbar.VirtualCard.Shown", 1, + 1); +} + TEST_F(AutofillSnackbarControllerImplTest, MandatoryReauthTypeMetricsTest) { base::HistogramTester histogram_tester; controller()->Show(AutofillSnackbarType::kMandatoryReauth);
diff --git a/chrome/browser/ui/autofill/payments/mandatory_reauth_bubble_controller_impl.cc b/chrome/browser/ui/autofill/payments/mandatory_reauth_bubble_controller_impl.cc index f1dcaae5..601cfb90 100644 --- a/chrome/browser/ui/autofill/payments/mandatory_reauth_bubble_controller_impl.cc +++ b/chrome/browser/ui/autofill/payments/mandatory_reauth_bubble_controller_impl.cc
@@ -108,6 +108,12 @@ PaymentsBubbleClosedReason closed_reason) { set_bubble_view(nullptr); +// After resetting the raw pointer to the view in the base class, the Android +// view has to be deleted. +#if BUILDFLAG(IS_ANDROID) + view_android_.reset(); +#endif + if (current_bubble_type_ == MandatoryReauthBubbleType::kOptIn) { if (closed_reason == PaymentsBubbleClosedReason::kAccepted) { std::move(accept_mandatory_reauth_callback_).Run(); @@ -144,13 +150,19 @@ } void MandatoryReauthBubbleControllerImpl::DoShowBubble() { -#if !BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_ANDROID) + // The Android view's lifecycle is managed by this controller. We also + // register it as a raw pointer in the base class to use its closing logic + // when this controller wants to close it. + view_android_ = MandatoryReauthOptInViewAndroid::CreateAndShow(); + set_bubble_view(view_android_.get()); +#else Browser* browser = chrome::FindBrowserWithWebContents(web_contents()); AutofillBubbleHandler* autofill_bubble_handler = browser->window()->GetAutofillBubbleHandler(); set_bubble_view(autofill_bubble_handler->ShowMandatoryReauthBubble( web_contents(), this, /*is_user_gesture=*/false, current_bubble_type_)); -#endif // !BUILDFLAG(IS_ANDROID) +#endif // BUILDFLAG(IS_ANDROID) } WEB_CONTENTS_USER_DATA_KEY_IMPL(MandatoryReauthBubbleControllerImpl);
diff --git a/chrome/browser/ui/autofill/payments/mandatory_reauth_bubble_controller_impl.h b/chrome/browser/ui/autofill/payments/mandatory_reauth_bubble_controller_impl.h index dd6340c..7c25431 100644 --- a/chrome/browser/ui/autofill/payments/mandatory_reauth_bubble_controller_impl.h +++ b/chrome/browser/ui/autofill/payments/mandatory_reauth_bubble_controller_impl.h
@@ -12,6 +12,10 @@ #include "chrome/browser/ui/autofill/payments/mandatory_reauth_bubble_controller.h" #include "content/public/browser/web_contents_user_data.h" +#if BUILDFLAG(IS_ANDROID) +#include "chrome/browser/mandatory_reauth/android/mandatory_reauth_opt_in_view_android.h" +#endif + namespace autofill { class MandatoryReauthBubbleControllerImpl @@ -60,6 +64,12 @@ MandatoryReauthBubbleType current_bubble_type_ = MandatoryReauthBubbleType::kInactive; +#if BUILDFLAG(IS_ANDROID) + // Handles Android view's lifecycle. The Desktop view is handled by the base + // class `AutofillBubbleControllerBase`. + std::unique_ptr<MandatoryReauthOptInViewAndroid> view_android_; +#endif + WEB_CONTENTS_USER_DATA_KEY_DECL(); };
diff --git a/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller.mm b/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller.mm index d70a057..0f91cab 100644 --- a/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller.mm +++ b/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller.mm
@@ -97,9 +97,9 @@ for (int i = 0; i < _controller->GetLineCount() && i < maxTouchBarItems; i++) { const autofill::Suggestion& suggestion = _controller->GetSuggestionAt(i); - if (suggestion.frontend_id.as_popup_item_id() != - autofill::PopupItemId::kAutocompleteEntry && - !suggestion.frontend_id.is_an_address_or_card_popup_item_id()) { + if (suggestion.popup_item_id != autofill::PopupItemId::kAutocompleteEntry && + suggestion.popup_item_id != autofill::PopupItemId::kAddressEntry && + suggestion.popup_item_id != autofill::PopupItemId::kCreditCardEntry) { continue; }
diff --git a/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller_unittest.mm b/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller_unittest.mm index d7cb5b0b2..749393fc 100644 --- a/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller_unittest.mm
@@ -52,11 +52,11 @@ } void SetSuggestions( - const std::vector<Suggestion::FrontendId>& frontends_ids) { + const std::vector<autofill::PopupItemId>& popup_item_ids) { std::vector<Suggestion> suggestions; - suggestions.reserve(frontends_ids.size()); - for (Suggestion::FrontendId frontend_id : frontends_ids) { - suggestions.emplace_back("", "", "", frontend_id); + suggestions.reserve(popup_item_ids.size()); + for (autofill::PopupItemId popup_item_id : popup_item_ids) { + suggestions.emplace_back("", "", "", popup_item_id); } SetSuggestions(std::move(suggestions)); } @@ -78,8 +78,8 @@ EXPECT_FALSE([touch_bar_controller_ makeTouchBar]); [touch_bar_controller_ setIsCreditCardPopup:true]; - SetSuggestions({Suggestion::FrontendId(PopupItemId::kCreditCardEntry), - Suggestion::FrontendId(PopupItemId::kCreditCardEntry)}); + SetSuggestions( + {PopupItemId::kCreditCardEntry, PopupItemId::kCreditCardEntry}); NSTouchBar* touch_bar = [touch_bar_controller_ makeTouchBar]; EXPECT_TRUE(touch_bar); EXPECT_TRUE([[touch_bar customizationIdentifier] @@ -90,10 +90,9 @@ // Tests to check that the touch bar doesn't show more than 3 items TEST_F(CreditCardAutofillTouchBarControllerUnitTest, TouchBarCardLimit) { [touch_bar_controller_ setIsCreditCardPopup:true]; - SetSuggestions({Suggestion::FrontendId(PopupItemId::kCreditCardEntry), - Suggestion::FrontendId(PopupItemId::kCreditCardEntry), - Suggestion::FrontendId(PopupItemId::kCreditCardEntry), - Suggestion::FrontendId(PopupItemId::kCreditCardEntry)}); + SetSuggestions({PopupItemId::kCreditCardEntry, PopupItemId::kCreditCardEntry, + PopupItemId::kCreditCardEntry, + PopupItemId::kCreditCardEntry}); NSTouchBar* touch_bar = [touch_bar_controller_ makeTouchBar]; EXPECT_TRUE(touch_bar); EXPECT_TRUE([[touch_bar customizationIdentifier] @@ -111,9 +110,8 @@ // Tests for for the credit card button. TEST_F(CreditCardAutofillTouchBarControllerUnitTest, CreditCardButtonCheck) { [touch_bar_controller_ setIsCreditCardPopup:true]; - SetSuggestions( - {Suggestion("bufflehead", "canvasback", "goldeneye", - Suggestion::FrontendId(PopupItemId::kCreditCardEntry))}); + SetSuggestions({Suggestion("bufflehead", "canvasback", "goldeneye", + PopupItemId::kCreditCardEntry)}); NSButton* button = [touch_bar_controller_ createCreditCardButtonAtRow:0]; EXPECT_TRUE(button); EXPECT_EQ(0, [button tag]);
diff --git a/chrome/browser/ui/fast_checkout/fast_checkout_controller_impl.cc b/chrome/browser/ui/fast_checkout/fast_checkout_controller_impl.cc index 9af061b..03afd54 100644 --- a/chrome/browser/ui/fast_checkout/fast_checkout_controller_impl.cc +++ b/chrome/browser/ui/fast_checkout/fast_checkout_controller_impl.cc
@@ -4,7 +4,7 @@ #include "chrome/browser/ui/fast_checkout/fast_checkout_controller_impl.h" -#include "chrome/browser/android/preferences/autofill/autofill_profile_bridge.h" +#include "chrome/browser/android/preferences/autofill/settings_launcher_helper.h" #include "components/autofill/core/browser/autofill_data_util.h" #include "components/autofill/core/browser/data_model/autofill_profile.h" #include "components/autofill/core/browser/data_model/credit_card.h"
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc index f895075..b688e30 100644 --- a/chrome/browser/ui/tab_helpers.cc +++ b/chrome/browser/ui/tab_helpers.cc
@@ -73,6 +73,7 @@ #include "chrome/browser/safe_browsing/trigger_creator.h" #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/sessions/session_tab_helper_factory.h" +#include "chrome/browser/signin/signin_features.h" #include "chrome/browser/ssl/chrome_security_blocking_page_factory.h" #include "chrome/browser/ssl/connection_help_tab_helper.h" #include "chrome/browser/ssl/https_only_mode_tab_helper.h" @@ -97,6 +98,7 @@ #include "chrome/browser/ui/tab_dialogs.h" #include "chrome/browser/ui/tab_ui_helper.h" #include "chrome/browser/ui/thumbnails/thumbnail_tab_helper.h" +#include "chrome/browser/ui/waffle/waffle_tab_helper.h" #include "chrome/browser/user_notes/user_notes_tab_helper.h" #include "chrome/browser/vr/vr_tab_helper.h" #include "chrome/common/buildflags.h" @@ -498,6 +500,13 @@ ManagePasswordsUIController::CreateForWebContents(web_contents); if (PrivacySandboxPromptHelper::ProfileRequiresPrompt(profile)) PrivacySandboxPromptHelper::CreateForWebContents(web_contents); + +#if BUILDFLAG(ENABLE_WAFFLE_DESKTOP) + if (base::FeatureList::IsEnabled(kWaffle)) { + WaffleTabHelper::CreateForWebContents(web_contents); + } +#endif + SadTabHelper::CreateForWebContents(web_contents); SearchTabHelper::CreateForWebContents(web_contents); TabDialogs::CreateForWebContents(web_contents);
diff --git a/chrome/browser/ui/views/accessibility/caption_bubble_controller_views_browsertest.cc b/chrome/browser/ui/views/accessibility/caption_bubble_controller_views_browsertest.cc index af8c467..29253ed 100644 --- a/chrome/browser/ui/views/accessibility/caption_bubble_controller_views_browsertest.cc +++ b/chrome/browser/ui/views/accessibility/caption_bubble_controller_views_browsertest.cc
@@ -86,9 +86,9 @@ : nullptr; } - views::StyledLabel* GetLiveTranslateLabel() { + views::StyledLabel* GetLanguageLabel() { return controller_ - ? controller_->caption_bubble_->GetLiveTranslateLabelForTesting() + ? controller_->caption_bubble_->GetLanguageLabelForTesting() : nullptr; } @@ -223,6 +223,15 @@ caption_bubble_context, media::SpeechRecognitionResult(text, true)); } + void OnLanguageIdentificationEvent(std::string language) { + media::mojom::LanguageIdentificationEventPtr event = + media::mojom::LanguageIdentificationEvent::New(); + event->language = language; + event->asr_switch_result = media::mojom::AsrSwitchResult::kSwitchSucceeded; + GetController()->OnLanguageIdentificationEvent(GetCaptionBubbleContext(), + event); + } + void OnError() { OnError(GetCaptionBubbleContext()); } void OnError(CaptionBubbleContext* caption_bubble_context) { @@ -1275,29 +1284,28 @@ OnPartialTranscription("Penguins' feet change colors as they get older."); EXPECT_TRUE(IsWidgetVisible()); - ASSERT_FALSE(GetLiveTranslateLabel()->GetVisible()); + ASSERT_TRUE(GetLanguageLabel()->GetVisible()); browser()->profile()->GetPrefs()->SetBoolean(prefs::kLiveTranslateEnabled, true); OnPartialTranscription( "Sea otters can hold their breath for over 5 minutes."); - ASSERT_TRUE(GetLiveTranslateLabel()->GetVisible()); + ASSERT_TRUE(GetLanguageLabel()->GetVisible()); EXPECT_EQ("Translating French to English", - base::UTF16ToUTF8(GetLiveTranslateLabel()->GetText())); - EXPECT_EQ(line_height, GetLiveTranslateLabel()->GetLineHeight()); + base::UTF16ToUTF8(GetLanguageLabel()->GetText())); + EXPECT_EQ(line_height, GetLanguageLabel()->GetLineHeight()); ui::CaptionStyle caption_style; caption_style.text_size = "200%"; GetController()->UpdateCaptionStyle(caption_style); - EXPECT_EQ(line_height * 2, GetLiveTranslateLabel()->GetLineHeight()); + EXPECT_EQ(line_height * 2, GetLanguageLabel()->GetLineHeight()); caption_style.text_size = "50%"; GetController()->UpdateCaptionStyle(caption_style); - EXPECT_EQ(line_height / 2, GetLiveTranslateLabel()->GetLineHeight()); + EXPECT_EQ(line_height / 2, GetLanguageLabel()->GetLineHeight()); - // Disabling Live Translate should hide the Live Translate label. browser()->profile()->GetPrefs()->SetBoolean(prefs::kLiveTranslateEnabled, false); - ASSERT_FALSE(GetLiveTranslateLabel()->GetVisible()); + ASSERT_TRUE(GetLanguageLabel()->GetVisible()); } IN_PROC_BROWSER_TEST_F(CaptionBubbleControllerViewsTest, HeaderView) { @@ -1309,22 +1317,31 @@ EXPECT_EQ(2u, GetHeader()->children().size()); views::View* left_header_container = GetHeader()->children()[0]; - // The left header container should contain the live translate label and the + // The left header container should contain the language label and the // caption settings icon. EXPECT_EQ(2u, left_header_container->children().size()); - // With Live Translate disabled, only the caption settings icon should be - // visible in the left header container. - auto* live_translate_label = left_header_container->children()[0]; + auto* language_label = left_header_container->children()[0]; auto* caption_settings_icon = left_header_container->children()[1]; - ASSERT_FALSE(live_translate_label->GetVisible()); + ASSERT_TRUE(language_label->GetVisible()); ASSERT_TRUE(caption_settings_icon->GetVisible()); - ASSERT_EQ(0, static_cast<views::BoxLayout*>( + ASSERT_EQ(4, static_cast<views::BoxLayout*>( left_header_container->GetLayoutManager()) ->inside_border_insets() .left()); EXPECT_EQ(464, left_header_container->GetPreferredSize().width()); + EXPECT_EQ(u"Captioning English", + static_cast<views::StyledLabel*>(language_label)->GetText()); + + OnLanguageIdentificationEvent("fr-FR"); + EXPECT_EQ(u"Captioning French (auto-detected)", + static_cast<views::StyledLabel*>(language_label)->GetText()); + + OnLanguageIdentificationEvent("en-GB"); + EXPECT_EQ(u"Captioning English", + static_cast<views::StyledLabel*>(language_label)->GetText()); + // Enable Live Translate. browser()->profile()->GetPrefs()->SetString( prefs::kLiveTranslateTargetLanguageCode, "en"); @@ -1333,12 +1350,22 @@ browser()->profile()->GetPrefs()->SetBoolean(prefs::kLiveTranslateEnabled, true); - ASSERT_TRUE(live_translate_label->GetVisible()); + ASSERT_TRUE(language_label->GetVisible()); ASSERT_TRUE(caption_settings_icon->GetVisible()); ASSERT_EQ(4, static_cast<views::BoxLayout*>( left_header_container->GetLayoutManager()) ->inside_border_insets() .left()); + EXPECT_EQ(u"Translating French to English", + static_cast<views::StyledLabel*>(language_label)->GetText()); + + OnLanguageIdentificationEvent("it-IT"); + EXPECT_EQ(u"Translating Italian (auto-detected) to English", + static_cast<views::StyledLabel*>(language_label)->GetText()); + + OnLanguageIdentificationEvent("en-US"); + EXPECT_EQ(u"Captioning English (auto-detected)", + static_cast<views::StyledLabel*>(language_label)->GetText()); } IN_PROC_BROWSER_TEST_F(CaptionBubbleControllerViewsTest,
diff --git a/chrome/browser/ui/views/autofill/popup/popup_row_strategy.cc b/chrome/browser/ui/views/autofill/popup/popup_row_strategy.cc index d8722f0..f7d9181f 100644 --- a/chrome/browser/ui/views/autofill/popup/popup_row_strategy.cc +++ b/chrome/browser/ui/views/autofill/popup/popup_row_strategy.cc
@@ -373,7 +373,7 @@ std::vector<std::unique_ptr<views::View>> subtext_views, PopupCellView& content_view) { bool has_control_element = - suggestion.frontend_id == PopupItemId::kAutocompleteEntry && + suggestion.popup_item_id == PopupItemId::kAutocompleteEntry && base::FeatureList::IsEnabled( features::kAutofillShowAutocompleteDeleteButton); views::BoxLayout& layout = @@ -544,7 +544,8 @@ set_size_ = 0; set_index_ = line_number + 1; for (int i = 0; i < controller->GetLineCount(); ++i) { - if (controller->GetSuggestionAt(i).frontend_id == PopupItemId::kSeparator) { + if (controller->GetSuggestionAt(i).popup_item_id == + PopupItemId::kSeparator) { if (i < line_number) { --set_index_; } @@ -719,7 +720,7 @@ } // If the feature is enabled, autocomplete entries have a delete button. - if (GetController()->GetSuggestionAt(GetLineNumber()).frontend_id == + if (GetController()->GetSuggestionAt(GetLineNumber()).popup_item_id == PopupItemId::kAutocompleteEntry && base::FeatureList::IsEnabled( features::kAutofillShowAutocompleteDeleteButton)) { @@ -869,7 +870,7 @@ std::unique_ptr<views::ImageView> icon = GetIconImageView(kSuggestion); const bool kUseLeadingIcon = - base::Contains(kItemTypesUsingLeadingIcons, kSuggestion.frontend_id); + base::Contains(kItemTypesUsingLeadingIcons, kSuggestion.popup_item_id); if (kSuggestion.is_loading) { view->AddChildView(std::make_unique<views::Throbber>())->Start();
diff --git a/chrome/browser/ui/views/autofill/popup/popup_row_strategy_unittest.cc b/chrome/browser/ui/views/autofill/popup/popup_row_strategy_unittest.cc index 201528b9..92c752c 100644 --- a/chrome/browser/ui/views/autofill/popup/popup_row_strategy_unittest.cc +++ b/chrome/browser/ui/views/autofill/popup/popup_row_strategy_unittest.cc
@@ -41,8 +41,8 @@ }; struct RowStrategyTestdata { - // The frontend ids of the suggestions to be shown. - std::vector<Suggestion::FrontendId> frontend_ids; + // The popup item ids of the suggestions to be shown. + std::vector<PopupItemId> popup_item_ids; // The index of the suggestion to be tested. int line_number; // The type of strategy to be tested. @@ -55,39 +55,37 @@ const RowStrategyTestdata kTestcases[] = { RowStrategyTestdata{ - .frontend_ids = {Suggestion::FrontendId(PopupItemId::kAddressEntry), - Suggestion::FrontendId(PopupItemId::kAddressEntry), - PopupItemId::kSeparator, - PopupItemId::kAutofillOptions}, + .popup_item_ids = {PopupItemId::kAddressEntry, + PopupItemId::kAddressEntry, PopupItemId::kSeparator, + PopupItemId::kAutofillOptions}, .line_number = 1, .strategy_type = StrategyType::kSuggestion, .set_size = 3, .set_index = 2, }, RowStrategyTestdata{ - .frontend_ids = {PopupItemId::kPasswordEntry, - PopupItemId::kAccountStoragePasswordEntry, - PopupItemId::kSeparator, - PopupItemId::kAllSavedPasswordsEntry}, + .popup_item_ids = {PopupItemId::kPasswordEntry, + PopupItemId::kAccountStoragePasswordEntry, + PopupItemId::kSeparator, + PopupItemId::kAllSavedPasswordsEntry}, .line_number = 0, .strategy_type = StrategyType::kPasswordSuggestion, .set_size = 3, .set_index = 1, }, RowStrategyTestdata{ - .frontend_ids = {Suggestion::FrontendId(PopupItemId::kAddressEntry), - Suggestion::FrontendId(PopupItemId::kAddressEntry), - PopupItemId::kSeparator, - PopupItemId::kAutofillOptions}, + .popup_item_ids = {PopupItemId::kAddressEntry, + PopupItemId::kAddressEntry, PopupItemId::kSeparator, + PopupItemId::kAutofillOptions}, .line_number = 3, .strategy_type = StrategyType::kFooter, .set_size = 3, .set_index = 3, }, RowStrategyTestdata{ - .frontend_ids = {PopupItemId::kAutocompleteEntry, - PopupItemId::kAutocompleteEntry, - PopupItemId::kAutocompleteEntry}, + .popup_item_ids = {PopupItemId::kAutocompleteEntry, + PopupItemId::kAutocompleteEntry, + PopupItemId::kAutocompleteEntry}, .line_number = 1, .strategy_type = StrategyType::kSuggestion, .set_size = 3, @@ -101,12 +99,12 @@ class PopupRowStrategyTest : public ChromeViewsTestBase { public: // Sets suggestions in the mocked popup controller. - void SetSuggestions(const std::vector<Suggestion::FrontendId>& frontend_ids) { + void SetSuggestions(const std::vector<PopupItemId>& popup_item_ids) { std::vector<Suggestion> suggestions; - suggestions.reserve(frontend_ids.size()); - for (Suggestion::FrontendId frontend_id : frontend_ids) { + suggestions.reserve(popup_item_ids.size()); + for (PopupItemId popup_item_id : popup_item_ids) { // Create a suggestion with empty labels. - suggestions.emplace_back("Main text", "", "", frontend_id); + suggestions.emplace_back("Main text", "", "", popup_item_id); } controller().set_suggestions(std::move(suggestions)); } @@ -285,7 +283,7 @@ TEST_P(PopupRowStrategyParametrizedTest, HasContentArea) { const RowStrategyTestdata kTestdata = GetParam(); - SetSuggestions(kTestdata.frontend_ids); + SetSuggestions(kTestdata.popup_item_ids); std::unique_ptr<PopupRowStrategy> strategy = CreateStrategy(kTestdata.strategy_type, kTestdata.line_number); @@ -296,7 +294,7 @@ TEST_P(PopupRowStrategyParametrizedTest, ContentAreaCallbacksWork) { const RowStrategyTestdata kTestdata = GetParam(); - SetSuggestions(kTestdata.frontend_ids); + SetSuggestions(kTestdata.popup_item_ids); std::unique_ptr<PopupRowStrategy> strategy = CreateStrategy(kTestdata.strategy_type, kTestdata.line_number); @@ -308,7 +306,7 @@ TEST_P(PopupRowStrategyParametrizedTest, DeletedControllerIsHandledGracefully) { const RowStrategyTestdata kTestdata = GetParam(); - SetSuggestions(kTestdata.frontend_ids); + SetSuggestions(kTestdata.popup_item_ids); std::unique_ptr<PopupRowStrategy> strategy = CreateStrategy(kTestdata.strategy_type, kTestdata.line_number); @@ -327,7 +325,7 @@ SetsAccessibilityAttributesForContentArea) { const RowStrategyTestdata kTestdata = GetParam(); - SetSuggestions(kTestdata.frontend_ids); + SetSuggestions(kTestdata.popup_item_ids); std::unique_ptr<PopupRowStrategy> strategy = CreateStrategy(kTestdata.strategy_type, kTestdata.line_number); @@ -349,7 +347,7 @@ TEST_P(PopupRowStrategyParametrizedTest, HasControlArea) { const RowStrategyTestdata kTestdata = GetParam(); - SetSuggestions(kTestdata.frontend_ids); + SetSuggestions(kTestdata.popup_item_ids); std::unique_ptr<PopupRowStrategy> strategy = CreateStrategy(kTestdata.strategy_type, kTestdata.line_number);
diff --git a/chrome/browser/ui/views/autofill/popup/popup_row_view.cc b/chrome/browser/ui/views/autofill/popup/popup_row_view.cc index 9d0b09c..a303526 100644 --- a/chrome/browser/ui/views/autofill/popup/popup_row_view.cc +++ b/chrome/browser/ui/views/autofill/popup/popup_row_view.cc
@@ -36,11 +36,11 @@ base::WeakPtr<AutofillPopupController> controller = popup_view.controller(); DCHECK(controller); - Suggestion::FrontendId frontend_id = - controller->GetSuggestionAt(line_number).frontend_id; + PopupItemId popup_item_id = + controller->GetSuggestionAt(line_number).popup_item_id; std::unique_ptr<PopupRowStrategy> strategy; - switch (frontend_id.as_popup_item_id()) { - // These frontend ids should never be displayed in a `PopupRowView`. + switch (popup_item_id) { + // These `popup_item_id` should never be displayed in a `PopupRowView`. case PopupItemId::kSeparator: case PopupItemId::kMixedFormMessage: case PopupItemId::kInsecureContextPaymentDisabledMessage: @@ -53,7 +53,7 @@ line_number); break; default: - if (IsFooterFrontendId(frontend_id.as_popup_item_id())) { + if (IsFooterFrontendId(popup_item_id)) { strategy = std::make_unique<PopupFooterStrategy>(controller, line_number); } else {
diff --git a/chrome/browser/ui/views/autofill/popup/popup_view_views.cc b/chrome/browser/ui/views/autofill/popup/popup_view_views.cc index 932d20f0..dda694f 100644 --- a/chrome/browser/ui/views/autofill/popup/popup_view_views.cc +++ b/chrome/browser/ui/views/autofill/popup/popup_view_views.cc
@@ -90,11 +90,10 @@ // Separators are a special case: They belong into the footer iff the next // item exists and is a footer item. - PopupItemId frontend_id = - suggestions[line_number].frontend_id.as_popup_item_id(); - return frontend_id == PopupItemId::kSeparator + PopupItemId popup_item_id = suggestions[line_number].popup_item_id; + return popup_item_id == PopupItemId::kSeparator ? IsFooterItem(suggestions, line_number + 1) - : IsFooterFrontendId(frontend_id); + : IsFooterFrontendId(popup_item_id); } } // namespace @@ -278,10 +277,10 @@ if (index->second != PopupRowView::CellType::kContent) { return false; } - Suggestion::FrontendId frontend_id = - controller_->GetSuggestionAt(index->first).frontend_id; - if (!base::Contains(kItemsTriggeringFieldFilling, frontend_id) && - frontend_id != PopupItemId::kScanCreditCard) { + PopupItemId popup_item_id = + controller_->GetSuggestionAt(index->first).popup_item_id; + if (!base::Contains(kItemsTriggeringFieldFilling, popup_item_id) && + popup_item_id != PopupItemId::kScanCreditCard) { return false; } } @@ -305,7 +304,7 @@ } bool was_autocomplete = - controller_->GetSuggestionAt(index->first).frontend_id == + controller_->GetSuggestionAt(index->first).popup_item_id == PopupItemId::kAutocompleteEntry; if (!controller_->RemoveSuggestion(index->first)) { return false; @@ -404,9 +403,7 @@ for (; current_line_number < kSuggestions.size() && !IsFooterItem(kSuggestions, current_line_number); ++current_line_number) { - Suggestion::FrontendId frontend_id = - kSuggestions[current_line_number].frontend_id; - switch (frontend_id.as_popup_item_id()) { + switch (kSuggestions[current_line_number].popup_item_id) { case PopupItemId::kSeparator: rows_.push_back(body_container->AddChildView( std::make_unique<PopupSeparatorView>())); @@ -477,7 +474,7 @@ for (; current_line_number < kSuggestions.size(); ++current_line_number) { DCHECK(IsFooterItem(kSuggestions, current_line_number)); // The footer can contain either footer views or separator lines. - if (kSuggestions[current_line_number].frontend_id == + if (kSuggestions[current_line_number].popup_item_id == PopupItemId::kSeparator) { rows_.push_back(footer_container->AddChildView( std::make_unique<PopupSeparatorView>()));
diff --git a/chrome/browser/ui/views/autofill/popup/popup_view_views_browsertest.cc b/chrome/browser/ui/views/autofill/popup/popup_view_views_browsertest.cc index cfcb966..529e3b9 100644 --- a/chrome/browser/ui/views/autofill/popup/popup_view_views_browsertest.cc +++ b/chrome/browser/ui/views/autofill/popup/popup_view_views_browsertest.cc
@@ -35,14 +35,14 @@ std::vector<Suggestion> CreateAutofillProfileSuggestions() { std::vector<Suggestion> suggestions; suggestions.emplace_back("123 Apple St.", "Charles", "accountIcon", - Suggestion::FrontendId(PopupItemId::kAddressEntry)); + PopupItemId::kAddressEntry); suggestions.emplace_back("3734 Elvis Presley Blvd.", "Elvis", "accountIcon", - Suggestion::FrontendId(PopupItemId::kAddressEntry)); + PopupItemId::kAddressEntry); suggestions.emplace_back(PopupItemId::kSeparator); Suggestion settings(l10n_util::GetStringUTF16(IDS_AUTOFILL_MANAGE_ADDRESSES)); - settings.frontend_id = PopupItemId::kAutofillOptions; + settings.popup_item_id = PopupItemId::kAutofillOptions; settings.icon = "settingsIcon"; suggestions.push_back(std::move(settings)); @@ -51,9 +51,9 @@ std::vector<Suggestion> CreateAutocompleteSuggestions() { return {Suggestion("Autocomplete entry 1", "", "", - Suggestion::FrontendId(PopupItemId::kAutocompleteEntry)), + PopupItemId::kAutocompleteEntry), Suggestion("Autocomplete entry 2", "", "", - Suggestion::FrontendId(PopupItemId::kAutocompleteEntry))}; + PopupItemId::kAutocompleteEntry)}; } } // namespace @@ -127,7 +127,7 @@ entry1.main_text.is_primary = Suggestion::Text::IsPrimary(true); entry1.additional_label = std::u16string(10, gfx::RenderText::kPasswordReplacementChar); - entry1.frontend_id = PopupItemId::kAccountStoragePasswordEntry; + entry1.popup_item_id = PopupItemId::kAccountStoragePasswordEntry; entry1.icon = "globeIcon"; entry1.trailing_icon = "google"; suggestions.push_back(std::move(entry1)); @@ -137,7 +137,7 @@ entry2.main_text.is_primary = Suggestion::Text::IsPrimary(true); entry2.additional_label = std::u16string(6, gfx::RenderText::kPasswordReplacementChar); - entry2.frontend_id = PopupItemId::kPasswordEntry; + entry2.popup_item_id = PopupItemId::kPasswordEntry; entry2.icon = "globeIcon"; entry2.trailing_icon = ""; suggestions.push_back(std::move(entry2)); @@ -147,7 +147,7 @@ // The entry to open settings. Suggestion settings( l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_MANAGE_PASSWORDS)); - settings.frontend_id = PopupItemId::kAllSavedPasswordsEntry; + settings.popup_item_id = PopupItemId::kAllSavedPasswordsEntry; settings.icon = "settingsIcon"; settings.trailing_icon = "googlePasswordManager"; suggestions.push_back(std::move(settings)); @@ -160,7 +160,7 @@ InvokeUi_InsecureContext_PaymentDisabled) { Suggestion warning( l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION)); - warning.frontend_id = PopupItemId::kInsecureContextPaymentDisabledMessage; + warning.popup_item_id = PopupItemId::kInsecureContextPaymentDisabledMessage; PrepareSuggestions({std::move(warning)}); ShowAndVerifyUi(); }
diff --git a/chrome/browser/ui/views/autofill/popup/popup_view_views_unittest.cc b/chrome/browser/ui/views/autofill/popup/popup_view_views_unittest.cc index 624b6d31..d03aafb 100644 --- a/chrome/browser/ui/views/autofill/popup/popup_view_views_unittest.cc +++ b/chrome/browser/ui/views/autofill/popup/popup_view_views_unittest.cc
@@ -109,7 +109,7 @@ view().SchedulePaint(); } - void CreateAndShowView(const std::vector<Suggestion::FrontendId>& ids) { + void CreateAndShowView(const std::vector<PopupItemId>& ids) { controller().set_suggestions(ids); CreateAndShowView(); } @@ -208,7 +208,7 @@ }; TEST_F(PopupViewViewsTest, ShowHideTest) { - CreateAndShowView({Suggestion::FrontendId(kAutocompleteEntry)}); + CreateAndShowView({PopupItemId::kAutocompleteEntry}); EXPECT_CALL(controller(), AcceptSuggestion).Times(0); EXPECT_CALL(controller(), AcceptSuggestionWithoutThreshold).Times(0); view().Hide(); @@ -217,8 +217,7 @@ // This is a regression test for crbug.com/1113255. TEST_F(PopupViewViewsTest, ShowViewWithOnlyFooterItemsShouldNotCrash) { // Set suggestions to have only a footer item. - std::vector<Suggestion::FrontendId> suggestion_ids = { - PopupItemId::kClearForm}; + std::vector<PopupItemId> suggestion_ids = {PopupItemId::kClearForm}; controller().set_suggestions(suggestion_ids); CreateAndShowView(); } @@ -420,8 +419,8 @@ } TEST_F(PopupViewViewsTest, MovingSelectionSkipsSeparator) { - CreateAndShowView({Suggestion::FrontendId(PopupItemId::kAddressEntry), - PopupItemId::kSeparator, PopupItemId::kAutofillOptions}); + CreateAndShowView({PopupItemId::kAddressEntry, PopupItemId::kSeparator, + PopupItemId::kAutofillOptions}); view().SetSelectedCell(CellIndex{0u, CellType::kContent}); // Going one down skips the separator. @@ -436,8 +435,7 @@ } TEST_F(PopupViewViewsTest, MovingSelectionSkipsInsecureFormWarning) { - CreateAndShowView({Suggestion::FrontendId(PopupItemId::kAddressEntry), - PopupItemId::kSeparator, + CreateAndShowView({PopupItemId::kAddressEntry, PopupItemId::kSeparator, PopupItemId::kInsecureContextPaymentDisabledMessage}); view().SetSelectedCell(CellIndex{0u, CellType::kContent}); @@ -460,8 +458,8 @@ base::test::ScopedFeatureList feature_list; feature_list.InitAndDisableFeature( features::kAutofillPopupUseThresholdForKeyboardAndMobileAccept); - CreateAndShowView({Suggestion::FrontendId(PopupItemId::kAddressEntry), - PopupItemId::kAutofillOptions}); + CreateAndShowView( + {PopupItemId::kAddressEntry, PopupItemId::kAutofillOptions}); // Select the first item. view().SetSelectedCell(CellIndex{0u, CellType::kContent}); @@ -477,8 +475,8 @@ TEST_F(PopupViewViewsTest, FillContentOnEnterUsesThresholdIfFeatureEnabled) { base::test::ScopedFeatureList feature_list{ features::kAutofillPopupUseThresholdForKeyboardAndMobileAccept}; - CreateAndShowView({Suggestion::FrontendId(PopupItemId::kAddressEntry), - PopupItemId::kAutofillOptions}); + CreateAndShowView( + {PopupItemId::kAddressEntry, PopupItemId::kAutofillOptions}); // Select the first item. view().SetSelectedCell(CellIndex{0u, CellType::kContent}); @@ -498,8 +496,8 @@ base::test::ScopedFeatureList feature_list; feature_list.InitAndDisableFeature( features::kAutofillPopupUseThresholdForKeyboardAndMobileAccept); - CreateAndShowView({Suggestion::FrontendId(PopupItemId::kAddressEntry), - PopupItemId::kAutofillOptions}); + CreateAndShowView( + {PopupItemId::kAddressEntry, PopupItemId::kAutofillOptions}); // Select the first item. view().SetSelectedCell(CellIndex{0u, CellType::kContent}); @@ -515,8 +513,8 @@ TEST_F(PopupViewViewsTest, FillOnTabPressedUsesThresholdIfFeatureEnabled) { base::test::ScopedFeatureList feature_list{ features::kAutofillPopupUseThresholdForKeyboardAndMobileAccept}; - CreateAndShowView({Suggestion::FrontendId(PopupItemId::kAddressEntry), - PopupItemId::kAutofillOptions}); + CreateAndShowView( + {PopupItemId::kAddressEntry, PopupItemId::kAutofillOptions}); // Select the first item. view().SetSelectedCell(CellIndex{0u, CellType::kContent}); @@ -530,8 +528,8 @@ } TEST_F(PopupViewViewsTest, NoFillOnTabPressedWithModifiers) { - CreateAndShowView({Suggestion::FrontendId(PopupItemId::kAddressEntry), - PopupItemId::kAutofillOptions}); + CreateAndShowView( + {PopupItemId::kAddressEntry, PopupItemId::kAutofillOptions}); // Select the first item. view().SetSelectedCell(CellIndex{0u, CellType::kContent}); @@ -551,8 +549,8 @@ // a tab with the autofill settings). TEST_F(PopupViewViewsTest, NoAutofillOptionsTriggeredOnTabPressed) { // Set up the popup and select the options cell. - CreateAndShowView({Suggestion::FrontendId(PopupItemId::kAddressEntry), - PopupItemId::kSeparator, PopupItemId::kAutofillOptions}); + CreateAndShowView({PopupItemId::kAddressEntry, PopupItemId::kSeparator, + PopupItemId::kAutofillOptions}); view().SetSelectedCell(CellIndex{2u, CellType::kContent}); EXPECT_EQ(view().GetSelectedCell(), absl::make_optional<CellIndex>(2u, CellType::kContent)); @@ -567,8 +565,8 @@ // This is a regression test for crbug.com/1309431 to ensure that we don't crash // when we press tab before a line is selected. TEST_F(PopupViewViewsTest, TabBeforeSelectingALine) { - CreateAndShowView({Suggestion::FrontendId(PopupItemId::kAddressEntry), - PopupItemId::kSeparator, PopupItemId::kAutofillOptions}); + CreateAndShowView({PopupItemId::kAddressEntry, PopupItemId::kSeparator, + PopupItemId::kAutofillOptions}); EXPECT_FALSE(view().GetSelectedCell().has_value()); // The following should not crash: @@ -576,8 +574,7 @@ } TEST_F(PopupViewViewsTest, RemoveLine) { - CreateAndShowView({Suggestion::FrontendId(PopupItemId::kAddressEntry), - Suggestion::FrontendId(PopupItemId::kAddressEntry), + CreateAndShowView({PopupItemId::kAddressEntry, PopupItemId::kAddressEntry, PopupItemId::kAutofillOptions}); // If no cell is selected, pressing delete has no effect. @@ -601,8 +598,7 @@ TEST_F(PopupViewViewsTest, RemoveAutofillRecordsNoAutocompleteDeletionMetrics) { base::HistogramTester histogram_tester; - CreateAndShowView({Suggestion::FrontendId(PopupItemId::kAddressEntry), - Suggestion::FrontendId(PopupItemId::kAddressEntry), + CreateAndShowView({PopupItemId::kAddressEntry, PopupItemId::kAddressEntry, PopupItemId::kAutofillOptions}); view().SetSelectedCell(CellIndex{1u, CellType::kContent}); @@ -650,7 +646,7 @@ suggestion.labels = {{Suggestion::Text(u"example.com")}}; suggestion.voice_over = voice_over_value; suggestion.additional_label = u"\u2022\u2022\u2022\u2022"; - suggestion.frontend_id = PopupItemId::kUsernameEntry; + suggestion.popup_item_id = PopupItemId::kUsernameEntry; // Create autofill menu. controller().set_suggestions({suggestion});
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h index 77825f4..339c01f4 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h +++ b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h
@@ -186,11 +186,11 @@ // an id. int GetAndIncrementNextMenuID(); - const raw_ptr<Browser> browser_; - raw_ptr<Profile> profile_; + const raw_ptr<Browser, LeakedDanglingUntriaged> browser_; + raw_ptr<Profile, LeakedDanglingUntriaged> profile_; // Parent of menus. - raw_ptr<views::Widget> parent_; + raw_ptr<views::Widget, LeakedDanglingUntriaged> parent_; // Maps from menu id to BookmarkNode. MenuIDToNodeMap menu_id_to_node_map_;
diff --git a/chrome/browser/ui/views/commerce/price_tracking_view.h b/chrome/browser/ui/views/commerce/price_tracking_view.h index c475ac0..196be29 100644 --- a/chrome/browser/ui/views/commerce/price_tracking_view.h +++ b/chrome/browser/ui/views/commerce/price_tracking_view.h
@@ -34,7 +34,7 @@ raw_ptr<views::Label> body_label_; raw_ptr<views::ToggleButton> toggle_button_; - raw_ptr<Profile> profile_; + raw_ptr<Profile, LeakedDanglingUntriaged> profile_; bool is_price_track_enabled_; base::WeakPtrFactory<PriceTrackingView> weak_ptr_factory_{this};
diff --git a/chrome/browser/ui/views/download/bubble/download_bubble_contents_view.cc b/chrome/browser/ui/views/download/bubble/download_bubble_contents_view.cc new file mode 100644 index 0000000..4755516 --- /dev/null +++ b/chrome/browser/ui/views/download/bubble/download_bubble_contents_view.cc
@@ -0,0 +1,99 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/download/bubble/download_bubble_contents_view.h" + +#include <utility> + +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/download/bubble/download_bubble_partial_view.h" +#include "chrome/browser/ui/views/download/bubble/download_bubble_row_list_view.h" +#include "chrome/browser/ui/views/download/bubble/download_bubble_security_view.h" +#include "chrome/browser/ui/views/download/bubble/download_dialog_view.h" +#include "chrome/browser/ui/views/download/bubble/download_toolbar_button_view.h" +#include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/views/layout/flex_layout.h" +#include "ui/views/layout/layout_provider.h" +#include "ui/views/layout/layout_types.h" +#include "ui/views/view.h" + +DownloadBubbleContentsView::DownloadBubbleContentsView( + base::WeakPtr<Browser> browser, + base::WeakPtr<DownloadBubbleUIController> bubble_controller, + base::WeakPtr<DownloadBubbleNavigationHandler> navigation_handler, + bool primary_view_is_partial_view, + std::vector<DownloadUIModel::DownloadUIModelPtr> primary_view_models, + views::BubbleDialogDelegate* bubble_delegate) + : primary_view_row_count_(primary_view_models.size()) { + SetLayoutManager(std::make_unique<views::FlexLayout>()) + ->SetOrientation(views::LayoutOrientation::kVertical); + + std::unique_ptr<views::View> primary_view; + if (primary_view_is_partial_view) { + primary_view = DownloadBubblePartialView::Create( + browser, bubble_controller, navigation_handler, + std::move(primary_view_models), + base::BindOnce(&DownloadBubbleNavigationHandler::OnDialogInteracted, + navigation_handler)); + } else { + std::unique_ptr<views::View> rows_with_scroll = + DownloadBubbleRowListView::CreateWithScroll( + /*is_partial_view=*/false, browser, bubble_controller, + navigation_handler, std::move(primary_view_models), + ChromeLayoutProvider::Get()->GetDistanceMetric( + views::DISTANCE_BUBBLE_PREFERRED_WIDTH)); + primary_view = std::make_unique<DownloadDialogView>( + browser, std::move(rows_with_scroll), navigation_handler); + } + // The primary view can be null if there are no rows. + if (!primary_view) { + CHECK_EQ(primary_view_row_count_, 0); + primary_view = std::make_unique<views::View>(); + } + + primary_view_ = AddChildView(std::move(primary_view)); + security_view_ = AddChildView(std::make_unique<DownloadBubbleSecurityView>( + bubble_controller, navigation_handler, bubble_delegate)); + + // Starts on the primary page. + SwitchToCurrentPage(); +} + +DownloadBubbleContentsView::~DownloadBubbleContentsView() = default; + +void DownloadBubbleContentsView::ShowPage(Page page) { + if (page_ == page) { + return; + } + page_ = page; + SwitchToCurrentPage(); +} + +DownloadBubbleContentsView::Page DownloadBubbleContentsView::VisiblePage() + const { + return page_; +} + +void DownloadBubbleContentsView::UpdateSecurityView( + DownloadBubbleRowView* row) { + security_view_->UpdateSecurityView(row); +} + +void DownloadBubbleContentsView::SwitchToCurrentPage() { + primary_view_->SetVisible(false); + security_view_->SetVisible(false); + + switch (page_) { + case Page::kPrimary: + primary_view_->SetVisible(true); + break; + case Page::kSecurity: + security_view_->UpdateAccessibilityTextAndFocus(); + security_view_->SetVisible(true); + break; + } +} + +BEGIN_METADATA(DownloadBubbleContentsView, views::View) +END_METADATA
diff --git a/chrome/browser/ui/views/download/bubble/download_bubble_contents_view.h b/chrome/browser/ui/views/download/bubble/download_bubble_contents_view.h new file mode 100644 index 0000000..ab94a3d --- /dev/null +++ b/chrome/browser/ui/views/download/bubble/download_bubble_contents_view.h
@@ -0,0 +1,83 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_DOWNLOAD_BUBBLE_DOWNLOAD_BUBBLE_CONTENTS_VIEW_H_ +#define CHROME_BROWSER_UI_VIEWS_DOWNLOAD_BUBBLE_DOWNLOAD_BUBBLE_CONTENTS_VIEW_H_ + +#include "base/memory/raw_ptr.h" +#include "base/memory/weak_ptr.h" +#include "chrome/browser/download/download_ui_model.h" +#include "ui/base/metadata/metadata_header_macros.h" +#include "ui/views/view.h" + +class Browser; +class DownloadBubbleNavigationHandler; +class DownloadBubbleRowView; +class DownloadBubbleSecurityView; +class DownloadBubbleUIController; + +namespace views { +class BubbleDialogDelegate; +} // namespace views + +// View that contains the contents of the download bubble. Owns and allows +// switching between a primary page (either the "main" or "partial" view, +// containing the download item rows), or the security page (which shows +// warnings if applicable). Always opens up to the primary view by default, +// before possibly being switched to the security view. +class DownloadBubbleContentsView : public views::View { + public: + // Types of pages that this view can show. + enum class Page { + kPrimary, + kSecurity, + }; + + METADATA_HEADER(DownloadBubbleContentsView); + + DownloadBubbleContentsView( + base::WeakPtr<Browser> browser, + base::WeakPtr<DownloadBubbleUIController> bubble_controller, + base::WeakPtr<DownloadBubbleNavigationHandler> navigation_handler, + // Whether the primary view is the partial view. + bool primary_view_is_partial_view, + // Models for rows that should go in the primary view. + std::vector<DownloadUIModel::DownloadUIModelPtr> primary_view_models, + // The owning bubble's delegate. + views::BubbleDialogDelegate* bubble_delegate); + ~DownloadBubbleContentsView() override; + + DownloadBubbleContentsView(const DownloadBubbleContentsView&) = delete; + DownloadBubbleContentsView& operator=(const DownloadBubbleContentsView&) = + delete; + + // Switches to the requested page by showing the page and hiding all other + // pages. + void ShowPage(Page page); + + // Which page is currently visible. + Page VisiblePage() const; + + // Forwards to `security_view_`. (Does not switch to the security view.) + void UpdateSecurityView(DownloadBubbleRowView* row); + + private: + // Switches to the page that should currently be showing. + void SwitchToCurrentPage(); + + // May be a DownloadBubblePartialView or a DownloadDialogView (main view). + // TODO(crbug.com/1450660): Make them inherit from a shared subclass of View. + raw_ptr<views::View> primary_view_ = nullptr; + // The security view is hidden by default but may be switched to. + raw_ptr<DownloadBubbleSecurityView> security_view_ = nullptr; + + // Number of download rows in the primary view. + // TODO(crbug.com/1450660): Expose this value. + int primary_view_row_count_ = 0; + + // The currently visible page. + Page page_ = Page::kPrimary; +}; + +#endif // CHROME_BROWSER_UI_VIEWS_DOWNLOAD_BUBBLE_DOWNLOAD_BUBBLE_CONTENTS_VIEW_H_
diff --git a/chrome/browser/ui/views/download/bubble/download_bubble_security_view_unittest.cc b/chrome/browser/ui/views/download/bubble/download_bubble_security_view_unittest.cc index 5dfbd01b..b54dab8 100644 --- a/chrome/browser/ui/views/download/bubble/download_bubble_security_view_unittest.cc +++ b/chrome/browser/ui/views/download/bubble/download_bubble_security_view_unittest.cc
@@ -47,6 +47,7 @@ void OpenSecurityDialog(DownloadBubbleRowView*) override {} void CloseDialog(views::Widget::ClosedReason) override {} void ResizeDialog() override {} + void OnDialogInteracted() override {} base::WeakPtr<DownloadBubbleNavigationHandler> GetWeakPtr() override { return weak_factory_.GetWeakPtr(); }
diff --git a/chrome/browser/ui/views/download/bubble/download_dialog_view.cc b/chrome/browser/ui/views/download/bubble/download_dialog_view.cc index 172ff1ad..df2d98c 100644 --- a/chrome/browser/ui/views/download/bubble/download_dialog_view.cc +++ b/chrome/browser/ui/views/download/bubble/download_dialog_view.cc
@@ -109,12 +109,16 @@ } // namespace void DownloadDialogView::CloseBubble() { - navigation_handler_->CloseDialog( - views::Widget::ClosedReason::kCloseButtonClicked); + if (navigation_handler_) { + navigation_handler_->CloseDialog( + views::Widget::ClosedReason::kCloseButtonClicked); + } } void DownloadDialogView::ShowAllDownloads() { - chrome::ShowDownloads(browser_); + if (browser_) { + chrome::ShowDownloads(browser_.get()); + } } void DownloadDialogView::AddHeader() { @@ -154,10 +158,11 @@ } DownloadDialogView::DownloadDialogView( - Browser* browser, + base::WeakPtr<Browser> browser, std::unique_ptr<views::View> row_list_scroll_view, - DownloadBubbleNavigationHandler* navigation_handler) - : navigation_handler_(navigation_handler), browser_(browser) { + base::WeakPtr<DownloadBubbleNavigationHandler> navigation_handler) + : navigation_handler_(std::move(navigation_handler)), + browser_(std::move(browser)) { SetLayoutManager(std::make_unique<views::FlexLayout>()) ->SetOrientation(views::LayoutOrientation::kVertical); AddHeader(); @@ -165,5 +170,7 @@ AddFooter(); } +DownloadDialogView::~DownloadDialogView() = default; + BEGIN_METADATA(DownloadDialogView, views::View) END_METADATA
diff --git a/chrome/browser/ui/views/download/bubble/download_dialog_view.h b/chrome/browser/ui/views/download/bubble/download_dialog_view.h index 0cef7a0..279d59d7 100644 --- a/chrome/browser/ui/views/download/bubble/download_dialog_view.h +++ b/chrome/browser/ui/views/download/bubble/download_dialog_view.h
@@ -5,7 +5,7 @@ #ifndef CHROME_BROWSER_UI_VIEWS_DOWNLOAD_BUBBLE_DOWNLOAD_DIALOG_VIEW_H_ #define CHROME_BROWSER_UI_VIEWS_DOWNLOAD_BUBBLE_DOWNLOAD_DIALOG_VIEW_H_ -#include "base/memory/raw_ptr.h" +#include "base/memory/weak_ptr.h" #include "chrome/browser/ui/views/download/bubble/download_bubble_row_list_view.h" #include "chrome/browser/ui/views/download/bubble/download_toolbar_button_view.h" #include "ui/base/metadata/metadata_header_macros.h" @@ -14,15 +14,21 @@ class Browser; +// This view represents the 'main view' that is shown when the user clicks on +// the download toolbar button. Unlike the partial view, it does not +// automatically close. It also has a header and close button, as well as a +// footer with a link to chrome://downloads. class DownloadDialogView : public views::View { public: METADATA_HEADER(DownloadDialogView); DownloadDialogView(const DownloadDialogView&) = delete; DownloadDialogView& operator=(const DownloadDialogView&) = delete; - DownloadDialogView(Browser* browser, - std::unique_ptr<views::View> row_list_scroll_view, - DownloadBubbleNavigationHandler* navigation_handler); + DownloadDialogView( + base::WeakPtr<Browser> browser, + std::unique_ptr<views::View> row_list_scroll_view, + base::WeakPtr<DownloadBubbleNavigationHandler> navigation_handler); + ~DownloadDialogView() override; private: void CloseBubble(); @@ -30,8 +36,8 @@ void AddHeader(); void AddFooter(); - raw_ptr<DownloadBubbleNavigationHandler> navigation_handler_ = nullptr; - raw_ptr<Browser> browser_ = nullptr; + base::WeakPtr<DownloadBubbleNavigationHandler> navigation_handler_; + base::WeakPtr<Browser> browser_; }; #endif // CHROME_BROWSER_UI_VIEWS_DOWNLOAD_BUBBLE_DOWNLOAD_DIALOG_VIEW_H_
diff --git a/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.cc b/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.cc index 289d4474..4a70d7d 100644 --- a/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.cc +++ b/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.cc
@@ -30,12 +30,10 @@ #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/accessibility/non_accessible_image_view.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" -#include "chrome/browser/ui/views/download/bubble/download_bubble_partial_view.h" +#include "chrome/browser/ui/views/download/bubble/download_bubble_contents_view.h" #include "chrome/browser/ui/views/download/bubble/download_bubble_row_list_view.h" #include "chrome/browser/ui/views/download/bubble/download_bubble_row_view.h" -#include "chrome/browser/ui/views/download/bubble/download_bubble_security_view.h" #include "chrome/browser/ui/views/download/bubble/download_bubble_started_animation_views.h" -#include "chrome/browser/ui/views/download/bubble/download_dialog_view.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/grit/generated_resources.h" @@ -341,7 +339,7 @@ if (create_auto_close_timer_ && !auto_close_bubble_timer_) { CreateAutoCloseTimer(); } - CreateBubbleDialogDelegate(GetPrimaryView()); + CreateBubbleDialogDelegate(); } if (auto_close_bubble_timer_) { auto_close_bubble_timer_->Reset(); @@ -436,30 +434,17 @@ return false; } -std::unique_ptr<views::View> DownloadToolbarButtonView::GetPrimaryView() { - if (is_primary_partial_view_) { - return DownloadBubblePartialView::Create( - browser_->AsWeakPtr(), bubble_controller_->GetWeakPtr(), GetWeakPtr(), - bubble_controller_->GetPartialView(), - base::BindOnce(&DownloadToolbarButtonView::DeactivateAutoClose, - base::Unretained(this))); - } - - std::unique_ptr<views::View> rows_with_scroll = - DownloadBubbleRowListView::CreateWithScroll( - /*is_partial_view=*/false, browser_->AsWeakPtr(), - bubble_controller_->GetWeakPtr(), GetWeakPtr(), - bubble_controller_->GetMainView(), - ChromeLayoutProvider::Get()->GetDistanceMetric( - views::DISTANCE_BUBBLE_PREFERRED_WIDTH)); - // raw ptr is safe as the toolbar view owns the bubble. - return std::make_unique<DownloadDialogView>( - browser_, std::move(rows_with_scroll), this); +std::vector<DownloadUIModel::DownloadUIModelPtr> +DownloadToolbarButtonView::GetPrimaryViewModels() { + return is_primary_partial_view_ ? bubble_controller_->GetPartialView() + : bubble_controller_->GetMainView(); } void DownloadToolbarButtonView::OpenPrimaryDialog() { - primary_view_->SetVisible(true); - security_view_->SetVisible(false); + if (!bubble_delegate_) { + return; + } + bubble_contents_->ShowPage(DownloadBubbleContentsView::Page::kPrimary); bubble_delegate_->SetButtons(ui::DIALOG_BUTTON_NONE); bubble_delegate_->SetDefaultButton(ui::DIALOG_BUTTON_NONE); bubble_delegate_->set_margins(GetPrimaryViewMargin()); @@ -468,11 +453,12 @@ void DownloadToolbarButtonView::OpenSecurityDialog( DownloadBubbleRowView* download_row_view) { - security_view_->UpdateSecurityView(download_row_view); - primary_view_->SetVisible(false); - security_view_->SetVisible(true); + if (!bubble_delegate_) { + return; + } + bubble_contents_->UpdateSecurityView(download_row_view); + bubble_contents_->ShowPage(DownloadBubbleContentsView::Page::kSecurity); bubble_delegate_->set_margins(GetSecurityViewMargin()); - security_view_->UpdateAccessibilityTextAndFocus(); ResizeDialog(); } @@ -489,6 +475,10 @@ bubble_delegate_->SizeToContents(); } +void DownloadToolbarButtonView::OnDialogInteracted() { + DeactivateAutoClose(); +} + base::WeakPtr<DownloadBubbleNavigationHandler> DownloadToolbarButtonView::GetWeakPtr() { return weak_factory_.GetWeakPtr(); @@ -497,14 +487,15 @@ void DownloadToolbarButtonView::OnBubbleClosing() { immersive_revealed_lock_.reset(); bubble_delegate_ = nullptr; - primary_view_ = nullptr; - security_view_ = nullptr; + bubble_contents_ = nullptr; } -void DownloadToolbarButtonView::CreateBubbleDialogDelegate( - std::unique_ptr<View> bubble_contents_view) { - if (!bubble_contents_view) +void DownloadToolbarButtonView::CreateBubbleDialogDelegate() { + std::vector<DownloadUIModel::DownloadUIModelPtr> primary_view_models = + GetPrimaryViewModels(); + if (primary_view_models.empty()) { return; + } // If the IPH is showing, close it to avoid showing the download dialog over // it. browser_->window()->CloseFeaturePromo( @@ -520,18 +511,13 @@ bubble_delegate->SetDefaultButton(ui::DIALOG_BUTTON_NONE); bubble_delegate->RegisterWindowClosingCallback(base::BindOnce( &DownloadToolbarButtonView::OnBubbleClosing, weak_factory_.GetWeakPtr())); - auto* switcher_view = - bubble_delegate->SetContentsView(std::make_unique<views::View>()); - switcher_view->SetLayoutManager(std::make_unique<views::FlexLayout>()) - ->SetOrientation(views::LayoutOrientation::kVertical); - primary_view_ = switcher_view->AddChildView(std::move(bubble_contents_view)); - // raw ptr for this bubble_delegate is safe as it owns the - // DownloadBubbleSecurityView. - security_view_ = - switcher_view->AddChildView(std::make_unique<DownloadBubbleSecurityView>( - bubble_controller_->GetWeakPtr(), GetWeakPtr(), - bubble_delegate.get())); - security_view_->SetVisible(false); + auto bubble_contents = std::make_unique<DownloadBubbleContentsView>( + browser_->AsWeakPtr(), bubble_controller_->GetWeakPtr(), GetWeakPtr(), + is_primary_partial_view_, std::move(primary_view_models), + bubble_delegate.get()); + bubble_contents_ = bubble_contents.get(); + bubble_delegate->SetContentsView(std::move(bubble_contents)); + // The contents view displays the primary view by default. bubble_delegate->set_margins(GetPrimaryViewMargin()); bubble_delegate->SetEnableArrowKeyTraversal(true); bubble_delegate_ = bubble_delegate.get(); @@ -595,10 +581,20 @@ } void DownloadToolbarButtonView::AutoClosePartialView() { + // Nothing to do if the bubble is not open. + if (!bubble_contents_) { + return; + } + // Don't close the security page. + if (bubble_contents_->VisiblePage() == + DownloadBubbleContentsView::Page::kSecurity) { + return; + } if (!is_primary_partial_view_ || !auto_close_bubble_timer_) { return; } - if (primary_view_ && primary_view_->IsMouseHovered()) { + // Don't close if the user is hovering over the bubble. + if (bubble_contents_->IsMouseHovered()) { return; } HideDetails(); @@ -611,7 +607,7 @@ void DownloadToolbarButtonView::ButtonPressed() { if (!bubble_delegate_) { is_primary_partial_view_ = false; - CreateBubbleDialogDelegate(GetPrimaryView()); + CreateBubbleDialogDelegate(); } controller_->OnButtonPressed(); }
diff --git a/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.h b/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.h index 902932d..d66a2cb2 100644 --- a/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.h +++ b/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.h
@@ -24,9 +24,9 @@ class Browser; class BrowserView; class DownloadDisplayController; +class DownloadBubbleContentsView; class DownloadBubbleUIController; class DownloadBubbleRowView; -class DownloadBubbleSecurityView; class DownloadBubbleNavigationHandler { public: @@ -35,6 +35,9 @@ virtual void OpenSecurityDialog(DownloadBubbleRowView* download_row_view) = 0; virtual void CloseDialog(views::Widget::ClosedReason reason) = 0; virtual void ResizeDialog() = 0; + // Callback invoked when the dialog has been interacted with by hovering over + // or by focusing (on the partial view). + virtual void OnDialogInteracted() = 0; virtual base::WeakPtr<DownloadBubbleNavigationHandler> GetWeakPtr() = 0; }; @@ -79,6 +82,7 @@ void OpenSecurityDialog(DownloadBubbleRowView* download_row_view) override; void CloseDialog(views::Widget::ClosedReason reason) override; void ResizeDialog() override; + void OnDialogInteracted() override; base::WeakPtr<DownloadBubbleNavigationHandler> GetWeakPtr() override; // BrowserListObserver @@ -118,7 +122,7 @@ SkColor badge_text_color); void ButtonPressed(); - void CreateBubbleDialogDelegate(std::unique_ptr<View> bubble_contents_view); + void CreateBubbleDialogDelegate(); void OnBubbleClosing(); // Callback invoked when the partial view is closed. @@ -131,8 +135,9 @@ // been deactivated. void AutoClosePartialView(); - // Get the primary view, which may be the full or the partial view. - std::unique_ptr<View> GetPrimaryView(); + // Get the models for the primary view, which may be the full or the partial + // view. + std::vector<DownloadUIModel::DownloadUIModelPtr> GetPrimaryViewModels(); // If |has_pending_download_started_animation_| is true, shows an animation of // a download icon moving upwards towards the toolbar icon. @@ -147,8 +152,7 @@ // Controller for keeping track of items for both main view and partial view. std::unique_ptr<DownloadBubbleUIController> bubble_controller_; raw_ptr<views::BubbleDialogDelegate> bubble_delegate_ = nullptr; - raw_ptr<View> primary_view_ = nullptr; - raw_ptr<DownloadBubbleSecurityView> security_view_ = nullptr; + raw_ptr<DownloadBubbleContentsView> bubble_contents_ = nullptr; // Marks whether there is a pending download started animation. This is needed // because the animation should only be triggered after the view has been
diff --git a/chrome/browser/ui/views/location_bar/location_bar_util.cc b/chrome/browser/ui/views/location_bar/location_bar_util.cc index 4cdf6fb..230475e 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_util.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_util.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/views/location_bar/location_bar_util.h" #include "chrome/browser/ui/color/chrome_color_id.h" +#include "components/omnibox/browser/omnibox_field_trial.h" #include "ui/base/ui_base_features.h" #include "ui/views/animation/flood_fill_ink_drop_ripple.h" #include "ui/views/animation/ink_drop.h" @@ -15,7 +16,9 @@ void ConfigureInkDropForRefresh2023(views::View* const host, const ChromeColorIds hover_color_id, const ChromeColorIds ripple_color_id) { - CHECK(features::IsChromeRefresh2023()); + // TODO(crbug.com/1450984): Figure out if one of these are redundant. + CHECK(features::IsChromeRefresh2023() || + OmniboxFieldTrial::IsChromeRefreshIconsEnabled()); views::InkDrop::Get(host)->SetMode(views::InkDropHost::InkDropMode::ON); views::InkDrop::Get(host)->SetLayerRegion(views::LayerRegion::kAbove);
diff --git a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view_browsertest.cc b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view_browsertest.cc index 6393d39..10a3976c 100644 --- a/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view_browsertest.cc +++ b/chrome/browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view_browsertest.cc
@@ -44,6 +44,9 @@ if (name == "Notice") { prompt_type = PrivacySandboxService::PromptType::kNotice; } + if (name == "RestrictedNotice") { + prompt_type = PrivacySandboxService::PromptType::kM1NoticeRestricted; + } ASSERT_NE(prompt_type, PrivacySandboxService::PromptType::kNone); // Resize the browser window to guarantee enough space for the dialog.
diff --git a/chrome/browser/ui/views/tabs/fake_tab_slot_controller.h b/chrome/browser/ui/views/tabs/fake_tab_slot_controller.h index 99ec61bf..20580ec 100644 --- a/chrome/browser/ui/views/tabs/fake_tab_slot_controller.h +++ b/chrome/browser/ui/views/tabs/fake_tab_slot_controller.h
@@ -110,7 +110,7 @@ } private: - raw_ptr<TabStripController> tab_strip_controller_; + raw_ptr<TabStripController, LeakedDanglingUntriaged> tab_strip_controller_; raw_ptr<TabContainer, DanglingUntriaged> tab_container_; ui::ListSelectionModel selection_model_; raw_ptr<Tab, DanglingUntriaged> active_tab_ = nullptr;
diff --git a/chrome/browser/ui/views/user_education/browser_user_education_service.cc b/chrome/browser/ui/views/user_education/browser_user_education_service.cc index 004cbf7..9b60fd6b 100644 --- a/chrome/browser/ui/views/user_education/browser_user_education_service.cc +++ b/chrome/browser/ui/views/user_education/browser_user_education_service.cc
@@ -526,6 +526,27 @@ if (tutorial_registry.IsTutorialRegistered(kTabGroupTutorialId)) return; + { // Menu item bubble test. + TutorialDescription test_description; + test_description.steps.emplace_back( + TutorialDescription::BubbleStep(kAppMenuButtonElementId) + .SetBubbleBodyText(IDS_OK) + .SetBubbleArrow(HelpBubbleArrow::kTopRight)); + test_description.steps.emplace_back( + TutorialDescription::BubbleStep(AppMenuModel::kDownloadsMenuItem) + .SetBubbleBodyText(IDS_OK) + .SetBubbleArrow(HelpBubbleArrow::kRightCenter)); + test_description.steps.emplace_back( + TutorialDescription::HiddenStep::WaitForHidden( + AppMenuModel::kDownloadsMenuItem)); + test_description.steps.emplace_back( + TutorialDescription::BubbleStep(kTopContainerElementId) + .SetBubbleBodyText(IDS_OK) + .SetBubbleArrow(HelpBubbleArrow::kNone)); + tutorial_registry.AddTutorial("Menu item bubble test tutorial", + std::move(test_description)); + } + { // Tab Group Tutorials // The Description for kTabGroupTutorialId.
diff --git a/chrome/browser/ui/views/user_education/help_bubble_view_interactive_uitest.cc b/chrome/browser/ui/views/user_education/help_bubble_view_interactive_uitest.cc index 72215f8..4f839b5 100644 --- a/chrome/browser/ui/views/user_education/help_bubble_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/user_education/help_bubble_view_interactive_uitest.cc
@@ -176,3 +176,47 @@ PressButton(HelpBubbleView::kDefaultButtonIdForTesting), WaitForHide(HelpBubbleView::kHelpBubbleElementIdForTesting)); } + +// This is a combined test for both help bubbles anchored to menus and menu +// annotation. +// +// This test does work on Linux, however, because of the way events are routed +// on Wayland specifically (and on Linux in general) the test itself isn't +// reliable on Linux. It has been manually tested, and based on the way the +// annotation event routing works, if it did not work (a) it would not work on +// any platform, and (b) it would not be possible to close a menu by clicking +// away from it and into e.g. the omnibox. +#if !BUILDFLAG(IS_LINUX) +IN_PROC_BROWSER_TEST_F(HelpBubbleViewInteractiveUiTest, AnnotateMenu) { + UNCALLED_MOCK_CALLBACK(base::OnceClosure, default_button_clicked); + constexpr char16_t kButton1Text[] = u"button 1"; + + user_education::HelpBubbleParams params = GetBubbleParams(); + + params.arrow = user_education::HelpBubbleArrow::kRightCenter; + + user_education::HelpBubbleButtonParams button1; + button1.text = kButton1Text; + button1.is_default = true; + button1.callback = default_button_clicked.Get(); + params.buttons.emplace_back(std::move(button1)); + + EXPECT_CALL(default_button_clicked, Run).Times(1); + + RunTestSequence( + // Show the application menu and attach a bubble to a menu item. + PressButton(kAppMenuButtonElementId), + ShowHelpBubble(AppMenuModel::kDownloadsMenuItem, std::move(params)), + + // Hover the default button and verify that the inkdrop is highlighted. + MoveMouseTo(HelpBubbleView::kDefaultButtonIdForTesting), + + // TODO(dfried): figure out if we can determine if an inkdrop is in a + // hovered state; currently that information can't be accessed. + + // Click the default button and verify that the help bubble closes but the + // menu does not. + ClickMouse(), WaitForHide(HelpBubbleView::kHelpBubbleElementIdForTesting), + EnsurePresent(AppMenuModel::kDownloadsMenuItem)); +} +#endif
diff --git a/chrome/browser/ui/views/waffle/DIR_METADATA b/chrome/browser/ui/views/waffle/DIR_METADATA new file mode 100644 index 0000000..6cfbfc2 --- /dev/null +++ b/chrome/browser/ui/views/waffle/DIR_METADATA
@@ -0,0 +1 @@ +mixins: "//chrome/browser/ui/waffle/COMMON_METADATA"
diff --git a/chrome/browser/ui/views/waffle/OWNERS b/chrome/browser/ui/views/waffle/OWNERS new file mode 100644 index 0000000..55c6bfb --- /dev/null +++ b/chrome/browser/ui/views/waffle/OWNERS
@@ -0,0 +1 @@ +file://chrome/browser/ui/waffle/OWNERS
diff --git a/chrome/browser/ui/views/waffle/waffle_dialog_view.cc b/chrome/browser/ui/views/waffle/waffle_dialog_view.cc new file mode 100644 index 0000000..686becd --- /dev/null +++ b/chrome/browser/ui/views/waffle/waffle_dialog_view.cc
@@ -0,0 +1,78 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/waffle/waffle_dialog_view.h" + +#include "base/feature_list.h" +#include "base/functional/bind.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/signin/signin_features.h" +#include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/browser/ui/views/frame/toolbar_button_provider.h" +#include "chrome/browser/ui/waffle/waffle_tab_helper.h" +#include "chrome/browser/ui/webui/waffle/waffle_ui.h" +#include "chrome/common/webui_url_constants.h" +#include "components/constrained_window/constrained_window_views.h" +#include "components/web_modal/web_contents_modal_dialog_host.h" +#include "ui/base/metadata/metadata_impl_macros.h" + +namespace { +// Temporary until the mocks are ready. +constexpr int kDialogWidth = 512; +constexpr int kDialogHeight = 569; +} // namespace + +void ShowWaffleDialog(Browser& browser) { + auto delegate = std::make_unique<views::DialogDelegate>(); + delegate->SetButtons(ui::DIALOG_BUTTON_NONE); + delegate->SetModalType(ui::MODAL_TYPE_WINDOW); + delegate->SetShowCloseButton(true); + delegate->SetOwnedByWidget(true); + + auto waffleDialogView = std::make_unique<WaffleDialogView>(&browser); + waffleDialogView->Initialize(); + delegate->SetContentsView(std::move(waffleDialogView)); + + constrained_window::CreateBrowserModalDialogViews( + std::move(delegate), browser.window()->GetNativeWindow()); +} + +WaffleDialogView::WaffleDialogView(Browser* browser) : browser_(browser) { + CHECK(base::FeatureList::IsEnabled(kWaffle)); + // Create the web view in the native dialog. + web_view_ = + AddChildView(std::make_unique<views::WebView>(browser->profile())); +} + +void WaffleDialogView::Initialize() { + web_view_->LoadInitialURL(GURL(chrome::kChromeUIWaffleURL)); + + const int max_width = browser_->window() + ->GetWebContentsModalDialogHost() + ->GetMaximumDialogSize() + .width(); + const int width = + views::LayoutProvider::Get()->GetSnappedDialogWidth(kDialogWidth); + web_view_->SetPreferredSize( + gfx::Size(std::min(width, max_width), kDialogHeight)); + + auto* web_ui = web_view_->GetWebContents() + ->GetWebUI() + ->GetController() + ->GetAs<WaffleUI>(); + CHECK(web_ui); + // Unretained is fine because this outlives the inner web UI. + web_ui->Initialize(base::BindOnce(&WaffleDialogView::ShowNativeView, + base::Unretained(this))); + + SetUseDefaultFillLayout(true); +} + +void WaffleDialogView::ShowNativeView() { + GetWidget()->Show(); + web_view_->RequestFocus(); +} + +BEGIN_METADATA(WaffleDialogView, views::View) +END_METADATA
diff --git a/chrome/browser/ui/views/waffle/waffle_dialog_view.h b/chrome/browser/ui/views/waffle/waffle_dialog_view.h new file mode 100644 index 0000000..d49a5da --- /dev/null +++ b/chrome/browser/ui/views/waffle/waffle_dialog_view.h
@@ -0,0 +1,35 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_WAFFLE_WAFFLE_DIALOG_VIEW_H_ +#define CHROME_BROWSER_UI_VIEWS_WAFFLE_WAFFLE_DIALOG_VIEW_H_ + +#include "ui/base/metadata/metadata_header_macros.h" +#include "ui/views/view.h" + +class Browser; + +namespace views { +class WebView; +} + +// Implements the Waffle dialog as a View. The view contains a WebView +// into which is loaded a WebUI page which renders the actual dialog content. +class WaffleDialogView : public views::View { + public: + METADATA_HEADER(WaffleDialogView); + explicit WaffleDialogView(Browser* browser); + + // Initialize WaffleDialogView's web_view_ element. + void Initialize(); + + private: + // Shows the dialog widget. + void ShowNativeView(); + + raw_ptr<views::WebView> web_view_ = nullptr; + const raw_ptr<const Browser> browser_; +}; + +#endif // CHROME_BROWSER_UI_VIEWS_WAFFLE_WAFFLE_DIALOG_VIEW_H_
diff --git a/chrome/browser/ui/waffle/waffle_tab_helper.cc b/chrome/browser/ui/waffle/waffle_tab_helper.cc new file mode 100644 index 0000000..4cffe14 --- /dev/null +++ b/chrome/browser/ui/waffle/waffle_tab_helper.cc
@@ -0,0 +1,28 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/waffle/waffle_tab_helper.h" + +#include "chrome/browser/signin/signin_features.h" +#include "chrome/browser/ui/browser_finder.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/web_contents.h" + +WaffleTabHelper::~WaffleTabHelper() = default; + +WaffleTabHelper::WaffleTabHelper(content::WebContents* web_contents) + : WebContentsObserver(web_contents), + content::WebContentsUserData<WaffleTabHelper>(*web_contents) { + CHECK(base::FeatureList::IsEnabled(kWaffle)); +} + +void WaffleTabHelper::DidFinishNavigation( + content::NavigationHandle* navigation_handle) { + if (auto* browser = chrome::FindBrowserWithWebContents( + navigation_handle->GetWebContents())) { + ShowWaffleDialog(*browser); + } +} + +WEB_CONTENTS_USER_DATA_KEY_IMPL(WaffleTabHelper);
diff --git a/chrome/browser/ui/waffle/waffle_tab_helper.h b/chrome/browser/ui/waffle/waffle_tab_helper.h new file mode 100644 index 0000000..fc85387 --- /dev/null +++ b/chrome/browser/ui/waffle/waffle_tab_helper.h
@@ -0,0 +1,42 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WAFFLE_WAFFLE_TAB_HELPER_H_ +#define CHROME_BROWSER_UI_WAFFLE_WAFFLE_TAB_HELPER_H_ + +#include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_contents_user_data.h" + +namespace content { +class WebContents; +} +class Browser; + +// Helper class which watches `web_contents` to determine whether there is an +// appropriate opportunity to show the WaffleDialogView. +class WaffleTabHelper : public content::WebContentsObserver, + public content::WebContentsUserData<WaffleTabHelper> { + public: + WaffleTabHelper(const WaffleTabHelper&) = delete; + WaffleTabHelper& operator=(const WaffleTabHelper&) = delete; + ~WaffleTabHelper() override; + + private: + friend class content::WebContentsUserData<WaffleTabHelper>; + + explicit WaffleTabHelper(content::WebContents* web_contents); + + // content::WebContentsObserver: + void DidFinishNavigation( + content::NavigationHandle* navigation_handle) override; + + WEB_CONTENTS_USER_DATA_KEY_DECL(); +}; + +// Implemented in `chrome/browser/ui/views/waffle/waffle_dialog_view.cc` +// because there isn't a dependency between `chrome/browser/ui/` and +// `chrome/browser/ui/views/`. +void ShowWaffleDialog(Browser& browser); + +#endif // CHROME_BROWSER_UI_WAFFLE_WAFFLE_TAB_HELPER_H_
diff --git a/chrome/browser/ui/web_applications/web_app_metrics_browsertest.cc b/chrome/browser/ui/web_applications/web_app_metrics_browsertest.cc index b75823e..9a17942 100644 --- a/chrome/browser/ui/web_applications/web_app_metrics_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_metrics_browsertest.cc
@@ -222,7 +222,7 @@ ukm::TestAutoSetUkmRecorder::ExpectEntryMetric( entry, UkmEntry::kCapturesLinksName, false); ukm::TestAutoSetUkmRecorder::ExpectEntryMetric( - entry, UkmEntry::kPromotableName, false); + entry, UkmEntry::kPromotableName, true); // Not in window, but is preinstalled, so should have session count (and would // be expected to have session time upon further interaction). ukm::TestAutoSetUkmRecorder::ExpectEntryMetric(entry,
diff --git a/chrome/browser/ui/webui/ash/login/enrollment_screen_handler.cc b/chrome/browser/ui/webui/ash/login/enrollment_screen_handler.cc index 0f661dd..90d1b3a8 100644 --- a/chrome/browser/ui/webui/ash/login/enrollment_screen_handler.cc +++ b/chrome/browser/ui/webui/ash/login/enrollment_screen_handler.cc
@@ -189,6 +189,12 @@ CallExternalAPI("doReload"); } +void EnrollmentScreenHandler::ResetEnrollmentScreen() { + // The empty string will be replaced by the correct initial step in the screen + // initialization code. + ShowStep(std::string()); +} + void EnrollmentScreenHandler::ShowUserError(const std::string& email) { // Reset the state of the GAIA so after error user would retry enrollment and // start from enter your account view. @@ -761,8 +767,8 @@ help_app_->ShowHelpTopic(HelpAppLauncher::HELP_DEVICE_ATTRIBUTES); } -void EnrollmentScreenHandler::ShowStep(const char* step) { - CallExternalAPI("showStep", std::string(step)); +void EnrollmentScreenHandler::ShowStep(const std::string& step) { + CallExternalAPI("showStep", step); } void EnrollmentScreenHandler::ShowError(int message_id, bool retry) {
diff --git a/chrome/browser/ui/webui/ash/login/enrollment_screen_handler.h b/chrome/browser/ui/webui/ash/login/enrollment_screen_handler.h index 93ec7d06..eb405ad7 100644 --- a/chrome/browser/ui/webui/ash/login/enrollment_screen_handler.h +++ b/chrome/browser/ui/webui/ash/login/enrollment_screen_handler.h
@@ -59,6 +59,7 @@ void Hide() override; void ShowSigninScreen() override; void ReloadSigninScreen() override; + void ResetEnrollmentScreen() override; void ShowSkipConfirmationDialog() override; void ShowUserError(const std::string& email) override; void ShowEnrollmentDuringTrialNotAllowedError() override; @@ -101,7 +102,7 @@ void HandleOnLearnMore(); // Shows a given enrollment step. - void ShowStep(const char* step); + void ShowStep(const std::string& step); // Display the given i18n resource as error message. void ShowError(int message_id, bool retry);
diff --git a/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler.cc b/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler.cc index 0d304232..3ea0880 100644 --- a/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler.cc +++ b/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler.cc
@@ -15,6 +15,10 @@ prompt_type == PrivacySandboxService::PromptType::kM1Consent; } +bool IsRestrictedNotice(PrivacySandboxService::PromptType prompt_type) { + return prompt_type == PrivacySandboxService::PromptType::kM1NoticeRestricted; +} + } // namespace PrivacySandboxDialogHandler::PrivacySandboxDialogHandler( @@ -73,6 +77,9 @@ if (IsConsent(prompt_type_)) { NotifyServiceAboutPromptAction( PrivacySandboxService::PromptAction::kConsentClosedNoDecision); + } else if (IsRestrictedNotice(prompt_type_)) { + NotifyServiceAboutPromptAction(PrivacySandboxService::PromptAction:: + kRestrictedNoticeClosedNoInteraction); } else { NotifyServiceAboutPromptAction( PrivacySandboxService::PromptAction::kNoticeClosedNoInteraction);
diff --git a/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler_unittest.cc b/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler_unittest.cc index 327a333e..9ed15b7 100644 --- a/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler_unittest.cc +++ b/chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_dialog_handler_unittest.cc
@@ -380,10 +380,9 @@ *mock_privacy_sandbox_service(), PromptActionOccurred( PrivacySandboxService::PromptAction::kRestrictedNoticeOpenSettings)); - EXPECT_CALL( - *mock_privacy_sandbox_service(), - PromptActionOccurred( - PrivacySandboxService::PromptAction::kNoticeClosedNoInteraction)) + EXPECT_CALL(*mock_privacy_sandbox_service(), + PromptActionOccurred(PrivacySandboxService::PromptAction:: + kRestrictedNoticeClosedNoInteraction)) .Times(0); base::Value::List args; @@ -401,10 +400,9 @@ *mock_privacy_sandbox_service(), PromptActionOccurred( PrivacySandboxService::PromptAction::kRestrictedNoticeAcknowledge)); - EXPECT_CALL( - *mock_privacy_sandbox_service(), - PromptActionOccurred( - PrivacySandboxService::PromptAction::kNoticeClosedNoInteraction)) + EXPECT_CALL(*mock_privacy_sandbox_service(), + PromptActionOccurred(PrivacySandboxService::PromptAction:: + kRestrictedNoticeClosedNoInteraction)) .Times(0); base::Value::List args;
diff --git a/chrome/browser/ui/webui/sandbox/sandbox_handler.cc b/chrome/browser/ui/webui/sandbox/sandbox_handler.cc index 03f61ae..0f872ef 100644 --- a/chrome/browser/ui/webui/sandbox/sandbox_handler.cc +++ b/chrome/browser/ui/webui/sandbox/sandbox_handler.cc
@@ -87,6 +87,8 @@ FeatureToValue(sandbox::policy::features::kRendererAppContainer)); features.Append( FeatureToValue(sandbox::policy::features::kWinSboxAllowSystemFonts)); + features.Append( + FeatureToValue(sandbox::policy::features::kWinSboxRendererCloseKsecDD)); features.Append(FeatureToValue( sandbox::policy::features::kWinSboxDisableExtensionPoints)); return features;
diff --git a/chrome/browser/ui/webui/waffle/waffle.mojom b/chrome/browser/ui/webui/waffle/waffle.mojom index 3a2457e..297c3fcd 100644 --- a/chrome/browser/ui/webui/waffle/waffle.mojom +++ b/chrome/browser/ui/webui/waffle/waffle.mojom
@@ -13,6 +13,7 @@ // Browser-side handler for requests from WebUI page. interface PageHandler { - // Closes the Waffle dialog. Triggered by the closeClicked() call in TS. - CloseClicked(); + // Displays the Waffle dialog. Triggered by the displayDialog() call in + // chrome/browser/resources/waffle/app.ts + DisplayDialog(); };
diff --git a/chrome/browser/ui/webui/waffle/waffle_handler.cc b/chrome/browser/ui/webui/waffle/waffle_handler.cc index 968772b..c9e3a5e5 100644 --- a/chrome/browser/ui/webui/waffle/waffle_handler.cc +++ b/chrome/browser/ui/webui/waffle/waffle_handler.cc
@@ -4,13 +4,23 @@ #include "chrome/browser/ui/webui/waffle/waffle_handler.h" +#include "chrome/browser/signin/signin_features.h" + WaffleHandler::WaffleHandler( - mojo::PendingReceiver<waffle::mojom::PageHandler> receiver) - : receiver_(this, std::move(receiver)) {} + mojo::PendingReceiver<waffle::mojom::PageHandler> receiver, + base::OnceClosure display_dialog_callback) + : receiver_(this, std::move(receiver)), + display_dialog_callback_(std::move(display_dialog_callback)) { + CHECK(base::FeatureList::IsEnabled(kWaffle)); + // `display_dialog_callback` being null would indicate that the handler is + // created before calling `WaffleUI::Initialize()`, which should never happen. + CHECK(display_dialog_callback_); +} WaffleHandler::~WaffleHandler() = default; -// Triggered by closeClicked() call in TS. -void WaffleHandler::CloseClicked() { - NOTIMPLEMENTED(); +void WaffleHandler::DisplayDialog() { + if (display_dialog_callback_) { + std::move(display_dialog_callback_).Run(); + } }
diff --git a/chrome/browser/ui/webui/waffle/waffle_handler.h b/chrome/browser/ui/webui/waffle/waffle_handler.h index 0bb4b9f..e59bcb0 100644 --- a/chrome/browser/ui/webui/waffle/waffle_handler.h +++ b/chrome/browser/ui/webui/waffle/waffle_handler.h
@@ -5,13 +5,15 @@ #ifndef CHROME_BROWSER_UI_WEBUI_WAFFLE_WAFFLE_HANDLER_H_ #define CHROME_BROWSER_UI_WEBUI_WAFFLE_WAFFLE_HANDLER_H_ +#include "base/functional/callback_forward.h" #include "chrome/browser/ui/webui/waffle/waffle.mojom.h" #include "mojo/public/cpp/bindings/receiver.h" class WaffleHandler : public waffle::mojom::PageHandler { public: explicit WaffleHandler( - mojo::PendingReceiver<waffle::mojom::PageHandler> receiver); + mojo::PendingReceiver<waffle::mojom::PageHandler> receiver, + base::OnceClosure display_dialog_callback); WaffleHandler(const WaffleHandler&) = delete; WaffleHandler& operator=(const WaffleHandler&) = delete; @@ -19,10 +21,11 @@ ~WaffleHandler() override; // waffle::mojom::PageHandler: - void CloseClicked() override; + void DisplayDialog() override; private: mojo::Receiver<waffle::mojom::PageHandler> receiver_; + base::OnceClosure display_dialog_callback_; }; #endif // CHROME_BROWSER_UI_WEBUI_WAFFLE_WAFFLE_HANDLER_H_
diff --git a/chrome/browser/ui/webui/waffle/waffle_ui.cc b/chrome/browser/ui/webui/waffle/waffle_ui.cc index 248350f..744b6d4 100644 --- a/chrome/browser/ui/webui/waffle/waffle_ui.cc +++ b/chrome/browser/ui/webui/waffle/waffle_ui.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ui/webui/waffle/waffle_ui.h" #include "base/feature_list.h" +#include "base/functional/callback_forward.h" #include "chrome/browser/signin/signin_features.h" #include "chrome/browser/ui/webui/waffle/waffle_handler.h" #include "chrome/browser/ui/webui/webui_util.h" @@ -12,20 +13,18 @@ #include "chrome/grit/generated_resources.h" #include "chrome/grit/waffle_resources.h" #include "chrome/grit/waffle_resources_map.h" -#include "components/strings/grit/components_strings.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_ui_data_source.h" WaffleUI::WaffleUI(content::WebUI* web_ui) : ui::MojoWebUIController(web_ui, true) { - DCHECK(base::FeatureList::IsEnabled(kWaffle)); + CHECK(base::FeatureList::IsEnabled(kWaffle)); content::WebUIDataSource* source = content::WebUIDataSource::CreateAndAdd( web_ui->GetWebContents()->GetBrowserContext(), chrome::kChromeUIWaffleHost); source->AddLocalizedString("title", IDS_WAFFLE_PAGE_TITLE); - source->AddLocalizedString("closeButtonTitle", IDS_CLOSE); webui::SetupWebUIDataSource( source, base::make_span(kWaffleResources, kWaffleResourcesSize), @@ -42,7 +41,13 @@ page_factory_receiver_.Bind(std::move(receiver)); } +void WaffleUI::Initialize(base::OnceClosure display_dialog_callback) { + CHECK(display_dialog_callback); + display_dialog_callback_ = std::move(display_dialog_callback); +} + void WaffleUI::CreatePageHandler( mojo::PendingReceiver<waffle::mojom::PageHandler> receiver) { - page_handler_ = std::make_unique<WaffleHandler>(std::move(receiver)); + page_handler_ = std::make_unique<WaffleHandler>( + std::move(receiver), std::move(display_dialog_callback_)); }
diff --git a/chrome/browser/ui/webui/waffle/waffle_ui.h b/chrome/browser/ui/webui/waffle/waffle_ui.h index 695985b..0e951e7 100644 --- a/chrome/browser/ui/webui/waffle/waffle_ui.h +++ b/chrome/browser/ui/webui/waffle/waffle_ui.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_UI_WEBUI_WAFFLE_WAFFLE_UI_H_ #define CHROME_BROWSER_UI_WEBUI_WAFFLE_WAFFLE_UI_H_ +#include "base/functional/callback_forward.h" #include "chrome/browser/ui/webui/waffle/waffle.mojom.h" #include "chrome/browser/ui/webui/waffle/waffle_handler.h" #include "ui/webui/mojo_web_ui_controller.h" @@ -25,6 +26,12 @@ void BindInterface( mojo::PendingReceiver<waffle::mojom::PageHandlerFactory> receiver); + // Initializes the callbacks that need to be passed to the handler. + // `display_dialog_callback` is how we display the waffle dialog. It will + // be called when the page content is laid out, so that the dialog will be + // able to measure the page to fit to its size. + void Initialize(base::OnceClosure display_dialog_callback); + private: // waffle::mojom::PageHandlerFactory: void CreatePageHandler( @@ -35,6 +42,8 @@ mojo::Receiver<waffle::mojom::PageHandlerFactory> page_factory_receiver_{ this}; + base::OnceClosure display_dialog_callback_; + WEB_UI_CONTROLLER_TYPE_DECL(); };
diff --git a/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_command.cc b/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_command.cc index a5721b3..5aab228 100644 --- a/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_command.cc +++ b/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_command.cc
@@ -287,7 +287,12 @@ "Manifest `version` is not present. manifest_url: " + manifest_url.possibly_invalid_spec()); } - std::string version_string = base::UTF16ToUTF8(*manifest.version); + std::string version_string; + if (!base::UTF16ToUTF8(manifest.version->data(), manifest.version->length(), + &version_string)) { + return base::unexpected( + "Failed to convert manifest `version` from UTF16 to UTF8."); + } base::expected<std::array<uint32_t, 3>, IwaVersionParseError> version_components = ParseIwaVersionIntoComponents(version_string);
diff --git a/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_command_unittest.cc b/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_command_unittest.cc index 640f17f..f073eae8 100644 --- a/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_command_unittest.cc +++ b/chrome/browser/web_applications/isolated_web_apps/install_isolated_web_app_command_unittest.cc
@@ -594,12 +594,17 @@ INSTANTIATE_TEST_SUITE_P( /* no prefix */, InstallIsolatedWebAppCommandInvalidVersionTest, - ::testing::Values(InvalidVersionParam{.version = absl::nullopt, - .error = "`version` is not present", - .test_name = "NoVersion"}, - InvalidVersionParam{.version = u"10", - .error = "Failed to parse `version`", - .test_name = "InvalidVersionFormat"}), + ::testing::Values( + InvalidVersionParam{.version = absl::nullopt, + .error = "`version` is not present", + .test_name = "NoVersion"}, + InvalidVersionParam{ + .version = u"\xD801", + .error = "Failed to convert manifest `version` from UTF16 to UTF8", + .test_name = "InvalidUtf8"}, + InvalidVersionParam{.version = u"10", + .error = "Failed to parse `version`", + .test_name = "InvalidVersionFormat"}), [](const ::testing::TestParamInfo< InstallIsolatedWebAppCommandInvalidVersionTest::ParamType>& info) { return info.param.test_name;
diff --git a/chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_reader.cc b/chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_reader.cc index 069396a..5a4adfa 100644 --- a/chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_reader.cc +++ b/chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_reader.cc
@@ -11,6 +11,8 @@ #include "base/check_is_test.h" #include "base/check_op.h" +#include "base/files/file.h" +#include "base/functional/bind.h" #include "base/functional/callback.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_functions.h" @@ -20,6 +22,7 @@ #include "base/task/task_traits.h" #include "base/task/thread_pool.h" #include "base/time/time.h" +#include "base/types/expected.h" #include "chrome/browser/web_applications/isolated_web_apps/error/unusable_swbn_file_error.h" #include "components/web_package/mojom/web_bundle_parser.mojom.h" #include "components/web_package/signed_web_bundles/signed_web_bundle_integrity_block.h" @@ -30,15 +33,161 @@ #include "url/gurl.h" namespace web_app { +namespace { +// This is blocking operation. +base::expected<uint64_t, base::File::Error> ReadLengthOfSharedFile( + scoped_refptr<web_package::SharedFile> file) { + int64_t length = (*file)->GetLength(); + if (length < 0) { + return base::unexpected((*file)->GetLastFileError()); + } + return static_cast<uint64_t>(length); +} +} // namespace + +namespace internal { + +SafeWebBundleParserConnection::SafeWebBundleParserConnection( + base::FilePath web_bundle_path, + absl::optional<GURL> base_url) + : web_bundle_path_(std::move(web_bundle_path)), + base_url_(std::move(base_url)) {} + +SafeWebBundleParserConnection::~SafeWebBundleParserConnection() = default; + +void SafeWebBundleParserConnection::Initialize( + InitCompleteCallback init_complete_callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + CHECK_EQ(state_, State::kUninitialized); + state_ = State::kInitializing; + + parser_ = std::make_unique<data_decoder::SafeWebBundleParser>(base_url_); + + base::ThreadPool::PostTaskAndReplyWithResult( + FROM_HERE, {base::MayBlock()}, + base::BindOnce( + [](const base::FilePath& file_path) -> std::unique_ptr<base::File> { + return std::make_unique<base::File>( + file_path, base::File::FLAG_OPEN | base::File::FLAG_READ); + }, + web_bundle_path_), + base::BindOnce(&SafeWebBundleParserConnection::OnFileOpened, + weak_ptr_factory_.GetWeakPtr(), + std::move(init_complete_callback))); +} + +void SafeWebBundleParserConnection::StartProcessingDisconnects() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + CHECK_EQ(state_, State::kConnected); + parser_->SetDisconnectCallback( + base::BindOnce(&SafeWebBundleParserConnection::OnParserDisconnected, + // `base::Unretained` is okay to use here, since + // `parser_` will be deleted before `this` is deleted. + base::Unretained(this))); +} + +void SafeWebBundleParserConnection::OnFileOpened( + InitCompleteCallback init_complete_callback, + std::unique_ptr<base::File> file) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + CHECK_EQ(state_, State::kInitializing); + + if (!file->IsValid()) { + UnusableSwbnFileError error = UnusableSwbnFileError( + UnusableSwbnFileError::Error::kIntegrityBlockParserInternalError, + base::File::ErrorToString(file->error_details())); + std::move(init_complete_callback).Run(base::unexpected(error)); + return; + } + + file_ = base::MakeRefCounted<web_package::SharedFile>(std::move(file)); + file_->DuplicateFile(base::BindOnce( + &SafeWebBundleParserConnection::OnFileDuplicated, + weak_ptr_factory_.GetWeakPtr(), std::move(init_complete_callback))); +} + +void SafeWebBundleParserConnection::OnFileDuplicated( + InitCompleteCallback init_complete_callback, + base::File file) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + CHECK_EQ(state_, State::kInitializing); + + base::File::Error file_error = parser_->OpenFile(std::move(file)); + if (file_error != base::File::FILE_OK) { + UnusableSwbnFileError error = UnusableSwbnFileError( + UnusableSwbnFileError::Error::kIntegrityBlockParserInternalError, + base::File::ErrorToString(file_error)); + std::move(init_complete_callback).Run(base::unexpected(error)); + return; + } + + state_ = State::kConnected; + std::move(init_complete_callback).Run(base::ok()); +} + +void SafeWebBundleParserConnection::OnParserDisconnected() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + CHECK_EQ(state_, State::kConnected); + + state_ = State::kDisconnected; + parser_ = nullptr; + if (!parser_disconnect_callback_for_testing_.is_null()) { + CHECK_IS_TEST(); + parser_disconnect_callback_for_testing_.Run(); + } +} + +void SafeWebBundleParserConnection::Reconnect( + ReconnectCompleteCallback reconnect_callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + CHECK(!parser_); + CHECK_EQ(state_, State::kDisconnected); + parser_ = std::make_unique<data_decoder::SafeWebBundleParser>(base_url_); + state_ = State::kReconnecting; + + file_->DuplicateFile(base::BindOnce( + &SafeWebBundleParserConnection::ReconnectForFile, + weak_ptr_factory_.GetWeakPtr(), std::move(reconnect_callback))); +} + +void SafeWebBundleParserConnection::ReconnectForFile( + ReconnectCompleteCallback reconnect_callback, + base::File file) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + CHECK_EQ(state_, State::kReconnecting); + base::File::Error file_error; + if (reconnection_file_error_for_testing_.has_value()) { + CHECK_IS_TEST(); + file_error = *reconnection_file_error_for_testing_; + } else { + file_error = parser_->OpenFile(std::move(file)); + } + + base::expected<void, std::string> status; + if (file_error != base::File::FILE_OK) { + state_ = State::kDisconnected; + status = base::unexpected(base::File::ErrorToString(file_error)); + } else { + state_ = State::kConnected; + StartProcessingDisconnects(); + } + + base::SequencedTaskRunner::GetCurrentDefault()->PostTask( + FROM_HERE, + base::BindOnce(std::move(reconnect_callback), std::move(status))); +} + +} // namespace internal SignedWebBundleReader::SignedWebBundleReader( const base::FilePath& web_bundle_path, const absl::optional<GURL>& base_url, std::unique_ptr<web_package::SignedWebBundleSignatureVerifier> signature_verifier) - : web_bundle_path_(web_bundle_path), - base_url_(base_url), - signature_verifier_(std::move(signature_verifier)) {} + : signature_verifier_(std::move(signature_verifier)), + connection_(std::make_unique<internal::SafeWebBundleParserConnection>( + web_bundle_path, + base_url)) {} SignedWebBundleReader::~SignedWebBundleReader() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -60,73 +209,28 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); CHECK_EQ(state_, State::kUninitialized); - Initialize(std::move(integrity_block_result_callback), - std::move(read_error_callback)); -} - -void SignedWebBundleReader::Initialize( - IntegrityBlockReadResultCallback integrity_block_result_callback, - ReadErrorCallback read_error_callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - CHECK_EQ(state_, State::kUninitialized); - state_ = State::kInitializing; - - parser_ = std::make_unique<data_decoder::SafeWebBundleParser>(base_url_); - - base::ThreadPool::PostTaskAndReplyWithResult( - FROM_HERE, {base::MayBlock()}, - base::BindOnce( - [](const base::FilePath& file_path) -> std::unique_ptr<base::File> { - return std::make_unique<base::File>( - file_path, base::File::FLAG_OPEN | base::File::FLAG_READ); - }, - web_bundle_path_), - base::BindOnce(&SignedWebBundleReader::OnFileOpened, + connection_->Initialize( + base::BindOnce(&SignedWebBundleReader::OnConnectionInitialized, weak_ptr_factory_.GetWeakPtr(), std::move(integrity_block_result_callback), std::move(read_error_callback))); } -void SignedWebBundleReader::OnFileOpened( +void SignedWebBundleReader::OnConnectionInitialized( IntegrityBlockReadResultCallback integrity_block_result_callback, ReadErrorCallback read_error_callback, - std::unique_ptr<base::File> file) { + base::expected<void, UnusableSwbnFileError> init_status) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); CHECK_EQ(state_, State::kInitializing); - if (!file->IsValid()) { - UnusableSwbnFileError error = UnusableSwbnFileError( - UnusableSwbnFileError::Error::kIntegrityBlockParserInternalError, - base::File::ErrorToString(file->error_details())); - FulfillWithError(std::move(read_error_callback), std::move(error)); + if (!init_status.has_value()) { + FulfillWithError(std::move(read_error_callback), + std::move(init_status.error())); return; } - file_ = base::MakeRefCounted<web_package::SharedFile>(std::move(file)); - file_->DuplicateFile(base::BindOnce( - &SignedWebBundleReader::OnFileDuplicated, weak_ptr_factory_.GetWeakPtr(), - std::move(integrity_block_result_callback), - std::move(read_error_callback))); -} - -void SignedWebBundleReader::OnFileDuplicated( - IntegrityBlockReadResultCallback integrity_block_result_callback, - ReadErrorCallback read_error_callback, - base::File file) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - CHECK_EQ(state_, State::kInitializing); - - base::File::Error file_error = parser_->OpenFile(std::move(file)); - if (file_error != base::File::FILE_OK) { - UnusableSwbnFileError error = UnusableSwbnFileError( - UnusableSwbnFileError::Error::kIntegrityBlockParserInternalError, - base::File::ErrorToString(file_error)); - FulfillWithError(std::move(read_error_callback), std::move(error)); - return; - } - - parser_->ParseIntegrityBlock( + connection_->parser_->ParseIntegrityBlock( base::BindOnce(&SignedWebBundleReader::OnIntegrityBlockParsed, weak_ptr_factory_.GetWeakPtr(), std::move(integrity_block_result_callback), @@ -188,7 +292,12 @@ action.abort_message())); return; case SignatureVerificationAction::Type::kContinueAndVerifySignatures: - VerifySignatures(std::move(integrity_block), std::move(callback)); + base::ThreadPool::PostTaskAndReplyWithResult( + FROM_HERE, {base::MayBlock()}, + base::BindOnce(ReadLengthOfSharedFile, connection_->file_), + base::BindOnce(&SignedWebBundleReader::OnFileLengthRead, + weak_ptr_factory_.GetWeakPtr(), + std::move(integrity_block), std::move(callback))); return; case SignatureVerificationAction::Type:: kContinueAndSkipSignatureVerification: @@ -197,29 +306,6 @@ } } -void SignedWebBundleReader::VerifySignatures( - web_package::SignedWebBundleIntegrityBlock integrity_block, - ReadErrorCallback callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - CHECK_EQ(state_, State::kInitializing); - - base::ThreadPool::PostTaskAndReplyWithResult( - FROM_HERE, {base::MayBlock()}, - base::BindOnce( - [](scoped_refptr<web_package::SharedFile> file) - -> base::expected<uint64_t, base::File::Error> { - int64_t length = (*file)->GetLength(); - if (length < 0) { - return base::unexpected((*file)->GetLastFileError()); - } - return static_cast<uint64_t>(length); - }, - file_), - base::BindOnce(&SignedWebBundleReader::OnFileLengthRead, - weak_ptr_factory_.GetWeakPtr(), std::move(integrity_block), - std::move(callback))); -} - void SignedWebBundleReader::OnFileLengthRead( web_package::SignedWebBundleIntegrityBlock integrity_block, ReadErrorCallback callback, @@ -233,7 +319,7 @@ } signature_verifier_->VerifySignatures( - file_, std::move(integrity_block), + connection_->file_, std::move(integrity_block), base::BindOnce(&SignedWebBundleReader::OnSignaturesVerified, weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now(), *file_length, std::move(callback))); @@ -274,7 +360,7 @@ << "The integrity block must have been read before reading metadata."; uint64_t metadata_offset = integrity_block_size_in_bytes_.value(); - parser_->ParseMetadata( + connection_->parser_->ParseMetadata( metadata_offset, base::BindOnce(&SignedWebBundleReader::OnMetadataParsed, weak_ptr_factory_.GetWeakPtr(), std::move(callback))); @@ -297,11 +383,7 @@ state_ = State::kInitialized; - parser_->SetDisconnectCallback( - base::BindOnce(&SignedWebBundleReader::OnParserDisconnected, - // `base::Unretained` is okay to use here, since - // `parser_` will be deleted before `this` is deleted. - base::Unretained(this))); + connection_->StartProcessingDisconnects(); std::move(callback).Run(base::ok()); } @@ -310,9 +392,9 @@ UnusableSwbnFileError error) { state_ = State::kError; - // This is an irrecoverable error state, thus we can safely delete `parser_` - // here to free up resources. - parser_.reset(); + // This is an irrecoverable error state, thus we can safely delete + // `connection_` here to free up resources. + connection_.reset(); std::move(callback).Run(base::unexpected(std::move(error))); } @@ -355,10 +437,11 @@ } auto response_location = entry_it->second->Clone(); - if (is_disconnected_) { + if (connection_->is_disconnected()) { // Try reconnecting the parser if it hasn't been attempted yet. if (pending_read_responses_.empty()) { - Reconnect(); + connection_->Reconnect(base::BindOnce(&SignedWebBundleReader::OnReconnect, + base::Unretained(this))); } pending_read_responses_.emplace_back(std::move(response_location), std::move(callback)); @@ -368,12 +451,35 @@ ReadResponseInternal(std::move(response_location), std::move(callback)); } +void SignedWebBundleReader::OnReconnect( + base::expected<void, std::string> status) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + std::vector<std::pair<web_package::mojom::BundleResponseLocationPtr, + ResponseCallback>> + read_tasks; + read_tasks.swap(pending_read_responses_); + + for (auto& [response_location, response_callback] : read_tasks) { + if (!status.has_value()) { + base::SequencedTaskRunner::GetCurrentDefault()->PostTask( + FROM_HERE, + base::BindOnce( + std::move(response_callback), + base::unexpected(ReadResponseError::ForParserInternalError( + "Unable to open file: " + status.error())))); + } else { + ReadResponseInternal(std::move(response_location), + std::move(response_callback)); + } + } +} + void SignedWebBundleReader::ReadResponseInternal( web_package::mojom::BundleResponseLocationPtr location, ResponseCallback callback) { CHECK_EQ(state_, State::kInitialized); - parser_->ParseResponse( + connection_->parser_->ParseResponse( location->offset, location->length, base::BindOnce(&SignedWebBundleReader::OnResponseParsed, weak_ptr_factory_.GetWeakPtr(), std::move(callback))); @@ -405,8 +511,8 @@ std::make_unique<mojo::DataPipeProducer>(std::move(producer_handle)); mojo::DataPipeProducer* raw_producer = data_producer.get(); raw_producer->Write( - file_->CreateDataSource(response->payload_offset, - response->payload_length), + connection_->file_->CreateDataSource(response->payload_offset, + response->payload_length), base::BindOnce( // `producer` is passed to this callback purely for its lifetime // management so that it is deleted once this callback runs. @@ -425,85 +531,12 @@ void SignedWebBundleReader::SetParserDisconnectCallbackForTesting( base::RepeatingClosure callback) { - parser_disconnect_callback_for_testing_ = std::move(callback); + connection_->parser_disconnect_callback_for_testing_ = std::move(callback); } void SignedWebBundleReader::SetReconnectionFileErrorForTesting( base::File::Error file_error) { - reconnection_file_error_for_testing_ = file_error; -} - -void SignedWebBundleReader::OnParserDisconnected() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(!is_disconnected_); - - is_disconnected_ = true; - parser_ = nullptr; - if (!parser_disconnect_callback_for_testing_.is_null()) { - CHECK_IS_TEST(); - parser_disconnect_callback_for_testing_.Run(); - } - // Reconnection will be attempted on the next call to `ReadResponse`. -} - -void SignedWebBundleReader::Reconnect() { - DCHECK(!parser_); - parser_ = std::make_unique<data_decoder::SafeWebBundleParser>(base_url_); - - file_->DuplicateFile(base::BindOnce(&SignedWebBundleReader::ReconnectForFile, - weak_ptr_factory_.GetWeakPtr())); -} - -void SignedWebBundleReader::ReconnectForFile(base::File file) { - base::File::Error file_error; - if (reconnection_file_error_for_testing_.has_value()) { - CHECK_IS_TEST(); - file_error = *reconnection_file_error_for_testing_; - } else { - file_error = parser_->OpenFile(std::move(file)); - } - - absl::optional<std::string> error; - if (file_error != base::File::FILE_OK) { - error = base::File::ErrorToString(file_error); - } - base::SequencedTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, - base::BindOnce(&SignedWebBundleReader::DidReconnect, - weak_ptr_factory_.GetWeakPtr(), std::move(error))); -} - -void SignedWebBundleReader::DidReconnect(absl::optional<std::string> error) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(is_disconnected_); - DCHECK(parser_); - std::vector<std::pair<web_package::mojom::BundleResponseLocationPtr, - ResponseCallback>> - read_tasks; - read_tasks.swap(pending_read_responses_); - - if (error) { - for (auto& [response_location, response_callback] : read_tasks) { - base::SequencedTaskRunner::GetCurrentDefault()->PostTask( - FROM_HERE, - base::BindOnce( - std::move(response_callback), - base::unexpected(ReadResponseError::ForParserInternalError( - "Unable to open file: " + *error)))); - } - return; - } - - is_disconnected_ = false; - parser_->SetDisconnectCallback( - base::BindOnce(&SignedWebBundleReader::OnParserDisconnected, - // `base::Unretained` is okay to use here, since `parser_` - // will be deleted before `this` is deleted. - base::Unretained(this))); - for (auto& [response_location, response_callback] : read_tasks) { - ReadResponseInternal(std::move(response_location), - std::move(response_callback)); - } + connection_->reconnection_file_error_for_testing_ = file_error; } // static
diff --git a/chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_reader.h b/chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_reader.h index 8593887..a216998 100644 --- a/chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_reader.h +++ b/chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_reader.h
@@ -32,6 +32,74 @@ namespace web_app { +namespace internal { + +// This class is responsible for establishing and maintaining of +// the IPC connection for parsing of the Signed Web Bundle. +class SafeWebBundleParserConnection { + public: + SafeWebBundleParserConnection(base::FilePath web_bundle_path, + absl::optional<GURL> base_url); + ~SafeWebBundleParserConnection(); + + using InitCompleteCallback = base::OnceCallback<void( + base::expected<void, UnusableSwbnFileError> status)>; + + using ReconnectCompleteCallback = + base::OnceCallback<void(base::expected<void, std::string> status)>; + + // Please call this function before any other. + void Initialize(InitCompleteCallback init_complete_callback); + + // Subscribes the instance of this class on OnParserDisconnected + // events. + void StartProcessingDisconnects(); + bool is_disconnected() const { return state_ != State::kConnected; } + // Tries to reestablish IPC connection. + void Reconnect(ReconnectCompleteCallback reconnect_callback); + + // The public fields below violate encapsulation. The problem is that + // there is no good way (so far) how to treat them. Returning + // const reference is currently not an option because reading + // is not a const function of these types (even though logically it is + // const). + // So far it is better to leave these fields in such an ugly form + // to pay attention to them in the nearest future. + // TODO(peletskyi): Make proper encapsulation here. + scoped_refptr<web_package::SharedFile> file_; + std::unique_ptr<data_decoder::SafeWebBundleParser> parser_; + + // These fields we may not need after refactoring of the tests. + base::RepeatingClosure parser_disconnect_callback_for_testing_; + absl::optional<base::File::Error> reconnection_file_error_for_testing_; + + private: + enum class State { + kUninitialized, + kInitializing, + kConnected, + kDisconnected, + kReconnecting, + }; + + void OnFileOpened(InitCompleteCallback init_complete_callback, + std::unique_ptr<base::File> file); + + void OnFileDuplicated(InitCompleteCallback init_complete_callback, + base::File file); + void OnParserDisconnected(); + void ReconnectForFile(ReconnectCompleteCallback reconnect_callback, + base::File file); + + base::FilePath web_bundle_path_; + absl::optional<GURL> base_url_; + State state_ = State::kUninitialized; + + SEQUENCE_CHECKER(sequence_checker_); + base::WeakPtrFactory<SafeWebBundleParserConnection> weak_ptr_factory_{this}; +}; +} // namespace internal + // This class is a reader for Signed Web Bundles. // // `Create` returns a new instance of this class. @@ -212,19 +280,10 @@ std::unique_ptr<web_package::SignedWebBundleSignatureVerifier> signature_verifier); - void Initialize( - IntegrityBlockReadResultCallback integrity_block_result_callback, - ReadErrorCallback read_error_callback); - - void OnFileOpened( + void OnConnectionInitialized( IntegrityBlockReadResultCallback integrity_block_result_callback, ReadErrorCallback read_error_callback, - std::unique_ptr<base::File> file); - - void OnFileDuplicated( - IntegrityBlockReadResultCallback integrity_block_result_callback, - ReadErrorCallback read_error_callback, - base::File file); + base::expected<void, UnusableSwbnFileError> init_status); void OnIntegrityBlockParsed( IntegrityBlockReadResultCallback integrity_block_result_callback, @@ -237,10 +296,6 @@ ReadErrorCallback callback, SignatureVerificationAction action); - void VerifySignatures( - web_package::SignedWebBundleIntegrityBlock integrity_block, - ReadErrorCallback callback); - void OnFileLengthRead( web_package::SignedWebBundleIntegrityBlock integrity_block, ReadErrorCallback callback, @@ -270,29 +325,18 @@ web_package::mojom::BundleResponsePtr response, web_package::mojom::BundleResponseParseErrorPtr error); - // The following methods are for reconnection handling if the - // `SafeWebBundleParser` disconnects at some point after integrity block and + // The following method is a callback for reconnection handling if the + // `SafeWebBundleParser` in the `SignedWebBundleParserConnection` + // disconnects at some point after integrity block and // metadata have been read. Reconnecting to a new parser will be attempted on // the next call to `ReadResponse`. - void OnParserDisconnected(); - void Reconnect(); - void ReconnectForFile(base::File file); - void DidReconnect(absl::optional<std::string> error); + void OnReconnect(base::expected<void, std::string> status); State state_ = State::kUninitialized; - bool is_disconnected_ = false; - base::FilePath web_bundle_path_; - absl::optional<GURL> base_url_; std::unique_ptr<web_package::SignedWebBundleSignatureVerifier> signature_verifier_; - std::unique_ptr<data_decoder::SafeWebBundleParser> parser_; - base::RepeatingClosure parser_disconnect_callback_for_testing_; - absl::optional<base::File::Error> reconnection_file_error_for_testing_; - - scoped_refptr<web_package::SharedFile> file_; - // Integrity Block absl::optional<uint64_t> integrity_block_size_in_bytes_; @@ -306,6 +350,8 @@ ResponseCallback>> pending_read_responses_; + std::unique_ptr<internal::SafeWebBundleParserConnection> connection_; + SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<SignedWebBundleReader> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/webauthn/android/webauthn_request_delegate_android.cc b/chrome/browser/webauthn/android/webauthn_request_delegate_android.cc index 8d05d24..4ab8130d 100644 --- a/chrome/browser/webauthn/android/webauthn_request_delegate_android.cc +++ b/chrome/browser/webauthn/android/webauthn_request_delegate_android.cc
@@ -78,10 +78,14 @@ if (is_conditional_request) { conditional_request_in_progress_ = true; ReportConditionalUiPasskeyCount(credentials.size()); - ChromeWebAuthnCredentialsDelegateFactory::GetFactory( - content::WebContents::FromRenderFrameHost(frame_host)) - ->GetDelegateForFrame(frame_host) - ->OnCredentialsReceived(std::move(display_credentials)); + ChromeWebAuthnCredentialsDelegate* credentials_delegate = + ChromeWebAuthnCredentialsDelegateFactory::GetFactory( + content::WebContents::FromRenderFrameHost(frame_host)) + ->GetDelegateForFrame(frame_host); + credentials_delegate->SetAndroidHybridAvailable( + ChromeWebAuthnCredentialsDelegate::AndroidHybridAvailable( + !hybrid_callback_.is_null())); + credentials_delegate->OnCredentialsReceived(std::move(display_credentials)); return; } @@ -90,17 +94,21 @@ } touch_to_fill_controller_->Show( std::vector<password_manager::UiCredential>(), display_credentials, - std::make_unique<TouchToFillControllerWebAuthnDelegate>(this)); + std::make_unique<TouchToFillControllerWebAuthnDelegate>( + this, !hybrid_callback_.is_null())); } void WebAuthnRequestDelegateAndroid::CleanupWebAuthnRequest( content::RenderFrameHost* frame_host) { if (conditional_request_in_progress_) { // Prevent autofill from offering WebAuthn credentials in the popup. - ChromeWebAuthnCredentialsDelegateFactory::GetFactory( - content::WebContents::FromRenderFrameHost(frame_host)) - ->GetDelegateForFrame(frame_host) - ->NotifyWebAuthnRequestAborted(); + ChromeWebAuthnCredentialsDelegate* credentials_delegate = + ChromeWebAuthnCredentialsDelegateFactory::GetFactory( + content::WebContents::FromRenderFrameHost(frame_host)) + ->GetDelegateForFrame(frame_host); + credentials_delegate->NotifyWebAuthnRequestAborted(); + credentials_delegate->SetAndroidHybridAvailable( + ChromeWebAuthnCredentialsDelegate::AndroidHybridAvailable(false)); } else { touch_to_fill_controller_->Close(); } @@ -116,6 +124,12 @@ } } +void WebAuthnRequestDelegateAndroid::ShowHybridSignIn() { + if (hybrid_callback_) { + hybrid_callback_.Run(); + } +} + content::WebContents* WebAuthnRequestDelegateAndroid::web_contents() { return web_contents_; }
diff --git a/chrome/browser/webauthn/android/webauthn_request_delegate_android.h b/chrome/browser/webauthn/android/webauthn_request_delegate_android.h index b16ec623..c919419c 100644 --- a/chrome/browser/webauthn/android/webauthn_request_delegate_android.h +++ b/chrome/browser/webauthn/android/webauthn_request_delegate_android.h
@@ -61,7 +61,7 @@ // Tells the WebAuthn Java implementation the the user has selected the // option for hybrid sign-in, which should be handled by the platform. - void ShowHybridSignIn(); + virtual void ShowHybridSignIn(); // Returns the WebContents that owns this object. content::WebContents* web_contents();
diff --git a/chrome/browser/webauthn/chrome_webauthn_autofill_interactive_uitest.cc b/chrome/browser/webauthn/chrome_webauthn_autofill_interactive_uitest.cc index cbd468b1..654bf29 100644 --- a/chrome/browser/webauthn/chrome_webauthn_autofill_interactive_uitest.cc +++ b/chrome/browser/webauthn/chrome_webauthn_autofill_interactive_uitest.cc
@@ -159,7 +159,7 @@ size_t webauthn_entry_count = 0; autofill::Suggestion webauthn_entry; for (size_t i = 0; i < suggestions.size(); ++i) { - if (suggestions[i].frontend_id == + if (suggestions[i].popup_item_id == autofill::PopupItemId::kWebauthnCredential) { webauthn_entry = suggestions[i]; suggestion_index = i; @@ -207,7 +207,7 @@ autofill::Suggestion webauthn_entry; for (suggestion_index = 0; suggestion_index < suggestions.size(); ++suggestion_index) { - if (suggestions[suggestion_index].frontend_id == + if (suggestions[suggestion_index].popup_item_id == autofill::PopupItemId::kWebauthnCredential) { webauthn_entry = suggestions[suggestion_index]; break; @@ -238,9 +238,9 @@ popup_controller = autofill_client->popup_controller_for_testing(); } for (const auto& suggestion : popup_controller->GetSuggestions()) { - EXPECT_NE(suggestion.frontend_id, + EXPECT_NE(suggestion.popup_item_id, autofill::PopupItemId::kWebauthnCredential); - EXPECT_NE(suggestion.frontend_id, + EXPECT_NE(suggestion.popup_item_id, autofill::PopupItemId::kWebauthnSignInWithAnotherDevice); } }
diff --git a/chrome/browser/webauthn/chrome_webauthn_autofill_mac_interactive_uitest.mm b/chrome/browser/webauthn/chrome_webauthn_autofill_mac_interactive_uitest.mm index bddd3cf..d21835b 100644 --- a/chrome/browser/webauthn/chrome_webauthn_autofill_mac_interactive_uitest.mm +++ b/chrome/browser/webauthn/chrome_webauthn_autofill_mac_interactive_uitest.mm
@@ -124,7 +124,7 @@ autofill::Suggestion webauthn_entry; for (suggestion_index = 0; suggestion_index < suggestions.size(); ++suggestion_index) { - if (suggestions[suggestion_index].frontend_id == + if (suggestions[suggestion_index].popup_item_id == autofill::PopupItemId::kWebauthnCredential) { webauthn_entry = suggestions[suggestion_index]; break;
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 0003b8f..61967a2 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1685973473-6ce445e67da224e060747da32ddfde6dd29c7d35.profdata +chrome-mac-arm-main-1685980729-fa83326bccfabab51437a6dfc854819e645b4aa9.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index b46d7f9..75b1964 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1685966279-d986259a1372e4bb8f3237a8b1d680ad90a28a9a.profdata +chrome-win32-main-1685977067-6fb06967e4238d5c4b1fa6013f2db02bf96266a4.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 95deb42..72fddd4 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1685966279-51da2fb2dc36da8ea8849cfe1a298dbfcc8aa8f8.profdata +chrome-win64-main-1685977067-9b2774c50b0d0ffbb9e2c5ac9f7b9f7448ee9709.profdata
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc index f38530ce..947071f 100644 --- a/chrome/common/webui_url_constants.cc +++ b/chrome/common/webui_url_constants.cc
@@ -661,6 +661,7 @@ #if BUILDFLAG(ENABLE_WAFFLE_DESKTOP) const char kChromeUIWaffleHost[] = "waffle"; +const char kChromeUIWaffleURL[] = "chrome://waffle"; #endif #if BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES)
diff --git a/chrome/renderer/accessibility/ax_tree_distiller.cc b/chrome/renderer/accessibility/ax_tree_distiller.cc index ed1f4354..51b72b5 100644 --- a/chrome/renderer/accessibility/ax_tree_distiller.cc +++ b/chrome/renderer/accessibility/ax_tree_distiller.cc
@@ -12,6 +12,9 @@ #include "base/containers/contains.h" #include "base/strings/utf_string_conversions.h" #include "content/public/renderer/render_frame.h" +#include "content/public/renderer/render_thread.h" +#include "services/metrics/public/cpp/mojo_ukm_recorder.h" +#include "services/metrics/public/cpp/ukm_builders.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "ui/accessibility/accessibility_features.h" #include "ui/accessibility/ax_node.h" @@ -91,16 +94,25 @@ content::RenderFrame* render_frame, OnAXTreeDistilledCallback on_ax_tree_distilled_callback) : render_frame_(render_frame), - on_ax_tree_distilled_callback_(on_ax_tree_distilled_callback) {} + on_ax_tree_distilled_callback_(on_ax_tree_distilled_callback) { + // TODO(crbug.com/1450930): Use a global ukm recorder instance instead. + mojo::Remote<ukm::mojom::UkmRecorderFactory> factory; + content::RenderThread::Get()->BindHostReceiver( + factory.BindNewPipeAndPassReceiver()); + ukm_recorder_ = ukm::MojoUkmRecorder::Create(*factory); +} AXTreeDistiller::~AXTreeDistiller() = default; void AXTreeDistiller::Distill(const ui::AXTree& tree, const ui::AXTreeUpdate& snapshot, - const ukm::SourceId& ukm_source_id) { + const ukm::SourceId ukm_source_id) { +#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) + base::TimeTicks start_time = base::TimeTicks::Now(); +#endif // Try with the algorithm first. std::vector<ui::AXNodeID> content_node_ids; - DistillViaAlgorithm(tree, &content_node_ids); + DistillViaAlgorithm(tree, ukm_source_id, &content_node_ids); // If Read Anything with Screen 2x is enabled and the main content extractor // is bound, kick off Screen 2x run, which distills the AXTree in the @@ -108,7 +120,8 @@ #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) if (features::IsReadAnythingWithScreen2xEnabled() && main_content_extractor_.is_bound()) { - DistillViaScreen2x(tree, snapshot, ukm_source_id, &content_node_ids); + DistillViaScreen2x(tree, snapshot, ukm_source_id, start_time, + &content_node_ids); return; } #endif @@ -119,19 +132,44 @@ void AXTreeDistiller::DistillViaAlgorithm( const ui::AXTree& tree, + const ukm::SourceId ukm_source_id, std::vector<ui::AXNodeID>* content_node_ids) { + base::TimeTicks start_time = base::TimeTicks::Now(); std::vector<const ui::AXNode*> content_root_nodes; GetContentRootNodes(tree.root(), &content_root_nodes); for (const ui::AXNode* content_root_node : content_root_nodes) { AddContentNodesToVector(content_root_node, content_node_ids); } + RecordRulesMetrics(ukm_source_id, base::TimeTicks::Now() - start_time, + !content_node_ids->empty()); +} + +void AXTreeDistiller::RecordRulesMetrics(ukm::SourceId ukm_source_id, + base::TimeDelta elapsed_time, + bool success) { + if (success) { + base::UmaHistogramTimes( + "Accessibility.ReadAnything.RulesDistillationTime.Success", + elapsed_time); + ukm::builders::Accessibility_ReadAnything(ukm_source_id) + .SetRulesDistillationTime_Success(elapsed_time.InMilliseconds()) + .Record(ukm_recorder_.get()); + } else { + base::UmaHistogramTimes( + "Accessibility.ReadAnything.RulesDistillationTime.Failure", + elapsed_time); + ukm::builders::Accessibility_ReadAnything(ukm_source_id) + .SetRulesDistillationTime_Failure(elapsed_time.InMilliseconds()) + .Record(ukm_recorder_.get()); + } } #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) void AXTreeDistiller::DistillViaScreen2x( const ui::AXTree& tree, const ui::AXTreeUpdate& snapshot, - const ukm::SourceId& ukm_source_id, + const ukm::SourceId ukm_source_id, + base::TimeTicks start_time, std::vector<ui::AXNodeID>* content_node_ids_algorithm) { DCHECK(main_content_extractor_.is_bound()); // Make a copy of |content_node_ids_algorithm| rather than sending a pointer. @@ -139,11 +177,13 @@ snapshot, ukm_source_id, base::BindOnce(&AXTreeDistiller::ProcessScreen2xResult, weak_ptr_factory_.GetWeakPtr(), tree.GetAXTreeID(), - *content_node_ids_algorithm)); + ukm_source_id, start_time, *content_node_ids_algorithm)); } void AXTreeDistiller::ProcessScreen2xResult( const ui::AXTreeID& tree_id, + const ukm::SourceId ukm_source_id, + base::TimeTicks start_time, std::vector<ui::AXNodeID> content_node_ids_algorithm, const std::vector<ui::AXNodeID>& content_node_ids_screen2x) { // Merge the results from the algorithm and from screen2x. @@ -152,6 +192,8 @@ content_node_ids_algorithm.push_back(content_node_id_screen2x); } } + RecordMergedMetrics(ukm_source_id, base::TimeTicks::Now() - start_time, + !content_node_ids_algorithm.empty()); on_ax_tree_distilled_callback_.Run(tree_id, content_node_ids_algorithm); // TODO(crbug.com/1266555): If no content nodes were identified, and @@ -174,4 +216,24 @@ on_ax_tree_distilled_callback_.Run(ui::AXTreeIDUnknown(), std::vector<ui::AXNodeID>()); } + +void AXTreeDistiller::RecordMergedMetrics(ukm::SourceId ukm_source_id, + base::TimeDelta elapsed_time, + bool success) { + if (success) { + base::UmaHistogramTimes( + "Accessibility.ReadAnything.MergedDistillationTime.Success", + elapsed_time); + ukm::builders::Accessibility_ReadAnything(ukm_source_id) + .SetMergedDistillationTime_Success(elapsed_time.InMilliseconds()) + .Record(ukm_recorder_.get()); + } else { + base::UmaHistogramTimes( + "Accessibility.ReadAnything.MergedDistillationTime.Failure", + elapsed_time); + ukm::builders::Accessibility_ReadAnything(ukm_source_id) + .SetMergedDistillationTime_Failure(elapsed_time.InMilliseconds()) + .Record(ukm_recorder_.get()); + } +} #endif
diff --git a/chrome/renderer/accessibility/ax_tree_distiller.h b/chrome/renderer/accessibility/ax_tree_distiller.h index 2e2b6d3..0e7d326d 100644 --- a/chrome/renderer/accessibility/ax_tree_distiller.h +++ b/chrome/renderer/accessibility/ax_tree_distiller.h
@@ -10,6 +10,7 @@ #include "base/functional/callback.h" #include "base/scoped_observation.h" +#include "base/time/time.h" #include "components/services/screen_ai/buildflags/buildflags.h" #include "services/metrics/public/cpp/ukm_source_id.h" #include "ui/accessibility/ax_node_id_forward.h" @@ -30,6 +31,10 @@ class AXTree; } +namespace ukm { +class MojoUkmRecorder; +} + /////////////////////////////////////////////////////////////////////////////// // AXTreeDistiller // @@ -60,7 +65,7 @@ // algorithm in this process. virtual void Distill(const ui::AXTree& tree, const ui::AXTreeUpdate& snapshot, - const ukm::SourceId& ukm_source_id); + const ukm::SourceId ukm_source_id); #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) void ScreenAIServiceReady(); @@ -70,8 +75,48 @@ // Distills the AXTree via a rules-based algorithm. Results are added to // |content_node_ids|. void DistillViaAlgorithm(const ui::AXTree& tree, + const ukm::SourceId ukm_source_id, std::vector<ui::AXNodeID>* content_node_ids); + void RecordRulesMetrics(const ukm::SourceId ukm_source_id, + base::TimeDelta elapsed_time, + bool success); + +#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) + // Passes |snapshot| to the Screen2x ML model, which identifes the main + // content nodes and calls |ProcessScreen2xResult()| on completion. + // |content_node_ids_algorithm| are the content nodes identified by the + // algorithm. They are passed along to the screen2x callback. start_time is + // the time when DistillViaAlgorithm started and is used for + // RecordMergedMetrics. + void DistillViaScreen2x( + const ui::AXTree& tree, + const ui::AXTreeUpdate& snapshot, + const ukm::SourceId ukm_source_id, + base::TimeTicks start_time, + std::vector<ui::AXNodeID>* content_node_ids_algorithm); + + // Called by the Screen2x service from the utility process. Merges the result + // from the algorithm with the result from Screen2x and passes the merged + // vector to the callback. + void ProcessScreen2xResult( + const ui::AXTreeID& tree_id, + const ukm::SourceId ukm_source_id, + base::TimeTicks start_time, + std::vector<ui::AXNodeID> content_node_ids_algorithm, + const std::vector<ui::AXNodeID>& content_node_ids_screen2x); + + // Called when the main content extractor is disconnected. Runs the callback + // with an empty list of content node IDs. + void OnMainContentExtractorDisconnected(); + + // Record time it takes for the merged algorithm (distillation via algorithm + // and via Screen2x) to run. + void RecordMergedMetrics(const ukm::SourceId ukm_source_id, + base::TimeDelta elapsed_time, + bool success); +#endif // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) + // render_frame_ is only used in the ENABLE_SCREEN_AI_SERVICE buildflag. // Fuchsia does not build with that buildflag so it is throwing // -Wunused-private-field errors. [[maybe_unused]] suppresses them. @@ -81,29 +126,9 @@ // disconnected. OnAXTreeDistilledCallback on_ax_tree_distilled_callback_; + std::unique_ptr<ukm::MojoUkmRecorder> ukm_recorder_; + #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) - // Passes |snapshot| to the Screen2x ML model, which identifes the main - // content nodes and calls |ProcessScreen2xResult()| on completion. - // |content_node_ids_algorithm| are the content nodes identified by the - // algorithm. They are passed along to the screen2x callback. - void DistillViaScreen2x( - const ui::AXTree& tree, - const ui::AXTreeUpdate& snapshot, - const ukm::SourceId& ukm_source_id, - std::vector<ui::AXNodeID>* content_node_ids_algorithm); - - // Called by the Screen2x service from the utility process. Merges the result - // from the algorithm with the result from Screen2x and passes the merged - // vector to the callback. - void ProcessScreen2xResult( - const ui::AXTreeID& tree_id, - std::vector<ui::AXNodeID> content_node_ids_algorithm, - const std::vector<ui::AXNodeID>& content_node_ids_screen2x); - - // Called when the main content extractor is disconnected. Runs the callback - // with an empty list of content node IDs. - void OnMainContentExtractorDisconnected(); - // The remote of the Screen2x main content extractor. The receiver lives in // the utility process. mojo::Remote<screen_ai::mojom::Screen2xMainContentExtractor>
diff --git a/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc b/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc index 6ec7122..55453991 100644 --- a/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc +++ b/chrome/renderer/accessibility/read_anything_app_controller_browsertest.cc
@@ -23,7 +23,7 @@ Distill, (const ui::AXTree& tree, const ui::AXTreeUpdate& snapshot, - const ukm::SourceId& ukm_source_id), + const ukm::SourceId ukm_source_id), (override)); };
diff --git a/chrome/services/speech/speech_recognition_recognizer_impl.cc b/chrome/services/speech/speech_recognition_recognizer_impl.cc index 734ea2e..77c3b67 100644 --- a/chrome/services/speech/speech_recognition_recognizer_impl.cc +++ b/chrome/services/speech/speech_recognition_recognizer_impl.cc
@@ -96,7 +96,9 @@ ->language_identification_event_callback() .Run(std::string(event.language()), static_cast<media::mojom::ConfidenceLevel>( - event.confidence_level())); + event.confidence_level()), + static_cast<media::mojom::AsrSwitchResult>( + event.asr_switch_result())); } if (response.soda_type() == soda::chrome::SodaResponse::STOP) { @@ -171,11 +173,12 @@ void SpeechRecognitionRecognizerImpl::OnLanguageIdentificationEvent( const std::string& language, - const media::mojom::ConfidenceLevel confidence_level) { + const media::mojom::ConfidenceLevel confidence_level, + const media::mojom::AsrSwitchResult asr_switch_result) { if (client_remote_.is_bound()) { client_remote_->OnLanguageIdentificationEvent( - media::mojom::LanguageIdentificationEvent::New(language, - confidence_level)); + media::mojom::LanguageIdentificationEvent::New( + language, confidence_level, asr_switch_result)); } }
diff --git a/chrome/services/speech/speech_recognition_recognizer_impl.h b/chrome/services/speech/speech_recognition_recognizer_impl.h index d2d33ec6..3548894 100644 --- a/chrome/services/speech/speech_recognition_recognizer_impl.h +++ b/chrome/services/speech/speech_recognition_recognizer_impl.h
@@ -33,7 +33,8 @@ using OnLanguageIdentificationEventCallback = base::RepeatingCallback<void( const std::string& language, - const media::mojom::ConfidenceLevel confidence_level)>; + const media::mojom::ConfidenceLevel confidence_level, + const media::mojom::AsrSwitchResult asr_switch_result)>; using OnSpeechRecognitionStoppedCallback = base::RepeatingCallback<void()>; @@ -104,7 +105,8 @@ void OnLanguageIdentificationEvent( const std::string& language, - const media::mojom::ConfidenceLevel confidence_level); + const media::mojom::ConfidenceLevel confidence_level, + const media::mojom::AsrSwitchResult asr_switch_result); void OnRecognitionStoppedCallback();
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index cb00780..0eb4325 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2133,6 +2133,7 @@ "../browser/page_load_metrics/observers/prerender_page_load_metrics_observer_browsertest.cc", "../browser/page_load_metrics/observers/security_state_page_load_metrics_observer_browsertest.cc", "../browser/page_load_metrics/observers/signed_exchange_page_load_metrics_browsertest.cc", + "../browser/page_load_metrics/observers/tab_strip_page_load_metrics_observer_browsertest.cc", "../browser/page_load_metrics/observers/third_party_metrics_observer_browsertest.cc", "../browser/page_load_metrics/observers/use_counter_page_load_metrics_observer_browsertest.cc", "../browser/page_load_metrics/page_load_metrics_browsertest.cc",
diff --git a/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js b/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js index 900911f..4dd25d8 100644 --- a/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js +++ b/chrome/test/data/extensions/platform_apps/web_view/newwindow/embedder.js
@@ -34,6 +34,9 @@ embedder.guestWithLinkURL = embedder.baseGuestURL + '/extensions/platform_apps/web_view/newwindow' + '/guest_with_link.html'; + embedder.guestOpenOnLoadURL = embedder.baseGuestURL + + '/extensions/platform_apps/web_view/newwindow' + + '/guest_opener_open_on_load.html'; }; /** @private */ @@ -652,6 +655,24 @@ embedder.setUpNewWindowRequest_(webview, 'guest.html', '', testName); } +// This is not a test in and of itself, but a means of creating a webview that +// is left in an unattached state while its opener webview is also in an +// unattached state, so that the C++ side can test it in that state. +function testDestroyOpenerBeforeAttachment() { + embedder.test.succeed(); + + let webview = new WebView(); + webview.src = embedder.guestOpenOnLoadURL; + document.body.appendChild(webview); + + // By spinning forever here, we prevent `webview` from completing the + // attachment process. But since the guest is still created and it calls + // window.open, we have a situation where two unattached webviews have an + // opener relationship. The C++ side will test that we can shutdown safely in + // this case. + while (true) {} +} + embedder.test.testList = { 'testNewWindowAttachAfterOpenerDestroyed': testNewWindowAttachAfterOpenerDestroyed, @@ -675,7 +696,9 @@ testNewWindowWebViewNameTakesPrecedence, 'testNewWindowAndUpdateOpener': testNewWindowAndUpdateOpener, 'testNewWindowDeferredAttachmentIndefinitely': - testNewWindowDeferredAttachmentIndefinitely + testNewWindowDeferredAttachmentIndefinitely, + 'testDestroyOpenerBeforeAttachment': + testDestroyOpenerBeforeAttachment }; onload = function() {
diff --git a/chrome/test/data/extensions/platform_apps/web_view/newwindow/guest_opener_open_on_load.html b/chrome/test/data/extensions/platform_apps/web_view/newwindow/guest_opener_open_on_load.html new file mode 100644 index 0000000..e961feb3 --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/newwindow/guest_opener_open_on_load.html
@@ -0,0 +1,13 @@ +<!-- +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. +--> +<html> +<body> +<script> + // A guest that opens a new window on load. + window.open('guest.html'); +</script> +</body> +</html>
diff --git a/chrome/test/data/webui/chromeos/print_management/print_management_test.ts b/chrome/test/data/webui/chromeos/print_management/print_management_test.ts index 94b4c193..a525cc7 100644 --- a/chrome/test/data/webui/chromeos/print_management/print_management_test.ts +++ b/chrome/test/data/webui/chromeos/print_management/print_management_test.ts
@@ -773,14 +773,24 @@ await mojoApi_.whenCalled('getPrintJobs'); flush(); - // Assert that printer setup UI is not hidden when flag enabled. + // Assert that printer setup UI is not hidden and ongoing empty state + // message is hidden when flag enabled and there are no printer jobs. + assertTrue( + querySelector<HTMLElement>(page!, '#ongoingEmptyState')?.hidden as + boolean); assertFalse( querySelector<PrinterSetupInfoElement>( page!, PrinterSetupInfoElement.is) ?.hidden as boolean); }); - test('CancelOngoingPrintJob', async () => { + // Verify expected elements render when there are no ongoing jobs, at least + // one historical job, and the printer setup flag is off. + test('CancelOngoingPrintJob_SetupAssistanceFlagOff', async () => { + // Ensure printer setup assistance flag is disabled for test. + loadTimeData.overrideValues({ + isSetupAssistanceEnabled: false, + }); const kId = 'fileA'; const kTitle = 'titleA'; const kTime = @@ -808,10 +818,54 @@ /*shouldAttemptCancel*/ true, expectedHistoryList); flush(); - // Verify that there are no ongoing print jobs and history list is - // populated. + // Verify that there are no ongoing print jobs, history list is + // populated, and printer setup UI is hidden. assertTrue(!querySelector(page!, '#ongoingList')); verifyPrintJobs(expectedHistoryList, getHistoryPrintJobEntries(page!)); + assertFalse(isVisible(querySelector<PrinterSetupInfoElement>( + page!, PrinterSetupInfoElement.is))); + }); + + // Verify expected elements render when there are no ongoing jobs, at least + // one historical job, and the printer setup flag is on. + test('CancelOngoingPrintJob_SetupAssistanceFlagOn', async () => { + // Ensure printer setup assistance flag is enabled for test. + loadTimeData.overrideValues({ + isSetupAssistanceEnabled: true, + }); + const kId = 'fileA'; + const kTitle = 'titleA'; + const kTime = + convertToMojoTime(new Date(Date.parse('February 5, 2020 03:23:00'))); + const expectedArr = [ + createJobEntry( + kId, kTitle, kTime, PrinterErrorCode.kNoError, + /*completedInfo=*/ undefined, + createOngoingPrintJobInfo( + /*printedPages=*/ 0, ActivePrintJobState.kStarted)), + ]; + + const expectedHistoryList = [createJobEntry( + kId, kTitle, kTime, PrinterErrorCode.kNoError, + createCompletedPrintJobInfo(PrintJobCompletionStatus.kCanceled))]; + + await initializePrintManagementApp(expectedArr); + await mojoApi_.whenCalled('getPrintJobs'); + flush(); + const jobEntries = getOngoingPrintJobEntries(page!); + verifyPrintJobs(expectedArr, jobEntries); + + await simulateCancelPrintJob( + jobEntries[0]!, mojoApi_, + /*shouldAttemptCancel*/ true, expectedHistoryList); + flush(); + + // Verify that there are no ongoing print jobs, history list is + // populated, and printer setup UI is hidden. + assertTrue(!querySelector(page!, '#ongoingList')); + verifyPrintJobs(expectedHistoryList, getHistoryPrintJobEntries(page!)); + assertFalse(isVisible(querySelector<PrinterSetupInfoElement>( + page!, PrinterSetupInfoElement.is))); }); test('CancelOngoingPrintJobNotAttempted', async () => {
diff --git a/chrome/test/data/webui/privacy_sandbox/privacy_sandbox_dialog_test.ts b/chrome/test/data/webui/privacy_sandbox/privacy_sandbox_dialog_test.ts index 148bdc9..36a331c 100644 --- a/chrome/test/data/webui/privacy_sandbox/privacy_sandbox_dialog_test.ts +++ b/chrome/test/data/webui/privacy_sandbox/privacy_sandbox_dialog_test.ts
@@ -767,13 +767,13 @@ test('validDialog', async function() { await verifyActionOccured( - browserProxy, PrivacySandboxPromptAction.NOTICE_SHOWN); + browserProxy, PrivacySandboxPromptAction.RESTRICTED_NOTICE_SHOWN); assertTrue(!!page.shadowRoot!.querySelector('div')); }); test('settingsClicked', async function() { await verifyActionOccured( - browserProxy, PrivacySandboxPromptAction.NOTICE_SHOWN); + browserProxy, PrivacySandboxPromptAction.RESTRICTED_NOTICE_SHOWN); testClickButton('#settingsButton', page); await verifyActionOccured( browserProxy, @@ -782,7 +782,7 @@ test('acknowledgeClicked', async function() { await verifyActionOccured( - browserProxy, PrivacySandboxPromptAction.NOTICE_SHOWN); + browserProxy, PrivacySandboxPromptAction.RESTRICTED_NOTICE_SHOWN); testClickButton('#ackButton', page); await verifyActionOccured( browserProxy, PrivacySandboxPromptAction.RESTRICTED_NOTICE_ACKNOWLEDGE); @@ -794,7 +794,7 @@ // resolved. test.skip('moreButton', async function() { await verifyActionOccured( - browserProxy, PrivacySandboxPromptAction.NOTICE_SHOWN); + browserProxy, PrivacySandboxPromptAction.RESTRICTED_NOTICE_SHOWN); await flushTasks(); const scrollable: HTMLElement = @@ -839,7 +839,8 @@ } await verifyActionOccured( - browserProxy, PrivacySandboxPromptAction.NOTICE_MORE_BUTTON_CLICKED); + browserProxy, + PrivacySandboxPromptAction.RESTRICTED_NOTICE_MORE_BUTTON_CLICKED); await page.whenWasScrolledToBottomForTest(); // After scrolling down, the "More" button is hidden and dialog button are
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn index b9f33e5..a05effde 100644 --- a/chrome/test/data/webui/settings/chromeos/BUILD.gn +++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -116,7 +116,6 @@ "app_management/fake_page_handler.ts", "app_management/file_handling_item_test.ts", "app_management/managed_apps_test.ts", - "app_management/pin_to_shelf_item_test.js", "app_management/plugin_vm_detail_view_test.js", "app_management/reducers_test.js", "app_management/resize_lock_item_test.js", @@ -204,6 +203,7 @@ "os_apps_page/app_management_page/borealis_detail_view_test.ts", "os_apps_page/app_management_page/chrome_app_detail_view_test.ts", "os_apps_page/app_management_page/main_view_test.ts", + "os_apps_page/app_management_page/pin_to_shelf_item_test.ts", "os_apps_page/app_management_page/pwa_detail_view_test.ts", "os_bluetooth_page/os_bluetooth_change_device_name_dialog_tests.js",
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/pin_to_shelf_item_test.js b/chrome/test/data/webui/settings/chromeos/app_management/pin_to_shelf_item_test.js deleted file mode 100644 index 3d3856a..0000000 --- a/chrome/test/data/webui/settings/chromeos/app_management/pin_to_shelf_item_test.js +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -'use strict'; - -import {AppManagementStore} from 'chrome://os-settings/os_settings.js'; -import {convertOptionalBoolToBool} from 'chrome://resources/cr_components/app_management/util.js'; -import {setupFakeHandler, replaceBody} from './test_util.js'; -import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; -import {AppType} from 'chrome://resources/cr_components/app_management/app_management.mojom-webui.js'; - -suite('<app-management-pin-to-shelf-item>', () => { - let pinToShelfItem; - let fakeHandler; - - setup(async () => { - fakeHandler = setupFakeHandler(); - pinToShelfItem = document.createElement('app-management-pin-to-shelf-item'); - - replaceBody(pinToShelfItem); - flushTasks(); - }); - - test('Toggle pin to shelf', async () => { - const arcOptions = { - type: AppType.kArc, - permissions: {}, - }; - - // Add an arc app, and make it the currently selected app. - const app = await fakeHandler.addApp('app1', arcOptions); - - await fakeHandler.flushPipesForTesting(); - pinToShelfItem.app = app; - assertFalse(convertOptionalBoolToBool( - AppManagementStore.getInstance().data.apps[app.id].isPinned)); - - pinToShelfItem.click(); - flushTasks(); - await fakeHandler.flushPipesForTesting(); - - assertTrue(convertOptionalBoolToBool( - AppManagementStore.getInstance().data.apps[app.id].isPinned)); - }); -});
diff --git a/chrome/test/data/webui/settings/chromeos/main_page_container_test.js b/chrome/test/data/webui/settings/chromeos/main_page_container_test.js index e1bd69a..25db0f7 100644 --- a/chrome/test/data/webui/settings/chromeos/main_page_container_test.js +++ b/chrome/test/data/webui/settings/chromeos/main_page_container_test.js
@@ -220,6 +220,12 @@ assertEquals(1, numActive); } + suite('From Initial', () => { + test('to Root should only show Network page', () => { + assertOnlyActivePageIsVisible('internet'); + }); + }); + suite('From Root', () => { test('to Page should result in only one active page', async () => { // Simulate navigating from root to Network page
diff --git a/chrome/test/data/webui/settings/chromeos/os_apps_page/app_management_page/pin_to_shelf_item_test.ts b/chrome/test/data/webui/settings/chromeos/os_apps_page/app_management_page/pin_to_shelf_item_test.ts new file mode 100644 index 0000000..64c18dd --- /dev/null +++ b/chrome/test/data/webui/settings/chromeos/os_apps_page/app_management_page/pin_to_shelf_item_test.ts
@@ -0,0 +1,56 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'chrome://os-settings/lazy_load.js'; + +import {AppManagementPinToShelfItemElement} from 'chrome://os-settings/lazy_load.js'; +import {AppManagementStore} from 'chrome://os-settings/os_settings.js'; +import {AppType} from 'chrome://resources/cr_components/app_management/app_management.mojom-webui.js'; +import {convertOptionalBoolToBool} from 'chrome://resources/cr_components/app_management/util.js'; +import {assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; + +import {FakePageHandler} from '../../app_management/fake_page_handler.js'; +import {replaceBody, setupFakeHandler} from '../../app_management/test_util.js'; + +suite('<app-management-pin-to-shelf-item>', () => { + let pinToShelfItem: AppManagementPinToShelfItemElement; + let fakeHandler: FakePageHandler; + + setup(() => { + fakeHandler = setupFakeHandler(); + pinToShelfItem = document.createElement('app-management-pin-to-shelf-item'); + + replaceBody(pinToShelfItem); + flushTasks(); + }); + + teardown(() => { + pinToShelfItem.remove(); + }); + + test('Toggle pin to shelf', async () => { + const arcOptions = { + type: AppType.kArc, + permissions: {}, + }; + + // Add an arc app, and make it the currently selected app. + const app = await fakeHandler.addApp('app1', arcOptions); + + await fakeHandler.flushPipesForTesting(); + pinToShelfItem.app = app; + let selectedApp = AppManagementStore.getInstance().data.apps[app.id]; + assertTrue(!!selectedApp); + assertFalse(convertOptionalBoolToBool(selectedApp.isPinned)); + + pinToShelfItem.click(); + flushTasks(); + await fakeHandler.flushPipesForTesting(); + + selectedApp = AppManagementStore.getInstance().data.apps[app.id]; + assertTrue(!!selectedApp); + assertTrue(convertOptionalBoolToBool(selectedApp.isPinned)); + }); +});
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js index e1c8d0cf..6fafe62 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -192,7 +192,6 @@ ['AppManagementFileHandlingItem', 'app_management/file_handling_item_test.js'], ['AppManagementManagedApps', 'app_management/managed_apps_test.js'], ['AppManagementPage', 'app_management/app_management_page_tests.js'], - ['AppManagementPinToShelfItem', 'app_management/pin_to_shelf_item_test.js'], [ 'AppManagementPluginVmDetailView', 'app_management/plugin_vm_detail_view_test.js', @@ -503,6 +502,10 @@ 'os_apps_page/app_management_page/main_view_test.js' ], [ + 'OsAppsPageAppManagementPagePinToShelfItem', + 'os_apps_page/app_management_page/pin_to_shelf_item_test.js' + ], + [ 'OsAppsPageAppManagementPagePwaDetailView', 'os_apps_page/app_management_page/pwa_detail_view_test.js' ],
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_ui/os_settings_ui_page_visibility_test.ts b/chrome/test/data/webui/settings/chromeos/os_settings_ui/os_settings_ui_page_visibility_test.ts index 40bac88..52f5ddf 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_ui/os_settings_ui_page_visibility_test.ts +++ b/chrome/test/data/webui/settings/chromeos/os_settings_ui/os_settings_ui_page_visibility_test.ts
@@ -11,7 +11,7 @@ import 'chrome://os-settings/os_settings.js'; -import {createRoutesForTesting, CrSettingsPrefs, MainPageContainerElement, OsSettingsMainElement, OsSettingsMenuElement, OsSettingsSectionElement, OsSettingsUiElement, Router} from 'chrome://os-settings/os_settings.js'; +import {createRoutesForTesting, CrSettingsPrefs, MainPageContainerElement, OsSettingsMainElement, OsSettingsMenuElement, OsSettingsRoutes, OsSettingsUiElement, Router} from 'chrome://os-settings/os_settings.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -23,6 +23,7 @@ let settingsMain: OsSettingsMainElement; let mainPageContainer: MainPageContainerElement; let menu: OsSettingsMenuElement; + let testRoutes: OsSettingsRoutes; async function createUi() { ui = document.createElement('os-settings-ui'); @@ -51,17 +52,36 @@ flush(); } - function queryActivePages(): NodeListOf<OsSettingsSectionElement> { - return mainPageContainer.shadowRoot! - .querySelectorAll<OsSettingsSectionElement>( - `os-settings-section[active]`); - } - function queryMenuItem(pageName: string): HTMLElement|null { return menu.shadowRoot!.querySelector<HTMLElement>( `a.item[data-page-name='${pageName}']`); } + /** + * Asserts the following: + * - Only one page is marked active + * - Active page does not have style "display: none" + * - Inactive pages have style "display: none" + */ + function assertOnlyActivePageIsVisible(pageName: string): void { + const pages = + mainPageContainer.shadowRoot!.querySelectorAll('os-settings-section'); + let numActive = 0; + + for (const page of pages) { + const displayStyle = getComputedStyle(page).display; + if (page.hasAttribute('active')) { + numActive++; + assertNotEquals('none', displayStyle); + assertEquals(pageName, page.section); + } else { + assertEquals('none', displayStyle); + } + } + + assertEquals(1, numActive); + } + suiteSetup(async () => { loadTimeData.overrideValues({ isRevampWayfindingEnabled: true, @@ -69,7 +89,7 @@ }); // Recreate routes and Router so Kerberos route exists - const testRoutes = createRoutesForTesting(); + testRoutes = createRoutesForTesting(); Router.resetInstanceForTesting(new Router(testRoutes)); await createUi(); @@ -84,6 +104,11 @@ assertTrue(document.body.classList.contains('revamp-wayfinding-enabled')); }); + test('Network page should be the default visible page', () => { + Router.getInstance().navigateTo(testRoutes.BASIC); + assertOnlyActivePageIsVisible('internet'); + }); + const pageNames = [ 'apps', 'bluetooth', @@ -105,7 +130,7 @@ ]; for (const pageName of pageNames) { test( - `Clicking menu item for ${pageName} page should show that page`, + `Clicking menu item for ${pageName} page should show only that page`, async () => { const pageReadyPromise = eventToPromise('show-container', window); @@ -116,13 +141,7 @@ await pageReadyPromise; - const activePages = queryActivePages(); - assertEquals(1, activePages.length); - - const page = activePages[0]; - assert(page); - assertEquals(pageName, page.section); - assertNotEquals('none', getComputedStyle(page).display); + assertOnlyActivePageIsVisible(pageName); }); } });
diff --git a/chrome/updater/mac/signing/config_factory.py b/chrome/updater/mac/signing/config_factory.py index 3cae0ed..00b3da3 100644 --- a/chrome/updater/mac/signing/config_factory.py +++ b/chrome/updater/mac/signing/config_factory.py
@@ -11,5 +11,11 @@ def get_invoker_class(): """Returns the subclass of |invoker.Interface| to use.""" + try: + from signing.internal_invoker import Invoker + return Invoker + except ImportError as e: + pass + from signing.standard_invoker import Invoker return Invoker
diff --git a/components/autofill/core/browser/autocomplete_history_manager.cc b/components/autofill/core/browser/autocomplete_history_manager.cc index c5e7945..77550406 100644 --- a/components/autofill/core/browser/autocomplete_history_manager.cc +++ b/components/autofill/core/browser/autocomplete_history_manager.cc
@@ -156,14 +156,14 @@ void AutocompleteHistoryManager::OnRemoveCurrentSingleFieldSuggestion( const std::u16string& field_name, const std::u16string& value, - Suggestion::FrontendId frontend_id) { + PopupItemId popup_item_id) { if (profile_database_) profile_database_->RemoveFormValueForElementName(field_name, value); } void AutocompleteHistoryManager::OnSingleFieldSuggestionSelected( const std::u16string& value, - Suggestion::FrontendId frontend_id) { + PopupItemId popup_item_id) { // Try to find the AutofillEntry associated with the given suggestion. auto last_entries_iter = last_entries_.find(value); if (last_entries_iter == last_entries_.end()) {
diff --git a/components/autofill/core/browser/autocomplete_history_manager.h b/components/autofill/core/browser/autocomplete_history_manager.h index 037472c..a6c735c4 100644 --- a/components/autofill/core/browser/autocomplete_history_manager.h +++ b/components/autofill/core/browser/autocomplete_history_manager.h
@@ -54,13 +54,11 @@ void OnWillSubmitFormWithFields(const std::vector<FormFieldData>& fields, bool is_autocomplete_enabled) override; void CancelPendingQueries(const SuggestionsHandler* handler) override; - void OnRemoveCurrentSingleFieldSuggestion( - const std::u16string& field_name, - const std::u16string& value, - Suggestion::FrontendId frontend_id) override; - void OnSingleFieldSuggestionSelected( - const std::u16string& value, - Suggestion::FrontendId frontend_id) override; + void OnRemoveCurrentSingleFieldSuggestion(const std::u16string& field_name, + const std::u16string& value, + PopupItemId popup_item_id) override; + void OnSingleFieldSuggestionSelected(const std::u16string& value, + PopupItemId popup_item_id) override; // Initializes the instance with the given parameters. // |profile_database_| is a profile-scope DB used to access autocomplete data.
diff --git a/components/autofill/core/browser/autofill_client.h b/components/autofill/core/browser/autofill_client.h index 69af57e..c34405e 100644 --- a/components/autofill/core/browser/autofill_client.h +++ b/components/autofill/core/browser/autofill_client.h
@@ -20,6 +20,7 @@ #include "components/autofill/core/browser/payments/legal_message_line.h" #include "components/autofill/core/browser/payments/risk_data_loader.h" #include "components/autofill/core/browser/ui/fast_checkout_client.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" #include "components/autofill/core/browser/ui/popup_types.h" #include "components/autofill/core/browser/ui/suggestion.h" #include "components/autofill/core/common/aliases.h" @@ -780,7 +781,7 @@ virtual bool IsContextSecure() const = 0; // Handles simple actions for the autofill popups. - virtual void ExecuteCommand(Suggestion::FrontendId id) = 0; + virtual void ExecuteCommand(PopupItemId popup_item_id) = 0; // Returns a LogManager instance. May be null for platforms that don't support // this.
diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc index 487cfde..72c74f8 100644 --- a/components/autofill/core/browser/autofill_external_delegate.cc +++ b/components/autofill/core/browser/autofill_external_delegate.cc
@@ -45,9 +45,9 @@ // Returns true if the suggestion entry is an Autofill warning message. // Warning messages should display on top of suggestion list. -bool IsAutofillWarningEntry(Suggestion::FrontendId frontend_id) { - return frontend_id == PopupItemId::kInsecureContextPaymentDisabledMessage || - frontend_id == PopupItemId::kMixedFormMessage; +bool IsAutofillWarningEntry(PopupItemId popup_item_id) { + return popup_item_id == PopupItemId::kInsecureContextPaymentDisabledMessage || + popup_item_id == PopupItemId::kMixedFormMessage; } } // namespace @@ -97,7 +97,7 @@ if (should_show_scan_credit_card_) { Suggestion scan_credit_card( l10n_util::GetStringUTF16(IDS_AUTOFILL_SCAN_CREDIT_CARD)); - scan_credit_card.frontend_id = PopupItemId::kScanCreditCard; + scan_credit_card.popup_item_id = PopupItemId::kScanCreditCard; scan_credit_card.icon = "scanCreditCardIcon"; suggestions.push_back(scan_credit_card); } @@ -106,7 +106,8 @@ // suggestions. has_autofill_suggestions_ = false; for (auto& suggestion : suggestions) { - if (suggestion.frontend_id.is_an_address_or_card_popup_item_id()) { + if (suggestion.popup_item_id == PopupItemId::kAddressEntry || + suggestion.popup_item_id == PopupItemId::kCreditCardEntry) { has_autofill_suggestions_ = true; break; } @@ -115,7 +116,7 @@ if (should_show_cards_from_account_option_) { suggestions.emplace_back( l10n_util::GetStringUTF16(IDS_AUTOFILL_SHOW_ACCOUNT_CARDS)); - suggestions.back().frontend_id = PopupItemId::kShowAccountCards; + suggestions.back().popup_item_id = PopupItemId::kShowAccountCards; suggestions.back().icon = "google"; } @@ -196,20 +197,20 @@ const Suggestion& suggestion) { ClearPreviewedForm(); - const Suggestion::FrontendId frontend_id = suggestion.frontend_id; const Suggestion::BackendId backend_id = suggestion.GetPayload<Suggestion::BackendId>(); // Only preview the data if it is a profile or a virtual card. - if (frontend_id.is_an_address_or_card_popup_item_id()) { - FillAutofillFormData(frontend_id, backend_id, true, + if (suggestion.popup_item_id == PopupItemId::kAddressEntry || + suggestion.popup_item_id == PopupItemId::kCreditCardEntry) { + FillAutofillFormData(suggestion.popup_item_id, backend_id, true, AutofillTriggerSource::kKeyboardAccessory); - } else if (frontend_id == PopupItemId::kAutocompleteEntry || - frontend_id == PopupItemId::kIbanEntry || - frontend_id == PopupItemId::kMerchantPromoCodeEntry) { + } else if (suggestion.popup_item_id == PopupItemId::kAutocompleteEntry || + suggestion.popup_item_id == PopupItemId::kIbanEntry || + suggestion.popup_item_id == PopupItemId::kMerchantPromoCodeEntry) { driver_->RendererShouldPreviewFieldWithValue(query_field_.global_id(), suggestion.main_text.value); - } else if (frontend_id == PopupItemId::kVirtualCreditCardEntry) { + } else if (suggestion.popup_item_id == PopupItemId::kVirtualCreditCardEntry) { manager_->FillOrPreviewVirtualCardInformation( mojom::RendererFormDataAction::kPreview, backend_id.value(), query_form_, query_field_, AutofillTriggerSource::kKeyboardAccessory); @@ -218,7 +219,7 @@ void AutofillExternalDelegate::DidAcceptSuggestion(const Suggestion& suggestion, int position) { - switch (suggestion.frontend_id.as_popup_item_id()) { + switch (suggestion.popup_item_id) { case PopupItemId::kAutofillOptions: // User selected 'Autofill Options'. autofill_metrics::LogAutofillSelectedManageEntry(popup_type_); @@ -246,7 +247,7 @@ query_field_.global_id(), suggestion.GetPayload<Suggestion::ValueToFill>().value()); manager_->OnSingleFieldSuggestionSelected(suggestion.main_text.value, - suggestion.frontend_id, + suggestion.popup_item_id, query_form_, query_field_); break; case PopupItemId::kAutocompleteEntry: @@ -258,7 +259,7 @@ driver_->RendererShouldFillFieldWithValue(query_field_.global_id(), suggestion.main_text.value); manager_->OnSingleFieldSuggestionSelected(suggestion.main_text.value, - suggestion.frontend_id, + suggestion.popup_item_id, query_form_, query_field_); break; case PopupItemId::kScanCreditCard: @@ -267,7 +268,7 @@ GetWeakPtr(), AutofillTriggerSource::kPopup)); break; case PopupItemId::kCreditCardSigninPromo: - manager_->client()->ExecuteCommand(suggestion.frontend_id); + manager_->client()->ExecuteCommand(suggestion.popup_item_id); break; case PopupItemId::kShowAccountCards: manager_->OnUserAcceptedCardsFromAccountOption(); @@ -281,9 +282,9 @@ break; case PopupItemId::kVirtualCreditCardEntry: // There can be multiple virtual credit cards that all rely on - // PopupItemId::kVirtualCreditCardEntry as a frontend_id. In this case, - // the payload contains the backend id, which is a GUID that identifies - // the actually chosen credit card. + // PopupItemId::kVirtualCreditCardEntry as a `popup_item_id`. In this + // case, the payload contains the backend id, which is a GUID that + // identifies the actually chosen credit card. manager_->FillOrPreviewVirtualCardInformation( mojom::RendererFormDataAction::kFill, suggestion.GetPayload<Suggestion::BackendId>().value(), query_form_, @@ -292,14 +293,15 @@ case PopupItemId::kSeePromoCodeDetails: manager_->OnSeePromoCodeOfferDetailsSelected( suggestion.GetPayload<GURL>(), suggestion.main_text.value, - suggestion.frontend_id, query_form_, query_field_); + suggestion.popup_item_id, query_form_, query_field_); break; default: - if (suggestion.frontend_id.is_an_address_or_card_popup_item_id()) { + if (suggestion.popup_item_id == PopupItemId::kAddressEntry || + suggestion.popup_item_id == PopupItemId::kCreditCardEntry) { autofill_metrics::LogAutofillSuggestionAcceptedIndex( position, popup_type_, manager_->client()->IsOffTheRecord()); } - FillAutofillFormData(suggestion.frontend_id, + FillAutofillFormData(suggestion.popup_item_id, suggestion.GetPayload<Suggestion::BackendId>(), false, AutofillTriggerSource::kPopup); break; @@ -307,12 +309,12 @@ if (should_show_scan_credit_card_) { AutofillMetrics::LogScanCreditCardPromptMetric( - suggestion.frontend_id == PopupItemId::kScanCreditCard + suggestion.popup_item_id == PopupItemId::kScanCreditCard ? AutofillMetrics::SCAN_CARD_ITEM_SELECTED : AutofillMetrics::SCAN_CARD_OTHER_ITEM_SELECTED); } - if (suggestion.frontend_id == PopupItemId::kShowAccountCards) { + if (suggestion.popup_item_id == PopupItemId::kShowAccountCards) { should_show_cards_from_account_option_ = false; manager_->RefetchCardsAndUpdatePopup(query_form_, query_field_); } else { @@ -322,25 +324,26 @@ bool AutofillExternalDelegate::GetDeletionConfirmationText( const std::u16string& value, - Suggestion::FrontendId frontend_id, + PopupItemId popup_item_id, Suggestion::BackendId backend_id, std::u16string* title, std::u16string* body) { - return manager_->GetDeletionConfirmationText(value, frontend_id, backend_id, + return manager_->GetDeletionConfirmationText(value, popup_item_id, backend_id, title, body); } bool AutofillExternalDelegate::RemoveSuggestion( const std::u16string& value, - Suggestion::FrontendId frontend_id, + PopupItemId popup_item_id, Suggestion::BackendId backend_id) { - if (frontend_id.is_an_address_or_card_popup_item_id()) { + if (popup_item_id == PopupItemId::kAddressEntry || + popup_item_id == PopupItemId::kCreditCardEntry) { return manager_->RemoveAutofillProfileOrCreditCard(backend_id); } - if (frontend_id == PopupItemId::kAutocompleteEntry) { + if (popup_item_id == PopupItemId::kAutocompleteEntry) { manager_->RemoveCurrentSingleFieldSuggestion(query_field_.name, value, - frontend_id); + popup_item_id); return true; } @@ -391,12 +394,12 @@ } void AutofillExternalDelegate::FillAutofillFormData( - Suggestion::FrontendId frontend_id, + PopupItemId popup_item_id, Suggestion::BackendId backend_id, bool is_preview, const AutofillTriggerSource trigger_source) { // If the selected element is a warning we don't want to do anything. - if (IsAutofillWarningEntry(frontend_id)) { + if (IsAutofillWarningEntry(popup_item_id)) { return; } @@ -413,8 +416,8 @@ void AutofillExternalDelegate::PossiblyRemoveAutofillWarnings( std::vector<Suggestion>* suggestions) { while (suggestions->size() > 1 && - IsAutofillWarningEntry(suggestions->front().frontend_id) && - !IsAutofillWarningEntry(suggestions->back().frontend_id)) { + IsAutofillWarningEntry(suggestions->front().popup_item_id) && + !IsAutofillWarningEntry(suggestions->back().popup_item_id)) { // If we received warnings instead of suggestions from Autofill but regular // suggestions from autocomplete, don't show the Autofill warnings. suggestions->erase(suggestions->begin()); @@ -443,8 +446,8 @@ value = base::i18n::ToUpper(value); #endif - suggestions->push_back(Suggestion(value)); - suggestions->back().frontend_id = PopupItemId::kClearForm; + suggestions->emplace_back(value); + suggestions->back().popup_item_id = PopupItemId::kClearForm; suggestions->back().icon = "clearIcon"; suggestions->back().acceptance_a11y_announcement = l10n_util::GetStringUTF16(IDS_AUTOFILL_A11Y_ANNOUNCE_CLEARED_FORM); @@ -452,8 +455,8 @@ // Append the 'Autofill settings' menu item, or the menu item specified in the // popup layout experiment. - suggestions->push_back(Suggestion(GetSettingsSuggestionValue())); - suggestions->back().frontend_id = PopupItemId::kAutofillOptions; + suggestions->emplace_back(GetSettingsSuggestionValue()); + suggestions->back().popup_item_id = PopupItemId::kAutofillOptions; suggestions->back().icon = "settingsIcon"; // On Android and Desktop, Google Pay branding is shown along with Settings. @@ -480,7 +483,7 @@ std::set<std::u16string> data_list_set(data_list_values_.begin(), data_list_values_.end()); base::EraseIf(*suggestions, [&data_list_set](const Suggestion& suggestion) { - return suggestion.frontend_id == PopupItemId::kAutocompleteEntry && + return suggestion.popup_item_id == PopupItemId::kAutocompleteEntry && base::Contains(data_list_set, suggestion.main_text.value); }); @@ -500,7 +503,7 @@ (*suggestions)[i].main_text = Suggestion::Text( data_list_values_[i], Suggestion::Text::IsPrimary(true)); (*suggestions)[i].labels = {{Suggestion::Text(data_list_labels_[i])}}; - (*suggestions)[i].frontend_id = PopupItemId::kDatalistEntry; + (*suggestions)[i].popup_item_id = PopupItemId::kDatalistEntry; } }
diff --git a/components/autofill/core/browser/autofill_external_delegate.h b/components/autofill/core/browser/autofill_external_delegate.h index be59cdd..afbfe40 100644 --- a/components/autofill/core/browser/autofill_external_delegate.h +++ b/components/autofill/core/browser/autofill_external_delegate.h
@@ -15,6 +15,7 @@ #include "base/memory/weak_ptr.h" #include "components/autofill/core/browser/autofill_trigger_source.h" #include "components/autofill/core/browser/ui/autofill_popup_delegate.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" #include "components/autofill/core/browser/ui/suggestion.h" #include "components/autofill/core/common/aliases.h" #include "components/autofill/core/common/form_data.h" @@ -51,12 +52,12 @@ void DidSelectSuggestion(const Suggestion& suggestion) override; void DidAcceptSuggestion(const Suggestion& suggestion, int position) override; bool GetDeletionConfirmationText(const std::u16string& value, - Suggestion::FrontendId frontend_id, + PopupItemId popup_item_id, Suggestion::BackendId backend_id, std::u16string* title, std::u16string* body) override; bool RemoveSuggestion(const std::u16string& value, - Suggestion::FrontendId frontend_id, + PopupItemId popup_item_id, Suggestion::BackendId backend_id) override; void ClearPreviewedForm() override; @@ -129,7 +130,7 @@ // If `is_preview` is true then this is just a preview to show the user what // would be selected and if `is_preview` is false then the user has selected // this data. - void FillAutofillFormData(Suggestion::FrontendId frontend_id, + void FillAutofillFormData(PopupItemId popup_item_id, Suggestion::BackendId backend_id, bool is_preview, const AutofillTriggerSource trigger_source);
diff --git a/components/autofill/core/browser/autofill_external_delegate_unittest.cc b/components/autofill/core/browser/autofill_external_delegate_unittest.cc index 15e346a..f2460ad2 100644 --- a/components/autofill/core/browser/autofill_external_delegate_unittest.cc +++ b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
@@ -43,11 +43,6 @@ namespace autofill { namespace { - -// A constant value to use as an Autofill profile ID. -constexpr Suggestion::FrontendId kAutofillProfileId = - Suggestion::FrontendId(kAddressEntry); - class MockAutofillDriver : public TestAutofillDriver { public: MockAutofillDriver() = default; @@ -90,7 +85,7 @@ const std::vector<std::u16string>& lables), (override)); MOCK_METHOD(void, HideAutofillPopup, (PopupHidingReason), (override)); - MOCK_METHOD(void, ExecuteCommand, (Suggestion::FrontendId), (override)); + MOCK_METHOD(void, ExecuteCommand, (PopupItemId), (override)); MOCK_METHOD(void, OpenPromoCodeOfferDetailsURL, (const GURL& url), @@ -209,7 +204,7 @@ void IssueOnSuggestionsReturned(FieldGlobalId field_id) { std::vector<Suggestion> suggestions; suggestions.emplace_back(); - suggestions[0].frontend_id = kAutofillProfileId; + suggestions[0].popup_item_id = PopupItemId::kAddressEntry; external_delegate_->OnSuggestionsReturned(field_id, suggestions, AutoselectFirstSuggestion(false)); } @@ -248,11 +243,11 @@ // This should call ShowAutofillPopup. std::vector<Suggestion> autofill_item; autofill_item.emplace_back(); - autofill_item[0].frontend_id = kAutofillProfileId; + autofill_item[0].popup_item_id = PopupItemId::kAddressEntry; external_delegate_->OnSuggestionsReturned(field_id_, autofill_item, AutoselectFirstSuggestion(false)); EXPECT_THAT(open_args.suggestions, - SuggestionVectorIdsAre(kAutofillProfileId, + SuggestionVectorIdsAre(PopupItemId::kAddressEntry, #if !BUILDFLAG(IS_ANDROID) PopupItemId::kSeparator, #endif @@ -290,7 +285,7 @@ // This should call ShowAutofillPopup. std::vector<Suggestion> autofill_item; autofill_item.emplace_back(); - autofill_item[0].frontend_id = kAutofillProfileId; + autofill_item[0].popup_item_id = PopupItemId::kAddressEntry; external_delegate_->OnSuggestionsReturned(field_id_, autofill_item, AutoselectFirstSuggestion(false)); EXPECT_THAT(open_args.suggestions, @@ -298,7 +293,7 @@ #if !BUILDFLAG(IS_ANDROID) PopupItemId::kSeparator, #endif - kAutofillProfileId, + PopupItemId::kAddressEntry, #if !BUILDFLAG(IS_ANDROID) PopupItemId::kSeparator, #endif @@ -343,7 +338,7 @@ // Ensure the popup is displayed. std::vector<Suggestion> autofill_item; autofill_item.emplace_back(); - autofill_item[0].frontend_id = kAutofillProfileId; + autofill_item[0].popup_item_id = PopupItemId::kAddressEntry; external_delegate_->OnSuggestionsReturned(field_id_, autofill_item, AutoselectFirstSuggestion(false)); EXPECT_THAT(open_args.suggestions, @@ -351,7 +346,7 @@ #if !BUILDFLAG(IS_ANDROID) PopupItemId::kSeparator, #endif - kAutofillProfileId, + PopupItemId::kAddressEntry, #if !BUILDFLAG(IS_ANDROID) PopupItemId::kSeparator, #endif @@ -396,7 +391,7 @@ autofill_item[0].main_text = Suggestion::Text(u"Rick", Suggestion::Text::IsPrimary(true)); autofill_item[0].labels = {{Suggestion::Text(u"Deckard")}}; - autofill_item[0].frontend_id = kAutofillProfileId; + autofill_item[0].popup_item_id = PopupItemId::kAddressEntry; external_delegate_->OnSuggestionsReturned(field_id_, autofill_item, AutoselectFirstSuggestion(false)); EXPECT_THAT(open_args.suggestions, @@ -405,7 +400,7 @@ #if !BUILDFLAG(IS_ANDROID) PopupItemId::kSeparator, #endif - kAutofillProfileId, + PopupItemId::kAddressEntry, #if !BUILDFLAG(IS_ANDROID) PopupItemId::kSeparator, #endif @@ -437,11 +432,11 @@ autocomplete_items.emplace_back(); autocomplete_items[0].main_text = Suggestion::Text(u"Rick", Suggestion::Text::IsPrimary(true)); - autocomplete_items[0].frontend_id = PopupItemId::kAutocompleteEntry; + autocomplete_items[0].popup_item_id = PopupItemId::kAutocompleteEntry; autocomplete_items.emplace_back(); autocomplete_items[1].main_text = Suggestion::Text(u"Cain", Suggestion::Text::IsPrimary(true)); - autocomplete_items[1].frontend_id = PopupItemId::kAutocompleteEntry; + autocomplete_items[1].popup_item_id = PopupItemId::kAutocompleteEntry; external_delegate_->OnSuggestionsReturned(field_id_, autocomplete_items, AutoselectFirstSuggestion(false)); EXPECT_THAT(open_args.suggestions, @@ -468,7 +463,7 @@ // This should call ShowAutofillPopup. std::vector<Suggestion> autofill_item; autofill_item.emplace_back(); - autofill_item[0].frontend_id = + autofill_item[0].popup_item_id = PopupItemId::kInsecureContextPaymentDisabledMessage; external_delegate_->OnSuggestionsReturned(field_id_, autofill_item, AutoselectFirstSuggestion(false)); @@ -494,12 +489,12 @@ // This should call ShowAutofillPopup. std::vector<Suggestion> suggestions; suggestions.emplace_back(); - suggestions[0].frontend_id = + suggestions[0].popup_item_id = PopupItemId::kInsecureContextPaymentDisabledMessage; suggestions.emplace_back(); suggestions[1].main_text = Suggestion::Text(u"Rick", Suggestion::Text::IsPrimary(true)); - suggestions[1].frontend_id = PopupItemId::kAutocompleteEntry; + suggestions[1].popup_item_id = PopupItemId::kAutocompleteEntry; external_delegate_->OnSuggestionsReturned(field_id_, suggestions, AutoselectFirstSuggestion(false)); @@ -516,7 +511,7 @@ .Times(0); EXPECT_CALL(*autofill_driver_, RendererShouldClearPreviewedForm()).Times(1); const Suggestion suggestion{ - Suggestion::FrontendId(kInsecureContextPaymentDisabledMessage)}; + PopupItemId::kInsecureContextPaymentDisabledMessage}; external_delegate_->DidSelectSuggestion(suggestion); // Ensure it doesn't try to fill the form in with the negative id. @@ -545,7 +540,7 @@ suggestions[0].main_text.value = masked_iban_value; suggestions[0].labels = {{Suggestion::Text(u"My doctor's IBAN")}}; suggestions[0].payload = Suggestion::ValueToFill(ummasked_iban_value); - suggestions[0].frontend_id = PopupItemId::kIbanEntry; + suggestions[0].popup_item_id = PopupItemId::kIbanEntry; external_delegate_->OnSuggestionsReturned(field_id_, suggestions, AutoselectFirstSuggestion(false)); @@ -579,7 +574,7 @@ std::u16string promo_code_value = u"PROMOCODE1234"; suggestions[0].main_text.value = promo_code_value; suggestions[0].labels = {{Suggestion::Text(u"12.34% off your purchase!")}}; - suggestions[0].frontend_id = PopupItemId::kMerchantPromoCodeEntry; + suggestions[0].popup_item_id = PopupItemId::kMerchantPromoCodeEntry; external_delegate_->OnSuggestionsReturned(field_id_, suggestions, AutoselectFirstSuggestion(false)); @@ -624,8 +619,8 @@ EXPECT_CALL( *browser_autofill_manager_, FillOrPreviewForm(mojom::RendererFormDataAction::kPreview, _, _, _, _)); - external_delegate_->DidSelectSuggestion(test::CreateAutofillSuggestion( - Suggestion::FrontendId(kAutofillProfileId), u"baz foo")); + external_delegate_->DidSelectSuggestion( + test::CreateAutofillSuggestion(PopupItemId::kAddressEntry, u"baz foo")); // Ensure selecting an autocomplete entry will cause any previews to // get cleared. @@ -683,7 +678,7 @@ FillOrPreviewForm(mojom::RendererFormDataAction::kFill, _, _, _, _)); external_delegate_->DidAcceptSuggestion( - test::CreateAutofillSuggestion(kAutofillProfileId, dummy_string), + test::CreateAutofillSuggestion(PopupItemId::kAddressEntry, dummy_string), 2); // Row 2 } @@ -776,8 +771,8 @@ // Test that autofill client will start the signin flow after the user accepted // the suggestion to sign in. TEST_F(AutofillExternalDelegateUnitTest, SigninPromoMenuItem) { - EXPECT_CALL(autofill_client_, ExecuteCommand(Suggestion::FrontendId( - PopupItemId::kCreditCardSigninPromo))); + EXPECT_CALL(autofill_client_, + ExecuteCommand(PopupItemId::kCreditCardSigninPromo)); EXPECT_CALL(autofill_client_, HideAutofillPopup(PopupHidingReason::kAcceptSuggestion)); @@ -810,7 +805,7 @@ std::vector<Suggestion> autofill_items; autofill_items.emplace_back(); - autofill_items[0].frontend_id = PopupItemId::kAutocompleteEntry; + autofill_items[0].popup_item_id = PopupItemId::kAutocompleteEntry; // Ensure the popup tries to show itself, despite autocomplete="off". EXPECT_CALL(autofill_client_, ShowAutofillPopup); @@ -829,9 +824,8 @@ EXPECT_CALL(*autofill_driver_, RendererShouldFillFieldWithValue(field_id_, dummy_string)); EXPECT_CALL(*autofill_client_.GetMockAutocompleteHistoryManager(), - OnSingleFieldSuggestionSelected( - dummy_string, - Suggestion::FrontendId(PopupItemId::kAutocompleteEntry))) + OnSingleFieldSuggestionSelected(dummy_string, + PopupItemId::kAutocompleteEntry)) .Times(1); base::HistogramTester histogram_tester; @@ -848,8 +842,7 @@ RendererShouldFillFieldWithValue(field_id_, dummy_string)); EXPECT_CALL(*autofill_client_.GetMockMerchantPromoCodeManager(), OnSingleFieldSuggestionSelected( - dummy_string, - Suggestion::FrontendId(PopupItemId::kMerchantPromoCodeEntry))) + dummy_string, PopupItemId::kMerchantPromoCodeEntry)) .Times(1); external_delegate_->DidAcceptSuggestion( test::CreateAutofillSuggestion(PopupItemId::kMerchantPromoCodeEntry, @@ -861,10 +854,9 @@ // Test that IBANs get autofilled. EXPECT_CALL(*autofill_driver_, RendererShouldFillFieldWithValue(field_id_, ummasked_iban_value)); - EXPECT_CALL( - *autofill_client_.GetMockIBANManager(), - OnSingleFieldSuggestionSelected( - masked_iban_value, Suggestion::FrontendId(PopupItemId::kIbanEntry))); + EXPECT_CALL(*autofill_client_.GetMockIBANManager(), + OnSingleFieldSuggestionSelected(masked_iban_value, + PopupItemId::kIbanEntry)); external_delegate_->DidAcceptSuggestion( test::CreateAutofillSuggestion( PopupItemId::kIbanEntry, masked_iban_value, @@ -881,7 +873,7 @@ std::vector<Suggestion> autofill_item; autofill_item.emplace_back(); - autofill_item[0].frontend_id = kAutofillProfileId; + autofill_item[0].popup_item_id = PopupItemId::kAddressEntry; // This should call ShowAutofillPopup. external_delegate_->OnSuggestionsReturned( @@ -914,7 +906,7 @@ std::vector<Suggestion> autofill_item; autofill_item.emplace_back(); - autofill_item[0].frontend_id = kAutofillProfileId; + autofill_item[0].popup_item_id = PopupItemId::kAddressEntry; // This should call ShowAutofillPopup. external_delegate_->OnSuggestionsReturned( @@ -936,7 +928,7 @@ std::vector<Suggestion> autofill_item; autofill_item.emplace_back(); - autofill_item[0].frontend_id = kAutofillProfileId; + autofill_item[0].popup_item_id = PopupItemId::kAddressEntry; autofill_item[0].main_text.is_primary = Suggestion::Text::IsPrimary(true); // This should call ShowAutofillPopup. @@ -987,7 +979,7 @@ std::vector<Suggestion> autofill_item; autofill_item.emplace_back(); - autofill_item[0].frontend_id = kAutofillProfileId; + autofill_item[0].popup_item_id = PopupItemId::kAddressEntry; autofill_item[0].main_text.is_primary = Suggestion::Text::IsPrimary(true); external_delegate_->OnSuggestionsReturned(field_id_, autofill_item,
diff --git a/components/autofill/core/browser/autofill_suggestion_generator.cc b/components/autofill/core/browser/autofill_suggestion_generator.cc index 0b08d72e..41f1c1b 100644 --- a/components/autofill/core/browser/autofill_suggestion_generator.cc +++ b/components/autofill/core/browser/autofill_suggestion_generator.cc
@@ -142,7 +142,7 @@ } for (auto& suggestion : suggestions) { - suggestion.frontend_id = kAddressEntry; + suggestion.popup_item_id = PopupItemId::kAddressEntry; // Populate feature IPH for externally created account profiles. const AutofillProfile* profile = personal_data_->GetProfileByGUID( @@ -234,7 +234,7 @@ // static Suggestion AutofillSuggestionGenerator::CreateSeparator() { Suggestion suggestion; - suggestion.frontend_id = PopupItemId::kSeparator; + suggestion.popup_item_id = PopupItemId::kSeparator; return suggestion; } @@ -242,7 +242,7 @@ Suggestion AutofillSuggestionGenerator::CreateManagePaymentMethodsEntry() { Suggestion suggestion( l10n_util::GetStringUTF16(IDS_AUTOFILL_MANAGE_PAYMENT_METHODS)); - suggestion.frontend_id = PopupItemId::kAutofillOptions; + suggestion.popup_item_id = PopupItemId::kAutofillOptions; suggestion.icon = "settingsIcon"; return suggestion; } @@ -298,7 +298,7 @@ suggestion.custom_icon = ui::ResourceBundle::GetSharedInstance().GetImageNamed( IDR_AUTOFILL_IBAN); - suggestion.frontend_id = PopupItemId::kIbanEntry; + suggestion.popup_item_id = PopupItemId::kIbanEntry; suggestion.payload = Suggestion::ValueToFill(iban->GetStrippedValue()); suggestion.main_text.value = iban->GetIdentifierStringForAutofillDisplay(); if (!iban->nickname().empty()) @@ -331,7 +331,7 @@ } suggestion.payload = Suggestion::BackendId( base::NumberToString(promo_code_offer->GetOfferId())); - suggestion.frontend_id = PopupItemId::kMerchantPromoCodeEntry; + suggestion.popup_item_id = PopupItemId::kMerchantPromoCodeEntry; // Every offer for a given merchant leads to the same GURL, so we grab the // first offer's offer details url as the payload for the footer to set @@ -356,7 +356,7 @@ suggestions.emplace_back(l10n_util::GetStringUTF16( IDS_AUTOFILL_PROMO_CODE_SUGGESTIONS_FOOTER_TEXT)); Suggestion& suggestion = suggestions.back(); - suggestion.frontend_id = PopupItemId::kSeePromoCodeDetails; + suggestion.popup_item_id = PopupItemId::kSeePromoCodeDetails; // We set the payload for the footer as |footer_offer_details_url|, which is // the offer details url of the first offer we had for this merchant. We @@ -466,8 +466,8 @@ Suggestion suggestion; suggestion.icon = credit_card.CardIconStringForAutofillSuggestion(); - CHECK(suggestion.frontend_id == kAutocompleteEntry); - suggestion.frontend_id = kCreditCardEntry; + CHECK(suggestion.popup_item_id == PopupItemId::kAutocompleteEntry); + suggestion.popup_item_id = PopupItemId::kCreditCardEntry; suggestion.payload = Suggestion::BackendId(credit_card.guid()); suggestion.match = prefix_matched_suggestion ? Suggestion::PREFIX_MATCH : Suggestion::SUBSTRING_MATCH; @@ -633,7 +633,7 @@ suggestion.payload = Suggestion::BackendId(server_duplicate_card->guid()); } - suggestion.frontend_id = PopupItemId::kVirtualCreditCardEntry; + suggestion.popup_item_id = PopupItemId::kVirtualCreditCardEntry; suggestion.feature_for_iph = feature_engagement::kIPHAutofillVirtualCardSuggestionFeature.name;
diff --git a/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc b/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc index 904eef8..8d93192b 100644 --- a/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc +++ b/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc
@@ -646,7 +646,7 @@ ASSERT_EQ(iban_suggestions[0].labels.size(), 1u); ASSERT_EQ(iban_suggestions[0].labels[0].size(), 1u); EXPECT_EQ(iban_suggestions[0].labels[0][0].value, u"My doctor's IBAN"); - EXPECT_EQ(iban_suggestions[0].frontend_id, PopupItemId::kIbanEntry); + EXPECT_EQ(iban_suggestions[0].popup_item_id, PopupItemId::kIbanEntry); EXPECT_TRUE( AreImagesEqual(iban_suggestions[0].custom_icon, CreateFakeImage())); @@ -657,7 +657,7 @@ ASSERT_EQ(iban_suggestions[1].labels.size(), 1u); ASSERT_EQ(iban_suggestions[1].labels[0].size(), 1u); EXPECT_EQ(iban_suggestions[1].labels[0][0].value, u"My brother's IBAN"); - EXPECT_EQ(iban_suggestions[1].frontend_id, PopupItemId::kIbanEntry); + EXPECT_EQ(iban_suggestions[1].popup_item_id, PopupItemId::kIbanEntry); EXPECT_TRUE( AreImagesEqual(iban_suggestions[1].custom_icon, CreateFakeImage())); @@ -668,7 +668,7 @@ ASSERT_EQ(iban_suggestions[2].labels.size(), 1u); ASSERT_EQ(iban_suggestions[2].labels[0].size(), 1u); EXPECT_EQ(iban_suggestions[2].labels[0][0].value, u"My teacher's IBAN"); - EXPECT_EQ(iban_suggestions[2].frontend_id, PopupItemId::kIbanEntry); + EXPECT_EQ(iban_suggestions[2].popup_item_id, PopupItemId::kIbanEntry); EXPECT_TRUE( AreImagesEqual(iban_suggestions[2].custom_icon, CreateFakeImage())); @@ -677,15 +677,15 @@ EXPECT_EQ(iban_suggestions[3].GetPayload<Suggestion::ValueToFill>().value(), iban3.GetStrippedValue()); EXPECT_EQ(iban_suggestions[3].labels.size(), 0u); - EXPECT_EQ(iban_suggestions[3].frontend_id, PopupItemId::kIbanEntry); + EXPECT_EQ(iban_suggestions[3].popup_item_id, PopupItemId::kIbanEntry); EXPECT_TRUE( AreImagesEqual(iban_suggestions[3].custom_icon, CreateFakeImage())); - EXPECT_EQ(iban_suggestions[4].frontend_id, PopupItemId::kSeparator); + EXPECT_EQ(iban_suggestions[4].popup_item_id, PopupItemId::kSeparator); EXPECT_EQ(iban_suggestions[5].main_text.value, l10n_util::GetStringUTF16(IDS_AUTOFILL_MANAGE_PAYMENT_METHODS)); - EXPECT_EQ(iban_suggestions[5].frontend_id, PopupItemId::kAutofillOptions); + EXPECT_EQ(iban_suggestions[5].popup_item_id, PopupItemId::kAutofillOptions); CleanUpIbanImageResources(); } @@ -730,7 +730,7 @@ u"test_value_prop_text_1"); EXPECT_EQ(promo_code_suggestions[0].GetPayload<Suggestion::BackendId>(), Suggestion::BackendId("1")); - EXPECT_EQ(promo_code_suggestions[0].frontend_id, + EXPECT_EQ(promo_code_suggestions[0].popup_item_id, PopupItemId::kMerchantPromoCodeEntry); EXPECT_EQ(promo_code_suggestions[1].main_text.value, u"test_promo_code_2"); @@ -742,17 +742,17 @@ u"test_value_prop_text_2"); EXPECT_EQ(promo_code_suggestions[1].GetPayload<Suggestion::BackendId>(), Suggestion::BackendId("2")); - EXPECT_EQ(promo_code_suggestions[1].frontend_id, + EXPECT_EQ(promo_code_suggestions[1].popup_item_id, PopupItemId::kMerchantPromoCodeEntry); - EXPECT_EQ(promo_code_suggestions[2].frontend_id, PopupItemId::kSeparator); + EXPECT_EQ(promo_code_suggestions[2].popup_item_id, PopupItemId::kSeparator); EXPECT_EQ(promo_code_suggestions[3].main_text.value, l10n_util::GetStringUTF16( IDS_AUTOFILL_PROMO_CODE_SUGGESTIONS_FOOTER_TEXT)); EXPECT_EQ(promo_code_suggestions[3].GetPayload<GURL>(), offer1.GetOfferDetailsUrl().spec()); - EXPECT_EQ(promo_code_suggestions[3].frontend_id, + EXPECT_EQ(promo_code_suggestions[3].popup_item_id, PopupItemId::kSeePromoCodeDetails); } @@ -778,7 +778,7 @@ u"test_value_prop_text_1"); EXPECT_FALSE( absl::holds_alternative<GURL>(promo_code_suggestions[0].payload)); - EXPECT_EQ(promo_code_suggestions[0].frontend_id, + EXPECT_EQ(promo_code_suggestions[0].popup_item_id, PopupItemId::kMerchantPromoCodeEntry); } @@ -1130,7 +1130,7 @@ /*virtual_card_option=*/true, /*card_linked_offer_available=*/false); - EXPECT_EQ(virtual_card_suggestion.frontend_id, + EXPECT_EQ(virtual_card_suggestion.popup_item_id, PopupItemId::kVirtualCreditCardEntry); EXPECT_EQ(virtual_card_suggestion.GetPayload<Suggestion::BackendId>(), Suggestion::BackendId("00000000-0000-0000-0000-000000000001")); @@ -1143,8 +1143,7 @@ /*virtual_card_option=*/false, /*card_linked_offer_available=*/false); - EXPECT_EQ(real_card_suggestion.frontend_id.as_popup_item_id(), - kCreditCardEntry); + EXPECT_EQ(real_card_suggestion.popup_item_id, PopupItemId::kCreditCardEntry); EXPECT_EQ(real_card_suggestion.GetPayload<Suggestion::BackendId>(), Suggestion::BackendId("00000000-0000-0000-0000-000000000001")); EXPECT_EQ(VerifyCardArtImageExpectation(real_card_suggestion, card_art_url, @@ -1163,8 +1162,7 @@ /*virtual_card_option=*/false, /*card_linked_offer_available=*/false); - EXPECT_EQ(real_card_suggestion.frontend_id.as_popup_item_id(), - kCreditCardEntry); + EXPECT_EQ(real_card_suggestion.popup_item_id, PopupItemId::kCreditCardEntry); EXPECT_EQ(real_card_suggestion.GetPayload<Suggestion::BackendId>(), Suggestion::BackendId("00000000-0000-0000-0000-000000000001")); EXPECT_TRUE(VerifyCardArtImageExpectation(real_card_suggestion, GURL(), @@ -1193,7 +1191,7 @@ /*virtual_card_option=*/true, /*card_linked_offer_available=*/false); - EXPECT_EQ(virtual_card_suggestion.frontend_id, + EXPECT_EQ(virtual_card_suggestion.popup_item_id, PopupItemId::kVirtualCreditCardEntry); EXPECT_EQ(virtual_card_suggestion.GetPayload<Suggestion::BackendId>(), Suggestion::BackendId("00000000-0000-0000-0000-000000000001")); @@ -1206,8 +1204,7 @@ /*virtual_card_option=*/false, /*card_linked_offer_available=*/false); - EXPECT_EQ(real_card_suggestion.frontend_id.as_popup_item_id(), - kCreditCardEntry); + EXPECT_EQ(real_card_suggestion.popup_item_id, PopupItemId::kCreditCardEntry); EXPECT_EQ(real_card_suggestion.GetPayload<Suggestion::BackendId>(), Suggestion::BackendId("00000000-0000-0000-0000-000000000002")); EXPECT_EQ(VerifyCardArtImageExpectation(real_card_suggestion, card_art_url, @@ -1335,7 +1332,7 @@ /*virtual_card_option=*/true, /*card_linked_offer_available=*/true); - EXPECT_EQ(virtual_card_suggestion.frontend_id, + EXPECT_EQ(virtual_card_suggestion.popup_item_id, PopupItemId::kVirtualCreditCardEntry); EXPECT_EQ(virtual_card_suggestion.GetPayload<Suggestion::BackendId>(), Suggestion::BackendId("00000000-0000-0000-0000-000000000001")); @@ -1348,8 +1345,7 @@ /*virtual_card_option=*/false, /*card_linked_offer_available=*/true); - EXPECT_EQ(real_card_suggestion.frontend_id.as_popup_item_id(), - kCreditCardEntry); + EXPECT_EQ(real_card_suggestion.popup_item_id, PopupItemId::kCreditCardEntry); EXPECT_EQ(real_card_suggestion.GetPayload<Suggestion::BackendId>(), Suggestion::BackendId("00000000-0000-0000-0000-000000000001"));
diff --git a/components/autofill/core/browser/autofill_test_utils.cc b/components/autofill/core/browser/autofill_test_utils.cc index dd814bd..7a94fdc 100644 --- a/components/autofill/core/browser/autofill_test_utils.cc +++ b/components/autofill/core/browser/autofill_test_utils.cc
@@ -24,6 +24,7 @@ #include "components/autofill/core/browser/data_model/iban.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/randomized_encoder.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" #include "components/autofill/core/browser/webdata/autofill_table.h" #include "components/autofill/core/common/autofill_clock.h" #include "components/autofill/core/common/autofill_constants.h" @@ -1228,11 +1229,11 @@ } } -Suggestion CreateAutofillSuggestion(Suggestion::FrontendId frontend_id, +Suggestion CreateAutofillSuggestion(PopupItemId popup_item_id, const std::u16string& main_text_value, const Suggestion::Payload& payload) { Suggestion suggestion; - suggestion.frontend_id = frontend_id; + suggestion.popup_item_id = popup_item_id; suggestion.main_text.value = main_text_value; suggestion.payload = payload; return suggestion;
diff --git a/components/autofill/core/browser/autofill_test_utils.h b/components/autofill/core/browser/autofill_test_utils.h index 6bcd0b9c..a3b7ba0 100644 --- a/components/autofill/core/browser/autofill_test_utils.h +++ b/components/autofill/core/browser/autofill_test_utils.h
@@ -24,6 +24,7 @@ #include "components/autofill/core/browser/payments/card_unmask_challenge_option.h" #include "components/autofill/core/browser/proto/api_v1.pb.h" #include "components/autofill/core/browser/proto/server.pb.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" #include "components/autofill/core/browser/ui/suggestion.h" class PrefService; @@ -553,7 +554,7 @@ ::autofill::AutofillQueryResponse_FormSuggestion* form_suggestion); Suggestion CreateAutofillSuggestion( - Suggestion::FrontendId frontend_id, + PopupItemId popup_item_id, const std::u16string& main_text_value = std::u16string(), const Suggestion::Payload& payload = Suggestion::Payload());
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc index 169fe71..d2a4761 100644 --- a/components/autofill/core/browser/browser_autofill_manager.cc +++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -80,6 +80,7 @@ #include "components/autofill/core/browser/suggestions_context.h" #include "components/autofill/core/browser/ui/payments/bubble_show_options.h" #include "components/autofill/core/browser/ui/popup_item_ids.h" +#include "components/autofill/core/browser/ui/popup_types.h" #include "components/autofill/core/browser/ui/suggestion.h" #include "components/autofill/core/browser/validation.h" #include "components/autofill/core/common/autocomplete_parsing_util.h" @@ -203,9 +204,9 @@ } } -FillDataType GetEventTypeFromSingleFieldSuggestionFrontendId( - Suggestion::FrontendId frontend_id) { - switch (frontend_id.as_popup_item_id()) { +FillDataType GetEventTypeFromSingleFieldSuggestionPopupItemId( + PopupItemId popup_item_id) { + switch (popup_item_id) { case PopupItemId::kAutocompleteEntry: return FillDataType::kSingleFieldFormFillerAutocomplete; case PopupItemId::kMerchantPromoCodeEntry: @@ -1574,11 +1575,11 @@ bool BrowserAutofillManager::GetDeletionConfirmationText( const std::u16string& value, - Suggestion::FrontendId identifier, + PopupItemId popup_item_id, Suggestion::BackendId backend_id, std::u16string* title, std::u16string* body) { - if (identifier == PopupItemId::kAutocompleteEntry) { + if (popup_item_id == PopupItemId::kAutocompleteEntry) { if (title) title->assign(value); if (body) { @@ -1589,7 +1590,8 @@ return true; } - if (!identifier.is_an_address_or_card_popup_item_id()) { + if (popup_item_id != PopupItemId::kAddressEntry && + popup_item_id != PopupItemId::kCreditCardEntry) { return false; } @@ -1645,25 +1647,26 @@ void BrowserAutofillManager::RemoveCurrentSingleFieldSuggestion( const std::u16string& name, const std::u16string& value, - Suggestion::FrontendId frontend_id) { + PopupItemId popup_item_id) { single_field_form_fill_router_->OnRemoveCurrentSingleFieldSuggestion( - name, value, frontend_id); + name, value, popup_item_id); } void BrowserAutofillManager::OnSingleFieldSuggestionSelected( const std::u16string& value, - Suggestion::FrontendId frontend_id, + PopupItemId popup_item_id, const FormData& form, const FormFieldData& field) { - single_field_form_fill_router_->OnSingleFieldSuggestionSelected(value, - frontend_id); + single_field_form_fill_router_->OnSingleFieldSuggestionSelected( + value, popup_item_id); AutofillField* autofill_trigger_field = GetAutofillField(form, field); if (!autofill_trigger_field) { return; } autofill_trigger_field->AppendLogEventIfNotRepeated(TriggerFillFieldLogEvent{ - .data_type = GetEventTypeFromSingleFieldSuggestionFrontendId(frontend_id), + .data_type = + GetEventTypeFromSingleFieldSuggestionPopupItemId(popup_item_id), .associated_country_code = "", .timestamp = AutofillClock::Now()}); } @@ -3233,7 +3236,7 @@ } else { Suggestion warning_suggestion( l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_MIXED_FORM)); - warning_suggestion.frontend_id = PopupItemId::kMixedFormMessage; + warning_suggestion.popup_item_id = PopupItemId::kMixedFormMessage; suggestions->emplace_back(warning_suggestion); } return; @@ -3312,7 +3315,7 @@ if (ShouldShowVirtualCardOption(context->form_structure)) { suggestions->emplace_back(l10n_util::GetStringUTF16( IDS_AUTOFILL_CLOUD_TOKEN_DROPDOWN_OPTION_LABEL)); - suggestions->back().frontend_id = PopupItemId::kUseVirtualCard; + suggestions->back().popup_item_id = PopupItemId::kUseVirtualCard; } #endif @@ -3325,7 +3328,7 @@ // credit card autofill HTTP warning experiment is enabled. Suggestion warning_suggestion( l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION)); - warning_suggestion.frontend_id = + warning_suggestion.popup_item_id = PopupItemId::kInsecureContextPaymentDisabledMessage; suggestions->assign(1, warning_suggestion); } @@ -3448,11 +3451,11 @@ void BrowserAutofillManager::OnSeePromoCodeOfferDetailsSelected( const GURL& offer_details_url, const std::u16string& value, - Suggestion::FrontendId frontend_id, + PopupItemId popup_item_id, const FormData& form, const FormFieldData& field) { client()->OpenPromoCodeOfferDetailsURL(offer_details_url); - OnSingleFieldSuggestionSelected(value, frontend_id, form, field); + OnSingleFieldSuggestionSelected(value, popup_item_id, form, field); } void BrowserAutofillManager::ProcessFieldLogEventsInForm(
diff --git a/components/autofill/core/browser/browser_autofill_manager.h b/components/autofill/core/browser/browser_autofill_manager.h index ee0430f8..10c07d6 100644 --- a/components/autofill/core/browser/browser_autofill_manager.h +++ b/components/autofill/core/browser/browser_autofill_manager.h
@@ -40,6 +40,7 @@ #include "components/autofill/core/browser/single_field_form_fill_router.h" #include "components/autofill/core/browser/sync_utils.h" #include "components/autofill/core/browser/ui/fast_checkout_delegate.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" #include "components/autofill/core/browser/ui/popup_types.h" #include "components/autofill/core/browser/ui/touch_to_fill_delegate.h" #include "components/autofill/core/common/dense_set.h" @@ -189,7 +190,7 @@ // Returns true if the value/identifier is deletable. Fills out // |title| and |body| with relevant user-facing text. bool GetDeletionConfirmationText(const std::u16string& value, - Suggestion::FrontendId identifier, + PopupItemId popup_item_id, Suggestion::BackendId backend_id, std::u16string* title, std::u16string* body); @@ -198,16 +199,16 @@ // from the database. Returns true if deletion is allowed. bool RemoveAutofillProfileOrCreditCard(Suggestion::BackendId backend_id); - // Remove the specified suggestion from single field filling. |frontend_id| is - // the PopupItemId of the suggestion. + // Remove the specified suggestion from single field filling. `popup_item_id` + // is the PopupItemId of the suggestion. void RemoveCurrentSingleFieldSuggestion(const std::u16string& name, const std::u16string& value, - Suggestion::FrontendId frontend_id); + PopupItemId popup_item_id); // Invoked when the user selected |value| in a suggestions list from single - // field filling. |frontend_id| is the PopupItemId of the suggestion. + // field filling. `popup_item_id` is the PopupItemId of the suggestion. void OnSingleFieldSuggestionSelected(const std::u16string& value, - Suggestion::FrontendId frontend_id, + PopupItemId popup_item_id, const FormData& form, const FormFieldData& field); @@ -310,7 +311,7 @@ // then logs that the promo code suggestions footer was selected. void OnSeePromoCodeOfferDetailsSelected(const GURL& offer_details_url, const std::u16string& value, - Suggestion::FrontendId frontend_id, + PopupItemId popup_item_id, const FormData& form, const FormFieldData& field);
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc index 5f7efde..f8cce4e 100644 --- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc +++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -1151,11 +1151,11 @@ test::ObfuscatedCardDigitsAsUTF8(last_four, ObfuscationLength()); } - protected: TestPersonalDataManager& personal_data() { return *autofill_client_.GetPersonalDataManager(); } + protected: base::test::TaskEnvironment task_environment_; test::AutofillUnitTestEnvironment autofill_test_environment_; NiceMock<MockAutofillClient> autofill_client_; @@ -1567,12 +1567,9 @@ // Check that suggestions are made for the field that has the autocomplete // attribute. GetAutofillSuggestions(form, form.fields[0]); - CheckSuggestions( - form.fields[0].global_id(), - Suggestion("Charles", "", "", - Suggestion::FrontendId(PopupItemId::kAddressEntry)), - Suggestion("Elvis", "", "", - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + CheckSuggestions(form.fields[0].global_id(), + Suggestion("Charles", "", "", PopupItemId::kAddressEntry), + Suggestion("Elvis", "", "", PopupItemId::kAddressEntry)); // Check that there are no suggestions for the field without the autocomplete // attribute. @@ -1601,20 +1598,18 @@ FormsSeen({form}); GetAutofillSuggestions(form, form.fields[0]); - CheckSuggestions( - form.fields[0].global_id(), - Suggestion("Charles", "Charles Hardin Holley", kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry)), - Suggestion("Elvis", "Elvis Aaron Presley", kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + CheckSuggestions(form.fields[0].global_id(), + Suggestion("Charles", "Charles Hardin Holley", + kAddressEntryIcon, PopupItemId::kAddressEntry), + Suggestion("Elvis", "Elvis Aaron Presley", kAddressEntryIcon, + PopupItemId::kAddressEntry)); GetAutofillSuggestions(form, form.fields[1]); - CheckSuggestions( - form.fields[1].global_id(), - Suggestion("Holley", "Charles Hardin Holley", kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry)), - Suggestion("Presley", "Elvis Aaron Presley", kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + CheckSuggestions(form.fields[1].global_id(), + Suggestion("Holley", "Charles Hardin Holley", + kAddressEntryIcon, PopupItemId::kAddressEntry), + Suggestion("Presley", "Elvis Aaron Presley", + kAddressEntryIcon, PopupItemId::kAddressEntry)); } // Test that the call is properly forwarded to its SingleFieldFormFillRouter. @@ -1624,27 +1619,25 @@ test::CreateTestAddressFormData(&form); FormFieldData field = form.fields[0]; - EXPECT_CALL( - *single_field_form_fill_router_, - OnSingleFieldSuggestionSelected( - test_value, Suggestion::FrontendId(PopupItemId::kAutocompleteEntry))) - .Times(1); - - browser_autofill_manager_->OnSingleFieldSuggestionSelected( - test_value, PopupItemId::kAutocompleteEntry, form, field); - - EXPECT_CALL( - *single_field_form_fill_router_, - OnSingleFieldSuggestionSelected( - test_value, Suggestion::FrontendId(PopupItemId::kAutocompleteEntry))) + EXPECT_CALL(*single_field_form_fill_router_, + OnSingleFieldSuggestionSelected(test_value, + PopupItemId::kAutocompleteEntry)) .Times(1); browser_autofill_manager_->OnSingleFieldSuggestionSelected( test_value, PopupItemId::kAutocompleteEntry, form, field); EXPECT_CALL(*single_field_form_fill_router_, - OnSingleFieldSuggestionSelected( - test_value, Suggestion::FrontendId(PopupItemId::kIbanEntry))) + OnSingleFieldSuggestionSelected(test_value, + PopupItemId::kAutocompleteEntry)) + .Times(1); + + browser_autofill_manager_->OnSingleFieldSuggestionSelected( + test_value, PopupItemId::kAutocompleteEntry, form, field); + + EXPECT_CALL( + *single_field_form_fill_router_, + OnSingleFieldSuggestionSelected(test_value, PopupItemId::kIbanEntry)) .Times(1); browser_autofill_manager_->OnSingleFieldSuggestionSelected( @@ -1652,8 +1645,7 @@ EXPECT_CALL(*single_field_form_fill_router_, OnSingleFieldSuggestionSelected( - test_value, - Suggestion::FrontendId(PopupItemId::kMerchantPromoCodeEntry))) + test_value, PopupItemId::kMerchantPromoCodeEntry)) .Times(1); browser_autofill_manager_->OnSingleFieldSuggestionSelected( @@ -1697,12 +1689,11 @@ label2 = "3734 Elvis Presley Blvd."; } // Test that we sent the right values to the external delegate. - CheckSuggestions( - form.fields[0].global_id(), - Suggestion("Charles", label1, kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry)), - Suggestion("Elvis", label2, kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + CheckSuggestions(form.fields[0].global_id(), + Suggestion("Charles", label1, kAddressEntryIcon, + PopupItemId::kAddressEntry), + Suggestion("Elvis", label2, kAddressEntryIcon, + PopupItemId::kAddressEntry)); } // Test that we return only matching address profile suggestions when the @@ -1729,10 +1720,9 @@ label = "3734 Elvis Presley Blvd."; } // Test that we sent the right values to the external delegate. - CheckSuggestions( - field.global_id(), - Suggestion("Elvis", label, kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + CheckSuggestions(field.global_id(), + Suggestion("Elvis", label, kAddressEntryIcon, + PopupItemId::kAddressEntry)); } // Tests that we return address profile suggestions values when the section @@ -1782,9 +1772,9 @@ CheckSuggestions( field.global_id(), Suggestion("Googler", "1600 Amphitheater pkwy", kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry)), + PopupItemId::kAddressEntry), Suggestion("Grimes", "1234 Smith Blvd.", kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + PopupItemId::kAddressEntry)); break; case EnabledFeature::kNone: // Test that we sent the right values to the external delegate. No labels @@ -1792,13 +1782,11 @@ CheckSuggestions( field.global_id(), Suggestion("Googler", "1600 Amphitheater pkwy", kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry)), + PopupItemId::kAddressEntry), Suggestion("Grimes", "1234 Smith Blvd., Carl Grimes", - kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry)), + kAddressEntryIcon, PopupItemId::kAddressEntry), Suggestion("Grimes", "1234 Smith Blvd., Robin Grimes", - kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + kAddressEntryIcon, PopupItemId::kAddressEntry)); } } @@ -1831,10 +1819,9 @@ label = "3734 Elvis Presley Blvd."; } // Test that we sent the right values to the external delegate. - CheckSuggestions( - field.global_id(), - Suggestion("Elvis", label, kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + CheckSuggestions(field.global_id(), + Suggestion("Elvis", label, kAddressEntryIcon, + PopupItemId::kAddressEntry)); } // Test that we return no suggestions when the form has no relevant fields. @@ -1902,12 +1889,11 @@ label2 = "3734 Elvis Presley Blvd."; } // Test that we sent the right values to the external delegate. - CheckSuggestions( - form.fields[0].global_id(), - Suggestion("Charles", label1, kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry)), - Suggestion("Elvis", label2, kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + CheckSuggestions(form.fields[0].global_id(), + Suggestion("Charles", label1, kAddressEntryIcon, + PopupItemId::kAddressEntry), + Suggestion("Elvis", label2, kAddressEntryIcon, + PopupItemId::kAddressEntry)); } // Test that we return no suggestions when autofill is disabled. @@ -1931,10 +1917,9 @@ OnSuggestionsReturned_CallsExternalDelegate) { FieldGlobalId field_id = test::MakeFieldGlobalId(); std::vector<Suggestion> suggestions = { - Suggestion("Charles", "123 Apple St.", "", - Suggestion::FrontendId(PopupItemId::kAddressEntry)), + Suggestion("Charles", "123 Apple St.", "", PopupItemId::kAddressEntry), Suggestion("Elvis", "3734 Elvis Presley Blvd.", "", - Suggestion::FrontendId(PopupItemId::kAddressEntry))}; + PopupItemId::kAddressEntry)}; { browser_autofill_manager_->OnSuggestionsReturned( @@ -2246,7 +2231,7 @@ CheckSuggestions( form.fields[0].global_id(), Suggestion(l10n_util::GetStringUTF8(IDS_AUTOFILL_WARNING_MIXED_FORM), "", - "", Suggestion::FrontendId(kMixedFormMessage))); + "", PopupItemId::kMixedFormMessage)); // Clear the test credit cards and try again -- we should still show the // mixed form warning. @@ -2255,7 +2240,7 @@ CheckSuggestions( form.fields[0].global_id(), Suggestion(l10n_util::GetStringUTF8(IDS_AUTOFILL_WARNING_MIXED_FORM), "", - "", Suggestion::FrontendId(kMixedFormMessage))); + "", PopupItemId::kMixedFormMessage)); } // Test that we return credit card suggestions for secure pages that have an @@ -2719,12 +2704,11 @@ } // Test that we sent the right values to the external delegate. - CheckSuggestions( - form.fields[0].global_id(), - Suggestion("Charles", label1, kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry)), - Suggestion("Elvis", label2, kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + CheckSuggestions(form.fields[0].global_id(), + Suggestion("Charles", label1, kAddressEntryIcon, + PopupItemId::kAddressEntry), + Suggestion("Elvis", label2, kAddressEntryIcon, + PopupItemId::kAddressEntry)); FormFieldData field; test::CreateTestFormField("Card Number", "cardnumber", "", "text", &field); @@ -2772,8 +2756,7 @@ field.global_id(), Suggestion( l10n_util::GetStringUTF8(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION), - "", "", - Suggestion::FrontendId(kInsecureContextPaymentDisabledMessage))); + "", "", PopupItemId::kInsecureContextPaymentDisabledMessage)); // Clear the test credit cards and try again -- we shouldn't return a warning. personal_data().ClearCreditCards(); @@ -3347,12 +3330,11 @@ label2 = "3734 Elvis Presley Blvd."; } // Test that we sent the right values to the external delegate. - CheckSuggestions( - form.fields[0].global_id(), - Suggestion("Charles", label1, kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry)), - Suggestion("Elvis", label2, kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + CheckSuggestions(form.fields[0].global_id(), + Suggestion("Charles", label1, kAddressEntryIcon, + PopupItemId::kAddressEntry), + Suggestion("Elvis", label2, kAddressEntryIcon, + PopupItemId::kAddressEntry)); } // Test that nothing breaks when there are single field form fill (Autocomplete) @@ -3377,10 +3359,9 @@ AutocompleteSuggestionsReturned(field.global_id(), suggestions); // Test that we sent the right values to the external delegate. - CheckSuggestions( - field.global_id(), - Suggestion("one", "", "", Suggestion::FrontendId(kAutocompleteEntry)), - Suggestion("two", "", "", Suggestion::FrontendId(kAutocompleteEntry))); + CheckSuggestions(field.global_id(), + Suggestion("one", "", "", PopupItemId::kAutocompleteEntry), + Suggestion("two", "", "", PopupItemId::kAutocompleteEntry)); } // Test that we do not return duplicate values drawn from multiple profiles when @@ -3424,10 +3405,9 @@ label = "3734 Elvis Presley Blvd."; } // Test that we sent the right values to the external delegate. - CheckSuggestions( - field.global_id(), - Suggestion("Elvis", label, kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + CheckSuggestions(field.global_id(), + Suggestion("Elvis", label, kAddressEntryIcon, + PopupItemId::kAddressEntry)); } TEST_P(SuggestionMatchingTest, GetProfileSuggestions_FancyPhone) { @@ -3493,12 +3473,10 @@ // Test that we sent the right values to the external delegate. CheckSuggestions( form.fields[9].global_id(), - Suggestion(value1, label1, kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry)), - Suggestion(value2, label2, kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry)), + Suggestion(value1, label1, kAddressEntryIcon, PopupItemId::kAddressEntry), + Suggestion(value2, label2, kAddressEntryIcon, PopupItemId::kAddressEntry), Suggestion(value3, label3, kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + PopupItemId::kAddressEntry)); } TEST_F(BrowserAutofillManagerTest, @@ -3539,19 +3517,17 @@ GetAutofillSuggestions(form, phone_prefix); // Test that we sent the right prefix values to the external delegate. - CheckSuggestions( - form.fields[2].global_id(), - Suggestion("356", "1800FLOWERS", kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + CheckSuggestions(form.fields[2].global_id(), + Suggestion("356", "1800FLOWERS", kAddressEntryIcon, + PopupItemId::kAddressEntry)); const FormFieldData& phone_suffix = form.fields[3]; GetAutofillSuggestions(form, phone_suffix); // Test that we sent the right suffix values to the external delegate. - CheckSuggestions( - form.fields[3].global_id(), - Suggestion("9377", "1800FLOWERS", kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + CheckSuggestions(form.fields[3].global_id(), + Suggestion("9377", "1800FLOWERS", kAddressEntryIcon, + PopupItemId::kAddressEntry)); } // Tests that the suggestion consists of phone number without the country code @@ -3572,10 +3548,9 @@ GetAutofillSuggestions(form, form.fields[9]); - CheckSuggestions( - form.fields[9].global_id(), - Suggestion("123456789", "Natty Bumppo", kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + CheckSuggestions(form.fields[9].global_id(), + Suggestion("123456789", "Natty Bumppo", kAddressEntryIcon, + PopupItemId::kAddressEntry)); } // Tests that we return email profile suggestions values @@ -3618,10 +3593,9 @@ personal_data().AddProfile(profile); GetAutofillSuggestions(form, form.fields[2]); - CheckSuggestions( - form.fields[2].global_id(), - Suggestion("test@example.com", "Natty Bumppo", kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + CheckSuggestions(form.fields[2].global_id(), + Suggestion("test@example.com", "Natty Bumppo", + kAddressEntryIcon, PopupItemId::kAddressEntry)); } // Test that we correctly fill an address form. @@ -7044,9 +7018,9 @@ EXPECT_EQ(0, personal_data().num_times_save_imported_profile_called()); } -// Test that we save form data when a <select> in the form contains the -// default value. -TEST_F(BrowserAutofillManagerTest, FormSubmittedSelectWithDefaultValue) { +void DoTestFormSubmittedControlWithDefaultValue( + BrowserAutofillManagerTest* test, + const std::string& form_control_type) { // Set up our form data. FormData form; test::CreateTestAddressFormData(&form); @@ -7055,27 +7029,39 @@ // reject default values for text fields. FormFieldData* state_field = form.FindFieldByName(u"state"); ASSERT_TRUE(state_field != nullptr); - state_field->form_control_type = "select-one"; + state_field->form_control_type = form_control_type; state_field->value = base::UTF8ToUTF16(kElvisAddressFillData.state); - FormsSeen({form}); + test->FormsSeen({form}); // Fill the form. FormData response_data; - FillAutofillFormDataAndSaveResults(form, form.fields[3], kElvisProfileGuid, - &response_data); + test->FillAutofillFormDataAndSaveResults(form, form.fields[3], + kElvisProfileGuid, &response_data); - FormSubmitted(response_data); - ASSERT_EQ(1, personal_data().num_times_save_imported_profile_called()); + test->FormSubmitted(response_data); + const TestPersonalDataManager& personal_data = test->personal_data(); + ASSERT_EQ(1, personal_data.num_times_save_imported_profile_called()); EXPECT_EQ(u"Tennessee", - personal_data().last_save_imported_profile()->GetRawInfo( + personal_data.last_save_imported_profile()->GetRawInfo( ADDRESS_HOME_STATE)); } -// Test that we save form data when a non-country, non-state <select> in the -// form contains the default value. -TEST_F(BrowserAutofillManagerTest, - FormSubmittedNonAddressSelectWithDefaultValue) { +// Test that we save form data when a <select> in the form contains the +// default value. +TEST_F(BrowserAutofillManagerTest, FormSubmittedSelectWithDefaultValue) { + DoTestFormSubmittedControlWithDefaultValue(this, "select-one"); +} + +// Test that we save form data when a <selectmenu> in the form contains the +// default value. +TEST_F(BrowserAutofillManagerTest, FormSubmittedSelectMenuWithDefaultValue) { + DoTestFormSubmittedControlWithDefaultValue(this, "selectmenu"); +} + +void DoTestFormSubmittedNonAddressControlWithDefaultValue( + BrowserAutofillManagerTest* test, + const std::string& form_control_type) { // Set up our form data. FormData form; test::CreateTestAddressFormData(&form); @@ -7090,7 +7076,7 @@ FormFieldData country_code_field; test::CreateTestFormField("Country Code", "countrycode", "1", "text", "tel-country-code", &country_code_field); - country_code_field.form_control_type = "select-one"; + country_code_field.form_control_type = form_control_type; form.fields.push_back(country_code_field); FormFieldData phonenumber_field; @@ -7098,25 +7084,40 @@ "tel-national", &phonenumber_field); form.fields.push_back(phonenumber_field); - FormsSeen({form}); + test->FormsSeen({form}); // Fill the form. FormData response_data; - FillAutofillFormDataAndSaveResults(form, form.fields[3], kElvisProfileGuid, - &response_data); + test->FillAutofillFormDataAndSaveResults(form, form.fields[3], + kElvisProfileGuid, &response_data); - FormSubmitted(response_data); + test->FormSubmitted(response_data); // Value of country code field should have been saved. - ASSERT_EQ(1, personal_data().num_times_save_imported_profile_called()); + const TestPersonalDataManager& personal_data = test->personal_data(); + ASSERT_EQ(1, personal_data.num_times_save_imported_profile_called()); std::u16string formatted_phone_number = - personal_data().last_save_imported_profile()->GetRawInfo( + personal_data.last_save_imported_profile()->GetRawInfo( PHONE_HOME_WHOLE_NUMBER); std::u16string phone_number_numbers_only; base::RemoveChars(formatted_phone_number, u"+- ", &phone_number_numbers_only); EXPECT_TRUE(base::StartsWith(phone_number_numbers_only, u"1")); } +// Test that we save form data when a non-country, non-state <select> in the +// form contains the default value. +TEST_F(BrowserAutofillManagerTest, + FormSubmittedNonAddressSelectWithDefaultValue) { + DoTestFormSubmittedNonAddressControlWithDefaultValue(this, "select-one"); +} + +// Test that we save form data when a non-country, non-state <selectmenu> in the +// form contains the default value. +TEST_F(BrowserAutofillManagerTest, + FormSubmittedNonAddressSelectMenuWithDefaultValue) { + DoTestFormSubmittedNonAddressControlWithDefaultValue(this, "selectmenu"); +} + struct ProfileMatchingTypesTestCase { const char* input_value; // The value to input in the field. ServerFieldTypeSet field_types; // The expected field types to be determined. @@ -8411,12 +8412,11 @@ label2 = "3734 Elvis Presley Blvd."; } // Test that we sent the right values to the external delegate. - CheckSuggestions( - field.global_id(), - Suggestion("buddy@gmail.com", label1, kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry)), - Suggestion("theking@gmail.com", label2, kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + CheckSuggestions(field.global_id(), + Suggestion("buddy@gmail.com", label1, kAddressEntryIcon, + PopupItemId::kAddressEntry), + Suggestion("theking@gmail.com", label2, kAddressEntryIcon, + PopupItemId::kAddressEntry)); } // Verify that typing "apple" will match "123 Apple St." when substring matching @@ -8451,10 +8451,9 @@ label = "123 Apple St."; } // Test that we sent the right values to the external delegate. - CheckSuggestions( - field.global_id(), - Suggestion("123 Apple St., unit 6", label, kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + CheckSuggestions(field.global_id(), + Suggestion("123 Apple St., unit 6", label, kAddressEntryIcon, + PopupItemId::kAddressEntry)); } // Verify that typing "mail" will not match any of the "@gmail.com" email @@ -8627,12 +8626,11 @@ label1 = "1234 Smith Blvd., Carl Shawn Smith Grimes"; label2 = "1234 Smith Blvd., Robin Adam Smith Grimes"; } - CheckSuggestions( - field.global_id(), - Suggestion("Shawn Smith", label1, kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry)), - Suggestion("Adam Smith", label2, kAddressEntryIcon, - Suggestion::FrontendId(PopupItemId::kAddressEntry))); + CheckSuggestions(field.global_id(), + Suggestion("Shawn Smith", label1, kAddressEntryIcon, + PopupItemId::kAddressEntry), + Suggestion("Adam Smith", label2, kAddressEntryIcon, + PopupItemId::kAddressEntry)); } TEST_F(BrowserAutofillManagerTest, ShouldUploadForm) {
diff --git a/components/autofill/core/browser/form_data_importer.cc b/components/autofill/core/browser/form_data_importer.cc index fdebd53..8e2e363 100644 --- a/components/autofill/core/browser/form_data_importer.cc +++ b/components/autofill/core/browser/form_data_importer.cc
@@ -1062,8 +1062,9 @@ std::move(guid_of_card_if_no_interactive_authentication_flow_completed); } -absl::optional<std::string>& -FormDataImporter::GetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted() { +const absl::optional<std::string>& +FormDataImporter::GetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted() + const { return guid_of_card_if_no_interactive_authentication_flow_completed_; }
diff --git a/components/autofill/core/browser/form_data_importer.h b/components/autofill/core/browser/form_data_importer.h index 70875de..3360a93 100644 --- a/components/autofill/core/browser/form_data_importer.h +++ b/components/autofill/core/browser/form_data_importer.h
@@ -142,8 +142,8 @@ void SetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted( absl::optional<std::string> guid_of_card_if_no_interactive_authentication_flow_completed); - absl::optional<std::string>& - GetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted(); + const absl::optional<std::string>& + GetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted() const; protected: void set_credit_card_save_manager_for_testing( @@ -394,7 +394,7 @@ // is empty upon form submission, it implies that the most recent autofill had // an interactive authentication. Set when // `SetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted()` is called, and - // cleared on pag navigation. + // cleared on page navigation. absl::optional<std::string> guid_of_card_if_no_interactive_authentication_flow_completed_;
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc index d8466d8e..e54a90a 100644 --- a/components/autofill/core/browser/form_structure.cc +++ b/components/autofill/core/browser/form_structure.cc
@@ -958,7 +958,7 @@ // During form parsing (as in "assigning field types to fields") // the `value` represents the initial value found at page load and needs // to be preserved. - if (field->form_control_type != "select-one") { + if (!field->IsSelectOrSelectMenuElement()) { field->value = cached_field->value; value_from_dynamic_change_form_ = true; } @@ -975,7 +975,7 @@ const bool field_is_neither_state_nor_country = field->server_type() != ADDRESS_HOME_COUNTRY && field->server_type() != ADDRESS_HOME_STATE; - if (field->form_control_type != "select-one" && + if (!field->IsSelectOrSelectMenuElement() && same_value_as_on_page_load && field_is_neither_state_nor_country) { field->value = std::u16string(); }
diff --git a/components/autofill/core/browser/iban_manager.cc b/components/autofill/core/browser/iban_manager.cc index 8f3ace9..be72c5e 100644 --- a/components/autofill/core/browser/iban_manager.cc +++ b/components/autofill/core/browser/iban_manager.cc
@@ -140,9 +140,8 @@ uma_recorder_.OnIbanSuggestionsShown(query_handler.field_id_); } -void IBANManager::OnSingleFieldSuggestionSelected( - const std::u16string& value, - Suggestion::FrontendId frontend_id) { +void IBANManager::OnSingleFieldSuggestionSelected(const std::u16string& value, + PopupItemId popup_item_id) { uma_recorder_.OnIbanSuggestionSelected(); }
diff --git a/components/autofill/core/browser/iban_manager.h b/components/autofill/core/browser/iban_manager.h index b5d4fc6..105b91b7 100644 --- a/components/autofill/core/browser/iban_manager.h +++ b/components/autofill/core/browser/iban_manager.h
@@ -12,6 +12,7 @@ #include "components/autofill/core/browser/metrics/payments/iban_metrics.h" #include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/core/browser/single_field_form_filler.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" #include "components/keyed_service/core/keyed_service.h" #include "components/webdata/common/web_data_service_consumer.h" @@ -51,10 +52,9 @@ void OnRemoveCurrentSingleFieldSuggestion( const std::u16string& field_name, const std::u16string& value, - Suggestion::FrontendId frontend_id) override {} - void OnSingleFieldSuggestionSelected( - const std::u16string& value, - Suggestion::FrontendId frontend_id) override; + PopupItemId popup_item_id) override {} + void OnSingleFieldSuggestionSelected(const std::u16string& value, + PopupItemId popup_item_id) override; base::WeakPtr<IBANManager> GetWeakPtr();
diff --git a/components/autofill/core/browser/iban_manager_unittest.cc b/components/autofill/core/browser/iban_manager_unittest.cc index e74fa1a2..e43390a 100644 --- a/components/autofill/core/browser/iban_manager_unittest.cc +++ b/components/autofill/core/browser/iban_manager_unittest.cc
@@ -115,20 +115,20 @@ base::StringPiece nickname) { IBAN iban = SetUpIBAN(value, nickname); Suggestion iban_suggestion(iban.GetIdentifierStringForAutofillDisplay()); - iban_suggestion.frontend_id = PopupItemId::kIbanEntry; + iban_suggestion.popup_item_id = PopupItemId::kIbanEntry; return iban_suggestion; } Suggestion SetUpSeparator() { Suggestion separator; - separator.frontend_id = PopupItemId::kSeparator; + separator.popup_item_id = PopupItemId::kSeparator; return separator; } Suggestion SetUpFooterManagePaymentMethods() { Suggestion footer_suggestion( l10n_util::GetStringUTF16(IDS_AUTOFILL_MANAGE_PAYMENT_METHODS)); - footer_suggestion.frontend_id = PopupItemId::kAutofillOptions; + footer_suggestion.popup_item_id = PopupItemId::kAutofillOptions; footer_suggestion.icon = "settingsIcon"; return footer_suggestion; } @@ -144,9 +144,9 @@ raw_ptr<ui::ResourceBundle> original_resource_bundle_; }; -MATCHER_P(MatchesTextAndFrontendId, suggestion, "") { +MATCHER_P(MatchesTextAndPopupItemId, suggestion, "") { return arg.main_text == suggestion.main_text && - arg.frontend_id == suggestion.frontend_id; + arg.popup_item_id == suggestion.popup_item_id; } TEST_F(IBANManagerTest, ShowsIBANSuggestions) { @@ -160,12 +160,12 @@ // Setting up mock to verify that the handler is returned a list of // IBAN-based suggestions. - EXPECT_CALL( - suggestions_handler_, - OnSuggestionsReturned( - test_field.global_id(), AutoselectFirstSuggestion(false), - testing::IsSupersetOf({MatchesTextAndFrontendId(iban_suggestion_0), - MatchesTextAndFrontendId(iban_suggestion_1)}))) + EXPECT_CALL(suggestions_handler_, + OnSuggestionsReturned( + test_field.global_id(), AutoselectFirstSuggestion(false), + testing::IsSupersetOf( + {MatchesTextAndPopupItemId(iban_suggestion_0), + MatchesTextAndPopupItemId(iban_suggestion_1)}))) .Times(1); // Simulate request for suggestions. @@ -211,9 +211,9 @@ OnSuggestionsReturned( test_field.global_id(), AutoselectFirstSuggestion(false), testing::UnorderedElementsAre( - MatchesTextAndFrontendId(iban_suggestion_0), - MatchesTextAndFrontendId(iban_suggestion_1), - MatchesTextAndFrontendId(iban_suggestion_2)))) + MatchesTextAndPopupItemId(iban_suggestion_0), + MatchesTextAndPopupItemId(iban_suggestion_1), + MatchesTextAndPopupItemId(iban_suggestion_2)))) .Times(1); // Simulate request for suggestions. @@ -268,10 +268,10 @@ OnSuggestionsReturned( test_field.global_id(), AutoselectFirstSuggestion(false), testing::UnorderedElementsAre( - MatchesTextAndFrontendId(iban_suggestion_0), - MatchesTextAndFrontendId(iban_suggestion_1), - MatchesTextAndFrontendId(iban_suggestion_2), - MatchesTextAndFrontendId(iban_suggestion_3)))) + MatchesTextAndPopupItemId(iban_suggestion_0), + MatchesTextAndPopupItemId(iban_suggestion_1), + MatchesTextAndPopupItemId(iban_suggestion_2), + MatchesTextAndPopupItemId(iban_suggestion_3)))) .Times(1); // Simulate request for suggestions. @@ -292,9 +292,9 @@ OnSuggestionsReturned( test_field.global_id(), AutoselectFirstSuggestion(false), testing::UnorderedElementsAre( - MatchesTextAndFrontendId(iban_suggestion_0), - MatchesTextAndFrontendId(iban_suggestion_2), - MatchesTextAndFrontendId(iban_suggestion_3)))) + MatchesTextAndPopupItemId(iban_suggestion_0), + MatchesTextAndPopupItemId(iban_suggestion_2), + MatchesTextAndPopupItemId(iban_suggestion_3)))) .Times(1); // Simulate request for suggestions. @@ -354,11 +354,11 @@ // Setting up mock to verify that the handler is returned a list of // IBAN-based suggestions. - EXPECT_CALL( - suggestions_handler_, - OnSuggestionsReturned( - test_field.global_id(), AutoselectFirstSuggestion(false), - testing::IsSupersetOf({MatchesTextAndFrontendId(iban_suggestion_0)}))) + EXPECT_CALL(suggestions_handler_, + OnSuggestionsReturned( + test_field.global_id(), AutoselectFirstSuggestion(false), + testing::IsSupersetOf( + {MatchesTextAndPopupItemId(iban_suggestion_0)}))) .Times(1); // Simulate request for suggestions.
diff --git a/components/autofill/core/browser/merchant_promo_code_manager.cc b/components/autofill/core/browser/merchant_promo_code_manager.cc index 0b9ee361..f194544 100644 --- a/components/autofill/core/browser/merchant_promo_code_manager.cc +++ b/components/autofill/core/browser/merchant_promo_code_manager.cc
@@ -58,12 +58,12 @@ void MerchantPromoCodeManager::OnRemoveCurrentSingleFieldSuggestion( const std::u16string& field_name, const std::u16string& value, - Suggestion::FrontendId frontend_id) {} + PopupItemId popup_item_id) {} void MerchantPromoCodeManager::OnSingleFieldSuggestionSelected( const std::u16string& value, - Suggestion::FrontendId frontend_id) { - uma_recorder_.OnOfferSuggestionSelected(frontend_id); + PopupItemId popup_item_id) { + uma_recorder_.OnOfferSuggestionSelected(popup_item_id); } void MerchantPromoCodeManager::Init(PersonalDataManager* personal_data_manager, @@ -106,8 +106,8 @@ } void MerchantPromoCodeManager::UMARecorder::OnOfferSuggestionSelected( - Suggestion::FrontendId frontend_id) { - if (frontend_id == PopupItemId::kMerchantPromoCodeEntry) { + PopupItemId popup_item_id) { + if (popup_item_id == PopupItemId::kMerchantPromoCodeEntry) { // We log every time an individual offer suggestion is selected, regardless // if the user is repeatedly autofilling the same field. autofill_metrics::LogIndividualOfferSuggestionEvent( @@ -123,7 +123,7 @@ kOfferSuggestionSelectedOnce, AutofillOfferData::OfferType::GPAY_PROMO_CODE_OFFER); } - } else if (frontend_id == PopupItemId::kSeePromoCodeDetails) { + } else if (popup_item_id == PopupItemId::kSeePromoCodeDetails) { // We log every time the see offer details suggestion in the footer is // selected, regardless if the user is repeatedly autofilling the same // field.
diff --git a/components/autofill/core/browser/merchant_promo_code_manager.h b/components/autofill/core/browser/merchant_promo_code_manager.h index ff60317..9590d67f 100644 --- a/components/autofill/core/browser/merchant_promo_code_manager.h +++ b/components/autofill/core/browser/merchant_promo_code_manager.h
@@ -9,6 +9,7 @@ #include "components/autofill/core/browser/autofill_subject.h" #include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/core/browser/single_field_form_filler.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" #include "components/autofill/core/common/unique_ids.h" #include "components/keyed_service/core/keyed_service.h" #include "components/webdata/common/web_data_service_consumer.h" @@ -45,13 +46,11 @@ void OnWillSubmitFormWithFields(const std::vector<FormFieldData>& fields, bool is_autocomplete_enabled) override; void CancelPendingQueries(const SuggestionsHandler* handler) override; - void OnRemoveCurrentSingleFieldSuggestion( - const std::u16string& field_name, - const std::u16string& value, - Suggestion::FrontendId frontend_id) override; - void OnSingleFieldSuggestionSelected( - const std::u16string& value, - Suggestion::FrontendId frontend_id) override; + void OnRemoveCurrentSingleFieldSuggestion(const std::u16string& field_name, + const std::u16string& value, + PopupItemId popup_item_id) override; + void OnSingleFieldSuggestionSelected(const std::u16string& value, + PopupItemId popup_item_id) override; // Initializes the instance with the given parameters. |personal_data_manager| // is a profile-scope data manager used to retrieve promo code offers from the @@ -84,7 +83,7 @@ void OnOffersSuggestionsShown( const FieldGlobalId& field_global_id, const std::vector<const AutofillOfferData*>& offers); - void OnOfferSuggestionSelected(Suggestion::FrontendId frontend_id); + void OnOfferSuggestionSelected(PopupItemId popup_item_id); private: // The global id of the field that most recently had suggestions shown.
diff --git a/components/autofill/core/browser/merchant_promo_code_manager_unittest.cc b/components/autofill/core/browser/merchant_promo_code_manager_unittest.cc index 2422c6ba8..2bee1645 100644 --- a/components/autofill/core/browser/merchant_promo_code_manager_unittest.cc +++ b/components/autofill/core/browser/merchant_promo_code_manager_unittest.cc
@@ -124,7 +124,7 @@ _, autoselect_first_suggestion, UnorderedElementsAre( Field(&Suggestion::main_text, promo_code_suggestion.main_text), - Field(&Suggestion::frontend_id, PopupItemId::kSeparator), + Field(&Suggestion::popup_item_id, PopupItemId::kSeparator), Field(&Suggestion::main_text, footer_suggestion.main_text)))) .Times(3); @@ -540,7 +540,7 @@ SetUpPromoCodeOffer(last_committed_origin_url, GURL("https://offer-details-url.com/")); - // Check that non promo code frontend id's do not log as offer suggestion + // Check that non promo code popup item id's do not log as offer suggestion // selected. merchant_promo_code_manager_->OnSingleFieldSuggestionSelected( test_promo_code, PopupItemId::kAutocompleteEntry); @@ -605,7 +605,7 @@ SetUpPromoCodeOffer(last_committed_origin_url, GURL("https://offer-details-url.com/")); - // Check that non promo code footer frontend id's do not log as offer + // Check that non promo code footer popup item id's do not log as offer // suggestions footer selected. merchant_promo_code_manager_->OnSingleFieldSuggestionSelected( test_promo_code, PopupItemId::kAutocompleteEntry);
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 21175cf..4cc2e22 100644 --- a/components/autofill/core/browser/metrics/autofill_metrics_test_base.h +++ b/components/autofill/core/browser/metrics/autofill_metrics_test_base.h
@@ -37,7 +37,7 @@ public: MockAutofillClient(); ~MockAutofillClient() override; - MOCK_METHOD(void, ExecuteCommand, (Suggestion::FrontendId), (override)); + MOCK_METHOD(void, ExecuteCommand, (PopupItemId), (override)); MOCK_METHOD(bool, IsTouchToFillCreditCardSupported, (), (override)); MOCK_METHOD(bool, ShowTouchToFillCreditCard,
diff --git a/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.cc b/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.cc index 07eeb34..98d98c7 100644 --- a/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.cc +++ b/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.cc
@@ -460,7 +460,7 @@ bool CreditCardFormEventLogger::DoSuggestionsIncludeVirtualCard() { auto is_virtual_card = [](const Suggestion& suggestion) { - return suggestion.frontend_id == PopupItemId::kVirtualCreditCardEntry; + return suggestion.popup_item_id == PopupItemId::kVirtualCreditCardEntry; }; return base::ranges::any_of(suggestions_, is_virtual_card); }
diff --git a/components/autofill/core/browser/mock_autocomplete_history_manager.h b/components/autofill/core/browser/mock_autocomplete_history_manager.h index dacf958..995235be 100644 --- a/components/autofill/core/browser/mock_autocomplete_history_manager.h +++ b/components/autofill/core/browser/mock_autocomplete_history_manager.h
@@ -40,13 +40,11 @@ (override)); MOCK_METHOD(void, OnRemoveCurrentSingleFieldSuggestion, - (const std::u16string&, - const std::u16string&, - Suggestion::FrontendId), + (const std::u16string&, const std::u16string&, PopupItemId), (override)); MOCK_METHOD(void, OnSingleFieldSuggestionSelected, - (const std::u16string&, Suggestion::FrontendId), + (const std::u16string&, PopupItemId), (override)); };
diff --git a/components/autofill/core/browser/mock_iban_manager.h b/components/autofill/core/browser/mock_iban_manager.h index 3fc4915..ecf2bd0 100644 --- a/components/autofill/core/browser/mock_iban_manager.h +++ b/components/autofill/core/browser/mock_iban_manager.h
@@ -8,6 +8,7 @@ #include "base/memory/weak_ptr.h" #include "components/autofill/core/browser/iban_manager.h" #include "components/autofill/core/browser/personal_data_manager.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" #include "testing/gmock/include/gmock/gmock.h" namespace autofill { @@ -37,13 +38,11 @@ (override)); MOCK_METHOD(void, OnRemoveCurrentSingleFieldSuggestion, - (const std::u16string&, - const std::u16string&, - Suggestion::FrontendId), + (const std::u16string&, const std::u16string&, PopupItemId), (override)); MOCK_METHOD(void, OnSingleFieldSuggestionSelected, - (const std::u16string&, Suggestion::FrontendId), + (const std::u16string&, PopupItemId), (override)); };
diff --git a/components/autofill/core/browser/mock_merchant_promo_code_manager.h b/components/autofill/core/browser/mock_merchant_promo_code_manager.h index 8b35e1e..72a25d1 100644 --- a/components/autofill/core/browser/mock_merchant_promo_code_manager.h +++ b/components/autofill/core/browser/mock_merchant_promo_code_manager.h
@@ -36,13 +36,11 @@ (override)); MOCK_METHOD(void, OnRemoveCurrentSingleFieldSuggestion, - (const std::u16string&, - const std::u16string&, - Suggestion::FrontendId), + (const std::u16string&, const std::u16string&, PopupItemId), (override)); MOCK_METHOD(void, OnSingleFieldSuggestionSelected, - (const std::u16string&, Suggestion::FrontendId), + (const std::u16string&, PopupItemId), (override)); };
diff --git a/components/autofill/core/browser/mock_single_field_form_fill_router.h b/components/autofill/core/browser/mock_single_field_form_fill_router.h index 2b565665..af00b2e 100644 --- a/components/autofill/core/browser/mock_single_field_form_fill_router.h +++ b/components/autofill/core/browser/mock_single_field_form_fill_router.h
@@ -46,13 +46,11 @@ (override)); MOCK_METHOD(void, OnRemoveCurrentSingleFieldSuggestion, - (const std::u16string&, - const std::u16string&, - Suggestion::FrontendId), + (const std::u16string&, const std::u16string&, PopupItemId), (override)); MOCK_METHOD(void, OnSingleFieldSuggestionSelected, - (const std::u16string&, Suggestion::FrontendId), + (const std::u16string&, PopupItemId), (override)); };
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc index 092b097..f911fd2 100644 --- a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc +++ b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
@@ -2542,8 +2542,7 @@ const absl::optional<std::string>& guid = autofill_client_.GetFormDataImporter() ->GetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted(); - EXPECT_TRUE(guid.has_value()); - EXPECT_EQ(guid.value(), kTestGUID); + EXPECT_EQ(guid, kTestGUID); // Expect the metrics are logged correctly. histogram_tester.ExpectUniqueSample(
diff --git a/components/autofill/core/browser/single_field_form_fill_router.cc b/components/autofill/core/browser/single_field_form_fill_router.cc index bada62a..43e57502 100644 --- a/components/autofill/core/browser/single_field_form_fill_router.cc +++ b/components/autofill/core/browser/single_field_form_fill_router.cc
@@ -102,33 +102,33 @@ void SingleFieldFormFillRouter::OnRemoveCurrentSingleFieldSuggestion( const std::u16string& field_name, const std::u16string& value, - Suggestion::FrontendId frontend_id) { + PopupItemId popup_item_id) { if (merchant_promo_code_manager_ && - frontend_id == PopupItemId::kMerchantPromoCodeEntry) { + popup_item_id == PopupItemId::kMerchantPromoCodeEntry) { merchant_promo_code_manager_->OnRemoveCurrentSingleFieldSuggestion( - field_name, value, frontend_id); - } else if (iban_manager_ && frontend_id == PopupItemId::kIbanEntry) { + field_name, value, popup_item_id); + } else if (iban_manager_ && popup_item_id == PopupItemId::kIbanEntry) { iban_manager_->OnRemoveCurrentSingleFieldSuggestion(field_name, value, - frontend_id); + popup_item_id); } else { autocomplete_history_manager_->OnRemoveCurrentSingleFieldSuggestion( - field_name, value, frontend_id); + field_name, value, popup_item_id); } } void SingleFieldFormFillRouter::OnSingleFieldSuggestionSelected( const std::u16string& value, - Suggestion::FrontendId frontend_id) { + PopupItemId popup_item_id) { if (merchant_promo_code_manager_ && - (frontend_id == PopupItemId::kMerchantPromoCodeEntry || - frontend_id == PopupItemId::kSeePromoCodeDetails)) { - merchant_promo_code_manager_->OnSingleFieldSuggestionSelected(value, - frontend_id); - } else if (iban_manager_ && frontend_id == PopupItemId::kIbanEntry) { - iban_manager_->OnSingleFieldSuggestionSelected(value, frontend_id); + (popup_item_id == PopupItemId::kMerchantPromoCodeEntry || + popup_item_id == PopupItemId::kSeePromoCodeDetails)) { + merchant_promo_code_manager_->OnSingleFieldSuggestionSelected( + value, popup_item_id); + } else if (iban_manager_ && popup_item_id == PopupItemId::kIbanEntry) { + iban_manager_->OnSingleFieldSuggestionSelected(value, popup_item_id); } else { - autocomplete_history_manager_->OnSingleFieldSuggestionSelected(value, - frontend_id); + autocomplete_history_manager_->OnSingleFieldSuggestionSelected( + value, popup_item_id); } }
diff --git a/components/autofill/core/browser/single_field_form_fill_router.h b/components/autofill/core/browser/single_field_form_fill_router.h index aa40903..84a5808 100644 --- a/components/autofill/core/browser/single_field_form_fill_router.h +++ b/components/autofill/core/browser/single_field_form_fill_router.h
@@ -55,13 +55,11 @@ bool is_autocomplete_enabled) override; void CancelPendingQueries( const SingleFieldFormFiller::SuggestionsHandler* handler) override; - void OnRemoveCurrentSingleFieldSuggestion( - const std::u16string& field_name, - const std::u16string& value, - Suggestion::FrontendId frontend_id) override; - void OnSingleFieldSuggestionSelected( - const std::u16string& value, - Suggestion::FrontendId frontend_id) override; + void OnRemoveCurrentSingleFieldSuggestion(const std::u16string& field_name, + const std::u16string& value, + PopupItemId popup_item_id) override; + void OnSingleFieldSuggestionSelected(const std::u16string& value, + PopupItemId popup_item_id) override; private: // Handles autocompleting single fields.
diff --git a/components/autofill/core/browser/single_field_form_filler.h b/components/autofill/core/browser/single_field_form_filler.h index 2e26353..79572d2d 100644 --- a/components/autofill/core/browser/single_field_form_filler.h +++ b/components/autofill/core/browser/single_field_form_filler.h
@@ -75,19 +75,18 @@ virtual void CancelPendingQueries(const SuggestionsHandler* handler) = 0; // If applicable, removes the currently-selected suggestion from the database. - // |frontend_id| is the PopupItemId of the suggestion to be removed. + // `popup_item_id` is the PopupItemId of the suggestion to be removed. virtual void OnRemoveCurrentSingleFieldSuggestion( const std::u16string& field_name, const std::u16string& value, - Suggestion::FrontendId frontend_id) = 0; + PopupItemId popup_item_id) = 0; // Invoked when the user selects |value| in the list of suggestions. For // Autocomplete, this function logs the DaysSinceLastUse of the Autocomplete - // entry associated with |value|. |frontend_id| is the PopupItemId of the + // entry associated with |value|. `popup_item_id` is the PopupItemId of the // suggestion selected. - virtual void OnSingleFieldSuggestionSelected( - const std::u16string& value, - Suggestion::FrontendId frontend_id) = 0; + virtual void OnSingleFieldSuggestionSelected(const std::u16string& value, + PopupItemId popup_item_id) = 0; protected: // Internal data object used to keep a request's context to associate it
diff --git a/components/autofill/core/browser/test_autofill_client.h b/components/autofill/core/browser/test_autofill_client.h index f66858e..95fc09d 100644 --- a/components/autofill/core/browser/test_autofill_client.h +++ b/components/autofill/core/browser/test_autofill_client.h
@@ -43,6 +43,7 @@ #include "components/autofill/core/browser/test_personal_data_manager.h" #include "components/autofill/core/browser/ui/mock_fast_checkout_client.h" #include "components/autofill/core/browser/ui/payments/card_unmask_prompt_options.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" #include "components/autofill/core/browser/ui/popup_types.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/autofill/core/common/autofill_features.h" @@ -446,7 +447,7 @@ return form_origin_.SchemeIs("https"); } - void ExecuteCommand(Suggestion::FrontendId id) override {} + void ExecuteCommand(PopupItemId popup_item_id) override {} void OpenPromoCodeOfferDetailsURL(const GURL& url) override {}
diff --git a/components/autofill/core/browser/test_autofill_external_delegate.cc b/components/autofill/core/browser/test_autofill_external_delegate.cc index a41f6161..e4d4894 100644 --- a/components/autofill/core/browser/test_autofill_external_delegate.cc +++ b/components/autofill/core/browser/test_autofill_external_delegate.cc
@@ -99,7 +99,8 @@ suggestions_[i].minor_text.value); EXPECT_EQ(expected_suggestions[i].labels, suggestions_[i].labels); EXPECT_EQ(expected_suggestions[i].icon, suggestions_[i].icon); - EXPECT_EQ(expected_suggestions[i].frontend_id, suggestions_[i].frontend_id); + EXPECT_EQ(expected_suggestions[i].popup_item_id, + suggestions_[i].popup_item_id); } ASSERT_EQ(expected_num_suggestions, suggestions_.size()); }
diff --git a/components/autofill/core/browser/test_browser_autofill_manager.h b/components/autofill/core/browser/test_browser_autofill_manager.h index 6e060f1..2cb0fd2b 100644 --- a/components/autofill/core/browser/test_browser_autofill_manager.h +++ b/components/autofill/core/browser/test_browser_autofill_manager.h
@@ -127,13 +127,6 @@ void SetExpectedObservedSubmission(bool expected); - struct MakeFrontendIdParams { - std::string credit_card_id; - std::string profile_id; - }; - - Suggestion::FrontendId MakeFrontendId(const MakeFrontendIdParams& params); - private: bool autofill_profile_enabled_ = true; bool autofill_credit_card_enabled_ = true;
diff --git a/components/autofill/core/browser/test_personal_data_manager.h b/components/autofill/core/browser/test_personal_data_manager.h index 906d73b..b1efcd5 100644 --- a/components/autofill/core/browser/test_personal_data_manager.h +++ b/components/autofill/core/browser/test_personal_data_manager.h
@@ -127,7 +127,7 @@ return num_times_save_imported_profile_called_; } - AutofillProfile* last_save_imported_profile() { + const AutofillProfile* last_save_imported_profile() const { return last_save_imported_profile_.get(); }
diff --git a/components/autofill/core/browser/ui/autofill_popup_delegate.h b/components/autofill/core/browser/ui/autofill_popup_delegate.h index 9e7aecd4..9eca591 100644 --- a/components/autofill/core/browser/ui/autofill_popup_delegate.h +++ b/components/autofill/core/browser/ui/autofill_popup_delegate.h
@@ -45,7 +45,7 @@ // Returns whether the given value can be deleted, and if true, // fills out |title| and |body|. virtual bool GetDeletionConfirmationText(const std::u16string& value, - Suggestion::FrontendId frontend_id, + PopupItemId popup_item_id, Suggestion::BackendId backend_id, std::u16string* title, std::u16string* body) = 0; @@ -53,7 +53,7 @@ // Delete the described suggestion. Returns true if something was deleted, // or false if deletion is not allowed. virtual bool RemoveSuggestion(const std::u16string& value, - Suggestion::FrontendId frontend_id, + PopupItemId popup_item_id, Suggestion::BackendId backend_id) = 0; // Informs the delegate that the Autofill previewed form should be cleared.
diff --git a/components/autofill/core/browser/ui/mock_autofill_popup_delegate.h b/components/autofill/core/browser/ui/mock_autofill_popup_delegate.h index 53e9cc9..17cffea 100644 --- a/components/autofill/core/browser/ui/mock_autofill_popup_delegate.h +++ b/components/autofill/core/browser/ui/mock_autofill_popup_delegate.h
@@ -34,7 +34,7 @@ MOCK_METHOD(bool, GetDeletionConfirmationText, (const std::u16string& value, - Suggestion::FrontendId frontend_id, + PopupItemId popup_item_id, Suggestion::BackendId backend_id, std::u16string* title, std::u16string* body), @@ -42,7 +42,7 @@ MOCK_METHOD(bool, RemoveSuggestion, (const std::u16string& value, - Suggestion::FrontendId frontend_id, + PopupItemId popup_item_id, Suggestion::BackendId backend_id), (override)); MOCK_METHOD(void, ClearPreviewedForm, (), (override));
diff --git a/components/autofill/core/browser/ui/popup_item_ids.h b/components/autofill/core/browser/ui/popup_item_ids.h index aa05cbe..b5eed81 100644 --- a/components/autofill/core/browser/ui/popup_item_ids.h +++ b/components/autofill/core/browser/ui/popup_item_ids.h
@@ -7,40 +7,39 @@ namespace autofill { -// TODO(crbug.com/1394920): Remove the values from this enum. // This enum defines item identifiers for Autofill popup controller. // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.autofill -enum PopupItemId { - kCreditCardEntry = 2, - kAddressEntry = 1, - kAutocompleteEntry = 0, - kInsecureContextPaymentDisabledMessage = -1, - kPasswordEntry = -2, - kSeparator = -3, - kClearForm = -4, - kAutofillOptions = -5, - kDatalistEntry = -6, - kScanCreditCard = -7, - kTitle = -8, - kCreditCardSigninPromo = -9, - kUsernameEntry = -11, - kAllSavedPasswordsEntry = -13, - kGeneratePasswordEntry = -14, - kShowAccountCards = -15, - kPasswordAccountStorageOptIn = -16, - kUseVirtualCard = -18, - kPasswordAccountStorageOptInAndGenerate = -21, - kAccountStoragePasswordEntry = -22, - kAccountStorageUsernameEntry = -23, - kPasswordAccountStorageReSignin = -24, - kPasswordAccountStorageEmpty = -25, - kMixedFormMessage = -26, - kVirtualCreditCardEntry = -27, - kWebauthnCredential = -28, - kMerchantPromoCodeEntry = -29, - kSeePromoCodeDetails = -30, - kWebauthnSignInWithAnotherDevice = -31, - kIbanEntry = -32, +enum class PopupItemId : int { + kCreditCardEntry, + kAddressEntry, + kAutocompleteEntry, + kInsecureContextPaymentDisabledMessage, + kPasswordEntry, + kSeparator, + kClearForm, + kAutofillOptions, + kDatalistEntry, + kScanCreditCard, + kTitle, + kCreditCardSigninPromo, + kUsernameEntry, + kAllSavedPasswordsEntry, + kGeneratePasswordEntry, + kShowAccountCards, + kPasswordAccountStorageOptIn, + kUseVirtualCard, + kPasswordAccountStorageOptInAndGenerate, + kAccountStoragePasswordEntry, + kAccountStorageUsernameEntry, + kPasswordAccountStorageReSignin, + kPasswordAccountStorageEmpty, + kMixedFormMessage, + kVirtualCreditCardEntry, + kWebauthnCredential, + kMerchantPromoCodeEntry, + kSeePromoCodeDetails, + kWebauthnSignInWithAnotherDevice, + kIbanEntry, }; // List of `PopupItemId` that trigger filling a value into an input element
diff --git a/components/autofill/core/browser/ui/suggestion.cc b/components/autofill/core/browser/ui/suggestion.cc index cb20132..b844650 100644 --- a/components/autofill/core/browser/ui/suggestion.cc +++ b/components/autofill/core/browser/ui/suggestion.cc
@@ -9,37 +9,10 @@ #include "base/strings/utf_string_conversions.h" #include "base/types/cxx23_to_underlying.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" namespace autofill { -bool operator==(Suggestion::FrontendId lhs, Suggestion::FrontendId rhs) { - return lhs.as_popup_item_id() == rhs.as_popup_item_id(); -} - -bool operator==(Suggestion::FrontendId lhs, PopupItemId rhs) { - return lhs == Suggestion::FrontendId(rhs); -} - -bool operator==(PopupItemId lhs, Suggestion::FrontendId rhs) { - return Suggestion::FrontendId(lhs) == rhs; -} - -bool operator!=(Suggestion::FrontendId lhs, Suggestion::FrontendId rhs) { - return !(lhs == rhs); -} - -bool operator!=(Suggestion::FrontendId lhs, PopupItemId rhs) { - return !(lhs == rhs); -} - -bool operator!=(PopupItemId lhs, Suggestion::FrontendId rhs) { - return !(lhs == rhs); -} - -std::ostream& operator<<(std::ostream& os, Suggestion::FrontendId id) { - return os << base::to_underlying(id.as_popup_item_id()); -} - Suggestion::Text::Text() = default; Suggestion::Text::Text(std::u16string value, @@ -69,14 +42,14 @@ Suggestion::Suggestion(std::u16string main_text) : main_text(std::move(main_text), Text::IsPrimary(true)) {} -Suggestion::Suggestion(Suggestion::FrontendId frontend_id) - : frontend_id(frontend_id) {} +Suggestion::Suggestion(PopupItemId popup_item_id) + : popup_item_id(popup_item_id) {} Suggestion::Suggestion(base::StringPiece main_text, base::StringPiece label, std::string icon, - Suggestion::FrontendId frontend_id) - : frontend_id(frontend_id), + PopupItemId popup_item_id) + : popup_item_id(popup_item_id), main_text(base::UTF8ToUTF16(main_text), Text::IsPrimary(true)), icon(std::move(icon)) { if (!label.empty()) @@ -87,8 +60,8 @@ base::StringPiece minor_text, base::StringPiece label, std::string icon, - Suggestion::FrontendId frontend_id) - : frontend_id(frontend_id), + PopupItemId popup_item_id) + : popup_item_id(popup_item_id), main_text(base::UTF8ToUTF16(main_text), Text::IsPrimary(true)), minor_text(base::UTF8ToUTF16(minor_text)), icon(std::move(icon)) {
diff --git a/components/autofill/core/browser/ui/suggestion.h b/components/autofill/core/browser/ui/suggestion.h index 5cb818e..a3ab0d13 100644 --- a/components/autofill/core/browser/ui/suggestion.h +++ b/components/autofill/core/browser/ui/suggestion.h
@@ -27,31 +27,6 @@ using ValueToFill = base::StrongAlias<struct ValueToFill, std::u16string>; using Payload = absl::variant<BackendId, GURL, ValueToFill>; - // A frontend ID is just a PopupItemId. - // Frontend IDs are deprecated and will be eliminated: crbug.com/1394920. - // - // TODO(crbug.com/1394920): Convert frontend id into a PopupItemId. - class FrontendId { - public: - constexpr FrontendId() : value_(kAutocompleteEntry) {} - constexpr FrontendId( // NOLINT(google-explicit-constructor) - PopupItemId popup_item_id) - : value_(popup_item_id) {} - - // Returns the content of the variant as `PopupItemId`, even if it holds a - // raw integer. - PopupItemId as_popup_item_id() const { - return static_cast<PopupItemId>(value_); - } - - bool is_an_address_or_card_popup_item_id() const { - return value_ == kAddressEntry || value_ == kCreditCardEntry; - } - - private: - PopupItemId value_; - }; - enum MatchMode { PREFIX_MATCH, // for prefix matched suggestions; SUBSTRING_MATCH // for substring matched suggestions; @@ -86,18 +61,18 @@ Suggestion(); explicit Suggestion(std::u16string main_text); - explicit Suggestion(Suggestion::FrontendId frontend_id); + explicit Suggestion(PopupItemId popup_item_id); // Constructor for unit tests. It will convert the strings from UTF-8 to // UTF-16. Suggestion(base::StringPiece main_text, base::StringPiece label, std::string icon, - Suggestion::FrontendId frontend_id); + PopupItemId popup_item_id); Suggestion(base::StringPiece main_text, base::StringPiece minor_text, base::StringPiece label, std::string icon, - Suggestion::FrontendId frontend_id); + PopupItemId popup_item_id); Suggestion(const Suggestion& other); Suggestion(Suggestion&& other); Suggestion& operator=(const Suggestion& other); @@ -114,7 +89,7 @@ #if DCHECK_IS_ON() bool Invariant() const { - switch (frontend_id.as_popup_item_id()) { + switch (popup_item_id) { case PopupItemId::kSeePromoCodeDetails: return absl::holds_alternative<GURL>(payload); case PopupItemId::kIbanEntry: @@ -133,12 +108,8 @@ // shown other than main_text. Payload payload; - // TODO(crbug.com/1325509): Convert |frontend_id| from an int to a - // PopupItemId. - // ID for the frontend to use in identifying the particular result. Positive - // values are sent over IPC to identify the item selected. Negative values - // (see popup_item_ids.h) have special built-in meanings. - Suggestion::FrontendId frontend_id{}; + // Determines popup identifier for the suggestion. + PopupItemId popup_item_id = PopupItemId::kAutocompleteEntry; // The texts that will be displayed on the first line in a suggestion. The // order of showing the two texts on the first line depends on whether it is @@ -201,20 +172,12 @@ absl::optional<std::u16string> acceptance_a11y_announcement; }; -bool operator==(Suggestion::FrontendId lhs, Suggestion::FrontendId rhs); -bool operator==(Suggestion::FrontendId lhs, PopupItemId rhs); -bool operator==(PopupItemId lhs, Suggestion::FrontendId rhs); -bool operator!=(Suggestion::FrontendId lhs, Suggestion::FrontendId rhs); -bool operator!=(Suggestion::FrontendId lhs, PopupItemId rhs); -bool operator!=(PopupItemId lhs, Suggestion::FrontendId rhs); - -std::ostream& operator<<(std::ostream& os, Suggestion::FrontendId id); - #if defined(UNIT_TEST) inline void PrintTo(const Suggestion& suggestion, std::ostream* os) { *os << std::endl - << "Suggestion (frontend_id:" << suggestion.frontend_id - << ", main_text:\"" << suggestion.main_text.value << "\"" + << "Suggestion (popup_item_id:" + << base::to_underlying(suggestion.popup_item_id) << ", main_text:\"" + << suggestion.main_text.value << "\"" << (suggestion.main_text.is_primary ? "(Primary)" : "(Not Primary)") << ", minor_text:\"" << suggestion.minor_text.value << "\"" << (suggestion.minor_text.is_primary ? "(Primary)" : "(Not Primary)")
diff --git a/components/autofill/core/browser/ui/suggestion_test_helpers.h b/components/autofill/core/browser/ui/suggestion_test_helpers.h index 292ed2f9..0949122 100644 --- a/components/autofill/core/browser/ui/suggestion_test_helpers.h +++ b/components/autofill/core/browser/ui/suggestion_test_helpers.h
@@ -13,8 +13,8 @@ template <class... Matchers> inline auto SuggestionVectorIdsAre(const Matchers&... matchers) { - return ::testing::ElementsAre( - ::testing::Field("frontend_id", &Suggestion::frontend_id, matchers)...); + return ::testing::ElementsAre(::testing::Field( + "popup_item_id", &Suggestion::popup_item_id, matchers)...); } template <class... Matchers>
diff --git a/components/autofill/core/common/form_field_data.h b/components/autofill/core/common/form_field_data.h index 7311c5b..d74fa929 100644 --- a/components/autofill/core/common/form_field_data.h +++ b/components/autofill/core/common/form_field_data.h
@@ -217,6 +217,8 @@ bool IsPasswordInputElement() const; // Returns true for `form_control_type` select-one or selectmenu. + // + // <select> and <selectmenu>s should be treated identically by autofill. bool IsSelectOrSelectMenuElement() const; // Returns true if the field is focusable to the user.
diff --git a/components/autofill/ios/browser/autofill_agent.mm b/components/autofill/ios/browser/autofill_agent.mm index a6e2aa9..385c43b 100644 --- a/components/autofill/ios/browser/autofill_agent.mm +++ b/components/autofill/ios/browser/autofill_agent.mm
@@ -473,7 +473,7 @@ autofill::Suggestion autofill_suggestion; autofill_suggestion.main_text.value = SysNSStringToUTF16(suggestion.value); - autofill_suggestion.frontend_id = suggestion.popupItemId; + autofill_suggestion.popup_item_id = suggestion.popupItemId; if (!suggestion.backendIdentifier.length) { autofill_suggestion.payload = autofill::Suggestion::BackendId(); } else { @@ -532,7 +532,8 @@ autofillManager->OnUserAcceptedCardsFromAccountOption(); } } else { - NOTREACHED() << "unknown identifier " << suggestion.popupItemId; + NOTREACHED() << "unknown identifier " + << base::to_underlying(suggestion.popupItemId); } } @@ -634,11 +635,14 @@ NSString* value = nil; NSString* displayDescription = nil; UIImage* icon = nil; - if (popup_suggestion.frontend_id == + if (popup_suggestion.popup_item_id == autofill::PopupItemId::kAutocompleteEntry || - popup_suggestion.frontend_id.is_an_address_or_card_popup_item_id()) { + popup_suggestion.popup_item_id == + autofill::PopupItemId::kAddressEntry || + popup_suggestion.popup_item_id == + autofill::PopupItemId::kCreditCardEntry) { // Filter out any key/value suggestions if the user hasn't typed yet. - if (popup_suggestion.frontend_id == + if (popup_suggestion.popup_item_id == autofill::PopupItemId::kAutocompleteEntry && [_typedValue length] == 0) { continue; @@ -670,11 +674,11 @@ .ToUIImage(); } } - } else if (popup_suggestion.frontend_id == + } else if (popup_suggestion.popup_item_id == autofill::PopupItemId::kClearForm) { // Show the "clear form" button. value = SysUTF16ToNSString(popup_suggestion.main_text.value); - } else if (popup_suggestion.frontend_id == + } else if (popup_suggestion.popup_item_id == autofill::PopupItemId::kShowAccountCards) { // Show opt-in for showing cards from account. value = SysUTF16ToNSString(popup_suggestion.main_text.value); @@ -692,8 +696,7 @@ suggestionWithValue:value displayDescription:displayDescription icon:icon - popupItemId:popup_suggestion.frontend_id - .as_popup_item_id() + popupItemId:popup_suggestion.popup_item_id backendIdentifier: SysUTF8ToNSString( popup_suggestion @@ -708,7 +711,7 @@ } // Put "clear form" entry at the front of the suggestions. - if (popup_suggestion.frontend_id == autofill::PopupItemId::kClearForm) { + if (popup_suggestion.popup_item_id == autofill::PopupItemId::kClearForm) { [suggestions insertObject:suggestion atIndex:0]; } else { [suggestions addObject:suggestion];
diff --git a/components/autofill/ios/browser/autofill_agent_unittests.mm b/components/autofill/ios/browser/autofill_agent_unittests.mm index fb43a23..fa64686 100644 --- a/components/autofill/ios/browser/autofill_agent_unittests.mm +++ b/components/autofill/ios/browser/autofill_agent_unittests.mm
@@ -277,8 +277,7 @@ // Initialize suggestion. std::vector<autofill::Suggestion> autofillSuggestions = { autofill::Suggestion("", "", "visaCC", - autofill::Suggestion::FrontendId( - autofill::PopupItemId::kCreditCardEntry)), + autofill::PopupItemId::kCreditCardEntry), // This suggestion has a valid credit card icon, but the Suggestion type // (kShowAccountCards) is wrong. autofill::Suggestion("", "", "visaCC", @@ -329,10 +328,8 @@ .WillRepeatedly(testing::Return(PopupType::kCreditCards)); const std::string emptyIcon = ""; - std::vector<autofill::Suggestion> autofillSuggestions = { - autofill::Suggestion("", "", emptyIcon, - autofill::Suggestion::FrontendId( - autofill::PopupItemId::kCreditCardEntry))}; + std::vector<autofill::Suggestion> autofillSuggestions = {autofill::Suggestion( + "", "", emptyIcon, autofill::PopupItemId::kCreditCardEntry)}; // Completion handler to retrieve suggestions. auto completionHandler = ^(NSArray<FormSuggestion*>* suggestions, @@ -375,8 +372,7 @@ // Initialize suggestion, initially without a custom icon. std::vector<autofill::Suggestion> autofillSuggestions = { autofill::Suggestion("", "", suggestion_network_icon, - autofill::Suggestion::FrontendId( - autofill::PopupItemId::kCreditCardEntry))}; + autofill::PopupItemId::kCreditCardEntry)}; ASSERT_TRUE(autofillSuggestions[0].custom_icon.IsEmpty()); // When the custom icon is not present, the default icon should be used. @@ -408,12 +404,10 @@ // Make the suggestions available to AutofillAgent. std::vector<autofill::Suggestion> autofillSuggestions; - autofillSuggestions.push_back(autofill::Suggestion( - "", "", "", - autofill::Suggestion::FrontendId(autofill::PopupItemId::kAddressEntry))); - autofillSuggestions.push_back(autofill::Suggestion( - "", "", "", - autofill::Suggestion::FrontendId(autofill::PopupItemId::kAddressEntry))); + autofillSuggestions.push_back( + autofill::Suggestion("", "", "", autofill::PopupItemId::kAddressEntry)); + autofillSuggestions.push_back( + autofill::Suggestion("", "", "", autofill::PopupItemId::kAddressEntry)); autofillSuggestions.push_back( autofill::Suggestion("", "", "", PopupItemId::kClearForm)); [autofill_agent_ @@ -464,14 +458,10 @@ // Make the suggestions available to AutofillAgent. std::vector<autofill::Suggestion> autofillSuggestions; - autofillSuggestions.push_back( - autofill::Suggestion("", "", "", - autofill::Suggestion::FrontendId( - autofill::PopupItemId::kCreditCardEntry))); - autofillSuggestions.push_back( - autofill::Suggestion("", "", "", - autofill::Suggestion::FrontendId( - autofill::PopupItemId::kCreditCardEntry))); + autofillSuggestions.push_back(autofill::Suggestion( + "", "", "", autofill::PopupItemId::kCreditCardEntry)); + autofillSuggestions.push_back(autofill::Suggestion( + "", "", "", autofill::PopupItemId::kCreditCardEntry)); autofillSuggestions.push_back( autofill::Suggestion("", "", "", PopupItemId::kClearForm)); [autofill_agent_
diff --git a/components/components_chromium_strings.grd b/components/components_chromium_strings.grd index fcd4388..73c4c6a5 100644 --- a/components/components_chromium_strings.grd +++ b/components/components_chromium_strings.grd
@@ -296,9 +296,18 @@ </if> <!-- Page Info --> - <message name="IDS_PAGE_INFO_INTERNAL_PAGE" desc="Message to display in the page info bubble when the page you are on is a chrome:// page or about:something."> - You're viewing a secure Chromium page - </message> + <if expr="_is_chrome_for_testing_branded"> + <then> + <message name="IDS_PAGE_INFO_INTERNAL_PAGE" desc="Message to display in the page info bubble when the page you are on is a chrome:// page or about:something."> + You're viewing a secure Chrome for Testing page + </message> + </then> + <else> + <message name="IDS_PAGE_INFO_INTERNAL_PAGE" desc="Message to display in the page info bubble when the page you are on is a chrome:// page or about:something."> + You're viewing a secure Chromium page + </message> + </else> + </if> <!-- Session Crash --> <message name="IDS_SESSION_CRASHED_VIEW_MESSAGE" desc="Message shown when the last session didn't exit cleanly.">
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestRule.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestRule.java index 5d060ea5..0c452dc 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestRule.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetTestRule.java
@@ -34,7 +34,6 @@ import java.lang.annotation.Target; import java.net.URL; import java.net.URLStreamHandlerFactory; -import java.util.function.Function; /** * Custom TestRule for Cronet instrumentation tests. @@ -534,26 +533,30 @@ AUTOMATIC, } + // This is a replacement for java.util.function.Function as Function is only available + // starting android API level 24. + private interface EngineBuilderSupplier { + ExperimentalCronetEngine.Builder getCronetEngineBuilder(Context context); + } + public enum CronetImplementation { - STATICALLY_LINKED( - (context) - -> (ExperimentalCronetEngine.Builder) new NativeCronetProvider(context) - .createBuilder()), + STATICALLY_LINKED(context + -> (ExperimentalCronetEngine.Builder) new NativeCronetProvider(context) + .createBuilder()), FALLBACK((context) -> (ExperimentalCronetEngine.Builder) new JavaCronetProvider(context) .createBuilder()), AOSP_PLATFORM( (context) -> { throw new UnsupportedOperationException("Not implemented yet"); }); - private final Function<Context, ExperimentalCronetEngine.Builder> mBuilderSupplier; + private final EngineBuilderSupplier mEngineSupplier; - private CronetImplementation( - Function<Context, ExperimentalCronetEngine.Builder> builderSupplier) { - this.mBuilderSupplier = builderSupplier; + private CronetImplementation(EngineBuilderSupplier engineSupplier) { + this.mEngineSupplier = engineSupplier; } ExperimentalCronetEngine.Builder createBuilder(Context context) { - return mBuilderSupplier.apply(context); + return mEngineSupplier.getCronetEngineBuilder(context); } private void verifyCronetEngineInstance(CronetEngine engine) {
diff --git a/components/guest_view/browser/guest_view_manager.cc b/components/guest_view/browser/guest_view_manager.cc index 7739b5a..2847d7db7 100644 --- a/components/guest_view/browser/guest_view_manager.cc +++ b/components/guest_view/browser/guest_view_manager.cc
@@ -353,7 +353,20 @@ void GuestViewManager::EmbedderProcessDestroyed(int embedder_process_id) { embedders_observed_.erase(embedder_process_id); + + // We can't just call std::multimap::erase here because destroying a guest + // could trigger the destruction of another guest which is also owned by + // `owned_guests_`. Recursively calling std::multimap::erase is unsafe (see + // https://crbug.com/1450397). So we take ownership of all of the guests that + // will be destroyed before erasing the entries from the map. + std::vector<std::unique_ptr<GuestViewBase>> guests_to_destroy; + const auto destroy_range = owned_guests_.equal_range(embedder_process_id); + for (auto it = destroy_range.first; it != destroy_range.second; ++it) { + guests_to_destroy.push_back(std::move(it->second)); + } owned_guests_.erase(embedder_process_id); + guests_to_destroy.clear(); + CallViewDestructionCallbacks(embedder_process_id); }
diff --git a/components/guest_view/browser/test_guest_view_manager.cc b/components/guest_view/browser/test_guest_view_manager.cc index 0a5acac..fac07a1 100644 --- a/components/guest_view/browser/test_guest_view_manager.cc +++ b/components/guest_view/browser/test_guest_view_manager.cc
@@ -122,14 +122,15 @@ } void TestGuestViewManager::WaitForNumGuestsCreated(size_t count) { - if (count == num_guests_created_) + if (count == num_guests_created_) { return; + } - waiting_for_guests_created_ = true; expected_num_guests_created_ = count; num_created_run_loop_ = std::make_unique<base::RunLoop>(); num_created_run_loop_->Run(); + num_created_run_loop_ = nullptr; } void TestGuestViewManager::WaitUntilAttached(GuestViewBase* guest_view) { @@ -173,13 +174,11 @@ created_run_loop_->Quit(); ++num_guests_created_; - if (!waiting_for_guests_created_ && - num_guests_created_ != expected_num_guests_created_) { - return; - } - if (num_created_run_loop_) + if (num_created_run_loop_ && + num_guests_created_ == expected_num_guests_created_) { num_created_run_loop_->Quit(); + } } void TestGuestViewManager::AttachGuest(int embedder_process_id,
diff --git a/components/guest_view/browser/test_guest_view_manager.h b/components/guest_view/browser/test_guest_view_manager.h index 2bbc2b99..876ed221 100644 --- a/components/guest_view/browser/test_guest_view_manager.h +++ b/components/guest_view/browser/test_guest_view_manager.h
@@ -119,7 +119,6 @@ size_t num_guests_created_ = 0; size_t expected_num_guests_created_ = 0; int num_views_garbage_collected_ = 0; - bool waiting_for_guests_created_ = false; // Tracks the life time of the GuestView's main FrameTreeNode. The main FTN // has the same lifesspan as the GuestView.
diff --git a/components/live_caption/caption_bubble_controller.h b/components/live_caption/caption_bubble_controller.h index 32d1fc1..05d683b 100644 --- a/components/live_caption/caption_bubble_controller.h +++ b/components/live_caption/caption_bubble_controller.h
@@ -69,6 +69,10 @@ virtual bool IsGenericErrorMessageVisibleForTesting() = 0; virtual std::string GetBubbleLabelTextForTesting() = 0; virtual void CloseActiveModelForTesting() = 0; + + virtual void OnLanguageIdentificationEvent( + CaptionBubbleContext* caption_bubble_context, + const media::mojom::LanguageIdentificationEventPtr& event) = 0; }; } // namespace captions
diff --git a/components/live_caption/live_caption_controller.cc b/components/live_caption/live_caption_controller.cc index 5bca6b4..39ddc8c 100644 --- a/components/live_caption/live_caption_controller.cc +++ b/components/live_caption/live_caption_controller.cc
@@ -250,8 +250,13 @@ } void LiveCaptionController::OnLanguageIdentificationEvent( + CaptionBubbleContext* caption_bubble_context, const media::mojom::LanguageIdentificationEventPtr& event) { // TODO(crbug.com/1175357): Implement the UI for language identification. + if (caption_bubble_controller_) { + return caption_bubble_controller_->OnLanguageIdentificationEvent( + caption_bubble_context, event); + } } #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS)
diff --git a/components/live_caption/live_caption_controller.h b/components/live_caption/live_caption_controller.h index fcec207..81b9b2c 100644 --- a/components/live_caption/live_caption_controller.h +++ b/components/live_caption/live_caption_controller.h
@@ -62,6 +62,7 @@ const media::SpeechRecognitionResult& result); void OnLanguageIdentificationEvent( + CaptionBubbleContext* caption_bubble_context, const media::mojom::LanguageIdentificationEventPtr& event); // Alerts the CaptionBubbleController that there is an error in the speech
diff --git a/components/live_caption/live_caption_ui_remote_driver.cc b/components/live_caption/live_caption_ui_remote_driver.cc index 1ad57df..f0b4df1 100644 --- a/components/live_caption/live_caption_ui_remote_driver.cc +++ b/components/live_caption/live_caption_ui_remote_driver.cc
@@ -36,7 +36,7 @@ void LiveCaptionUiRemoteDriver::OnLanguageIdentificationEvent( media::mojom::LanguageIdentificationEventPtr event) { - controller_->OnLanguageIdentificationEvent(std::move(event)); + controller_->OnLanguageIdentificationEvent(&context_, std::move(event)); } void LiveCaptionUiRemoteDriver::OnSpeechRecognitionError() {
diff --git a/components/live_caption/views/caption_bubble.cc b/components/live_caption/views/caption_bubble.cc index 1bd0da79..c805815 100644 --- a/components/live_caption/views/caption_bubble.cc +++ b/components/live_caption/views/caption_bubble.cc
@@ -435,7 +435,14 @@ prefs::kLiveTranslateEnabled, base::BindRepeating(&CaptionBubble::OnLiveTranslateEnabledChanged, base::Unretained(this))); - + pref_change_registrar_->Add( + prefs::kLiveCaptionLanguageCode, + base::BindRepeating(&CaptionBubble::OnLiveCaptionLanguageChanged, + base::Unretained(this))); + pref_change_registrar_->Add( + prefs::kLiveTranslateTargetLanguageCode, + base::BindRepeating(&CaptionBubble::OnLiveTranslateTargetLanguageChanged, + base::Unretained(this))); inactivity_timer_ = std::make_unique<base::RetainingOneShotTimer>( FROM_HERE, base::Seconds(kNoActivityIntervalSeconds), base::BindRepeating(&CaptionBubble::OnInactivityTimeout, @@ -475,10 +482,6 @@ views::BoxLayout::Orientation::kHorizontal)); views::View* right_header_container = new views::View(); - right_header_container - ->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kHorizontal)) - ->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kEnd); views::View* left_header_container = new views::View(); views::View* content_container = new views::View(); @@ -643,34 +646,51 @@ content_container->AddChildView(std::move(collapse_button)); if (base::FeatureList::IsEnabled(media::kLiveTranslate)) { - auto live_translate_label = std::make_unique<views::StyledLabel>(); - live_translate_label->SetVisible( - profile_prefs_->GetBoolean(prefs::kLiveTranslateEnabled)); - live_translate_label->SetDisplayedOnBackgroundColor(SK_ColorTRANSPARENT); - live_translate_label->SetHorizontalAlignment( + auto language_label = std::make_unique<views::StyledLabel>(); + language_label->SetDisplayedOnBackgroundColor(SK_ColorTRANSPARENT); + language_label->SetHorizontalAlignment( gfx::HorizontalAlignment::ALIGN_LEFT); - live_translate_label->GetViewAccessibility().OverrideIsIgnored(true); + language_label->GetViewAccessibility().OverrideIsIgnored(true); - source_language_ = speech::GetLanguageDisplayName( - profile_prefs_->GetString(prefs::kLiveCaptionLanguageCode), - application_locale_); - target_language_ = speech::GetLanguageDisplayName( - profile_prefs_->GetString(prefs::kLiveTranslateTargetLanguageCode), - application_locale_); - std::u16string label_text = l10n_util::GetStringFUTF16( - IDS_LIVE_CAPTION_TRANSLATED_CAPTIONS, source_language_, - target_language_, &live_translate_label_offsets_); - live_translate_label->SetText(label_text); - live_translate_label_ = - left_header_container->AddChildView(std::move(live_translate_label)); + source_language_code_ = + profile_prefs_->GetString(prefs::kLiveCaptionLanguageCode); + source_language_text_ = speech::GetLanguageDisplayName( + source_language_code_, application_locale_); + target_language_code_ = + profile_prefs_->GetString(prefs::kLiveTranslateTargetLanguageCode); + target_language_text_ = speech::GetLanguageDisplayName( + target_language_code_, application_locale_); + language_label_ = + left_header_container->AddChildView(std::move(language_label)); + UpdateLanguageLabelText(); + + auto caption_settings_button = BuildImageButton( + base::BindRepeating(&CaptionBubble::CaptionSettingsButtonPressed, + base::Unretained(this)), + IDS_LIVE_CAPTION_BUBBLE_CAPTION_SETTINGS); + caption_settings_button_ = + left_header_container->AddChildView(std::move(caption_settings_button)); } - auto caption_settings_button = BuildImageButton( - base::BindRepeating(&CaptionBubble::CaptionSettingsButtonPressed, - base::Unretained(this)), - IDS_LIVE_CAPTION_BUBBLE_CAPTION_SETTINGS); - caption_settings_button_ = - left_header_container->AddChildView(std::move(caption_settings_button)); + std::unique_ptr<views::BoxLayout> right_header_container_layout = + std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal); + right_header_container_layout->set_main_axis_alignment( + views::BoxLayout::MainAxisAlignment::kEnd); + right_header_container_layout->set_cross_axis_alignment( + views::BoxLayout::CrossAxisAlignment::kCenter); + right_header_container->SetLayoutManager( + std::move(right_header_container_layout)); + std::unique_ptr<views::BoxLayout> left_header_container_layout = + std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal, + gfx::Insets::TLBR( + 0, close_button_->GetBorder()->GetInsets().width() / 2, 0, 0)); + left_header_container_layout->set_cross_axis_alignment( + views::BoxLayout::CrossAxisAlignment::kCenter); + left_header_container->SetLayoutManager( + std::move(left_header_container_layout)); + left_header_container_ = header_container->AddChildView(std::move(left_header_container)); header_container->AddChildView(std::move(right_header_container)); @@ -728,8 +748,30 @@ } void CaptionBubble::OnLiveTranslateEnabledChanged() { - live_translate_label_->SetVisible( - profile_prefs_->GetBoolean(prefs::kLiveTranslateEnabled)); + UpdateLanguageLabelText(); + SetTextColor(); + Redraw(); +} + +void CaptionBubble::OnLiveCaptionLanguageChanged() { + source_language_code_ = + profile_prefs_->GetString(prefs::kLiveCaptionLanguageCode); + source_language_text_ = speech::GetLanguageDisplayName(source_language_code_, + application_locale_); + + UpdateLanguageLabelText(); + SetTextColor(); + Redraw(); +} + +void CaptionBubble::OnLiveTranslateTargetLanguageChanged() { + target_language_code_ = + profile_prefs_->GetString(prefs::kLiveTranslateTargetLanguageCode); + target_language_text_ = speech::GetLanguageDisplayName(target_language_code_, + application_locale_); + + UpdateLanguageLabelText(); + SetTextColor(); Redraw(); } @@ -826,6 +868,28 @@ ResetInactivityTimer(); } +void CaptionBubble::OnAutoDetectedLanguageChanged() { + if (!base::FeatureList::IsEnabled(media::kLiveTranslate)) { + return; + } + + source_language_code_ = model_->GetAutoDetectedLanguageCode(); + source_language_text_ = speech::GetLanguageDisplayName(source_language_code_, + application_locale_); + + if (l10n_util::GetLanguage( + profile_prefs_->GetString(prefs::kLiveCaptionLanguageCode)) != + l10n_util::GetLanguage(source_language_code_)) { + // Append `(auto-detected)` to the end of the source language text. + source_language_text_ = l10n_util::GetStringFUTF16( + IDS_LIVE_CAPTION_AUTODETECTED_SOURCE_LANGUAGE, source_language_text_); + } + + UpdateLanguageLabelText(); + SetTextColor(); + Redraw(); +} + bool CaptionBubble::ThemeColorsChanged() { const auto* const color_provider = GetColorProvider(); SkColor text_color = @@ -989,8 +1053,8 @@ label_->SetMaximumWidth(kMaxWidthDip * textScaleFactor - kSidePaddingDip * 2); title_->SetLineHeight(kLineHeightDip * textScaleFactor); if (base::FeatureList::IsEnabled(media::kLiveTranslate)) { - live_translate_label_->SetLineHeight(kLiveTranslateLabelLineHeightDip * - textScaleFactor); + language_label_->SetLineHeight(kLiveTranslateLabelLineHeightDip * + textScaleFactor); } generic_error_text_->SetLineHeight(kLineHeightDip * textScaleFactor); generic_error_icon_->SetImageSize( @@ -1029,16 +1093,16 @@ const gfx::FontList live_translate_font_list = GetFontList(kLiveTranslateLabelFontSizePx); - views::StyledLabel::RangeStyleInfo live_translate_label_style; - live_translate_label_style.custom_font = live_translate_font_list; - live_translate_label_style.override_color = color_provider->GetColor( + views::StyledLabel::RangeStyleInfo language_label_style; + language_label_style.custom_font = live_translate_font_list; + language_label_style.override_color = color_provider->GetColor( ui::kColorLiveCaptionBubbleForegroundSecondary); views::StyledLabel::RangeStyleInfo live_translate_language_style; live_translate_language_style.custom_font = live_translate_font_list; live_translate_language_style.override_color = text_color; - UpdateLiveTranslateLabelStyle(live_translate_label_style, + UpdateLiveTranslateLabelStyle(language_label_style, live_translate_language_style); } #if BUILDFLAG(IS_WIN) @@ -1118,20 +1182,42 @@ void CaptionBubble::UpdateLiveTranslateLabelStyle( views::StyledLabel::RangeStyleInfo label_style, views::StyledLabel::RangeStyleInfo languages_style) { - live_translate_label_->AddStyleRange( - gfx::Range(0, live_translate_label_offsets_[0]), label_style); - live_translate_label_->AddStyleRange( - gfx::Range(live_translate_label_offsets_[0], - live_translate_label_offsets_[0] + source_language_.length()), + // Update the style of the label and source language. + language_label_->AddStyleRange(gfx::Range(0, language_label_offsets_[0]), + label_style); + language_label_->AddStyleRange( + gfx::Range(language_label_offsets_[0], + language_label_offsets_[0] + source_language_text_.length()), languages_style); - live_translate_label_->AddStyleRange( - gfx::Range(live_translate_label_offsets_[0] + source_language_.length(), - live_translate_label_offsets_[1]), - label_style); - live_translate_label_->AddStyleRange( - gfx::Range(live_translate_label_offsets_[1], - live_translate_label_offsets_[1] + target_language_.length()), - languages_style); + + // Update the style of the target language if applicable. + if (language_label_offsets_.size() > 1) { + language_label_->AddStyleRange( + gfx::Range(language_label_offsets_[0] + source_language_text_.length(), + language_label_offsets_[1]), + label_style); + language_label_->AddStyleRange( + gfx::Range(language_label_offsets_[1], + language_label_offsets_[1] + target_language_text_.length()), + languages_style); + } +} + +void CaptionBubble::UpdateLanguageLabelText() { + language_label_offsets_.clear(); + + if (profile_prefs_->GetBoolean(prefs::kLiveTranslateEnabled) && + l10n_util::GetLanguage(source_language_code_) != + l10n_util::GetLanguage(target_language_code_)) { + language_label_->SetText(l10n_util::GetStringFUTF16( + IDS_LIVE_CAPTION_TRANSLATED_CAPTION_LANGUAGE, source_language_text_, + target_language_text_, &language_label_offsets_)); + } else { + size_t offset; + language_label_->SetText(l10n_util::GetStringFUTF16( + IDS_LIVE_CAPTION_CAPTION_LANGUAGE, source_language_text_, &offset)); + language_label_offsets_.push_back(offset); + } } void CaptionBubble::RepositionInContextRect(CaptionBubbleModel::Id model_id, @@ -1175,16 +1261,15 @@ auto button_size = close_button_->GetPreferredSize(); left_header_container_->SetPreferredSize( gfx::Size(width - 3 * button_size.width(), button_size.height())); - int left_header_padding = - base::FeatureList::IsEnabled(media::kLiveTranslate) && - live_translate_label_->GetVisible() - ? caption_settings_button_->GetBorder()->GetInsets().width() / 2 - : 0; - left_header_container_ - ->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kHorizontal, - gfx::Insets::TLBR(0, left_header_padding, 0, 0), 0)) - ->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart); + + if (base::FeatureList::IsEnabled(media::kLiveTranslate)) { + // Set the maximum width of the live translate label to ensure that the + // caption settings button doesn't get crowded out. + language_label_->SizeToFit( + left_header_container_->GetPreferredSize().width() - + button_size.width()); + } + #if BUILDFLAG(IS_WIN) // The Media Foundation renderer error message should not scale with the // user's caption style preference. @@ -1289,8 +1374,8 @@ return static_cast<views::Label*>(label_); } -views::StyledLabel* CaptionBubble::GetLiveTranslateLabelForTesting() { - return static_cast<views::StyledLabel*>(live_translate_label_); +views::StyledLabel* CaptionBubble::GetLanguageLabelForTesting() { + return static_cast<views::StyledLabel*>(language_label_); } bool CaptionBubble::IsGenericErrorMessageVisibleForTesting() const {
diff --git a/components/live_caption/views/caption_bubble.h b/components/live_caption/views/caption_bubble.h index 14f4dd3..65d072a 100644 --- a/components/live_caption/views/caption_bubble.h +++ b/components/live_caption/views/caption_bubble.h
@@ -96,7 +96,7 @@ bool HasActivity(); views::Label* GetLabelForTesting(); - views::StyledLabel* GetLiveTranslateLabelForTesting(); + views::StyledLabel* GetLanguageLabelForTesting(); bool IsGenericErrorMessageVisibleForTesting() const; base::RetainingOneShotTimer* GetInactivityTimerForTesting(); void set_tick_clock_for_testing(const base::TickClock* tick_clock) { @@ -125,6 +125,8 @@ const gfx::Rect& new_bounds) override; void OnWidgetActivationChanged(views::Widget* widget, bool active) override; void OnLiveTranslateEnabledChanged(); + void OnLiveCaptionLanguageChanged(); + void OnLiveTranslateTargetLanguageChanged(); void GetAccessibleNodeData(ui::AXNodeData* node_data) override; std::u16string GetAccessibleWindowTitle() const override; void OnThemeChanged() override; @@ -146,6 +148,10 @@ // has changed. Sets the text of the caption bubble to the model's text. void OnTextChanged(); + // Called by CaptionBubbleModel to notify this object that the model's + // auto-detected language has changed. + void OnAutoDetectedLanguageChanged(); + // Used to prevent propagating theme changes when no theme colors have // changed. Returns whether the caption theme colors have changed since the // last time this function was called. @@ -188,6 +194,7 @@ void UpdateLiveTranslateLabelStyle( views::StyledLabel::RangeStyleInfo label_style, views::StyledLabel::RangeStyleInfo languages_style); + void UpdateLanguageLabelText(); // Places the bubble at the bottom center of the context widget for the active // model, ensuring that it's positioned where the user will spot it. If there @@ -219,12 +226,14 @@ raw_ptr<CaptionBubbleLabel> label_; raw_ptr<views::Label> title_; raw_ptr<views::Label> generic_error_text_; - raw_ptr<views::StyledLabel> live_translate_label_; + raw_ptr<views::StyledLabel> language_label_; raw_ptr<views::View> header_container_; raw_ptr<views::View> left_header_container_; - std::u16string source_language_; - std::u16string target_language_; - std::vector<size_t> live_translate_label_offsets_; + std::string source_language_code_; + std::string target_language_code_; + std::u16string source_language_text_; + std::u16string target_language_text_; + std::vector<size_t> language_label_offsets_; raw_ptr<views::ImageView> generic_error_icon_; raw_ptr<views::View> generic_error_message_; raw_ptr<views::ImageButton> back_to_tab_button_; @@ -236,6 +245,10 @@ raw_ptr<views::ImageButton> caption_settings_button_; raw_ptr<CaptionBubbleFrameView> frame_; + // Flag indicating whether the current source language does not match the user + // preference source language. + bool auto_detected_language_switched_ = false; + #if BUILDFLAG(IS_WIN) raw_ptr<views::StyledLabel> media_foundation_renderer_error_text_; raw_ptr<views::ImageView> media_foundation_renderer_error_icon_;
diff --git a/components/live_caption/views/caption_bubble_controller_views.cc b/components/live_caption/views/caption_bubble_controller_views.cc index 16621f7f..2030aa69 100644 --- a/components/live_caption/views/caption_bubble_controller_views.cc +++ b/components/live_caption/views/caption_bubble_controller_views.cc
@@ -206,4 +206,21 @@ return caption_bubble_; } +void CaptionBubbleControllerViews::OnLanguageIdentificationEvent( + CaptionBubbleContext* caption_bubble_context, + const media::mojom::LanguageIdentificationEventPtr& event) { + if (!caption_bubble_) { + return; + } + SetActiveModel(caption_bubble_context); + if (active_model_->IsClosed()) { + return; + } + + if (event->asr_switch_result == + media::mojom::AsrSwitchResult::kSwitchSucceeded) { + active_model_->SetLanguage(event->language); + } +} + } // namespace captions
diff --git a/components/live_caption/views/caption_bubble_controller_views.h b/components/live_caption/views/caption_bubble_controller_views.h index 29a27085..a32f9c7 100644 --- a/components/live_caption/views/caption_bubble_controller_views.h +++ b/components/live_caption/views/caption_bubble_controller_views.h
@@ -64,6 +64,9 @@ bool IsWidgetVisibleForTesting() override; bool IsGenericErrorMessageVisibleForTesting() override; std::string GetBubbleLabelTextForTesting() override; + void OnLanguageIdentificationEvent( + CaptionBubbleContext* caption_bubble_context, + const media::mojom::LanguageIdentificationEventPtr& event) override; void CloseActiveModelForTesting() override; views::Widget* GetCaptionWidgetForTesting(); CaptionBubble* GetCaptionBubbleForTesting();
diff --git a/components/live_caption/views/caption_bubble_model.cc b/components/live_caption/views/caption_bubble_model.cc index 7eb28f1c..7b5c599 100644 --- a/components/live_caption/views/caption_bubble_model.cc +++ b/components/live_caption/views/caption_bubble_model.cc
@@ -52,6 +52,12 @@ observer_->OnTextChanged(); } +void CaptionBubbleModel::OnAutoDetectedLanguageChanged() { + if (observer_) { + observer_->OnAutoDetectedLanguageChanged(); + } +} + void CaptionBubbleModel::SetPartialText(const std::string& partial_text) { partial_text_ = partial_text; OnTextChanged(); @@ -112,6 +118,15 @@ } } +void CaptionBubbleModel::SetLanguage(const std::string& language_code) { + if (!observer_) { + return; + } + + auto_detected_language_code_ = language_code; + OnAutoDetectedLanguageChanged(); +} + // static CaptionBubbleModel::Id CaptionBubbleModel::GetNextId() { static Id::Generator generator;
diff --git a/components/live_caption/views/caption_bubble_model.h b/components/live_caption/views/caption_bubble_model.h index 0749fbd3..c4fa46b 100644 --- a/components/live_caption/views/caption_bubble_model.h +++ b/components/live_caption/views/caption_bubble_model.h
@@ -92,8 +92,16 @@ std::string GetFullText() const { return final_text_ + partial_text_; } CaptionBubbleContext* GetContext() { return context_; } + // Returns the auto-detected language code or an empty string if the language + // was not automatically switched. + std::string GetAutoDetectedLanguageCode() const { + return auto_detected_language_code_; + } + Id unique_id() const { return unique_id_; } + void SetLanguage(const std::string& language_code); + private: // Generates the next unique id. static Id GetNextId(); @@ -101,11 +109,17 @@ // Alert the observer that a change has occurred to the model text. void OnTextChanged(); + // Alert the observer that the auto-detected language of the model has + // changed. + void OnAutoDetectedLanguageChanged(); + const Id unique_id_; std::string final_text_; std::string partial_text_; + std::string auto_detected_language_code_ = std::string(); + // Whether the bubble has been closed by the user. bool is_closed_ = false;
diff --git a/components/live_caption_strings.grdp b/components/live_caption_strings.grdp index f24fa22..afa81372 100644 --- a/components/live_caption_strings.grdp +++ b/components/live_caption_strings.grdp
@@ -37,9 +37,15 @@ <message name="IDS_LIVE_CAPTION_BUBBLE_APPEAR_SCREENREADER_ANNOUNCEMENT" desc="Announcement to screen readers on ChromeOS when the Live Caption bubble appears to inform users of how to focus the bubble."> Live Caption visible, use window switcher to focus </message> - <message name="IDS_LIVE_CAPTION_TRANSLATED_CAPTIONS" desc="Label for the Live Caption bubble displaying the source and target translation languages."> + <message name="IDS_LIVE_CAPTION_CAPTION_LANGUAGE" desc="Label for the Live Caption bubble displaying the source language."> + Captioning <ph name="SOURCE">$1<ex>Spanish</ex></ph> + </message> + <message name="IDS_LIVE_CAPTION_TRANSLATED_CAPTION_LANGUAGE" desc="Label for the Live Caption bubble displaying the source and target translation languages."> Translating <ph name="SOURCE">$1<ex>Spanish</ex></ph> to <ph name="TARGET">$2<ex>English</ex></ph> </message> + <message name="IDS_LIVE_CAPTION_AUTODETECTED_SOURCE_LANGUAGE" desc="Label for the auto-detected source language displayed when the language of an audio stream differs from the language set by the user preference."> + <ph name="SOURCE">$1<ex>Spanish</ex></ph> (auto-detected) + </message> <message name="IDS_LIVE_CAPTION_BUBBLE_CAPTION_SETTINGS" desc="Tooltip for the caption settings button"> Caption settings </message>
diff --git a/components/live_caption_strings_grdp/IDS_LIVE_CAPTION_AUTODETECTED_SOURCE_LANGUAGE.png.sha1 b/components/live_caption_strings_grdp/IDS_LIVE_CAPTION_AUTODETECTED_SOURCE_LANGUAGE.png.sha1 new file mode 100644 index 0000000..66276be --- /dev/null +++ b/components/live_caption_strings_grdp/IDS_LIVE_CAPTION_AUTODETECTED_SOURCE_LANGUAGE.png.sha1
@@ -0,0 +1 @@ +b78fde8dac2537171d701599c4eaef7ccf328c9e \ No newline at end of file
diff --git a/components/live_caption_strings_grdp/IDS_LIVE_CAPTION_CAPTION_LANGUAGE.png.sha1 b/components/live_caption_strings_grdp/IDS_LIVE_CAPTION_CAPTION_LANGUAGE.png.sha1 new file mode 100644 index 0000000..66276be --- /dev/null +++ b/components/live_caption_strings_grdp/IDS_LIVE_CAPTION_CAPTION_LANGUAGE.png.sha1
@@ -0,0 +1 @@ +b78fde8dac2537171d701599c4eaef7ccf328c9e \ No newline at end of file
diff --git a/components/live_caption_strings_grdp/IDS_LIVE_CAPTION_TRANSLATED_CAPTIONS.png.sha1 b/components/live_caption_strings_grdp/IDS_LIVE_CAPTION_TRANSLATED_CAPTION_LANGUAGE.png.sha1 similarity index 100% rename from components/live_caption_strings_grdp/IDS_LIVE_CAPTION_TRANSLATED_CAPTIONS.png.sha1 rename to components/live_caption_strings_grdp/IDS_LIVE_CAPTION_TRANSLATED_CAPTION_LANGUAGE.png.sha1
diff --git a/components/page_info/android/BUILD.gn b/components/page_info/android/BUILD.gn index d57bcfe..2300f84 100644 --- a/components/page_info/android/BUILD.gn +++ b/components/page_info/android/BUILD.gn
@@ -68,7 +68,6 @@ "java/src/org/chromium/components/page_info/PageInfoCookiesController.java", "java/src/org/chromium/components/page_info/PageInfoCookiesPreference.java", "java/src/org/chromium/components/page_info/PageInfoDialog.java", - "java/src/org/chromium/components/page_info/PageInfoDiscoverabilityMetrics.java", "java/src/org/chromium/components/page_info/PageInfoFeatures.java", "java/src/org/chromium/components/page_info/PageInfoHighlight.java", "java/src/org/chromium/components/page_info/PageInfoMainController.java",
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoDiscoverabilityMetrics.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoDiscoverabilityMetrics.java deleted file mode 100644 index 346d7016..0000000 --- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoDiscoverabilityMetrics.java +++ /dev/null
@@ -1,96 +0,0 @@ -// Copyright 2021 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.components.page_info; - -import android.os.SystemClock; - -import androidx.annotation.IntDef; - -import org.chromium.base.metrics.RecordHistogram; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * A class for controlling the page info discoverability metrics reporting. - */ -public class PageInfoDiscoverabilityMetrics { - /** - * UMA statistics for PageInfoDiscoverability. Do not reorder or remove existing fields. All - * values here should have corresponding entries in WebsiteSettingsDiscoverabilityAction area of - * enums.xml. - */ - @IntDef({DiscoverabilityAction.PERMISSION_ICON_SHOWN, DiscoverabilityAction.PAGE_INFO_OPENED, - DiscoverabilityAction.PERMISSIONS_OPENED, DiscoverabilityAction.PERMISSION_CHANGED, - DiscoverabilityAction.STORE_ICON_SHOWN, - DiscoverabilityAction.PAGE_INFO_OPENED_FROM_STORE_ICON, - DiscoverabilityAction.STORE_INFO_OPENED}) - @Retention(RetentionPolicy.SOURCE) - public @interface DiscoverabilityAction { - int PERMISSION_ICON_SHOWN = 0; - int PAGE_INFO_OPENED = 1; - int PERMISSIONS_OPENED = 2; - int PERMISSION_CHANGED = 3; - int STORE_ICON_SHOWN = 4; - int PAGE_INFO_OPENED_FROM_STORE_ICON = 5; - int STORE_INFO_OPENED = 6; - int NUM_ENTRIES = 7; - } - private Long mPermissionIconShownTime; - private Long mPageInfoOpenedTime; - private Long mStoreIconShownTime; - private Long mPageInfoOpenedFromStoreIconTime; - - public void recordDiscoverabilityAction(@DiscoverabilityAction int action) { - RecordHistogram.recordEnumeratedHistogram("WebsiteSettings.Discoverability.Action", action, - DiscoverabilityAction.NUM_ENTRIES); - - switch (action) { - case DiscoverabilityAction.PERMISSION_ICON_SHOWN: - mPermissionIconShownTime = SystemClock.elapsedRealtime(); - break; - case DiscoverabilityAction.PAGE_INFO_OPENED: - assert mPermissionIconShownTime != null; - mPageInfoOpenedTime = SystemClock.elapsedRealtime(); - RecordHistogram.recordTimesHistogram("WebsiteSettings.Discoverability.TimeToOpen", - mPageInfoOpenedTime - mPermissionIconShownTime); - mPermissionIconShownTime = null; - break; - case DiscoverabilityAction.PERMISSIONS_OPENED: - // A user can open permissions multiple times but we only want to include the first - // time after the page info was opened. - if (mPageInfoOpenedTime != null) { - RecordHistogram.recordMediumTimesHistogram( - "WebsiteSettings.Discoverability.TimeToClickHighlight", - SystemClock.elapsedRealtime() - mPageInfoOpenedTime); - } - mPageInfoOpenedTime = null; - break; - case DiscoverabilityAction.STORE_ICON_SHOWN: - mStoreIconShownTime = SystemClock.elapsedRealtime(); - break; - case DiscoverabilityAction.PAGE_INFO_OPENED_FROM_STORE_ICON: - assert mStoreIconShownTime != null; - mPageInfoOpenedFromStoreIconTime = SystemClock.elapsedRealtime(); - RecordHistogram.recordTimesHistogram( - "WebsiteSettings.Discoverability.TimeToOpenFromStoreIcon", - mPageInfoOpenedFromStoreIconTime - mStoreIconShownTime); - mStoreIconShownTime = null; - break; - case DiscoverabilityAction.STORE_INFO_OPENED: - // A user can open store info multiple times but we only want to include the first - // time after the page info was opened. - if (mPageInfoOpenedFromStoreIconTime != null) { - RecordHistogram.recordMediumTimesHistogram( - "WebsiteSettings.Discoverability.TimeToClickHighlightStoreInfo", - SystemClock.elapsedRealtime() - mPageInfoOpenedFromStoreIconTime); - } - mPageInfoOpenedFromStoreIconTime = null; - break; - default: - break; - } - } -}
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoPermissionsController.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoPermissionsController.java index cd39795..ad964c7 100644 --- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoPermissionsController.java +++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoPermissionsController.java
@@ -23,7 +23,6 @@ import org.chromium.components.browsing_data.DeleteBrowsingDataAction; import org.chromium.components.content_settings.ContentSettingsType; import org.chromium.components.embedder_support.util.Origin; -import org.chromium.components.page_info.PageInfoDiscoverabilityMetrics.DiscoverabilityAction; import org.chromium.content_public.browser.BrowserContextHandle; import java.util.Collection; @@ -54,8 +53,6 @@ private int mHighlightedPermission; @ColorRes private int mHighlightColor; - private final PageInfoDiscoverabilityMetrics mDiscoverabilityMetrics = - new PageInfoDiscoverabilityMetrics(); public PageInfoPermissionsController(PageInfoMainController mainController, PageInfoRowView view, PageInfoControllerDelegate delegate, @@ -71,10 +68,6 @@ } private void launchSubpage() { - if (mHighlightedPermission != ContentSettingsType.DEFAULT) { - mDiscoverabilityMetrics.recordDiscoverabilityAction( - DiscoverabilityAction.PERMISSIONS_OPENED); - } mMainController.recordAction(PageInfoAction.PAGE_INFO_PERMISSION_DIALOG_OPENED); mMainController.launchSubpage(this); } @@ -227,10 +220,6 @@ @Override public void onPermissionChanged() { - if (mHighlightedPermission != ContentSettingsType.DEFAULT) { - mDiscoverabilityMetrics.recordDiscoverabilityAction( - DiscoverabilityAction.PERMISSION_CHANGED); - } mMainController.recordAction(PageInfoAction.PAGE_INFO_CHANGED_PERMISSION); mDataIsStale = true; }
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer.cc b/components/page_load_metrics/browser/metrics_web_contents_observer.cc index bea2263..d827490 100644 --- a/components/page_load_metrics/browser/metrics_web_contents_observer.cc +++ b/components/page_load_metrics/browser/metrics_web_contents_observer.cc
@@ -13,6 +13,7 @@ #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" #include "base/observer_list.h" +#include "base/time/time.h" #include "base/trace_event/trace_event.h" #include "components/page_load_metrics/browser/metrics_lifecycle_observer.h" #include "components/page_load_metrics/browser/page_load_metrics_embedder_interface.h" @@ -112,6 +113,7 @@ metrics = new MetricsWebContentsObserver(web_contents, std::move(embedder_interface)); web_contents->SetUserData(UserDataKey(), base::WrapUnique(metrics)); + metrics->created_ = base::TimeTicks::Now(); } return metrics; } @@ -1260,6 +1262,10 @@ tracker->OnSharedStorageWorkletHostCreated(); } +base::TimeTicks MetricsWebContentsObserver::GetCreated() { + return created_; +} + // This contains some bugs. RenderFrameHost::IsActive is not relevant to // determine what members we have to search. //
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer.h b/components/page_load_metrics/browser/metrics_web_contents_observer.h index 8102b58..75171fc 100644 --- a/components/page_load_metrics/browser/metrics_web_contents_observer.h +++ b/components/page_load_metrics/browser/metrics_web_contents_observer.h
@@ -168,6 +168,9 @@ // Called when a `SharedStorageWorkletHost` is created for `rfh`. void OnSharedStorageWorkletHostCreated(content::RenderFrameHost* rfh); + // Returns the time this MetricsWebContentsObserver was created. + base::TimeTicks GetCreated(); + protected: // Protected rather than private so that derived test classes can call // constructor. @@ -359,6 +362,8 @@ bool web_contents_will_soon_be_destroyed_ = false; + base::TimeTicks created_; + WEB_CONTENTS_USER_DATA_KEY_DECL(); };
diff --git a/components/password_manager/core/browser/mock_webauthn_credentials_delegate.h b/components/password_manager/core/browser/mock_webauthn_credentials_delegate.h index cbe256c..4a775f6e 100644 --- a/components/password_manager/core/browser/mock_webauthn_credentials_delegate.h +++ b/components/password_manager/core/browser/mock_webauthn_credentials_delegate.h
@@ -8,6 +8,7 @@ #include <string> #include <vector> +#include "build/build_config.h" #include "components/password_manager/core/browser/passkey_credential.h" #include "components/password_manager/core/browser/webauthn_credentials_delegate.h" #include "testing/gmock/include/gmock/gmock.h" @@ -32,6 +33,10 @@ (), (const override)); MOCK_METHOD(void, RetrievePasskeys, (base::OnceClosure), (override)); +#if BUILDFLAG(IS_ANDROID) + MOCK_METHOD(void, ShowAndroidHybridSignIn, (), (override)); + MOCK_METHOD(bool, IsAndroidHybridAvailable, (), (const override)); +#endif }; } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_autofill_manager.cc b/components/password_manager/core/browser/password_autofill_manager.cc index 3e9e887..d0ac5ad 100644 --- a/components/password_manager/core/browser/password_autofill_manager.cc +++ b/components/password_manager/core/browser/password_autofill_manager.cc
@@ -135,14 +135,14 @@ *suggestion.voice_over += suggestion.labels[0][0].value; } if (from_account_store) { - suggestion.frontend_id = + suggestion.popup_item_id = is_password_field ? autofill::PopupItemId::kAccountStoragePasswordEntry : autofill::PopupItemId::kAccountStorageUsernameEntry; } else { - suggestion.frontend_id = is_password_field - ? autofill::PopupItemId::kPasswordEntry - : autofill::PopupItemId::kUsernameEntry; + suggestion.popup_item_id = is_password_field + ? autofill::PopupItemId::kPasswordEntry + : autofill::PopupItemId::kUsernameEntry; } suggestion.match = show_all || base::StartsWith(lower_suggestion, lower_contents, @@ -203,7 +203,7 @@ std::vector<autofill::Suggestion>* suggestions) { bool has_no_fillable_suggestions = base::ranges::none_of( *suggestions, - [](autofill::Suggestion::FrontendId id) { + [](autofill::PopupItemId id) { return id == autofill::PopupItemId::kUsernameEntry || id == autofill::PopupItemId::kPasswordEntry || id == autofill::PopupItemId::kAccountStorageUsernameEntry || @@ -211,16 +211,16 @@ id == autofill::PopupItemId::kGeneratePasswordEntry || id == autofill::PopupItemId::kWebauthnCredential; }, - &autofill::Suggestion::frontend_id); + &autofill::Suggestion::popup_item_id); if (has_no_fillable_suggestions) return; bool has_webauthn_credential = base::ranges::any_of( *suggestions, - [](autofill::Suggestion::FrontendId id) { - return id == autofill::PopupItemId::kWebauthnCredential; + [](autofill::PopupItemId popup_item_id) { + return popup_item_id == autofill::PopupItemId::kWebauthnCredential; }, - &autofill::Suggestion::frontend_id); + &autofill::Suggestion::popup_item_id); #if !BUILDFLAG(IS_ANDROID) // Add a separator before the manage option unless there are no suggestions @@ -235,7 +235,7 @@ has_webauthn_credential ? IDS_PASSWORD_MANAGER_MANAGE_PASSWORDS_AND_PASSKEYS : IDS_PASSWORD_MANAGER_MANAGE_PASSWORDS)); - suggestion.frontend_id = autofill::PopupItemId::kAllSavedPasswordsEntry; + suggestion.popup_item_id = autofill::PopupItemId::kAllSavedPasswordsEntry; if (base::FeatureList::IsEnabled( password_manager::features::kEnablePasswordsAccountStorage)) { // The UI code will pick up an icon from the resources based on the string. @@ -251,7 +251,7 @@ autofill::Suggestion suggestion( l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_USE_DEVICE_PASSKEY)); suggestion.icon = "device"; - suggestion.frontend_id = + suggestion.popup_item_id = autofill::PopupItemId::kWebauthnSignInWithAnotherDevice; return suggestion; } @@ -262,7 +262,7 @@ l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_GENERATE_PASSWORD)); // The UI code will pick up an icon from the resources based on the string. suggestion.icon = "keyIcon"; - suggestion.frontend_id = autofill::PopupItemId::kGeneratePasswordEntry; + suggestion.popup_item_id = autofill::PopupItemId::kGeneratePasswordEntry; return suggestion; } @@ -270,7 +270,8 @@ autofill::Suggestion CreateEntryToOptInToAccountStorageThenFill() { autofill::Suggestion suggestion( l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_OPT_INTO_ACCOUNT_STORE)); - suggestion.frontend_id = autofill::PopupItemId::kPasswordAccountStorageOptIn; + suggestion.popup_item_id = + autofill::PopupItemId::kPasswordAccountStorageOptIn; suggestion.icon = "google"; return suggestion; } @@ -279,7 +280,7 @@ autofill::Suggestion CreateEntryToOptInToAccountStorageThenGenerate() { autofill::Suggestion suggestion( l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_GENERATE_PASSWORD)); - suggestion.frontend_id = + suggestion.popup_item_id = autofill::PopupItemId::kPasswordAccountStorageOptInAndGenerate; suggestion.icon = "keyIcon"; return suggestion; @@ -289,7 +290,7 @@ autofill::Suggestion CreateEntryToReSignin() { autofill::Suggestion suggestion( l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_RE_SIGNIN_ACCOUNT_STORE)); - suggestion.frontend_id = + suggestion.popup_item_id = autofill::PopupItemId::kPasswordAccountStorageReSignin; suggestion.icon = "google"; return suggestion; @@ -299,7 +300,8 @@ autofill::Suggestion CreateAccountStorageEmptyEntry() { autofill::Suggestion suggestion( l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_NO_ACCOUNT_STORE_MATCHES)); - suggestion.frontend_id = autofill::PopupItemId::kPasswordAccountStorageEmpty; + suggestion.popup_item_id = + autofill::PopupItemId::kPasswordAccountStorageEmpty; suggestion.icon = "empty"; return suggestion; } @@ -307,21 +309,21 @@ bool ContainsOtherThanManagePasswords( base::span<const autofill::Suggestion> suggestions) { return base::ranges::any_of(suggestions, [](const auto& s) { - return s.frontend_id != autofill::PopupItemId::kAllSavedPasswordsEntry; + return s.popup_item_id != autofill::PopupItemId::kAllSavedPasswordsEntry; }); } bool AreSuggestionForPasswordField( base::span<const autofill::Suggestion> suggestions) { return base::ranges::any_of(suggestions, [](const auto& suggestion) { - return suggestion.frontend_id == autofill::PopupItemId::kPasswordEntry; + return suggestion.popup_item_id == autofill::PopupItemId::kPasswordEntry; }); } bool HasLoadingSuggestion(base::span<const autofill::Suggestion> suggestions, autofill::PopupItemId item_id) { return base::ranges::any_of(suggestions, [&item_id](const auto& suggestion) { - return suggestion.frontend_id == item_id && suggestion.is_loading; + return suggestion.popup_item_id == item_id && suggestion.is_loading; }); } @@ -338,7 +340,7 @@ new_suggestions.reserve(suggestions.size()); base::ranges::copy(suggestions, std::back_inserter(new_suggestions)); auto unlock_iter = base::ranges::find(new_suggestions, unlock_item, - &autofill::Suggestion::frontend_id); + &autofill::Suggestion::popup_item_id); unlock_iter->is_loading = is_loading; return new_suggestions; } @@ -386,21 +388,25 @@ void PasswordAutofillManager::DidSelectSuggestion( const autofill::Suggestion& suggestion) { ClearPreviewedForm(); - - const autofill::Suggestion::FrontendId frontend_id = suggestion.frontend_id; - if (frontend_id == autofill::PopupItemId::kAllSavedPasswordsEntry || - frontend_id == autofill::PopupItemId::kPasswordAccountStorageEmpty || - frontend_id == autofill::PopupItemId::kGeneratePasswordEntry || - frontend_id == autofill::PopupItemId::kPasswordAccountStorageOptIn || - frontend_id == autofill::PopupItemId::kPasswordAccountStorageReSignin || - frontend_id == + if (suggestion.popup_item_id == + autofill::PopupItemId::kAllSavedPasswordsEntry || + suggestion.popup_item_id == + autofill::PopupItemId::kPasswordAccountStorageEmpty || + suggestion.popup_item_id == + autofill::PopupItemId::kGeneratePasswordEntry || + suggestion.popup_item_id == + autofill::PopupItemId::kPasswordAccountStorageOptIn || + suggestion.popup_item_id == + autofill::PopupItemId::kPasswordAccountStorageReSignin || + suggestion.popup_item_id == autofill::PopupItemId::kPasswordAccountStorageOptInAndGenerate || - frontend_id == autofill::PopupItemId::kWebauthnSignInWithAnotherDevice) { + suggestion.popup_item_id == + autofill::PopupItemId::kWebauthnSignInWithAnotherDevice) { return; } PreviewSuggestion(GetUsernameFromSuggestion(suggestion.main_text.value), - frontend_id); + suggestion.popup_item_id); } void PasswordAutofillManager::OnUnlockItemAccepted( @@ -427,7 +433,7 @@ const autofill::Suggestion& suggestion, int position) { using metrics_util::PasswordDropdownSelectedOption; - switch (suggestion.frontend_id.as_popup_item_id()) { + switch (suggestion.popup_item_id) { case autofill::PopupItemId::kGeneratePasswordEntry: password_client_->GeneratePassword(PasswordGenerationType::kAutomatic); metrics_util::LogPasswordDropdownItemSelected( @@ -458,9 +464,9 @@ break; case autofill::PopupItemId::kPasswordAccountStorageOptIn: case autofill::PopupItemId::kPasswordAccountStorageOptInAndGenerate: - OnUnlockItemAccepted(suggestion.frontend_id.as_popup_item_id()); + OnUnlockItemAccepted(suggestion.popup_item_id); metrics_util::LogPasswordDropdownItemSelected( - suggestion.frontend_id == + suggestion.popup_item_id == autofill::PopupItemId::kPasswordAccountStorageOptIn ? PasswordDropdownSelectedOption::kUnlockAccountStorePasswords : PasswordDropdownSelectedOption::kUnlockAccountStoreGeneration, @@ -502,7 +508,7 @@ password_client_)) { bool success = FillSuggestion( GetUsernameFromSuggestion(suggestion.main_text.value), - suggestion.frontend_id); + suggestion.popup_item_id); DCHECK(success); } else { authenticator_ = std::move(authenticator); @@ -511,17 +517,18 @@ device_reauth::DeviceAuthRequester::kAutofillSuggestion, base::BindOnce(&PasswordAutofillManager::OnBiometricReauthCompleted, weak_ptr_factory_.GetWeakPtr(), - suggestion.main_text.value, suggestion.frontend_id), + suggestion.main_text.value, + suggestion.popup_item_id), /*use_last_valid_auth=*/true); #elif BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) const std::u16string origin = base::UTF8ToUTF16(GetShownOrigin(url::Origin::Create( password_manager_driver_->GetLastCommittedURL()))); - auto on_reath_complete = - base::BindOnce(&PasswordAutofillManager::OnBiometricReauthCompleted, - weak_ptr_factory_.GetWeakPtr(), - suggestion.main_text.value, suggestion.frontend_id); + auto on_reath_complete = base::BindOnce( + &PasswordAutofillManager::OnBiometricReauthCompleted, + weak_ptr_factory_.GetWeakPtr(), suggestion.main_text.value, + suggestion.popup_item_id); authenticator_->AuthenticateWithMessage( l10n_util::GetStringFUTF16(IDS_PASSWORD_MANAGER_FILLING_REAUTH, @@ -540,7 +547,7 @@ bool PasswordAutofillManager::GetDeletionConfirmationText( const std::u16string& value, - autofill::Suggestion::FrontendId frontend_id, + autofill::PopupItemId popup_item_id, autofill::Suggestion::BackendId backend_id, std::u16string* title, std::u16string* body) { @@ -549,7 +556,7 @@ bool PasswordAutofillManager::RemoveSuggestion( const std::u16string& value, - autofill::Suggestion::FrontendId frontend_id, + autofill::PopupItemId popup_item_id, autofill::Suggestion::BackendId backend_id) { // Password suggestions cannot be deleted this way. // See http://crbug.com/329038#c15 @@ -730,7 +737,7 @@ [this](const auto& passkey) { autofill::Suggestion suggestion(ToUsernameString(passkey.username())); suggestion.icon = "globeIcon"; - suggestion.frontend_id = autofill::PopupItemId::kWebauthnCredential; + suggestion.popup_item_id = autofill::PopupItemId::kWebauthnCredential; suggestion.custom_icon = page_favicon_; suggestion.payload = autofill::Suggestion::BackendId( base::Base64Encode(passkey.credential_id())); @@ -787,7 +794,7 @@ metrics_util::PasswordDropdownState dropdown_state = metrics_util::PasswordDropdownState::kStandard; for (const auto& suggestion : suggestions) { - switch (suggestion.frontend_id.as_popup_item_id()) { + switch (suggestion.popup_item_id) { case autofill::PopupItemId::kGeneratePasswordEntry: // TODO(crbug.com/1062709): Revisit metrics for the "opt in and // generate" button. @@ -836,10 +843,10 @@ bool PasswordAutofillManager::FillSuggestion( const std::u16string& username, - autofill::Suggestion::FrontendId item_id) { + autofill::PopupItemId popup_item_id) { autofill::PasswordAndMetadata password_and_meta_data; if (fill_data_ && - GetPasswordAndMetadataForUsername(username, item_id, *fill_data_, + GetPasswordAndMetadataForUsername(username, popup_item_id, *fill_data_, &password_and_meta_data)) { bool is_android_credential = FacetURI::FromPotentiallyInvalidSpec(password_and_meta_data.realm) @@ -854,8 +861,8 @@ bool PasswordAutofillManager::PreviewSuggestion( const std::u16string& username, - autofill::Suggestion::FrontendId item_id) { - if (item_id == autofill::PopupItemId::kWebauthnCredential) { + autofill::PopupItemId popup_item_id) { + if (popup_item_id == autofill::PopupItemId::kWebauthnCredential) { password_manager_driver_->PreviewSuggestion(username, /*password=*/u""); return true; } @@ -865,7 +872,7 @@ } autofill::PasswordAndMetadata password_and_meta_data; if (fill_data_ && - GetPasswordAndMetadataForUsername(username, item_id, *fill_data_, + GetPasswordAndMetadataForUsername(username, popup_item_id, *fill_data_, &password_and_meta_data)) { password_manager_driver_->PreviewSuggestion( username, password_and_meta_data.password_value); @@ -876,7 +883,7 @@ bool PasswordAutofillManager::GetPasswordAndMetadataForUsername( const std::u16string& current_username, - autofill::Suggestion::FrontendId item_id, + autofill::PopupItemId popup_item_id, const autofill::PasswordFormFillData& fill_data, autofill::PasswordAndMetadata* password_and_meta_data) { // TODO(dubroy): When password access requires some kind of authentication @@ -884,8 +891,8 @@ // fetch the actual password. See crbug.com/178358 for more context. bool item_uses_account_store = - item_id == autofill::PopupItemId::kAccountStorageUsernameEntry || - item_id == autofill::PopupItemId::kAccountStoragePasswordEntry; + popup_item_id == autofill::PopupItemId::kAccountStorageUsernameEntry || + popup_item_id == autofill::PopupItemId::kAccountStoragePasswordEntry; // Look for any suitable matches to current field text. if (fill_data.preferred_login.username_value == current_username && @@ -953,14 +960,15 @@ void PasswordAutofillManager::OnBiometricReauthCompleted( const std::u16string& value, - autofill::Suggestion::FrontendId frontend_id, + autofill::PopupItemId popup_item_id, bool auth_succeeded) { authenticator_.reset(); base::UmaHistogramBoolean( "PasswordManager.PasswordFilling.AuthenticationResult", auth_succeeded); if (!auth_succeeded) return; - bool success = FillSuggestion(GetUsernameFromSuggestion(value), frontend_id); + bool success = + FillSuggestion(GetUsernameFromSuggestion(value), popup_item_id); DCHECK(success); }
diff --git a/components/password_manager/core/browser/password_autofill_manager.h b/components/password_manager/core/browser/password_autofill_manager.h index 6a8242f0..1c78ad7 100644 --- a/components/password_manager/core/browser/password_autofill_manager.h +++ b/components/password_manager/core/browser/password_autofill_manager.h
@@ -15,6 +15,7 @@ #include "base/types/strong_alias.h" #include "components/autofill/core/browser/autofill_client.h" #include "components/autofill/core/browser/ui/autofill_popup_delegate.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" #include "components/autofill/core/browser/ui/suggestion.h" #include "components/autofill/core/common/password_form_fill_data.h" #include "components/password_manager/core/browser/password_manager_client.h" @@ -54,16 +55,17 @@ void OnPopupShown() override; void OnPopupHidden() override; void OnPopupSuppressed() override; + void DidSelectSuggestion(const autofill::Suggestion& suggestion) override; void DidAcceptSuggestion(const autofill::Suggestion& suggestion, int position) override; bool GetDeletionConfirmationText(const std::u16string& value, - autofill::Suggestion::FrontendId frontend_id, + autofill::PopupItemId popup_item_id, autofill::Suggestion::BackendId backend_id, std::u16string* title, std::u16string* body) override; bool RemoveSuggestion(const std::u16string& value, - autofill::Suggestion::FrontendId frontend_id, + autofill::PopupItemId popup_item_id, autofill::Suggestion::BackendId backend_id) override; void ClearPreviewedForm() override; autofill::PopupType GetPopupType() const override; @@ -150,19 +152,19 @@ void UpdatePopup(const std::vector<autofill::Suggestion>& suggestions); // Attempts to find and fill the suggestions with the user name |username| and - // the |item_id| indicating the store (account-stored or local). Returns true - // if it was successful. + // the `popup_item_id` indicating the store (account-stored or local). Returns + // true if it was successful. bool FillSuggestion(const std::u16string& username, - autofill::Suggestion::FrontendId item_id); + autofill::PopupItemId popup_item_id); // Attempts to find and preview the suggestions with the user name |username| - // and the |item_id| indicating the store (account-stored or local). Returns - // true if it was successful. + // and the `popup_item_id` indicating the store (account-stored or local). + // Returns true if it was successful. bool PreviewSuggestion(const std::u16string& username, - autofill::Suggestion::FrontendId item_id); + autofill::PopupItemId popup_item_id); // If one of the login mappings in |fill_data| matches |current_username| and - // |item_id| (indicating whether a credential is stored in account or + // `popup_item_id` (indicating whether a credential is stored in account or // locally), return true and assign the password and the original signon // realm to |password_and_meta_data|. Note that if the credential comes from // the same realm as the one we're filling to, the |realm| field will be left @@ -170,7 +172,7 @@ // Otherwise, returns false and leaves |password_and_meta_data| untouched. bool GetPasswordAndMetadataForUsername( const std::u16string& current_username, - autofill::Suggestion::FrontendId item_id, + autofill::PopupItemId popup_item_id, const autofill::PasswordFormFillData& fill_data, autofill::PasswordAndMetadata* password_and_meta_data); @@ -196,9 +198,9 @@ PasswordManagerClient::ReauthSucceeded reauth_succeeded); // Called when the biometric reauth that guards password filling completes. - // |frontend_id| identifies the suggestion that was selected for filling. + // `popup_item_id` identifies the suggestion that was selected for filling. void OnBiometricReauthCompleted(const std::u16string& username_value, - autofill::Suggestion::FrontendId frontend_id, + autofill::PopupItemId popup_item_id, bool auth_succeded); // Cancels an ongoing biometric re-authentication. Usually, because
diff --git a/components/password_manager/core/browser/password_autofill_manager_unittest.cc b/components/password_manager/core/browser/password_autofill_manager_unittest.cc index 1883fb30..d7658d2 100644 --- a/components/password_manager/core/browser/password_autofill_manager_unittest.cc +++ b/components/password_manager/core/browser/password_autofill_manager_unittest.cc
@@ -228,10 +228,7 @@ HideAutofillPopup, (autofill::PopupHidingReason), (override)); - MOCK_METHOD(void, - ExecuteCommand, - (autofill::Suggestion::FrontendId), - (override)); + MOCK_METHOD(void, ExecuteCommand, (autofill::PopupItemId), (override)); }; base::CancelableTaskTracker::TaskId @@ -249,26 +246,26 @@ std::vector<Suggestion> suggestions; suggestions.emplace_back( /*value=*/"User1", /*label=*/"PW1", /*icon=*/"", - /*frontend_id=*/autofill::PopupItemId::kPasswordEntry); + /*popup_item_id=*/autofill::PopupItemId::kPasswordEntry); suggestions.emplace_back( /*value=*/"Show all pwds", /*label=*/"", /*icon=*/"", - /*frontend_id=*/autofill::PopupItemId::kAllSavedPasswordsEntry); + /*popup_item_id=*/autofill::PopupItemId::kAllSavedPasswordsEntry); if (has_opt_in_and_fill) { suggestions.emplace_back( /*value=*/"Unlock passwords and fill", /*label=*/"", /*icon=*/"", - /*frontend_id=*/ + /*popup_item_id=*/ autofill::PopupItemId::kPasswordAccountStorageOptIn); } if (has_opt_in_and_generate) { suggestions.emplace_back( /*value=*/"Unlock passwords and generate", /*label=*/"", /*icon=*/"", - /*frontend_id=*/ + /*popup_item_id=*/ autofill::PopupItemId::kPasswordAccountStorageOptInAndGenerate); } if (has_re_signin) { suggestions.emplace_back( /*value=*/"Sign in to access passwords", /*label=*/"", /*icon=*/"", - /*frontend_id=*/ + /*popup_item_id=*/ autofill::PopupItemId::kPasswordAccountStorageReSignin); } return suggestions; @@ -924,7 +921,7 @@ // loading state which the DeleteFillData() call will end. Suggestion unlock_suggestion( /*main_text=*/"Unlock passwords and fill", /*label=*/"", /*icon=*/"", - /*frontend_id=*/ + /*popup_item_id=*/ autofill::PopupItemId::kPasswordAccountStorageOptIn); unlock_suggestion.is_loading = Suggestion::IsLoading(true); EXPECT_CALL(autofill_client, GetPopupSuggestions) @@ -1600,10 +1597,10 @@ gfx::RectF(), base::i18n::RIGHT_TO_LEFT, /*show_password_suggestions=*/true); EXPECT_THAT(open_args.suggestions, - Not(Contains(Field(&autofill::Suggestion::frontend_id, + Not(Contains(Field(&autofill::Suggestion::popup_item_id, Eq(regular_generate_id))))); EXPECT_THAT(open_args.suggestions, - Contains(Field(&autofill::Suggestion::frontend_id, + Contains(Field(&autofill::Suggestion::popup_item_id, Eq(opt_in_and_generate_id)))); } @@ -2112,7 +2109,7 @@ autofill::PopupItemId::kAllSavedPasswordsEntry)); EXPECT_EQ(open_args.suggestions[0].GetPayload<Suggestion::BackendId>(), Suggestion::BackendId(kIdBase64)); - EXPECT_EQ(open_args.suggestions[0].frontend_id, + EXPECT_EQ(open_args.suggestions[0].popup_item_id, autofill::PopupItemId::kWebauthnCredential); EXPECT_EQ(open_args.suggestions[0].main_text.value, kName); EXPECT_TRUE( @@ -2280,7 +2277,7 @@ Suggestion suggestion; suggestion.main_text.value = l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_USE_DEVICE_PASSKEY); - suggestion.frontend_id = + suggestion.popup_item_id = autofill::PopupItemId::kWebauthnSignInWithAnotherDevice; suggestion.payload = autofill::Suggestion::BackendId(); password_autofill_manager_->DidAcceptSuggestion(suggestion, /*position=*/1);
diff --git a/components/password_manager/core/browser/password_manager_util_unittest.cc b/components/password_manager/core/browser/password_manager_util_unittest.cc index b66ac8b..32015ba1 100644 --- a/components/password_manager/core/browser/password_manager_util_unittest.cc +++ b/components/password_manager/core/browser/password_manager_util_unittest.cc
@@ -21,6 +21,7 @@ #include "components/autofill/core/browser/data_model/credit_card.h" #include "components/autofill/core/browser/payments/local_card_migration_manager.h" #include "components/autofill/core/browser/ui/payments/card_unmask_prompt_options.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" #include "components/autofill/core/browser/ui/popup_types.h" #include "components/autofill/core/browser/ui/suggestion.h" #include "components/autofill/core/common/password_generation_util.h" @@ -281,10 +282,7 @@ (const std::u16string&, const std::u16string&), (override)); MOCK_METHOD(bool, IsContextSecure, (), (const, override)); - MOCK_METHOD(void, - ExecuteCommand, - (autofill::Suggestion::FrontendId), - (override)); + MOCK_METHOD(void, ExecuteCommand, (autofill::PopupItemId), (override)); MOCK_METHOD(autofill::LogManager*, GetLogManager, (), (const, override)); MOCK_METHOD(const autofill::AutofillAblationStudy&, GetAblationStudy,
diff --git a/components/password_manager/core/browser/webauthn_credentials_delegate.h b/components/password_manager/core/browser/webauthn_credentials_delegate.h index 390ab23..5dfa8c87 100644 --- a/components/password_manager/core/browser/webauthn_credentials_delegate.h +++ b/components/password_manager/core/browser/webauthn_credentials_delegate.h
@@ -9,6 +9,7 @@ #include <vector> #include "base/functional/callback.h" +#include "build/build_config.h" #include "components/password_manager/core/browser/passkey_credential.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -39,6 +40,15 @@ // |callback| is invoked when credentials have been received, which could be // immediately. virtual void RetrievePasskeys(base::OnceCallback<void()> callback) = 0; + +#if BUILDFLAG(IS_ANDROID) + // Called to start the hybrid sign-in flow in Play Services. + virtual void ShowAndroidHybridSignIn() = 0; + + // Returns true if hybrid sign-in is available, and the option should be + // shown on conditional UI autofill surfaces. + virtual bool IsAndroidHybridAvailable() const = 0; +#endif }; } // namespace password_manager
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto index 594f7f1..d0aeba8 100644 --- a/components/policy/proto/device_management_backend.proto +++ b/components/policy/proto/device_management_backend.proto
@@ -3711,16 +3711,32 @@ // Information about an eSIM profile installed on an EUICC (Embedded Universal // Integrated Circuit Card). message ESimProfileInfo { - // ICCID of the eSIM profile. Upto 22 decimal digits encoded - // as ASCII string. + // ICCID of the eSIM profile. Up to 22 decimal digits encoded as ASCII string. // Example: 3554020401587593554020. optional string iccid = 1; - // SMDP (Subscription Management - Data Preparation) server address - // that was used to install this eSIM profile. Upto 255 characters + // SM-DP+ (Subscription Manager - Data Preparation) activation code that was + // used to install this eSIM profile. The "address" terminology is historical + // since the string is not strictly just an address. This field should be + // considered mutually exclusive with |smds_address|. Up to 255 characters + // encoded as UTF8 string. + // Example: LPA:1$esim.example.com$matchingId + optional string smdp_address = 2; + + // SM-DS (Subscription Manager - Discovery Service) activation code that was + // used to install this eSIM profile. The "address" terminology is historical + // since the string is not strictly just an address. This field should be + // considered mutually exclusive with |smdp_address|. Up to 255 characters // encoded as UTF8 string. // Example: LPA:1$esim.example.com$ - optional string smdp_address = 2; + optional string smds_address = 3; + + // The name of the policy-defined network that resulted in the installation of + // this eSIM profile. This metadata is required to guarantee that multiple + // policy-defined networks that are configured with the same activation code + // are handled correctly, and will result in the appropriate number of eSIM + // profiles being installed. + optional string name = 4; } // Request from device to server to update information about EUICCs
diff --git a/components/segmentation_platform/internal/data_collection/training_data_cache.cc b/components/segmentation_platform/internal/data_collection/training_data_cache.cc index ba6564a..3679bef6 100644 --- a/components/segmentation_platform/internal/data_collection/training_data_cache.cc +++ b/components/segmentation_platform/internal/data_collection/training_data_cache.cc
@@ -40,8 +40,10 @@ segment_data.erase(it); std::move(callback).Run(result); } else { + // TODO (ritikagup@) : Add handling for default models, if required. segment_info_database_->GetTrainingData( - segment_id, request_id, /*delete_from_db=*/true, std::move(callback)); + segment_id, proto::ModelSource::SERVER_MODEL_SOURCE, request_id, + /*delete_from_db=*/true, std::move(callback)); } }
diff --git a/components/segmentation_platform/internal/data_collection/training_data_collector_impl.cc b/components/segmentation_platform/internal/data_collection/training_data_collector_impl.cc index 0812304..f7308f3f 100644 --- a/components/segmentation_platform/internal/data_collection/training_data_collector_impl.cc +++ b/components/segmentation_platform/internal/data_collection/training_data_collector_impl.cc
@@ -233,8 +233,9 @@ param->output_metric_hash = hash; param->output_value = static_cast<float>(sample); for (auto segment : segments) { + // TODO (ritikagup@) : Add handling for default models, if required. segment_info_database_->GetSegmentInfo( - segment, + segment, proto::ModelSource::SERVER_MODEL_SOURCE, base::BindOnce( &TrainingDataCollectorImpl::OnUmaUpdatedReportForSegmentInfo, weak_ptr_factory_.GetWeakPtr(), param)); @@ -251,8 +252,9 @@ if (it != immediate_trigger_user_actions_.end()) { auto segments = it->second; for (auto segment : segments) { + // TODO (ritikagup@) : Add handling for default models, if required. segment_info_database_->GetSegmentInfo( - segment, + segment, ModelSource::SERVER_MODEL_SOURCE, base::BindOnce( &TrainingDataCollectorImpl::OnUmaUpdatedReportForSegmentInfo, weak_ptr_factory_.GetWeakPtr(), absl::nullopt)); @@ -430,7 +432,9 @@ TrainingRequestId request_id, const TrainingLabels& param, SuccessCallback callback) { - auto segment_info = segment_info_database_->GetCachedSegmentInfo(segment_id); + // TODO (ritikagup@) : Add handling for default models, if required. + auto segment_info = segment_info_database_->GetCachedSegmentInfo( + segment_id, proto::ModelSource::SERVER_MODEL_SOURCE); if (!segment_info) { return; }
diff --git a/components/segmentation_platform/internal/data_collection/training_data_collector_impl.h b/components/segmentation_platform/internal/data_collection/training_data_collector_impl.h index 26bd002e..d8854bd4 100644 --- a/components/segmentation_platform/internal/data_collection/training_data_collector_impl.h +++ b/components/segmentation_platform/internal/data_collection/training_data_collector_impl.h
@@ -27,6 +27,7 @@ #include "third_party/abseil-cpp/absl/types/optional.h" namespace segmentation_platform { +using proto::ModelSource; using proto::SegmentId; class SegmentationResultPrefs;
diff --git a/components/segmentation_platform/internal/database/segment_info_database.cc b/components/segmentation_platform/internal/database/segment_info_database.cc index 31ab364..9ed31a3d 100644 --- a/components/segmentation_platform/internal/database/segment_info_database.cc +++ b/components/segmentation_platform/internal/database/segment_info_database.cc
@@ -48,16 +48,19 @@ } void SegmentInfoDatabase::GetSegmentInfo(SegmentId segment_id, + ModelSource model_source, SegmentInfoCallback callback) { std::move(callback).Run(cache_->GetSegmentInfo(segment_id)); } absl::optional<SegmentInfo> SegmentInfoDatabase::GetCachedSegmentInfo( - SegmentId segment_id) { + SegmentId segment_id, + ModelSource model_source) { return cache_->GetSegmentInfo(segment_id); } void SegmentInfoDatabase::GetTrainingData(SegmentId segment_id, + ModelSource model_source, TrainingRequestId request_id, bool delete_from_db, TrainingDataCallback callback) {
diff --git a/components/segmentation_platform/internal/database/segment_info_database.h b/components/segmentation_platform/internal/database/segment_info_database.h index 66e7428..987d7c16 100644 --- a/components/segmentation_platform/internal/database/segment_info_database.h +++ b/components/segmentation_platform/internal/database/segment_info_database.h
@@ -20,6 +20,7 @@ namespace segmentation_platform { +using proto::ModelSource; using proto::SegmentId; namespace proto { @@ -53,22 +54,26 @@ virtual void Initialize(SuccessCallback callback); - // Called to get metadata for a given list of segments. + // Called to get metadata for a given list of server model segments. virtual void GetSegmentInfoForSegments( const base::flat_set<SegmentId>& segment_ids, MultipleSegmentInfoCallback callback); - // Called to get the metadata for a given segment. + // Called to get the metadata for a given segment. ModelSource defines whether + // to give metadata from server/default models for the given segment. virtual void GetSegmentInfo(SegmentId segment_id, + ModelSource model_source, SegmentInfoCallback callback); virtual absl::optional<SegmentInfo> GetCachedSegmentInfo( - SegmentId segment_id); + SegmentId segment_id, + ModelSource model_source); - // Called to get the training data for a given segment and request ID. If - // delete_from_db is set to true, it will delete the corresponding entry in - // the cache and in the database. + // Called to get the training data for a given segment with given model source + // and request ID. If delete_from_db is set to true, it will delete the + // corresponding entry in the cache and in the database. virtual void GetTrainingData(SegmentId segment_id, + ModelSource model_source, TrainingRequestId request_id, bool delete_from_db, TrainingDataCallback callback);
diff --git a/components/segmentation_platform/internal/database/segment_info_database_unittest.cc b/components/segmentation_platform/internal/database/segment_info_database_unittest.cc index 909cb3e..b1c6cd4 100644 --- a/components/segmentation_platform/internal/database/segment_info_database_unittest.cc +++ b/components/segmentation_platform/internal/database/segment_info_database_unittest.cc
@@ -24,14 +24,18 @@ SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_NEW_TAB; const SegmentId kSegmentId2 = SegmentId::OPTIMIZATION_TARGET_SEGMENTATION_SHARE; -std::string ToString(SegmentId segment_id) { +const ModelSource kServerModelSource = ModelSource::SERVER_MODEL_SOURCE; + +std::string ToString(SegmentId segment_id, ModelSource model_source) { return base::NumberToString(static_cast<int>(segment_id)); } proto::SegmentInfo CreateSegment(SegmentId segment_id, + ModelSource model_source, absl::optional<int> result = absl::nullopt) { proto::SegmentInfo info; info.set_segment_id(segment_id); + info.set_model_source(model_source); if (result.has_value()) { info.mutable_prediction_result()->add_result(result.value()); @@ -77,13 +81,20 @@ segment_db_.reset(); } - void VerifyDb(base::flat_set<SegmentId> expected_ids) { - EXPECT_EQ(expected_ids.size(), db_entries_.size()); - for (auto segment_id : expected_ids) - EXPECT_TRUE(db_entries_.find(ToString(segment_id)) != db_entries_.end()); + void VerifyDb(base::flat_set<std::pair<SegmentId, ModelSource>> + expected_ids_with_model_source) { + EXPECT_EQ(expected_ids_with_model_source.size(), db_entries_.size()); + for (auto segment_id_and_model_source : expected_ids_with_model_source) { + EXPECT_TRUE( + db_entries_.find(ToString(segment_id_and_model_source.first, + segment_id_and_model_source.second)) != + db_entries_.end()); + } } - void WriteResult(SegmentId segment_id, absl::optional<float> result) { + void WriteResult(SegmentId segment_id, + ModelSource model_source, + absl::optional<float> result) { proto::PredictionResult prediction_result; if (result.has_value()) prediction_result.add_result(result.value()); @@ -99,7 +110,10 @@ db_->UpdateCallback(true); } - void WriteTrainingData(SegmentId segment_id, int64_t request_id, float data) { + void WriteTrainingData(SegmentId segment_id, + ModelSource model_source, + int64_t request_id, + float data) { proto::TrainingData training_data; training_data.add_inputs(data); training_data.set_request_id(request_id); @@ -112,12 +126,14 @@ } void VerifyResult(SegmentId segment_id, + ModelSource model_source, absl::optional<float> result, absl::optional<std::vector<ModelProvider::Request>> training_inputs = absl::nullopt) { segment_db_->GetSegmentInfo( - segment_id, base::BindOnce(&SegmentInfoDatabaseTest::OnGetSegment, - base::Unretained(this))); + segment_id, model_source, + base::BindOnce(&SegmentInfoDatabaseTest::OnGetSegment, + base::Unretained(this))); if (!segment_info_cache_->GetSegmentInfo(segment_id).has_value()) { db_->GetCallback(true); } @@ -177,21 +193,23 @@ TEST_F(SegmentInfoDatabaseTest, Get) { // Initialize DB with one entry. db_entries_.insert( - std::make_pair(ToString(kSegmentId), CreateSegment(kSegmentId))); + std::make_pair(ToString(kSegmentId, kServerModelSource), + CreateSegment(kSegmentId, kServerModelSource))); SetUpDB(); segment_db_->Initialize(base::DoNothing()); db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK); db_->LoadCallback(true); - VerifyDb({kSegmentId}); + VerifyDb({std::make_pair(kSegmentId, kServerModelSource)}); // Get all segments. ExecuteAndVerifyGetSegmentInfoForSegments({kSegmentId}); // Get a single segment. segment_db_->GetSegmentInfo( - kSegmentId, base::BindOnce(&SegmentInfoDatabaseTest::OnGetSegment, - base::Unretained(this))); + kSegmentId, kServerModelSource, + base::BindOnce(&SegmentInfoDatabaseTest::OnGetSegment, + base::Unretained(this))); if (!segment_info_cache_->GetSegmentInfo(kSegmentId).has_value()) { db_->GetCallback(true); } @@ -202,7 +220,8 @@ TEST_F(SegmentInfoDatabaseTest, Update) { // Initialize DB with one entry. db_entries_.insert( - std::make_pair(ToString(kSegmentId), CreateSegment(kSegmentId))); + std::make_pair(ToString(kSegmentId, kServerModelSource), + CreateSegment(kSegmentId, kServerModelSource))); SetUpDB(); segment_db_->Initialize(base::DoNothing()); @@ -215,16 +234,19 @@ VerifyDb({}); // Insert a segment and verify. - segment_db_->UpdateSegment(kSegmentId, CreateSegment(kSegmentId), + segment_db_->UpdateSegment(kSegmentId, + CreateSegment(kSegmentId, kServerModelSource), base::DoNothing()); db_->UpdateCallback(true); - VerifyDb({kSegmentId}); + VerifyDb({std::make_pair(kSegmentId, kServerModelSource)}); // Insert another segment and verify. - segment_db_->UpdateSegment(kSegmentId2, CreateSegment(kSegmentId2), + segment_db_->UpdateSegment(kSegmentId2, + CreateSegment(kSegmentId2, kServerModelSource), base::DoNothing()); db_->UpdateCallback(true); - VerifyDb({kSegmentId, kSegmentId2}); + VerifyDb({std::make_pair(kSegmentId, kServerModelSource), + std::make_pair(kSegmentId2, kServerModelSource)}); // Verify GetSegmentInfoForSegments. ExecuteAndVerifyGetSegmentInfoForSegments({kSegmentId2}); @@ -237,9 +259,11 @@ TEST_F(SegmentInfoDatabaseTest, UpdateMultipleSegments) { // Initialize DB with two entry. db_entries_.insert( - std::make_pair(ToString(kSegmentId), CreateSegment(kSegmentId))); + std::make_pair(ToString(kSegmentId, kServerModelSource), + CreateSegment(kSegmentId, kServerModelSource))); db_entries_.insert( - std::make_pair(ToString(kSegmentId2), CreateSegment(kSegmentId2))); + std::make_pair(ToString(kSegmentId2, kServerModelSource), + CreateSegment(kSegmentId2, kServerModelSource))); SetUpDB(); segment_db_->Initialize(base::DoNothing()); @@ -255,16 +279,18 @@ // Insert multiple segments and verify. std::vector<std::pair<SegmentId, proto::SegmentInfo>> segments_to_update; segments_to_update.emplace_back( - std::make_pair(kSegmentId, CreateSegment(kSegmentId))); + kSegmentId, CreateSegment(kSegmentId, kServerModelSource)); segments_to_update.emplace_back( - std::make_pair(kSegmentId2, CreateSegment(kSegmentId2))); + kSegmentId2, CreateSegment(kSegmentId2, kServerModelSource)); segment_db_->UpdateMultipleSegments(segments_to_update, {}, base::DoNothing()); db_->UpdateCallback(true); - VerifyDb({kSegmentId, kSegmentId2}); + VerifyDb({std::make_pair(kSegmentId, kServerModelSource), + std::make_pair(kSegmentId2, kServerModelSource)}); // Update one of the existing segment and verify. - proto::SegmentInfo segment_info = CreateSegment(kSegmentId2); + proto::SegmentInfo segment_info = + CreateSegment(kSegmentId2, kServerModelSource); segment_info.mutable_prediction_result()->add_result(0.9f); // Add this entry to `segments_to_update`. segments_to_update.clear(); @@ -273,8 +299,9 @@ segment_db_->UpdateMultipleSegments(segments_to_update, {}, base::DoNothing()); db_->UpdateCallback(true); - VerifyDb({kSegmentId, kSegmentId2}); - VerifyResult(kSegmentId2, 0.9f); + VerifyDb({std::make_pair(kSegmentId, kServerModelSource), + std::make_pair(kSegmentId2, kServerModelSource)}); + VerifyResult(kSegmentId2, kServerModelSource, 0.9f); // Verify GetSegmentInfoForSegments. ExecuteAndVerifyGetSegmentInfoForSegments({kSegmentId2}); @@ -287,8 +314,9 @@ TEST_F(SegmentInfoDatabaseTest, WriteResult) { // Initialize DB with cache enabled and one entry. db_entries_.insert( - std::make_pair(ToString(kSegmentId), CreateSegment(kSegmentId))); - VerifyDb({kSegmentId}); + std::make_pair(ToString(kSegmentId, kServerModelSource), + CreateSegment(kSegmentId, kServerModelSource))); + VerifyDb({{kSegmentId, kServerModelSource}}); SetUpDB(); segment_db_->Initialize(base::DoNothing()); @@ -300,24 +328,25 @@ EXPECT_TRUE(segment_info_cache_->GetSegmentInfo(kSegmentId).has_value()); // Update results and verify that db is updated. - WriteResult(kSegmentId, 0.4f); + WriteResult(kSegmentId, kServerModelSource, 0.4f); // Verify that cache is updated. - VerifyResult(kSegmentId, 0.4f); + VerifyResult(kSegmentId, kServerModelSource, 0.4f); // Overwrite results and verify. - WriteResult(kSegmentId, 0.9f); - VerifyResult(kSegmentId, 0.9f); + WriteResult(kSegmentId, kServerModelSource, 0.9f); + VerifyResult(kSegmentId, kServerModelSource, 0.9f); // Clear results and verify. - WriteResult(kSegmentId, absl::nullopt); - VerifyResult(kSegmentId, absl::nullopt); + WriteResult(kSegmentId, kServerModelSource, absl::nullopt); + VerifyResult(kSegmentId, kServerModelSource, absl::nullopt); } TEST_F(SegmentInfoDatabaseTest, WriteTrainingData) { // Initialize DB with one entry. db_entries_.insert( - std::make_pair(ToString(kSegmentId), CreateSegment(kSegmentId))); + std::make_pair(ToString(kSegmentId, kServerModelSource), + CreateSegment(kSegmentId, kServerModelSource))); SetUpDB(); segment_db_->Initialize(base::DoNothing()); @@ -328,30 +357,36 @@ std::vector<ModelProvider::Request> expected_training_inputs; // Add training data and verify. - WriteTrainingData(kSegmentId, /*request_id=*/0, /*data=*/0.4f); + WriteTrainingData(kSegmentId, kServerModelSource, /*request_id=*/0, + /*data=*/0.4f); expected_training_inputs.push_back({0.4f}); - VerifyResult(kSegmentId, absl::nullopt, expected_training_inputs); + VerifyResult(kSegmentId, kServerModelSource, absl::nullopt, + expected_training_inputs); // Add another training data and verify. int64_t request_id = 1; - WriteTrainingData(kSegmentId, request_id, /*data=*/0.9f); + WriteTrainingData(kSegmentId, kServerModelSource, request_id, /*data=*/0.9f); expected_training_inputs.push_back({0.9f}); - VerifyResult(kSegmentId, absl::nullopt, expected_training_inputs); + VerifyResult(kSegmentId, kServerModelSource, absl::nullopt, + expected_training_inputs); // Remove the last training data and verify. - segment_db_->GetTrainingData(kSegmentId, + segment_db_->GetTrainingData(kSegmentId, kServerModelSource, TrainingRequestId::FromUnsafeValue(request_id), /*delete_from_db=*/true, base::DoNothing()); expected_training_inputs.pop_back(); - VerifyResult(kSegmentId, absl::nullopt, expected_training_inputs); + VerifyResult(kSegmentId, kServerModelSource, absl::nullopt, + expected_training_inputs); } TEST_F(SegmentInfoDatabaseTest, WriteResultForTwoSegments) { // Initialize DB with two entries. db_entries_.insert( - std::make_pair(ToString(kSegmentId), CreateSegment(kSegmentId))); + std::make_pair(ToString(kSegmentId, kServerModelSource), + CreateSegment(kSegmentId, kServerModelSource))); db_entries_.insert( - std::make_pair(ToString(kSegmentId2), CreateSegment(kSegmentId2))); + std::make_pair(ToString(kSegmentId2, kServerModelSource), + CreateSegment(kSegmentId2, kServerModelSource))); SetUpDB(); segment_db_->Initialize(base::DoNothing()); @@ -359,14 +394,14 @@ db_->LoadCallback(true); // Update results for first segment. - WriteResult(kSegmentId, 0.4f); + WriteResult(kSegmentId, kServerModelSource, 0.4f); // Update results for second segment. - WriteResult(kSegmentId2, 0.9f); + WriteResult(kSegmentId2, kServerModelSource, 0.9f); // Verify results for both segments. - VerifyResult(kSegmentId, 0.4f); - VerifyResult(kSegmentId2, 0.9f); + VerifyResult(kSegmentId, kServerModelSource, 0.4f); + VerifyResult(kSegmentId2, kServerModelSource, 0.9f); } } // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/database/test_segment_info_database.cc b/components/segmentation_platform/internal/database/test_segment_info_database.cc index 3203c89..51ecde2a 100644 --- a/components/segmentation_platform/internal/database/test_segment_info_database.cc +++ b/components/segmentation_platform/internal/database/test_segment_info_database.cc
@@ -37,12 +37,14 @@ } void TestSegmentInfoDatabase::GetSegmentInfo(SegmentId segment_id, + ModelSource model_source, SegmentInfoCallback callback) { - std::move(callback).Run(GetCachedSegmentInfo(segment_id)); + std::move(callback).Run(GetCachedSegmentInfo(segment_id, model_source)); } absl::optional<SegmentInfo> TestSegmentInfoDatabase::GetCachedSegmentInfo( - SegmentId segment_id) { + SegmentId segment_id, + ModelSource model_source) { auto result = base::ranges::find(segment_infos_, segment_id, &std::pair<SegmentId, proto::SegmentInfo>::first); @@ -92,6 +94,7 @@ } void TestSegmentInfoDatabase::GetTrainingData(SegmentId segment_id, + ModelSource model_source, TrainingRequestId request_id, bool delete_from_db, TrainingDataCallback callback) {
diff --git a/components/segmentation_platform/internal/database/test_segment_info_database.h b/components/segmentation_platform/internal/database/test_segment_info_database.h index 01d57fc..1812927f 100644 --- a/components/segmentation_platform/internal/database/test_segment_info_database.h +++ b/components/segmentation_platform/internal/database/test_segment_info_database.h
@@ -29,9 +29,11 @@ void GetSegmentInfoForSegments(const base::flat_set<SegmentId>& segment_ids, MultipleSegmentInfoCallback callback) override; void GetSegmentInfo(SegmentId segment_id, + ModelSource model_source, SegmentInfoCallback callback) override; absl::optional<SegmentInfo> GetCachedSegmentInfo( - SegmentId segment_id) override; + SegmentId segment_id, + ModelSource model_source) override; void UpdateSegment(SegmentId segment_id, absl::optional<proto::SegmentInfo> segment_info, SuccessCallback callback) override; @@ -42,6 +44,7 @@ const proto::TrainingData& data, SuccessCallback callback) override; void GetTrainingData(SegmentId segment_id, + ModelSource model_source, TrainingRequestId request_id, bool delete_from_db, TrainingDataCallback callback) override;
diff --git a/components/segmentation_platform/internal/execution/model_execution_manager_impl.cc b/components/segmentation_platform/internal/execution/model_execution_manager_impl.cc index 608fc2b5..b9ba9c9 100644 --- a/components/segmentation_platform/internal/execution/model_execution_manager_impl.cc +++ b/components/segmentation_platform/internal/execution/model_execution_manager_impl.cc
@@ -79,9 +79,9 @@ segment_id, /* processed = */ false, validation); if (validation != metadata_utils::ValidationResult::kValidationSuccess) return; - + // TODO (ritikagup@) : Add handling for default models, if required. segment_database_->GetSegmentInfo( - segment_id, + segment_id, proto::ModelSource::SERVER_MODEL_SOURCE, base::BindOnce( &ModelExecutionManagerImpl::OnSegmentInfoFetchedForModelUpdate, weak_ptr_factory_.GetWeakPtr(), segment_id, std::move(metadata),
diff --git a/components/segmentation_platform/internal/execution/model_execution_manager_impl_unittest.cc b/components/segmentation_platform/internal/execution/model_execution_manager_impl_unittest.cc index e0c4f9e..63ef24f 100644 --- a/components/segmentation_platform/internal/execution/model_execution_manager_impl_unittest.cc +++ b/components/segmentation_platform/internal/execution/model_execution_manager_impl_unittest.cc
@@ -58,7 +58,9 @@ (override)); MOCK_METHOD(void, GetSegmentInfo, - (SegmentId segment_id, SegmentInfoCallback callback), + (SegmentId segment_id, + proto::ModelSource model_source, + SegmentInfoCallback callback), (override)); MOCK_METHOD(void, UpdateSegment, @@ -142,7 +144,7 @@ // Verify that the ModelExecutionManager never invokes its // SegmentInfoDatabase, nor invokes the callback. - EXPECT_CALL(*mock_segment_database_ptr, GetSegmentInfo(_, _)).Times(0); + EXPECT_CALL(*mock_segment_database_ptr, GetSegmentInfo(_, _, _)).Times(0); EXPECT_CALL(callback, Run(_)).Times(0); model_provider_data_.model_providers_callbacks[segment_id].Run( segment_id, metadata, kModelVersion); @@ -174,7 +176,8 @@ EXPECT_CALL(db_callback, Run(_)).WillOnce(SaveArg<0>(&segment_info_from_db)); // Fetch SegmentInfo from the database. - segment_database_->GetSegmentInfo(segment_id, db_callback.Get()); + segment_database_->GetSegmentInfo( + segment_id, proto::ModelSource::SERVER_MODEL_SOURCE, db_callback.Get()); EXPECT_TRUE(segment_info_from_db.has_value()); EXPECT_EQ(segment_id, segment_info_from_db->segment_id()); @@ -203,7 +206,8 @@ absl::optional<proto::SegmentInfo> segment_info_from_db_1; EXPECT_CALL(db_callback_1, Run(_)) .WillOnce(SaveArg<0>(&segment_info_from_db_1)); - segment_database_->GetSegmentInfo(segment_id, db_callback_1.Get()); + segment_database_->GetSegmentInfo( + segment_id, proto::ModelSource::SERVER_MODEL_SOURCE, db_callback_1.Get()); EXPECT_TRUE(segment_info_from_db_1.has_value()); EXPECT_EQ(segment_id, segment_info_from_db_1->segment_id()); @@ -271,7 +275,8 @@ absl::optional<proto::SegmentInfo> segment_info_from_db_2; EXPECT_CALL(db_callback_2, Run(_)) .WillOnce(SaveArg<0>(&segment_info_from_db_2)); - segment_database_->GetSegmentInfo(segment_id, db_callback_2.Get()); + segment_database_->GetSegmentInfo( + segment_id, proto::ModelSource::SERVER_MODEL_SOURCE, db_callback_2.Get()); EXPECT_TRUE(segment_info_from_db_2.has_value()); EXPECT_EQ(segment_id, segment_info_from_db_2->segment_id()); EXPECT_EQ(clock_.Now().ToDeltaSinceWindowsEpoch().InSeconds(),
diff --git a/components/stylus_handwriting/android/java/src/org/chromium/components/stylus_handwriting/AndroidStylusWritingHandler.java b/components/stylus_handwriting/android/java/src/org/chromium/components/stylus_handwriting/AndroidStylusWritingHandler.java index f989fbcf..a47bd20 100644 --- a/components/stylus_handwriting/android/java/src/org/chromium/components/stylus_handwriting/AndroidStylusWritingHandler.java +++ b/components/stylus_handwriting/android/java/src/org/chromium/components/stylus_handwriting/AndroidStylusWritingHandler.java
@@ -41,11 +41,18 @@ private final InputMethodManager mInputMethodManager; private View mTargetView; + @OptIn(markerClass = androidx.core.os.BuildCompat.PrereleaseSdkCheck.class) public static boolean isEnabled(Context context) { if (!BuildInfo.isAtLeastT()) return false; - int value = Settings.Global.getInt( - context.getContentResolver(), "stylus_handwriting_enabled", -1); + int value = -1; + if (BuildCompat.isAtLeastU()) { + value = Settings.Secure.getInt( + context.getContentResolver(), "stylus_handwriting_enabled", -1); + } else { + value = Settings.Global.getInt( + context.getContentResolver(), "stylus_handwriting_enabled", -1); + } if (value != 1) { Log.d(TAG, "Stylus feature disabled.", value);
diff --git a/components/user_education/DEPS b/components/user_education/DEPS index a74f63f36..a94f8e6 100644 --- a/components/user_education/DEPS +++ b/components/user_education/DEPS
@@ -6,5 +6,6 @@ "+ui/accessibility", "+ui/base", "+ui/color", + "+ui/events", "+ui/gfx", ]
diff --git a/components/user_education/views/help_bubble_view.cc b/components/user_education/views/help_bubble_view.cc index a523680c..fd0d62c 100644 --- a/components/user_education/views/help_bubble_view.cc +++ b/components/user_education/views/help_bubble_view.cc
@@ -13,6 +13,7 @@ #include "base/functional/bind.h" #include "base/memory/raw_ptr.h" #include "base/metrics/user_metrics.h" +#include "base/notreached.h" #include "base/strings/string_number_conversions.h" #include "base/time/time.h" #include "components/strings/grit/components_strings.h" @@ -27,9 +28,13 @@ #include "ui/base/models/image_model.h" #include "ui/base/ui_base_features.h" #include "ui/color/color_provider.h" +#include "ui/events/event.h" +#include "ui/events/event_constants.h" +#include "ui/events/types/event_type.h" #include "ui/gfx/canvas.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/geometry/insets.h" +#include "ui/gfx/geometry/point_f.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/paint_vector_icon.h" @@ -52,8 +57,8 @@ #include "ui/views/controls/highlight_path_generator.h" #include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" -#include "ui/views/controls/menu/menu_scroll_view_container.h" -#include "ui/views/event_monitor.h" +#include "ui/views/controls/menu/menu_config.h" +#include "ui/views/controls/menu/menu_item_view.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/layout/flex_layout.h" #include "ui/views/layout/flex_layout_types.h" @@ -65,6 +70,7 @@ #include "ui/views/view_class_properties.h" #include "ui/views/view_tracker.h" #include "ui/views/view_utils.h" +#include "ui/views/widget/widget.h" namespace user_education { @@ -295,8 +301,164 @@ BEGIN_METADATA(DotView, views::View) END_METADATA +views::MenuItemView* GetAnchorAsMenuItem( + const views::BubbleDialogDelegate* delegate) { + return views::AsViewClass<views::MenuItemView>(delegate->GetAnchorView()); +} + } // namespace +namespace internal { + +// Because menus use event capture, a help bubble anchored to a menu cannot +// respond to events in the normal way. However, help bubbles are not +// complicated and only have buttons. When a help bubble is anchored to a menu, +// this object will monitor events that would be captured by the menu, and +// ensures that the buttons on the help bubble still behavior predictably. +class MenuEventMonitor { + public: + MenuEventMonitor(HelpBubbleView* help_bubble, views::MenuItemView* menu_item) + : help_bubble_(help_bubble), + callback_handle_(menu_item->GetMenuController()->SetAnnotationCallback( + base::BindRepeating(&MenuEventMonitor::OnEvent, + base::Unretained(this)))) {} + + ~MenuEventMonitor() = default; + + private: + bool OnEvent(const ui::LocatedEvent& event) { + gfx::Point screen_coords; + screen_coords = event.root_location(); + + const views::Widget* const widget = help_bubble_->GetWidget(); + if (!widget || !widget->GetWindowBoundsInScreen().Contains(screen_coords)) { + return false; + } + + views::Button* const target_button = GetButtonAt(screen_coords); + const gfx::Point target_point = + target_button + ? views::View::ConvertPointFromScreen(target_button, screen_coords) + : gfx::Point(); + + switch (event.type()) { + // Pass mouse events on to the button as normal. + case ui::ET_MOUSE_PRESSED: + if (target_button) { + auto* const mouse_event = event.AsMouseEvent(); + target_button->OnMousePressed(ui::MouseEvent( + ui::ET_MOUSE_PRESSED, gfx::PointF(target_point), + gfx::PointF(screen_coords), mouse_event->time_stamp(), + mouse_event->flags(), mouse_event->changed_button_flags())); + } + break; + case ui::ET_MOUSE_RELEASED: + if (target_button) { + auto* const mouse_event = event.AsMouseEvent(); + target_button->OnMouseReleased(ui::MouseEvent( + ui::ET_MOUSE_RELEASED, gfx::PointF(target_point), + gfx::PointF(screen_coords), mouse_event->time_stamp(), + mouse_event->flags(), mouse_event->changed_button_flags())); + } + break; + + // Touch events are not processed directly by Views; they are typically + // converted to something else. So, convert them to mouse clicks for the + // purpose of pressing buttons. + case ui::ET_TOUCH_PRESSED: + if (target_button) { + auto* const touch_event = event.AsTouchEvent(); + target_button->OnMousePressed(ui::MouseEvent( + ui::ET_MOUSE_PRESSED, gfx::PointF(target_point), + gfx::PointF(screen_coords), touch_event->time_stamp(), + touch_event->flags() | ui::EF_LEFT_MOUSE_BUTTON | + ui::EF_FROM_TOUCH, + ui::EF_LEFT_MOUSE_BUTTON)); + } + break; + case ui::ET_TOUCH_RELEASED: + if (target_button) { + auto* const touch_event = event.AsTouchEvent(); + target_button->OnMouseReleased(ui::MouseEvent( + ui::ET_MOUSE_RELEASED, gfx::PointF(target_point), + gfx::PointF(screen_coords), touch_event->time_stamp(), + touch_event->flags() | ui::EF_LEFT_MOUSE_BUTTON | + ui::EF_FROM_TOUCH, + ui::EF_LEFT_MOUSE_BUTTON)); + } + break; + + // If a gesture is received, forward it as-is. + case ui::ET_GESTURE_TAP: + if (target_button) { + auto* const gesture = event.AsGestureEvent(); + ui::GestureEvent tap(gesture->x(), gesture->y(), gesture->flags(), + gesture->time_stamp(), gesture->details(), + gesture->unique_touch_event_id()); + target_button->button_controller()->OnGestureEvent(&tap); + } + break; + + // Mouse moves could be routed through the inkdrop controller but it's + // easier to just set hovered state directly. + case ui::ET_MOUSE_MOVED: + if (target_button != hovered_button_) { + if (hovered_button_) { + views::InkDrop* const ink_drop = + views::InkDrop::Get(hovered_button_)->GetInkDrop(); + if (ink_drop) { + ink_drop->SetHovered(false); + } + } + if (target_button) { + views::InkDrop* const ink_drop = + views::InkDrop::Get(target_button)->GetInkDrop(); + if (ink_drop) { + ink_drop->SetHovered(true); + } + } + hovered_button_ = target_button; + } + break; + default: + return false; + } + + return true; + } + + // Gets which (if any) of the help bubble buttons are at the given + // `screen_coords`. + views::Button* GetButtonAt(const gfx::Point& screen_coords) const { + if (IsInButton(screen_coords, help_bubble_->close_button_)) { + return help_bubble_->close_button_; + } + if (IsInButton(screen_coords, help_bubble_->default_button_)) { + return help_bubble_->default_button_; + } + for (auto* const button : help_bubble_->non_default_buttons_) { + if (IsInButton(screen_coords, button)) { + return button; + } + } + return nullptr; + } + + // Returns whether `screen_coords` are in `button`, which may be null. + static bool IsInButton(const gfx::Point& screen_coords, + const views::Button* button) { + return button && button->HitTestPoint(views::View::ConvertPointFromScreen( + button, screen_coords)); + } + + const raw_ptr<HelpBubbleView> help_bubble_; + raw_ptr<views::Button> hovered_button_ = nullptr; + // std::unique_ptr<views::EventMonitor> event_monitor_; + views::MenuController::AnnotationCallbackHandle callback_handle_; +}; + +} // namespace internal + DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(HelpBubbleView, kHelpBubbleElementIdForTesting); DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(HelpBubbleView, @@ -651,10 +813,13 @@ SizeToContents(); widget->ShowInactive(); - auto* const anchor_bubble = - anchor.view->GetWidget()->widget_delegate()->AsBubbleDialogDelegate(); - if (anchor_bubble) + if (auto* const anchor_bubble = + anchor_widget()->widget_delegate()->AsBubbleDialogDelegate()) { anchor_pin_ = anchor_bubble->PreventCloseOnDeactivate(); + } else if (auto* const menu_item = GetAnchorAsMenuItem(this)) { + menu_event_monitor_ = + std::make_unique<internal::MenuEventMonitor>(this, menu_item); + } MaybeStartAutoCloseTimer(); } @@ -775,12 +940,7 @@ // issues in Weston, the windowing environment used on chrome's Wayland // testbots: // https://gitlab.freedesktop.org/wayland/weston/-/issues/669 - const views::View* const contents = - const_cast<HelpBubbleView*>(this)->anchor_widget()->GetContentsView(); - if (contents && - views::IsViewClass<views::MenuScrollViewContainer>(contents)) { - params->requires_accelerated_widget = true; - } + params->requires_accelerated_widget = (GetAnchorAsMenuItem(this) != nullptr); #endif }
diff --git a/components/user_education/views/help_bubble_view.h b/components/user_education/views/help_bubble_view.h index 9bc3cae..d2db8ce 100644 --- a/components/user_education/views/help_bubble_view.h +++ b/components/user_education/views/help_bubble_view.h
@@ -34,6 +34,8 @@ namespace internal { +class MenuEventMonitor; + // Describes how a help bubble should be anchored to a Views element, beyond // what is specified by the HelpBubbleParams. Should only be instantiated by // classes derived from HelpBubbleFactory (or in tests). @@ -93,6 +95,7 @@ FRIEND_TEST_ALL_PREFIXES(HelpBubbleViewTimeoutTest, RespectsProvidedTimeoutAfterActivate); friend class HelpBubbleViewsTest; + friend class internal::MenuEventMonitor; void MaybeStartAutoCloseTimer(); @@ -125,6 +128,10 @@ // focus, even if it's marked as close_on_deactivate. std::unique_ptr<CloseOnDeactivatePin> anchor_pin_; + // Sniffs events intended for a menu to ensure that for bubbles anchored to + // menus, hover, click, and tap events are still registered. + std::unique_ptr<internal::MenuEventMonitor> menu_event_monitor_; + // Auto close timeout. If the value is 0 (default), the bubble never times // out. base::TimeDelta timeout_;
diff --git a/components/viz/common/features.cc b/components/viz/common/features.cc index 48ff8af..ddce6f3 100644 --- a/components/viz/common/features.cc +++ b/components/viz/common/features.cc
@@ -177,8 +177,6 @@ "AllowBypassRenderPassQuads", base::FEATURE_DISABLED_BY_DEFAULT); -// TODO(crbug.com/1357744): Solve the vulkan flakiness issue before enabling -// this on Linux. BASE_FEATURE(kAllowUndamagedNonrootRenderPassToSkip, "AllowUndamagedNonrootRenderPassToSkip", base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/components/web_resource/resource_request_allowed_notifier.h b/components/web_resource/resource_request_allowed_notifier.h index 76531f0..5d3764d 100644 --- a/components/web_resource/resource_request_allowed_notifier.h +++ b/components/web_resource/resource_request_allowed_notifier.h
@@ -139,8 +139,8 @@ raw_ptr<Observer> observer_; NetworkConnectionTrackerGetter network_connection_tracker_getter_; - raw_ptr<network::NetworkConnectionTracker> network_connection_tracker_ = - nullptr; + raw_ptr<network::NetworkConnectionTracker, LeakedDanglingUntriaged> + network_connection_tracker_ = nullptr; network::mojom::ConnectionType connection_type_ = network::mojom::ConnectionType::CONNECTION_UNKNOWN; bool connection_initialized_ = false;
diff --git a/components/webapps/browser/android/add_to_homescreen_data_fetcher.cc b/components/webapps/browser/android/add_to_homescreen_data_fetcher.cc index 1982c10..f721dbe 100644 --- a/components/webapps/browser/android/add_to_homescreen_data_fetcher.cc +++ b/components/webapps/browser/android/add_to_homescreen_data_fetcher.cc
@@ -65,8 +65,8 @@ InstallableParams params; params.check_eligibility = true; params.valid_manifest = true; - params.has_worker = !features::SkipInstallServiceWorkerCheck(); - params.wait_for_worker = !features::SkipInstallServiceWorkerCheck(); + params.has_worker = false; + params.wait_for_worker = false; return params; }
diff --git a/components/webapps/browser/android/add_to_homescreen_data_fetcher_unittest.cc b/components/webapps/browser/android/add_to_homescreen_data_fetcher_unittest.cc index 5963f34..be49578 100644 --- a/components/webapps/browser/android/add_to_homescreen_data_fetcher_unittest.cc +++ b/components/webapps/browser/android/add_to_homescreen_data_fetcher_unittest.cc
@@ -429,85 +429,6 @@ EXPECT_TRUE(fetcher->shortcut_info().best_primary_icon_url.is_empty()); } -// Check that the AddToHomescreenDataFetcher::Observer methods are called if -// the service worker check times out on a page that is installable (i.e. it's -// taken too long). This should use the short_name and icon from the manifest, -// but not be WebAPK-compatible. Only relevant when checking WebAPK -// compatibility. -TEST_F(AddToHomescreenDataFetcherTest, ServiceWorkerCheckTimesOutPwa) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndDisableFeature( - features::kSkipServiceWorkerCheckInstallOnly); - - SetManifest(BuildDefaultManifest()); - SetShouldServiceWorkerTimeOut(true); - - // Check where InstallableManager finishes working after the timeout and - // determines PWA-ness. - base::HistogramTester histograms; - ObserverWaiter waiter; - std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter); - RunFetcher(fetcher.get(), waiter, kDefaultManifestShortName, - blink::mojom::DisplayMode::kStandalone, false, - InstallableStatusCode::DATA_TIMED_OUT); - CheckHistograms(histograms); - - EXPECT_FALSE(fetcher->primary_icon().drawsNothing()); - EXPECT_EQ(fetcher->shortcut_info().best_primary_icon_url, - GURL(kDefaultIconUrl)); -} - -TEST_F(AddToHomescreenDataFetcherTest, ServiceWorkerCheckTimesOutNonPwa) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndDisableFeature( - features::kSkipServiceWorkerCheckInstallOnly); - - SetManifest(BuildDefaultManifest()); - SetShouldServiceWorkerTimeOut(true); - SetHasServiceWorker(false); - - // Check where InstallableManager finishes working after the timeout and - // determines non-PWA-ness. - base::HistogramTester histograms; - ObserverWaiter waiter; - std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter); - RunFetcher(fetcher.get(), waiter, kDefaultManifestShortName, - blink::mojom::DisplayMode::kStandalone, false, - InstallableStatusCode::DATA_TIMED_OUT); - CheckHistograms(histograms); - - EXPECT_FALSE(fetcher->primary_icon().drawsNothing()); - EXPECT_EQ(fetcher->shortcut_info().best_primary_icon_url, - GURL(kDefaultIconUrl)); -} - -TEST_F(AddToHomescreenDataFetcherTest, ServiceWorkerCheckTimesOutUnknown) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndDisableFeature( - features::kSkipServiceWorkerCheckInstallOnly); - - SetManifest(BuildDefaultManifest()); - SetShouldServiceWorkerTimeOut(true); - SetHasServiceWorker(false); - - // Check where InstallableManager doesn't finish working after the timeout. - // This is akin to waiting for a service worker forever. - base::HistogramTester histograms; - ObserverWaiter waiter; - std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter); - RunFetcher(fetcher.get(), waiter, kDefaultManifestShortName, - blink::mojom::DisplayMode::kStandalone, false, - InstallableStatusCode::DATA_TIMED_OUT); - - // Navigate to ensure the histograms are written. - NavigateAndCommit(GURL("about:blank")); - CheckHistograms(histograms); - - EXPECT_FALSE(fetcher->primary_icon().drawsNothing()); - EXPECT_EQ(fetcher->shortcut_info().best_primary_icon_url, - GURL(kDefaultIconUrl)); -} - TEST_F(AddToHomescreenDataFetcherTest, InstallableManifest) { // Test a site that has an offline-capable service worker. SetManifest(BuildDefaultManifest()); @@ -529,85 +450,6 @@ CheckHistograms(histograms); } -TEST_F(AddToHomescreenDataFetcherTest, ManifestNameClobbersWebApplicationName) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndDisableFeature( - features::kSkipServiceWorkerCheckInstallOnly); - - // Test that when the manifest provides Manifest::name but not - // Manifest::short_name that Manifest::name is used as the title. - { - // Check the case where we have no icons. - blink::mojom::ManifestPtr manifest = BuildDefaultManifest(); - manifest->icons.clear(); - manifest->short_name = absl::nullopt; - SetManifest(std::move(manifest)); - - ObserverWaiter waiter; - std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter); - RunFetcher(fetcher.get(), waiter, kDefaultManifestName, - blink::mojom::DisplayMode::kStandalone, false, - InstallableStatusCode::NO_ACCEPTABLE_ICON); - - EXPECT_TRUE(fetcher->shortcut_info().best_primary_icon_url.is_empty()); - EXPECT_TRUE(base::EqualsASCII(fetcher->shortcut_info().short_name, - kDefaultManifestName)); - } - - blink::mojom::ManifestPtr manifest = BuildDefaultManifest(); - manifest->short_name = absl::nullopt; - SetManifest(std::move(manifest)); - - { - // Check a site with no offline-capable service worker. - SetHasServiceWorker(false); - ObserverWaiter waiter; - std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter); - RunFetcher(fetcher.get(), waiter, kDefaultManifestName, - blink::mojom::DisplayMode::kStandalone, false, - InstallableStatusCode::NOT_OFFLINE_CAPABLE); - - EXPECT_FALSE(fetcher->primary_icon().drawsNothing()); - EXPECT_EQ(fetcher->shortcut_info().best_primary_icon_url, - GURL(kDefaultIconUrl)); - EXPECT_TRUE(base::EqualsASCII(fetcher->shortcut_info().short_name, - kDefaultManifestName)); - } - - { - // Check a site where we time out waiting for the service worker. - SetShouldServiceWorkerTimeOut(true); - ObserverWaiter waiter; - std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter); - RunFetcher(fetcher.get(), waiter, kDefaultManifestName, - blink::mojom::DisplayMode::kStandalone, false, - InstallableStatusCode::DATA_TIMED_OUT); - - EXPECT_FALSE(fetcher->primary_icon().drawsNothing()); - EXPECT_EQ(fetcher->shortcut_info().best_primary_icon_url, - GURL(kDefaultIconUrl)); - EXPECT_TRUE(base::EqualsASCII(fetcher->shortcut_info().short_name, - kDefaultManifestName)); - } - - { - // Check a site with an offline-capable service worker. - SetHasServiceWorker(true); - SetShouldServiceWorkerTimeOut(false); - ObserverWaiter waiter; - std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter); - RunFetcher(fetcher.get(), waiter, kDefaultManifestName, - blink::mojom::DisplayMode::kStandalone, true, - InstallableStatusCode::NO_ERROR_DETECTED); - - EXPECT_FALSE(fetcher->primary_icon().drawsNothing()); - EXPECT_EQ(fetcher->shortcut_info().best_primary_icon_url, - GURL(kDefaultIconUrl)); - EXPECT_TRUE(base::EqualsASCII(fetcher->shortcut_info().short_name, - kDefaultManifestName)); - } -} - TEST_F(AddToHomescreenDataFetcherTest, ManifestNoNameNoShortName) { // Test that when the manifest does not provide either Manifest::short_name // nor Manifest::name that: @@ -635,56 +477,4 @@ GURL(kDefaultIconUrl)); } -TEST_F(AddToHomescreenDataFetcherTest, NoServiceWorkerInstallable) { - base::test::ScopedFeatureList scoped_feature_list( - features::kSkipServiceWorkerCheckInstallOnly); - - SetManifest(BuildDefaultManifest()); - SetHasServiceWorker(false); - - // Check where InstallableManager doesn't finish working after the timeout. - // This is akin to waiting for a service worker forever. - base::HistogramTester histograms; - ObserverWaiter waiter; - std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter); - RunFetcher(fetcher.get(), waiter, kDefaultManifestShortName, - kDefaultManifestName, blink::mojom::DisplayMode::kStandalone, - true /*is_webapk_compatible*/, - InstallableStatusCode::NO_ERROR_DETECTED); - - // Navigate to ensure the histograms are written. - NavigateAndCommit(GURL("about:blank")); - CheckHistograms(histograms); - - EXPECT_FALSE(fetcher->primary_icon().drawsNothing()); - EXPECT_EQ(fetcher->shortcut_info().best_primary_icon_url, - GURL(kDefaultIconUrl)); -} - -TEST_F(AddToHomescreenDataFetcherTest, ServiceWorkerTimeOutInstallable) { - base::test::ScopedFeatureList scoped_feature_list( - features::kSkipServiceWorkerCheckInstallOnly); - - SetManifest(BuildDefaultManifest()); - SetShouldServiceWorkerTimeOut(true); - - // Check where InstallableManager doesn't finish working after the timeout. - // This is akin to waiting for a service worker forever. - base::HistogramTester histograms; - ObserverWaiter waiter; - std::unique_ptr<AddToHomescreenDataFetcher> fetcher = BuildFetcher(&waiter); - RunFetcher(fetcher.get(), waiter, kDefaultManifestShortName, - kDefaultManifestName, blink::mojom::DisplayMode::kStandalone, - true /*is_webapk_compatible*/, - InstallableStatusCode::NO_ERROR_DETECTED); - - // Navigate to ensure the histograms are written. - NavigateAndCommit(GURL("about:blank")); - CheckHistograms(histograms); - - EXPECT_FALSE(fetcher->primary_icon().drawsNothing()); - EXPECT_EQ(fetcher->shortcut_info().best_primary_icon_url, - GURL(kDefaultIconUrl)); -} - } // namespace webapps
diff --git a/components/webapps/browser/android/ambient_badge_manager.cc b/components/webapps/browser/android/ambient_badge_manager.cc index 3b63848..fd500ab 100644 --- a/components/webapps/browser/android/ambient_badge_manager.cc +++ b/components/webapps/browser/android/ambient_badge_manager.cc
@@ -155,7 +155,6 @@ // if it's showing for web app (not native app), only show if the worker check // already passed. if (a2hs_params_->app_type == AddToHomescreenParams::AppType::WEBAPK && - features::SkipServiceWorkerForInstallPromotion() && !passed_worker_check_) { InstallableParams params = ParamsToPerformWorkerCheck(); params.wait_for_worker = true;
diff --git a/components/webapps/browser/banners/app_banner_manager.cc b/components/webapps/browser/banners/app_banner_manager.cc index 403784f..7f99f4d 100644 --- a/components/webapps/browser/banners/app_banner_manager.cc +++ b/components/webapps/browser/banners/app_banner_manager.cc
@@ -47,6 +47,19 @@ #include "third_party/skia/include/core/SkBitmap.h" namespace webapps { +namespace { + +bool IsManifestUrlChange(const InstallableData& result) { + if (result.errors.empty()) { + return false; + } + if (result.errors[0] != MANIFEST_URL_CHANGED) { + return false; + } + return true; +} + +} // namespace class AppBannerManager::StatusReporter { public: @@ -276,26 +289,14 @@ } bool AppBannerManager::CheckIfShouldShowBanner() { - if (ShouldBypassEngagementChecks()) + if (ShouldBypassEngagementChecks()) { return true; - - InstallableStatusCode code = ShouldShowBannerCode(); - switch (code) { - case NO_ERROR_DETECTED: - return true; - case PREVIOUSLY_BLOCKED: - TrackDisplayEvent(DISPLAY_EVENT_BLOCKED_PREVIOUSLY); - break; - case PREVIOUSLY_IGNORED: - TrackDisplayEvent(DISPLAY_EVENT_IGNORED_PREVIOUSLY); - break; - case PACKAGE_NAME_OR_START_URL_EMPTY: - break; - default: - NOTREACHED(); } - Stop(code); - return false; + if (GetAppIdentifier().empty()) { + Stop(PACKAGE_NAME_OR_START_URL_EMPTY); + return false; + } + return true; } bool AppBannerManager::ShouldDeferToRelatedNonWebApp() const { @@ -342,37 +343,11 @@ return false; } -bool AppBannerManager::DidRetryInstallableManagerRequest( - const InstallableData& result) { - if (result.errors.empty()) - return false; - if (result.errors[0] != MANIFEST_URL_CHANGED) - return false; - ReportStatus(MANIFEST_URL_CHANGED); - switch (state_) { - case State::FETCHING_MANIFEST: - case State::PENDING_INSTALLABLE_CHECK: - UpdateState(State::INACTIVE); - RequestAppBanner(validated_url_); - return true; - case State::INACTIVE: - case State::ACTIVE: - case State::FETCHING_NATIVE_DATA: - case State::PENDING_WORKER: - case State::PENDING_ENGAGEMENT: - case State::SENDING_EVENT: - case State::SENDING_EVENT_GOT_EARLY_PROMPT: - case State::PENDING_PROMPT_CANCELED: - case State::PENDING_PROMPT_NOT_CANCELED: - case State::COMPLETE: - NOTREACHED(); - return false; - } -} - void AppBannerManager::OnDidGetManifest(const InstallableData& data) { - if (DidRetryInstallableManagerRequest(data)) + // The pipeline will be restarted from DidUpdateWebManifestURL. + if (IsManifestUrlChange(data)) { return; + } UpdateState(State::ACTIVE); if (!data.NoBlockingErrors()) { Stop(data.errors[0]); @@ -415,14 +390,6 @@ return params; } -InstallableParams AppBannerManager::ParamsToPerformWorkerCheck() { - InstallableParams params; - params.has_worker = true; - params.wait_for_worker = true; - - return params; -} - void AppBannerManager::PerformInstallableChecks() { PerformInstallableWebAppCheck(); } @@ -441,8 +408,10 @@ void AppBannerManager::OnDidPerformInstallableWebAppCheck( const InstallableData& data) { - if (DidRetryInstallableManagerRequest(data)) + // The pipeline will be restarted from DidUpdateWebManifestURL. + if (IsManifestUrlChange(data)) { return; + } UpdateState(State::ACTIVE); if (data.valid_manifest) @@ -481,45 +450,9 @@ has_maskable_primary_icon_ = data.has_maskable_primary_icon; screenshots_ = *(data.screenshots); - if (features::SkipInstallServiceWorkerCheck() || - base::FeatureList::IsEnabled(features::kCreateShortcutIgnoresManifest)) { - SetInstallableWebAppCheckResult( - InstallableWebAppCheckResult::kYes_ByUserRequest); - } - - if (features::SkipServiceWorkerForInstallPromotion()) { - SetInstallableWebAppCheckResult( - InstallableWebAppCheckResult::kYes_Promotable); - CheckSufficientEngagement(); - return; - } - - PerformServiceWorkerCheck(); -} - -void AppBannerManager::PerformServiceWorkerCheck() { - UpdateState(State::PENDING_WORKER); - manager_->GetData( - ParamsToPerformWorkerCheck(), - base::BindOnce(&AppBannerManager::OnDidPerformWorkerCheck, GetWeakPtr())); -} - -void AppBannerManager::OnDidPerformWorkerCheck(const InstallableData& data) { - if (!data.NoBlockingErrors()) { - TrackDisplayEvent(DISPLAY_EVENT_LACKS_SERVICE_WORKER); - Stop(data.FirstNoBlockingError()); - return; - } - - passed_worker_check_ = true; - - if (state_ == State::PENDING_WORKER) { - UpdateState(State::ACTIVE); - - SetInstallableWebAppCheckResult( - InstallableWebAppCheckResult::kYes_Promotable); - CheckSufficientEngagement(); - } + SetInstallableWebAppCheckResult( + InstallableWebAppCheckResult::kYes_Promotable); + CheckSufficientEngagement(); } void AppBannerManager::CheckSufficientEngagement() { @@ -579,10 +512,6 @@ TrackBeforeInstallEvent( BEFORE_INSTALL_EVENT_PROMPT_NOT_CALLED_NOT_CANCELLED); break; - case State::PENDING_WORKER: - if (!passed_worker_check_) - TrackDisplayEvent(DISPLAY_EVENT_LACKS_SERVICE_WORKER); - break; case State::PENDING_ENGAGEMENT: if (!has_sufficient_engagement_) TrackDisplayEvent(DISPLAY_EVENT_NOT_VISITED_ENOUGH); @@ -599,9 +528,6 @@ case State::PENDING_PROMPT_CANCELED: case State::PENDING_PROMPT_NOT_CANCELED: return RENDERER_CANCELLED; - case State::PENDING_WORKER: - return passed_worker_check_ ? NO_ERROR_DETECTED - : NO_MATCHING_SERVICE_WORKER; case State::PENDING_ENGAGEMENT: return has_sufficient_engagement_ ? NO_ERROR_DETECTED : INSUFFICIENT_ENGAGEMENT; @@ -730,7 +656,6 @@ ResetCurrentPageData(); if (handle->IsServedFromBackForwardCache()) { - UpdateState(State::INACTIVE); RequestAppBanner(validated_url_); } } @@ -782,12 +707,14 @@ GURL url = validated_url_; switch (state_) { case State::INACTIVE: + return; case State::FETCHING_MANIFEST: case State::PENDING_INSTALLABLE_CHECK: + UpdateState(State::INACTIVE); + RequestAppBanner(validated_url_); return; case State::ACTIVE: case State::FETCHING_NATIVE_DATA: - case State::PENDING_WORKER: case State::PENDING_ENGAGEMENT: case State::SENDING_EVENT: case State::SENDING_EVENT_GOT_EARLY_PROMPT: @@ -801,7 +728,8 @@ // re-compute that, instead of calling RequestAppBanner, DidFinishLoad // is called. That method will re-fetch the engagement data and re-set // that field. - RecheckInstallabilityForLoadedPage(url, false); + ResetCurrentPageData(); + DidFinishLoad(nullptr, url); } return; } @@ -866,7 +794,6 @@ case State::FETCHING_MANIFEST: case State::FETCHING_NATIVE_DATA: case State::PENDING_INSTALLABLE_CHECK: - case State::PENDING_WORKER: case State::SENDING_EVENT: case State::SENDING_EVENT_GOT_EARLY_PROMPT: return true; @@ -971,12 +898,6 @@ AppBannerSettingsHelper::APP_BANNER_EVENT_COULD_SHOW, GetCurrentTime()); } -InstallableStatusCode AppBannerManager::ShouldShowBannerCode() { - if (GetAppIdentifier().empty()) - return PACKAGE_NAME_OR_START_URL_EMPTY; - return NO_ERROR_DETECTED; -} - void AppBannerManager::OnBannerPromptReply( mojo::Remote<blink::mojom::AppBannerController> controller, blink::mojom::AppBannerPromptReply reply) {
diff --git a/components/webapps/browser/banners/app_banner_manager.h b/components/webapps/browser/banners/app_banner_manager.h index a1ff6c53..3746b7e 100644 --- a/components/webapps/browser/banners/app_banner_manager.h +++ b/components/webapps/browser/banners/app_banner_manager.h
@@ -90,9 +90,6 @@ // engagement to trigger the banner. PENDING_ENGAGEMENT, - // The pipeline is waiting for service worker install to trigger the banner. - PENDING_WORKER, - // The beforeinstallprompt event has been sent and the pipeline is waiting // for the response. SENDING_EVENT, @@ -310,11 +307,6 @@ // overwritten with a new app install for the current page. virtual bool ShouldAllowWebAppReplacementInstall(); - // Possibly retries the installable manager request given the current state - // and the result. Returns |true| if the request was restarted. - // Currently only called during requests to InstallationManager - bool DidRetryInstallableManagerRequest(const InstallableData& result); - // Callback invoked by the InstallableManager once it has fetched the page's // manifest. virtual void OnDidGetManifest(const InstallableData& data); @@ -323,10 +315,6 @@ // necessary for a web app banner. virtual InstallableParams ParamsToPerformInstallableWebAppCheck(); - // Returns an InstallableParams object that requests service worker check - // only. - virtual InstallableParams ParamsToPerformWorkerCheck(); - // Run at the conclusion of OnDidGetManifest. For web app banners, this calls // back to the InstallableManager to continue checking criteria. For native // app banners, this checks whether native apps are preferred in the manifest, @@ -340,15 +328,6 @@ // all other installable properties. virtual void OnDidPerformInstallableWebAppCheck(const InstallableData& data); - // Run at the conclusion of OnDidPerformInstallableWebAppCheck. This calls - // back to the InstallableManager to continue checking service worker criteria - // for web app banners. - virtual void PerformServiceWorkerCheck(); - - // Callback invoked by the InstallableManager once it has finished checking - // service worker. - virtual void OnDidPerformWorkerCheck(const InstallableData& data); - // Records that a banner was shown. void RecordDidShowBanner(); @@ -470,9 +449,6 @@ // requesting that it be shown later. void DisplayAppBanner() override; - // Returns a status code indicating whether a banner should be shown. - InstallableStatusCode ShouldShowBannerCode(); - // Returns a status code based on the current state, to log when terminating. InstallableStatusCode TerminationCode() const;
diff --git a/components/webapps/browser/features.cc b/components/webapps/browser/features.cc index 0464ea0..3b71660 100644 --- a/components/webapps/browser/features.cc +++ b/components/webapps/browser/features.cc
@@ -79,36 +79,16 @@ "CreateShortcutIgnoresManifest", base::FEATURE_DISABLED_BY_DEFAULT); -// Skip the service worker install criteria check for installing. This affect -// only the "installable" status but not "promotable". -BASE_FEATURE(kSkipServiceWorkerCheckInstallOnly, - "SkipServiceWorkerCheckInstallOnly", - base::FEATURE_ENABLED_BY_DEFAULT); - // Enables showing a detailed install dialog for user installs. BASE_FEATURE(kDesktopPWAsDetailedInstallDialog, "DesktopPWAsDetailedInstallDialog", base::FEATURE_ENABLED_BY_DEFAULT); -// Enables sending the beforeinstallprompt without a service worker check. -BASE_FEATURE(kSkipServiceWorkerForInstallPrompt, - "SkipServiceWorkerForInstallPromot", - base::FEATURE_ENABLED_BY_DEFAULT); - // Use segmentation to decide whether install prompt should be shown. BASE_FEATURE(kInstallPromptSegmentation, "InstallPromptSegmentation", base::FEATURE_DISABLED_BY_DEFAULT); -bool SkipInstallServiceWorkerCheck() { - return base::FeatureList::IsEnabled(kSkipServiceWorkerCheckInstallOnly); -} - -bool SkipServiceWorkerForInstallPromotion() { - return base::FeatureList::IsEnabled(kSkipServiceWorkerCheckInstallOnly) && - base::FeatureList::IsEnabled(kSkipServiceWorkerForInstallPrompt); -} - // Keys to use when querying the variations params. BASE_FEATURE(kAppBannerTriggering, "AppBannerTriggering",
diff --git a/components/webapps/browser/features.h b/components/webapps/browser/features.h index e940575..5a99b06 100644 --- a/components/webapps/browser/features.h +++ b/components/webapps/browser/features.h
@@ -43,15 +43,10 @@ #endif // BUILDFLAG(IS_ANDROID) BASE_DECLARE_FEATURE(kCreateShortcutIgnoresManifest); -BASE_DECLARE_FEATURE(kSkipServiceWorkerCheckInstallOnly); BASE_DECLARE_FEATURE(kDesktopPWAsDetailedInstallDialog); -BASE_DECLARE_FEATURE(kSkipServiceWorkerForInstallPrompt); BASE_DECLARE_FEATURE(kInstallPromptSegmentation); -bool SkipInstallServiceWorkerCheck(); -bool SkipServiceWorkerForInstallPromotion(); - BASE_DECLARE_FEATURE(kAppBannerTriggering); extern const base::FeatureParam<double> kBannerParamsEngagementTotalKey; extern const base::FeatureParam<int> kBannerParamsDaysAfterBannerDismissedKey;
diff --git a/content/browser/attribution_reporting/attribution_data_host_manager.h b/content/browser/attribution_reporting/attribution_data_host_manager.h index 89a894f..3d1d62d 100644 --- a/content/browser/attribution_reporting/attribution_data_host_manager.h +++ b/content/browser/attribution_reporting/attribution_data_host_manager.h
@@ -15,7 +15,6 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/tokens/tokens.h" #include "third_party/blink/public/mojom/conversions/attribution_data_host.mojom-forward.h" -#include "third_party/blink/public/mojom/conversions/attribution_reporting.mojom-forward.h" namespace attribution_reporting { class SuitableOrigin; @@ -71,7 +70,6 @@ virtual void NotifyNavigationRegistrationStarted( const blink::AttributionSrcToken& attribution_src_token, const attribution_reporting::SuitableOrigin& source_origin, - blink::mojom::AttributionNavigationType nav_type, bool is_within_fenced_frame, GlobalRenderFrameHostId render_frame_id, int64_t navigation_id) = 0; @@ -88,7 +86,6 @@ attribution_reporting::SuitableOrigin reporting_origin, const attribution_reporting::SuitableOrigin& source_origin, AttributionInputEvent input_event, - blink::mojom::AttributionNavigationType nav_type, bool is_within_fenced_frame, GlobalRenderFrameHostId render_frame_id, int64_t navigation_id,
diff --git a/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc b/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc index d236da5..7367862 100644 --- a/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc +++ b/content/browser/attribution_reporting/attribution_data_host_manager_impl.cc
@@ -58,7 +58,6 @@ #include "third_party/abseil-cpp/absl/types/variant.h" #include "third_party/blink/public/common/tokens/tokens.h" #include "third_party/blink/public/mojom/conversions/attribution_data_host.mojom.h" -#include "third_party/blink/public/mojom/conversions/attribution_reporting.mojom.h" #include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom.h" #include "url/gurl.h" #include "url/origin.h" @@ -71,7 +70,6 @@ using ::attribution_reporting::mojom::RegistrationType; using ::attribution_reporting::mojom::SourceRegistrationError; using ::attribution_reporting::mojom::SourceType; -using ::blink::mojom::AttributionNavigationType; // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused. @@ -129,17 +127,14 @@ RegistrationType registration_type, bool is_within_fenced_frame, AttributionInputEvent input_event, - absl::optional<AttributionNavigationType> nav_type, GlobalRenderFrameHostId render_frame_id, absl::optional<int64_t> navigation_id) : context_origin_(std::move(context_origin)), registration_type_(registration_type), is_within_fenced_frame_(is_within_fenced_frame), input_event_(std::move(input_event)), - nav_type_(nav_type), render_frame_id_(render_frame_id), navigation_id_(navigation_id) { - DCHECK(!nav_type_ || registration_type_ == RegistrationType::kSource); DCHECK(!navigation_id_ || registration_type_ == RegistrationType::kSource); } @@ -159,10 +154,6 @@ absl::optional<int64_t> navigation_id() const { return navigation_id_; } - absl::optional<AttributionNavigationType> nav_type() const { - return nav_type_; - } - GlobalRenderFrameHostId render_frame_id() const { return render_frame_id_; } const AttributionInputEvent& input_event() const { return input_event_; } @@ -184,9 +175,6 @@ // Logically const. AttributionInputEvent input_event_; - // Logically const. - absl::optional<AttributionNavigationType> nav_type_; - // The ID of the topmost render frame host. // Logically const. GlobalRenderFrameHostId render_frame_id_; @@ -222,7 +210,6 @@ blink::AttributionSrcToken attribution_src_token; // Will not change over the course of the redirect chain. - AttributionNavigationType nav_type; int64_t navigation_id; }; @@ -412,11 +399,10 @@ RegistrationType registration_type, GlobalRenderFrameHostId render_frame_id, int64_t last_navigation_id) { - ReceiverContext receiver_context(std::move(context_origin), registration_type, - is_within_fenced_frame, - /*input_event=*/AttributionInputEvent(), - /*nav_type=*/absl::nullopt, render_frame_id, - /*navigation_id=*/absl::nullopt); + ReceiverContext receiver_context( + std::move(context_origin), registration_type, is_within_fenced_frame, + /*input_event=*/AttributionInputEvent(), render_frame_id, + /*navigation_id=*/absl::nullopt); switch (registration_type) { case RegistrationType::kTrigger: @@ -534,7 +520,6 @@ void AttributionDataHostManagerImpl::NotifyNavigationRegistrationStarted( const blink::AttributionSrcToken& attribution_src_token, const SuitableOrigin& source_origin, - AttributionNavigationType nav_type, bool is_within_fenced_frame, GlobalRenderFrameHostId render_frame_id, int64_t navigation_id) { @@ -555,7 +540,7 @@ receivers_.Add(this, std::move(it->second.data_host), ReceiverContext(source_origin, RegistrationType::kSource, is_within_fenced_frame, - std::move(it->second.input_event), nav_type, + std::move(it->second.input_event), render_frame_id, navigation_id)); navigation_data_host_map_.erase(it); @@ -571,7 +556,6 @@ SuitableOrigin reporting_origin, const SuitableOrigin& source_origin, AttributionInputEvent input_event, - AttributionNavigationType nav_type, bool is_within_fenced_frame, GlobalRenderFrameHostId render_frame_id, int64_t navigation_id, @@ -586,7 +570,6 @@ render_frame_id, SourceRegistrations::ForegroundNavigation{ .attribution_src_token = attribution_src_token, - .nav_type = nav_type, .navigation_id = navigation_id, }); DCHECK(!it->registrations_complete()); @@ -654,9 +637,8 @@ return; } - // TODO(csharrison): Remove `nav_type` via reverting crrev.com/c/4070064. auto source_type = SourceType::kEvent; - if (auto nav_type = context->nav_type()) { + if (context->navigation_id().has_value()) { source_type = SourceType::kNavigation; }
diff --git a/content/browser/attribution_reporting/attribution_data_host_manager_impl.h b/content/browser/attribution_reporting/attribution_data_host_manager_impl.h index 292d82c..1a1f911d 100644 --- a/content/browser/attribution_reporting/attribution_data_host_manager_impl.h +++ b/content/browser/attribution_reporting/attribution_data_host_manager_impl.h
@@ -80,7 +80,6 @@ void NotifyNavigationRegistrationStarted( const blink::AttributionSrcToken& attribution_src_token, const attribution_reporting::SuitableOrigin& source_origin, - blink::mojom::AttributionNavigationType nav_type, bool is_within_fenced_frame, GlobalRenderFrameHostId render_frame_id, int64_t navigation_id) override; @@ -90,7 +89,6 @@ attribution_reporting::SuitableOrigin reporting_origin, const attribution_reporting::SuitableOrigin& source_origin, AttributionInputEvent input_event, - blink::mojom::AttributionNavigationType nav_type, bool is_within_fenced_frame, GlobalRenderFrameHostId render_frame_id, int64_t navigation_id,
diff --git a/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc b/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc index d683570..68719b1e 100644 --- a/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc +++ b/content/browser/attribution_reporting/attribution_data_host_manager_impl_unittest.cc
@@ -61,7 +61,6 @@ #include "third_party/abseil-cpp/absl/numeric/int128.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/mojom/conversions/attribution_data_host.mojom.h" -#include "third_party/blink/public/mojom/conversions/attribution_reporting.mojom.h" #include "url/gurl.h" #include "url/origin.h" @@ -78,8 +77,6 @@ using ::attribution_reporting::mojom::SourceRegistrationError; using ::attribution_reporting::mojom::SourceType; -using ::blink::mojom::AttributionNavigationType; - using AttributionFilters = ::attribution_reporting::FiltersDisjunction; using ::testing::_; @@ -545,7 +542,6 @@ data_host_manager_.NotifyNavigationRegistrationStarted( attribution_src_token, page_origin, - AttributionNavigationType::kContextMenu, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId); @@ -621,7 +617,6 @@ data_host_manager_.NotifyNavigationRegistrationStarted( attribution_src_token, page_origin, - AttributionNavigationType::kContextMenu, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId); task_environment_.RunUntilIdle(); @@ -741,7 +736,6 @@ data_host_manager_.NotifyNavigationRegistrationStarted( attribution_src_token, *SuitableOrigin::Deserialize("https://page1.example"), - blink::mojom::AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId); @@ -790,7 +784,6 @@ data_host_manager_.NotifyNavigationRegistrationStarted( attribution_src_token, *SuitableOrigin::Deserialize("https://page1.example"), - blink::mojom::AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId); @@ -844,7 +837,6 @@ data_host_manager_.NotifyNavigationRegistrationStarted( attribution_src_token, source_origin, - blink::mojom::AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId); @@ -863,7 +855,7 @@ kRegisterSourceJson); data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporting_origin, source_origin, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/true); @@ -903,7 +895,6 @@ data_host_manager_.NotifyNavigationRegistrationStarted( attribution_src_token, *SuitableOrigin::Deserialize("https://page1.example"), - blink::mojom::AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId); @@ -952,7 +943,6 @@ data_host_manager_.NotifyNavigationRegistrationStarted( attribution_src_token, *SuitableOrigin::Deserialize("https://page1.example"), - blink::mojom::AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/1); mojo::Remote<blink::mojom::AttributionDataHost> trigger_data_host_remote; data_host_manager_.RegisterDataHost( @@ -973,7 +963,6 @@ data_host_manager_.NotifyNavigationRegistrationStarted( attribution_src_token_2, *SuitableOrigin::Deserialize("https://page1.example"), - blink::mojom::AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/2); mojo::Remote<blink::mojom::AttributionDataHost> trigger_data_host_remote_2; data_host_manager_.RegisterDataHost( @@ -996,7 +985,6 @@ data_host_manager_.NotifyNavigationRegistrationStarted( attribution_src_token_3, *SuitableOrigin::Deserialize("https://page1.example"), - blink::mojom::AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/3); mojo::Remote<blink::mojom::AttributionDataHost> trigger_data_host_remote_3; data_host_manager_.RegisterDataHost( @@ -1042,7 +1030,6 @@ data_host_manager_.NotifyNavigationRegistrationStarted( attribution_src_token, *SuitableOrigin::Deserialize("https://page1.example"), - blink::mojom::AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId); @@ -1074,12 +1061,12 @@ const blink::AttributionSrcToken attribution_src_token; data_host_manager_.NotifyNavigationRegistrationStarted( - attribution_src_token, source_site, AttributionNavigationType::kAnchor, + attribution_src_token, source_site, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId); data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/false); @@ -1088,7 +1075,7 @@ data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, /*headers=*/nullptr, reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/true); @@ -1115,7 +1102,7 @@ const blink::AttributionSrcToken attribution_src_token; data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, // The cross to web runtime feature defaults to false. network::AttributionReportingRuntimeFeatures(), @@ -1148,7 +1135,7 @@ const blink::AttributionSrcToken attribution_src_token; data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, {network::AttributionReportingRuntimeFeature::kCrossAppWeb}, /*is_final_response=*/false); @@ -1176,7 +1163,7 @@ const blink::AttributionSrcToken attribution_src_token; data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, {network::AttributionReportingRuntimeFeature::kCrossAppWeb}, /*is_final_response=*/false); @@ -1219,7 +1206,7 @@ data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, {network::AttributionReportingRuntimeFeature::kCrossAppWeb}, /*is_final_response=*/false); @@ -1232,7 +1219,7 @@ data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, {network::AttributionReportingRuntimeFeature::kCrossAppWeb}, /*is_final_response=*/false); @@ -1263,7 +1250,7 @@ const blink::AttributionSrcToken attribution_src_token; data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, {network::AttributionReportingRuntimeFeature::kCrossAppWeb}, /*is_final_response=*/false); @@ -1285,7 +1272,7 @@ const blink::AttributionSrcToken attribution_src_token; data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/true); @@ -1323,7 +1310,7 @@ data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/false); @@ -1337,7 +1324,7 @@ data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/false); @@ -1363,13 +1350,13 @@ const blink::AttributionSrcToken attribution_src_token; data_host_manager_.NotifyNavigationRegistrationStarted( - attribution_src_token, source_site, AttributionNavigationType::kAnchor, + attribution_src_token, source_site, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId); data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/false); @@ -1378,7 +1365,7 @@ data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/false); @@ -1403,7 +1390,7 @@ const blink::AttributionSrcToken attribution_src_token; data_host_manager_.NotifyNavigationRegistrationStarted( - attribution_src_token, source_site, AttributionNavigationType::kAnchor, + attribution_src_token, source_site, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId); @@ -1413,7 +1400,7 @@ "!!!invalid json"); data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/false); @@ -1424,7 +1411,7 @@ kRegisterSourceJson); data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/false); @@ -1454,7 +1441,7 @@ const blink::AttributionSrcToken attribution_src_token; data_host_manager_.NotifyNavigationRegistrationStarted( - attribution_src_token, source_site, AttributionNavigationType::kAnchor, + attribution_src_token, source_site, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId); @@ -1463,7 +1450,7 @@ kRegisterSourceJson); data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId, network::AttributionReportingRuntimeFeatures(), @@ -1480,7 +1467,7 @@ /*verifications=*/{}); data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, /*headers=*/nullptr, reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId, network::AttributionReportingRuntimeFeatures(), @@ -1517,18 +1504,18 @@ const blink::AttributionSrcToken attribution_src_token; data_host_manager_.NotifyNavigationRegistrationStarted( - attribution_src_token, source_site, AttributionNavigationType::kAnchor, + attribution_src_token, source_site, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId); data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/false); data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/false); @@ -1575,20 +1562,20 @@ const blink::AttributionSrcToken attribution_src_token; data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/false); data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/false); // Wait for parsing. data_host_manager_.NotifyNavigationRegistrationStarted( - attribution_src_token, source_site, AttributionNavigationType::kAnchor, + attribution_src_token, source_site, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId); @@ -1669,7 +1656,6 @@ data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, /*headers=*/nullptr, reporting_origin, source_origin, AttributionInputEvent(), - AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/true); @@ -1722,7 +1708,6 @@ data_host_manager_.NotifyNavigationRegistrationStarted( attribution_src_token, *SuitableOrigin::Deserialize("https://page1.example"), - AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId); @@ -1790,8 +1775,8 @@ data_host_manager_.NotifyNavigationRegistrationStarted( attribution_src_token, *SuitableOrigin::Deserialize("https://page.example"), - AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false, - kFrameId, /*navigation_id=*/kNavigationId); + /*is_within_fenced_frame=*/false, kFrameId, + /*navigation_id=*/kNavigationId); // kNotFound = 1. histograms.ExpectUniqueSample(kNavigationDataHostStatusHistogram, 1, 1); @@ -1811,8 +1796,8 @@ data_host_manager_.NotifyNavigationRegistrationStarted( attribution_src_token, *SuitableOrigin::Deserialize("https://s.test"), - AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false, - kFrameId, /*navigation_id=*/kNavigationId); + /*is_within_fenced_frame=*/false, kFrameId, + /*navigation_id=*/kNavigationId); mojo::test::BadMessageObserver bad_message_observer; @@ -1861,8 +1846,8 @@ data_host_manager_.NotifyNavigationRegistrationStarted( attribution_src_token, *SuitableOrigin::Deserialize("https://page.example"), - AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false, - kFrameId, /*navigation_id=*/kNavigationId); + /*is_within_fenced_frame=*/false, kFrameId, + /*navigation_id=*/kNavigationId); auto reporting_origin = *SuitableOrigin::Deserialize("https://reporter.example"); @@ -1953,8 +1938,8 @@ data_host_manager_.NotifyNavigationRegistrationStarted( attribution_src_token, /*source_origin=*/*SuitableOrigin::Deserialize("https://source.test"), - AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/true, - kFrameId, /*navigation_id=*/kNavigationId); + /*is_within_fenced_frame=*/true, kFrameId, + /*navigation_id=*/kNavigationId); data_host_remote->SourceDataAvailable( /*reporting_origin=*/*SuitableOrigin::Deserialize("https://report.test"), @@ -1977,7 +1962,7 @@ attribution_src_token, headers.get(), /*reporting_origin=*/*SuitableOrigin::Deserialize("https://report.test"), /*source_origin=*/*SuitableOrigin::Deserialize("https://source.test"), - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/true, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/false); @@ -2016,7 +2001,7 @@ data_host_manager_.NotifyNavigationRegistrationData( blink::AttributionSrcToken(), /*headers=*/nullptr, *SuitableOrigin::Deserialize("https://reporter.example"), source_origin, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/true); @@ -2051,7 +2036,7 @@ data_host_manager_.NotifyNavigationRegistrationData( blink::AttributionSrcToken(), /*headers=*/nullptr, *SuitableOrigin::Create(reporting_origin), source_origin, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/true); @@ -2100,7 +2085,6 @@ // This is irrelevant to beacon source registrations. data_host_manager_.NotifyNavigationRegistrationStarted( blink::AttributionSrcToken(), source_origin, - AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId); @@ -2152,7 +2136,6 @@ data_host_manager_.NotifyNavigationRegistrationData( blink::AttributionSrcToken(), /*headers=*/nullptr, source_origin, source_origin, AttributionInputEvent(), - AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId, network::AttributionReportingRuntimeFeatures(), @@ -2200,7 +2183,6 @@ // This is irrelevant to beacon source registrations. data_host_manager_.NotifyNavigationRegistrationStarted( blink::AttributionSrcToken(), source_origin, - AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId); @@ -2236,7 +2218,6 @@ // This is irrelevant to beacon source registrations. data_host_manager_.NotifyNavigationRegistrationStarted( blink::AttributionSrcToken(), source_origin, - AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId); @@ -2275,7 +2256,6 @@ // This is irrelevant to beacon source registrations. data_host_manager_.NotifyNavigationRegistrationStarted( blink::AttributionSrcToken(), source_origin, - AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId); } @@ -2430,7 +2410,6 @@ data_host_manager_.NotifyNavigationRegistrationStarted( attribution_src_token, source_origin, - blink::mojom::AttributionNavigationType::kAnchor, /*is_within_fenced_frame=*/false, kFrameId, /*navigation_id=*/kNavigationId); @@ -2449,7 +2428,7 @@ kRegisterSourceJson); data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporting_origin, source_origin, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/true); @@ -2720,7 +2699,7 @@ const blink::AttributionSrcToken attribution_src_token; data_host_manager_.NotifyNavigationRegistrationData( attribution_src_token, headers.get(), reporter, source_site, - AttributionInputEvent(), AttributionNavigationType::kAnchor, + AttributionInputEvent(), /*is_within_fenced_frame=*/false, kFrameId, kNavigationId, network::AttributionReportingRuntimeFeatures(), /*is_final_response=*/false);
diff --git a/content/browser/attribution_reporting/attribution_host.cc b/content/browser/attribution_reporting/attribution_host.cc index df0bb17..886b03de 100644 --- a/content/browser/attribution_reporting/attribution_host.cc +++ b/content/browser/attribution_reporting/attribution_host.cc
@@ -193,7 +193,7 @@ attribution_manager->GetDataHostManager() ->NotifyNavigationRegistrationStarted( impression->attribution_src_token, navigation_info.source_origin, - impression->nav_type, navigation_info.is_within_fenced_frame, + navigation_info.is_within_fenced_frame, navigation_info.initiator_root_frame_id, navigation_handle->GetNavigationId()); } @@ -261,7 +261,7 @@ attribution_manager->GetDataHostManager()->NotifyNavigationRegistrationData( impression->attribution_src_token, navigation_handle->GetResponseHeaders(), std::move(*reporting_origin), - it->second.source_origin, it->second.input_event, impression->nav_type, + it->second.source_origin, it->second.input_event, it->second.is_within_fenced_frame, it->second.initiator_root_frame_id, navigation_handle->GetNavigationId(), impression->runtime_features, is_final_response);
diff --git a/content/browser/attribution_reporting/attribution_host_unittest.cc b/content/browser/attribution_reporting/attribution_host_unittest.cc index c0f3ad30..2cfc1b9f 100644 --- a/content/browser/attribution_reporting/attribution_host_unittest.cc +++ b/content/browser/attribution_reporting/attribution_host_unittest.cc
@@ -69,7 +69,6 @@ using ::testing::Return; using ::attribution_reporting::mojom::RegistrationType; -using ::blink::mojom::AttributionNavigationType; const char kConversionUrl[] = "https://b.com"; @@ -180,13 +179,11 @@ TEST_F(AttributionHostTest, ValidAttributionSrc_ForwardedToManager) { blink::Impression impression; - impression.nav_type = AttributionNavigationType::kWindowOpen; EXPECT_CALL(*mock_data_host_manager(), NotifyNavigationRegistrationStarted( impression.attribution_src_token, *SuitableOrigin::Deserialize("https://secure_impression.com"), - impression.nav_type, /*is_within_fenced_frame=*/false, main_rfh()->GetGlobalId(), /*navigation_id=*/_)); @@ -200,7 +197,6 @@ TEST_F(AttributionHostTest, ValidSourceRegistrations_ForwardedToManager) { blink::Impression impression; - impression.nav_type = AttributionNavigationType::kWindowOpen; auto redirect_headers = base::MakeRefCounted<net::HttpResponseHeaders>(""); auto headers = base::MakeRefCounted<net::HttpResponseHeaders>(""); @@ -218,33 +214,29 @@ const SuitableOrigin d_origin = *SuitableOrigin::Create(d_url); GlobalRenderFrameHostId frame_id = main_rfh()->GetGlobalId(); - EXPECT_CALL( - *mock_data_host_manager(), - NotifyNavigationRegistrationStarted( - impression.attribution_src_token, source_origin, impression.nav_type, - /*is_within_fenced_frame=*/false, frame_id, - /*navigation_id=*/_)); - EXPECT_CALL( - *mock_data_host_manager(), - NotifyNavigationRegistrationData( - impression.attribution_src_token, redirect_headers.get(), - /*reporting_origin=*/b_origin, source_origin, _, impression.nav_type, - /*is_within_fenced_frame=*/false, frame_id, _, _, - /*is_final_response=*/false)); - EXPECT_CALL( - *mock_data_host_manager(), - NotifyNavigationRegistrationData( - impression.attribution_src_token, redirect_headers.get(), - /*reporting_origin=*/c_origin, source_origin, _, impression.nav_type, - /*is_within_fenced_frame=*/false, frame_id, _, _, - /*is_final_response=*/false)); - EXPECT_CALL( - *mock_data_host_manager(), - NotifyNavigationRegistrationData( - impression.attribution_src_token, headers.get(), - /*reporting_origin=*/d_origin, source_origin, _, impression.nav_type, - /*is_within_fenced_frame=*/false, frame_id, _, _, - /*is_final_response=*/true)); + EXPECT_CALL(*mock_data_host_manager(), + NotifyNavigationRegistrationStarted( + impression.attribution_src_token, source_origin, + /*is_within_fenced_frame=*/false, frame_id, + /*navigation_id=*/_)); + EXPECT_CALL(*mock_data_host_manager(), + NotifyNavigationRegistrationData( + impression.attribution_src_token, redirect_headers.get(), + /*reporting_origin=*/b_origin, source_origin, _, + /*is_within_fenced_frame=*/false, frame_id, _, _, + /*is_final_response=*/false)); + EXPECT_CALL(*mock_data_host_manager(), + NotifyNavigationRegistrationData( + impression.attribution_src_token, redirect_headers.get(), + /*reporting_origin=*/c_origin, source_origin, _, + /*is_within_fenced_frame=*/false, frame_id, _, _, + /*is_final_response=*/false)); + EXPECT_CALL(*mock_data_host_manager(), + NotifyNavigationRegistrationData( + impression.attribution_src_token, headers.get(), + /*reporting_origin=*/d_origin, source_origin, _, + /*is_within_fenced_frame=*/false, frame_id, _, _, + /*is_final_response=*/true)); contents()->NavigateAndCommit(GURL("https://secure_impression.com")); @@ -306,7 +298,7 @@ EXPECT_CALL(*mock_data_host_manager(), NotifyNavigationRegistrationData(impression.attribution_src_token, - _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, /*is_final_response=*/true)); contents()->NavigateAndCommit(GURL("https://secure_impression.com")); @@ -324,7 +316,7 @@ EXPECT_CALL(*mock_data_host_manager(), NotifyNavigationRegistrationData(impression.attribution_src_token, - _, _, _, _, _, _, _, _, _, + _, _, _, _, _, _, _, _, /*is_final_response=*/true)); contents()->NavigateAndCommit(GURL("https://secure_impression.com")); @@ -692,7 +684,6 @@ TEST_F(AttributionHostTest, ImpressionNavigation_FeaturePolicyChecked) { blink::Impression impression; - impression.nav_type = AttributionNavigationType::kWindowOpen; static constexpr char kAllowedOriginUrl[] = "https://a.test";
diff --git a/content/browser/attribution_reporting/test/mock_attribution_data_host_manager.h b/content/browser/attribution_reporting/test/mock_attribution_data_host_manager.h index 634e85b..1d2411e 100644 --- a/content/browser/attribution_reporting/test/mock_attribution_data_host_manager.h +++ b/content/browser/attribution_reporting/test/mock_attribution_data_host_manager.h
@@ -19,7 +19,6 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/tokens/tokens.h" #include "third_party/blink/public/mojom/conversions/attribution_data_host.mojom-forward.h" -#include "third_party/blink/public/mojom/conversions/attribution_reporting.mojom-forward.h" namespace net { class HttpResponseHeaders; @@ -55,7 +54,6 @@ NotifyNavigationRegistrationStarted, (const blink::AttributionSrcToken& attribution_src_token, const attribution_reporting::SuitableOrigin& source_origin, - blink::mojom::AttributionNavigationType, bool is_within_fenced_frame, GlobalRenderFrameHostId, int64_t navigation_id), @@ -68,7 +66,6 @@ attribution_reporting::SuitableOrigin reporting_origin, const attribution_reporting::SuitableOrigin& source_origin, AttributionInputEvent input_event, - blink::mojom::AttributionNavigationType, bool is_within_fenced_frame, GlobalRenderFrameHostId, int64_t navigation_id,
diff --git a/content/browser/preloading/prefetch/prefetch_container.cc b/content/browser/preloading/prefetch/prefetch_container.cc index 7784e60..6214bc2 100644 --- a/content/browser/preloading/prefetch/prefetch_container.cc +++ b/content/browser/preloading/prefetch/prefetch_container.cc
@@ -470,9 +470,9 @@ PrefetchContainer::Reader::GetCurrentNetworkContextToServe() const { const SinglePrefetch& this_prefetch = GetCurrentSinglePrefetchToServe(); - const auto& network_context_itr = prefetch_container_.network_contexts_.find( + const auto& network_context_itr = prefetch_container_->network_contexts_.find( this_prefetch.is_isolated_network_context_required_); - if (network_context_itr == prefetch_container_.network_contexts_.end()) { + if (network_context_itr == prefetch_container_->network_contexts_.end()) { // Not set in unit tests. return nullptr; } @@ -584,7 +584,7 @@ // We don't want any of the cookie listeners for this prefetch to pick up // changes from the copy. - prefetch_container_.StopAllCookieListeners(); + prefetch_container_->StopAllCookieListeners(); GetCurrentSinglePrefetchToServe().cookie_copy_status_ = SinglePrefetch::CookieCopyStatus::kInProgress; @@ -696,7 +696,7 @@ void PrefetchContainer::Reader::OnPrefetchProbeResult( PrefetchProbeResult probe_result) { - prefetch_container_.probe_result_ = probe_result; + prefetch_container_->probe_result_ = probe_result; switch (probe_result) { case PrefetchProbeResult::kNoProbing: @@ -705,14 +705,14 @@ // Wait to update the prefetch status until the probe for the final // redirect hop is a success. if (index_redirect_chain_to_serve_ == - prefetch_container_.redirect_chain_.size() - 1) { - prefetch_container_.SetPrefetchStatus( + prefetch_container_->redirect_chain_.size() - 1) { + prefetch_container_->SetPrefetchStatus( PrefetchStatus::kPrefetchResponseUsed); } break; case PrefetchProbeResult::kDNSProbeFailure: case PrefetchProbeResult::kTLSProbeFailure: - prefetch_container_.SetPrefetchStatusWithoutUpdatingTriggeringOutcome( + prefetch_container_->SetPrefetchStatusWithoutUpdatingTriggeringOutcome( PrefetchStatus::kPrefetchNotUsedProbeFailed); break; default: @@ -800,8 +800,8 @@ PrefetchContainer::Reader::GetCurrentSinglePrefetchToServe() const { DCHECK(index_redirect_chain_to_serve_ >= 0 && index_redirect_chain_to_serve_ < - prefetch_container_.redirect_chain_.size()); - return *prefetch_container_.redirect_chain_[index_redirect_chain_to_serve_]; + prefetch_container_->redirect_chain_.size()); + return *prefetch_container_->redirect_chain_[index_redirect_chain_to_serve_]; } const GURL& PrefetchContainer::Reader::GetCurrentURLToServe() const {
diff --git a/content/browser/preloading/prefetch/prefetch_container.h b/content/browser/preloading/prefetch/prefetch_container.h index c8c99bd..274731c 100644 --- a/content/browser/preloading/prefetch/prefetch_container.h +++ b/content/browser/preloading/prefetch/prefetch_container.h
@@ -7,6 +7,7 @@ #include <utility> +#include "base/memory/raw_ref.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "content/browser/preloading/prefetch/prefetch_probe_result.h" @@ -306,7 +307,7 @@ // Currently the lifetime of `Reader` and `PrefetchContainer` are the same // and thus this reference is always valid as long as `Reader` is valid. - PrefetchContainer& prefetch_container_; + const raw_ref<PrefetchContainer> prefetch_container_; // The index of the element in |prefetch_container_.redirect_chain_| that // can be served.
diff --git a/content/browser/renderer_host/navigation_controller_android.cc b/content/browser/renderer_host/navigation_controller_android.cc index f3d19d1e..2cb16276 100644 --- a/content/browser/renderer_host/navigation_controller_android.cc +++ b/content/browser/renderer_host/navigation_controller_android.cc
@@ -285,7 +285,6 @@ blink::Impression impression; impression.attribution_src_token = GetAttributionSrcTokenFromJavaImpression(env, j_impression).value(); - impression.nav_type = blink::mojom::AttributionNavigationType::kContextMenu; impression.runtime_features = GetAttributionRuntimeFeaturesFromJavaImpression(env, j_impression); params.impression = impression;
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index fd91b2f2..e987d93 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -1170,7 +1170,7 @@ // An expiry time for resetting the pending_user_activation_timer_. static const base::TimeDelta kActivationNotificationExpireTime; - raw_ptr<FrameTree> frame_tree_; + raw_ptr<FrameTree, LeakedDanglingUntriaged> frame_tree_; // RenderWidgetHost are either: // - Owned by RenderViewHostImpl. @@ -1212,7 +1212,8 @@ // dynamically fetching it from `site_instance_group_` since its // value gets cleared early in `SiteInstanceGroup` via // RenderProcessHostDestroyed before this object is destroyed. - const raw_ref<AgentSchedulingGroupHost> agent_scheduling_group_; + const raw_ref<AgentSchedulingGroupHost, LeakedDanglingUntriaged> + agent_scheduling_group_; // The SiteInstanceGroup this RenderWidgetHost belongs to. // TODO(https://crbug.com/1420333) Turn this into base::SafeRef
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc index 4e74a049..5d467660 100644 --- a/content/browser/webid/federated_auth_request_impl.cc +++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -14,6 +14,7 @@ #include "base/task/sequenced_task_runner.h" #include "base/time/time.h" #include "components/url_formatter/elide_url.h" +#include "components/url_formatter/url_formatter.h" #include "content/browser/bad_message.h" #include "content/browser/devtools/devtools_instrumentation.h" #include "content/browser/renderer_host/render_frame_host_impl.h" @@ -269,7 +270,8 @@ GURL(url.scheme() + "://" + formatted_url_str), url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS)); } - return GURL(url.scheme() + "://" + formatted_url_str).spec(); + return base::UTF16ToUTF8( + url_formatter::FormatUrl(GURL(url.scheme() + "://" + formatted_url_str))); } std::string FormatOriginForDisplay(const url::Origin& origin) {
diff --git a/content/browser/webid/federated_auth_request_impl_unittest.cc b/content/browser/webid/federated_auth_request_impl_unittest.cc index 24cf889f..b2cc4ba 100644 --- a/content/browser/webid/federated_auth_request_impl_unittest.cc +++ b/content/browser/webid/federated_auth_request_impl_unittest.cc
@@ -4246,4 +4246,40 @@ FederatedAuthRequestImpl::ShouldMediateAuthz({"profile", "email"})); } +class FederatedAuthRequestImplNewTabTest : public FederatedAuthRequestImplTest { + protected: + void SetUp() override { + RenderViewHostImplTestHarness::SetUp(); + test_api_permission_delegate_ = + std::make_unique<TestApiPermissionDelegate>(); + test_permission_delegate_ = std::make_unique<TestPermissionDelegate>(); + test_auto_reauthn_permission_delegate_ = + std::make_unique<TestAutoReauthnPermissionDelegate>(); + test_identity_registry_ = std::make_unique<TestIdentityRegistry>( + web_contents(), federated_auth_request_impl_, + url::Origin::Create(GURL(kIdpUrl))); + + static_cast<TestWebContents*>(web_contents()) + ->NavigateAndCommit(GURL("chrome://newtab/"), ui::PAGE_TRANSITION_LINK); + + federated_auth_request_impl_ = &FederatedAuthRequestImpl::CreateForTesting( + *main_test_rfh(), test_api_permission_delegate_.get(), + test_auto_reauthn_permission_delegate_.get(), + test_permission_delegate_.get(), test_identity_registry_.get(), + request_remote_.BindNewPipeAndPassReceiver()); + + std::unique_ptr<TestIdpNetworkRequestManager> network_request_manager = + std::make_unique<TestIdpNetworkRequestManager>(); + SetNetworkRequestManager(std::move(network_request_manager)); + + federated_auth_request_impl_->SetTokenRequestDelayForTests( + base::TimeDelta()); + } +}; + +TEST_F(FederatedAuthRequestImplNewTabTest, SuccessfulFlow) { + RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, + kConfigurationValid); +} + } // namespace content
diff --git a/device/bluetooth/floss/bluetooth_adapter_floss.cc b/device/bluetooth/floss/bluetooth_adapter_floss.cc index 695b074e..e5c698d 100644 --- a/device/bluetooth/floss/bluetooth_adapter_floss.cc +++ b/device/bluetooth/floss/bluetooth_adapter_floss.cc
@@ -835,6 +835,32 @@ BLUETOOTH_LOG(EVENT) << __func__ << device_cleared; } +void BluetoothAdapterFloss::AdapterDevicePropertyChanged( + FlossAdapterClient::BtPropertyType prop_type, + const FlossDeviceId& device) { + DCHECK(FlossDBusManager::Get()); + DCHECK(IsPresent()); + + BLUETOOTH_LOG(EVENT) << __func__ << device; + + BluetoothDeviceFloss* device_ptr = + static_cast<BluetoothDeviceFloss*>(GetDevice(device.address)); + + if (!device_ptr) { + return; + } + + switch (prop_type) { + case FlossAdapterClient::BtPropertyType::kBdName: + if (device.name.size() != 0) { + device_ptr->SetName(device.name); + NotifyDeviceChanged(device_ptr); + } + break; + default:; // Do nothing for other property types for now + } +} + void BluetoothAdapterFloss::AdapterSspRequest( const FlossDeviceId& remote_device, uint32_t cod,
diff --git a/device/bluetooth/floss/bluetooth_adapter_floss.h b/device/bluetooth/floss/bluetooth_adapter_floss.h index d13d410a8..5f93ad68 100644 --- a/device/bluetooth/floss/bluetooth_adapter_floss.h +++ b/device/bluetooth/floss/bluetooth_adapter_floss.h
@@ -273,6 +273,9 @@ void AdapterDiscoveringChanged(bool state) override; void AdapterFoundDevice(const FlossDeviceId& device_found) override; void AdapterClearedDevice(const FlossDeviceId& device_found) override; + void AdapterDevicePropertyChanged( + FlossAdapterClient::BtPropertyType prop_type, + const FlossDeviceId& device) override; void AdapterSspRequest(const FlossDeviceId& remote_device, uint32_t cod, FlossAdapterClient::BluetoothSspVariant variant,
diff --git a/device/bluetooth/floss/floss_adapter_client.cc b/device/bluetooth/floss/floss_adapter_client.cc index 188c498..51bf9fa 100644 --- a/device/bluetooth/floss/floss_adapter_client.cc +++ b/device/bluetooth/floss/floss_adapter_client.cc
@@ -239,6 +239,12 @@ base::BindOnce(&HandleExported, adapter::kOnDeviceCleared)); callbacks->ExportMethod( + adapter::kCallbackInterface, adapter::kOnDevicePropertiesChanged, + base::BindRepeating(&FlossAdapterClient::OnDevicePropertiesChanged, + weak_ptr_factory_.GetWeakPtr()), + base::BindOnce(&HandleExported, adapter::kOnDevicePropertiesChanged)); + + callbacks->ExportMethod( adapter::kCallbackInterface, adapter::kOnDiscoveringChanged, base::BindRepeating(&FlossAdapterClient::OnDiscoveringChanged, weak_ptr_factory_.GetWeakPtr()), @@ -435,6 +441,32 @@ std::move(response_sender).Run(dbus::Response::FromMethodCall(method_call)); } +void FlossAdapterClient::OnDevicePropertiesChanged( + dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender) { + dbus::MessageReader reader(method_call); + FlossDeviceId device; + std::vector<uint32_t> props; + + DVLOG(1) << __func__; + + if (!ReadAllDBusParams(&reader, &device, &props)) { + std::move(response_sender) + .Run(dbus::ErrorResponse::FromMethodCall( + method_call, kErrorInvalidParameters, std::string())); + return; + } + + for (auto& prop : props) { + BtPropertyType prop_type = static_cast<BtPropertyType>(prop); + for (auto& observer : observers_) { + observer.AdapterDevicePropertyChanged(prop_type, device); + } + } + + std::move(response_sender).Run(dbus::Response::FromMethodCall(method_call)); +} + void FlossAdapterClient::OnSspRequest( dbus::MethodCall* method_call, dbus::ExportedObject::ResponseSender response_sender) {
diff --git a/device/bluetooth/floss/floss_adapter_client.h b/device/bluetooth/floss/floss_adapter_client.h index f5e6898..3603804c 100644 --- a/device/bluetooth/floss/floss_adapter_client.h +++ b/device/bluetooth/floss/floss_adapter_client.h
@@ -123,6 +123,10 @@ // some amount of time ago). virtual void AdapterClearedDevice(const FlossDeviceId& device_cleared) {} + // Notification sent when a device property has changed. + virtual void AdapterDevicePropertyChanged(BtPropertyType prop_type, + const FlossDeviceId& device) {} + // Notification sent for Simple Secure Pairing. virtual void AdapterSspRequest(const FlossDeviceId& remote_device, uint32_t cod, @@ -342,6 +346,11 @@ void OnDeviceCleared(dbus::MethodCall* method_call, dbus::ExportedObject::ResponseSender response_sender); + // Handle callback |OnDevicePropertiesChanged| on exported object path. + void OnDevicePropertiesChanged( + dbus::MethodCall* method_call, + dbus::ExportedObject::ResponseSender response_sender); + // Handle callback |OnSspRequest| on exported object path. void OnSspRequest(dbus::MethodCall* method_call, dbus::ExportedObject::ResponseSender response_sender);
diff --git a/device/bluetooth/floss/floss_adapter_client_unittest.cc b/device/bluetooth/floss/floss_adapter_client_unittest.cc index ec9f12f..fd0a3156 100644 --- a/device/bluetooth/floss/floss_adapter_client_unittest.cc +++ b/device/bluetooth/floss/floss_adapter_client_unittest.cc
@@ -164,7 +164,7 @@ // Exported callback methods that we don't need to invoke. This will need // to be updated once new callbacks are added. // TODO(b/233124093): Reduce this count by 2 when SDP tests are added. - EXPECT_CALL(*exported_callbacks_.get(), ExportMethod).Times(12); + EXPECT_CALL(*exported_callbacks_.get(), ExportMethod).Times(13); // Save the method handlers of exported callbacks that we need to invoke in // test.
diff --git a/device/bluetooth/floss/floss_dbus_client.cc b/device/bluetooth/floss/floss_dbus_client.cc index 962fe61..1d0fced 100644 --- a/device/bluetooth/floss/floss_dbus_client.cc +++ b/device/bluetooth/floss/floss_dbus_client.cc
@@ -91,6 +91,7 @@ const char kOnDiscoverableChanged[] = "OnDiscoverableChanged"; const char kOnDeviceFound[] = "OnDeviceFound"; const char kOnDeviceCleared[] = "OnDeviceCleared"; +const char kOnDevicePropertiesChanged[] = "OnDevicePropertiesChanged"; const char kOnDiscoveringChanged[] = "OnDiscoveringChanged"; const char kOnSspRequest[] = "OnSspRequest"; const char kOnPinDisplay[] = "OnPinDisplay";
diff --git a/device/bluetooth/floss/floss_dbus_client.h b/device/bluetooth/floss/floss_dbus_client.h index 2199ecb..f5ad0756 100644 --- a/device/bluetooth/floss/floss_dbus_client.h +++ b/device/bluetooth/floss/floss_dbus_client.h
@@ -93,6 +93,7 @@ extern DEVICE_BLUETOOTH_EXPORT const char kOnDiscoverableChanged[]; extern DEVICE_BLUETOOTH_EXPORT const char kOnDeviceFound[]; extern DEVICE_BLUETOOTH_EXPORT const char kOnDeviceCleared[]; +extern DEVICE_BLUETOOTH_EXPORT const char kOnDevicePropertiesChanged[]; extern DEVICE_BLUETOOTH_EXPORT const char kOnDiscoveringChanged[]; extern DEVICE_BLUETOOTH_EXPORT const char kOnSspRequest[]; extern DEVICE_BLUETOOTH_EXPORT const char kOnPinDisplay[];
diff --git a/docs/mac_lld.md b/docs/mac_lld.md index fd6e9fe..f37e18b 100644 --- a/docs/mac_lld.md +++ b/docs/mac_lld.md
@@ -1,9 +1,6 @@ # LLD for Mac builds -Like on most other platforms, Chromium uses the LLD linker on iOS and macOS. -This is a recent change. If things go well, it will ship in m95, -but we might discover showstopper bugs that delay things a bit. - +Like on other platforms, Chromium uses the LLD linker on iOS and macOS. ## Background @@ -13,9 +10,9 @@ Chrome OS, Fuchsia), and it's faster than other COFF linkers (the executable file format on Windows). -LLD is currently 3-4x as fast as ld64, the macOS system linker, at linking +LLD is currently twice as fast as ld64, the macOS system linker, at linking Chromium Framework in symbol\_level=0 release builds, despite ld64 being already -fast. +fast. (Before Xcode 14.1, LLD was 6x as fast as ld64.) LLD has advantages unrelated to speed, too: @@ -47,16 +44,9 @@ ## Current status and known issues -LLD is used by default in almost all build configurations. All -tests on all bots are passing, both Intel and Arm. - -There are a few open issues: - -- LLD implements deduplication (aka "ICF"), but we don't yet - enable it in arm builds ([bug](https://crbug.com/1253924)). -- LLD doesn't yet implement call graph profile sort. -- LTO support in LLD/macOS isn't complete yet, and we don't use LTO - on macOS yet for that reason. +LLD is used by default in all build configurations. +All tests on all bots are passing, both Intel and Arm. +Most things even work. ## Hacking on LLD
diff --git a/gin/interceptor.h b/gin/interceptor.h index 8d2363d5..37f3258 100644 --- a/gin/interceptor.h +++ b/gin/interceptor.h
@@ -37,7 +37,7 @@ v8::Isolate* isolate); private: - raw_ptr<v8::Isolate> isolate_; + raw_ptr<v8::Isolate, LeakedDanglingUntriaged> isolate_; raw_ptr<WrappableBase> base_; }; @@ -59,7 +59,7 @@ v8::Isolate* isolate); private: - raw_ptr<v8::Isolate> isolate_; + raw_ptr<v8::Isolate, LeakedDanglingUntriaged> isolate_; raw_ptr<WrappableBase> base_; };
diff --git a/gpu/command_buffer/service/shared_context_state.cc b/gpu/command_buffer/service/shared_context_state.cc index d65f291b..3e2f4bc 100644 --- a/gpu/command_buffer/service/shared_context_state.cc +++ b/gpu/command_buffer/service/shared_context_state.cc
@@ -252,8 +252,8 @@ crash_key.Set( base::StringPrintf("%u", static_cast<uint32_t>(gr_context_type_))); - if (gpu_preferences.gr_context_type == GrContextType::kGraphiteDawn || - gpu_preferences.gr_context_type == GrContextType::kGraphiteMetal) { + if (gr_context_type_ == GrContextType::kGraphiteDawn || + gr_context_type_ == GrContextType::kGraphiteMetal) { return InitializeGraphite(gpu_preferences); }
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index e6c1d817..c1b21a2 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -56125,7 +56125,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -56215,7 +56215,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -56491,7 +56491,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -56581,7 +56581,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -56835,7 +56835,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -57111,7 +57111,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -57298,7 +57298,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -57470,7 +57470,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -57560,7 +57560,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -57650,7 +57650,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -57741,7 +57741,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -57831,7 +57831,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -57921,7 +57921,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -58011,7 +58011,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -58192,7 +58192,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -58282,7 +58282,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -58372,7 +58372,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -58462,7 +58462,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe {
diff --git a/infra/config/lib/linux-default.json b/infra/config/lib/linux-default.json index fdee148..99921aa 100644 --- a/infra/config/lib/linux-default.json +++ b/infra/config/lib/linux-default.json
@@ -96,11 +96,29 @@ "win11-wpt-content-shell-fyi-rel": "Ubuntu-22.04" }, "try": { + "android-11-x86-rel": "Ubuntu-22.04", + "android-12-x64-dbg": "Ubuntu-22.04", "android-12-x64-rel": "Ubuntu-22.04", "android-12-x64-rel-compilator": "Ubuntu-22.04", + "android-12l-x64-dbg": "Ubuntu-22.04", + "android-13-x64-rel": "Ubuntu-22.04", + "android-arm64-all-targets-dbg": "Ubuntu-22.04", "android-arm64-rel": "Ubuntu-22.04", "android-arm64-rel-compilator": "Ubuntu-22.04", + "android-bfcache-rel": "Ubuntu-22.04", "android-binary-size": "Ubuntu-22.04", + "android-chrome-pie-x86-wpt-fyi-rel": "Ubuntu-22.04", + "android-code-coverage": "Ubuntu-22.04", + "android-code-coverage-native": "Ubuntu-22.04", + "android-cronet-arm-dbg": "Ubuntu-22.04", + "android-cronet-arm64-dbg": "Ubuntu-22.04", + "android-cronet-arm64-rel": "Ubuntu-22.04", + "android-cronet-asan-arm-rel": "Ubuntu-22.04", + "android-cronet-x86-dbg": "Ubuntu-22.04", + "android-cronet-x86-dbg-11-tests": "Ubuntu-22.04", + "android-cronet-x86-dbg-oreo-tests": "Ubuntu-22.04", + "android-cronet-x86-dbg-pie-tests": "Ubuntu-22.04", + "android-cronet-x86-rel": "Ubuntu-22.04", "android-nougat-x86-rel": "Ubuntu-22.04", "android-x64-cast": "Ubuntu-22.04", "android_compile_dbg": "Ubuntu-22.04",
diff --git a/ios/chrome/app/application_delegate/metrics_mediator.mm b/ios/chrome/app/application_delegate/metrics_mediator.mm index a9b565ca5..d78b141 100644 --- a/ios/chrome/app/application_delegate/metrics_mediator.mm +++ b/ios/chrome/app/application_delegate/metrics_mediator.mm
@@ -317,30 +317,30 @@ + (void)recordInactiveTabsSettingsAtStartup:(int)preference; // Logs the number of active tabs (based on the arm's definition of // active/inactive). -+ (void)recordNumActiveTabAtStartup:(int)numTabs; ++ (void)recordStartupActiveTabCount:(int)tabCount; // Logs the number of inactive tabs (based on the arm's definition of // active/inactive). -+ (void)recordNumInactiveTabAtStartup:(int)numTabs; ++ (void)recordStartupInactiveTabCount:(int)tabCount; // Logs the number of tabs older than 21 days. -+ (void)recordNumAbsoluteInactiveTabAtStartup:(int)numTabs; ++ (void)recordStartupAbsoluteInactiveTabCount:(int)tabCount; // Logs the number of tabs with UMAHistogramCount100 and allows testing. -+ (void)recordNumTabAtStartup:(int)numTabs; ++ (void)recordStartupTabCount:(int)tabCount; // Logs the number of tabs with UMAHistogramCount100 and allows testing. -+ (void)recordNumTabAtResume:(int)numTabs; ++ (void)recordResumeTabCount:(int)tabCount; // Logs the number of NTP tabs with UMAHistogramCount100 and allows testing. -+ (void)recordNumNTPTabAtStartup:(int)numTabs; ++ (void)recordStartupNTPTabCount:(int)tabCount; // Logs the number of NTP tabs with UMAHistogramCount100 and allows testing. -+ (void)recordNumNTPTabAtResume:(int)numTabs; ++ (void)recordResumeNTPTabCount:(int)tabCount; // Logs the number of live NTP tabs with UMAHistogramCount100 and allows // testing. -+ (void)recordNumLiveNTPTabAtResume:(int)numTabs; ++ (void)recordResumeLiveNTPTabCount:(int)tabCount; // Logs the number of old (inactive for more than 7 days) tabs with // UMAHistogramCount100 and allows testing. -+ (void)recordNumOldTabAtStartup:(int)numTabs; ++ (void)recordStartupOldTabCount:(int)tabCount; // Logs the number of duplicated tabs with UMAHistogramCount100 and allows // testing. -+ (void)recordNumDuplicatedTabAtStartup:(int)numTabs; ++ (void)recordStartupDuplicatedTabCount:(int)tabCount; // Logs the age (time elapsed since creation) of each tab and allows testing. + (void)recordTabsAgeAtStartup:(const std::vector<base::TimeDelta>&)tabsAge; // Returns a corresponding TabAgeGroup for provided `timeSinceCreation` time. @@ -412,14 +412,14 @@ connectedScenes:(NSArray<SceneState*>*)scenes { RecordAndResetUkmLogSizeOnSuccessCounter(); - int numTabs = 0; - int numNTPTabs = 0; - int numLiveNTPTabs = 0; - int numOldTabs = 0; - int numDuplicatedTabs = 0; - int numActiveTabs = 0; - int numInactiveTabs = 0; - int numAbsoluteInactiveTabs = 0; + int tabCount = 0; + int NTPTabCount = 0; + int liveNTPTabCount = 0; + int oldTabCount = 0; + int duplicatedTabCount = 0; + int activeTabCount = 0; + int inactiveTabCount = 0; + int absoluteInactiveTabCount = 0; // Amount of time after which a tab is considered as old. constexpr base::TimeDelta kOldTabThreshold = base::Days(7); @@ -448,11 +448,11 @@ const int webStateListCount = webStateList->count(); const int inactiveWebStateListCount = inactiveWebStateList->count(); - numTabs += webStateListCount + inactiveWebStateListCount; - numActiveTabs += webStateListCount; - numInactiveTabs += inactiveWebStateListCount; + tabCount += webStateListCount + inactiveWebStateListCount; + activeTabCount += webStateListCount; + inactiveTabCount += inactiveWebStateListCount; // All inactive tabs are inactive since minimum 7 days or more. - numOldTabs += inactiveWebStateListCount; + oldTabCount += inactiveWebStateListCount; for (int i = 0; i < webStateListCount; i++) { web::WebState* webState = webStateList->GetWebStateAt(i); @@ -461,13 +461,13 @@ // Count NTPs. if (IsURLNewTabPage(URL)) { - numNTPTabs++; + NTPTabCount++; } // Count duplicate URLs. NSString* URLString = base::SysUTF8ToNSString(URL.GetWithoutRef().spec()); if ([uniqueURLs containsObject:URLString]) { - numDuplicatedTabs++; + duplicatedTabCount++; } else { [uniqueURLs addObject:URLString]; } @@ -475,10 +475,10 @@ // Count old tabs. base::TimeDelta inactiveTime = now - webState->GetLastActiveTime(); if (inactiveTime > kOldTabThreshold) { - numOldTabs++; + oldTabCount++; // Count absolute inactive tabs. if (inactiveTime > kAbsoluteInactiveTabThreshold) { - numAbsoluteInactiveTabs++; + absoluteInactiveTabCount++; } } @@ -500,7 +500,7 @@ base::TimeDelta inactiveTime = base::Time::Now() - webState->GetLastActiveTime(); if (inactiveTime > kAbsoluteInactiveTabThreshold) { - numAbsoluteInactiveTabs++; + absoluteInactiveTabCount++; } } } @@ -509,19 +509,19 @@ [self recordInactiveTabsSettingsAtStartup: GetApplicationContext()->GetLocalState()->GetInteger( prefs::kInactiveTabsTimeThreshold)]; - [self recordNumActiveTabAtStartup:numActiveTabs]; - [self recordNumInactiveTabAtStartup:numInactiveTabs]; - [self recordNumAbsoluteInactiveTabAtStartup:numAbsoluteInactiveTabs]; - [self recordNumTabAtStartup:numTabs]; - [self recordNumNTPTabAtStartup:numNTPTabs]; - [self recordNumOldTabAtStartup:numOldTabs]; - [self recordNumDuplicatedTabAtStartup:numDuplicatedTabs]; + [self recordStartupActiveTabCount:activeTabCount]; + [self recordStartupInactiveTabCount:inactiveTabCount]; + [self recordStartupAbsoluteInactiveTabCount:absoluteInactiveTabCount]; + [self recordStartupTabCount:tabCount]; + [self recordStartupNTPTabCount:NTPTabCount]; + [self recordStartupOldTabCount:oldTabCount]; + [self recordStartupDuplicatedTabCount:duplicatedTabCount]; [self recordTabsAgeAtStartup:timesSinceCreation]; } else { - [self recordNumTabAtResume:numTabs]; - [self recordNumNTPTabAtResume:numNTPTabs]; + [self recordResumeTabCount:tabCount]; + [self recordResumeNTPTabCount:NTPTabCount]; // Only log at resume since there are likely no live NTPs on startup. - [self recordNumLiveNTPTabAtResume:numLiveNTPTabs]; + [self recordResumeLiveNTPTabCount:liveNTPTabCount]; } if (UIAccessibilityIsVoiceOverRunning()) { @@ -729,44 +729,44 @@ InactiveTabsSettingFromPreference(preference)); } -+ (void)recordNumActiveTabAtStartup:(int)numTabs { - base::UmaHistogramCounts100("Tabs.ActiveCountAtStartup", numTabs); ++ (void)recordStartupActiveTabCount:(int)tabCount { + base::UmaHistogramCounts100("Tabs.ActiveCountAtStartup", tabCount); } -+ (void)recordNumInactiveTabAtStartup:(int)numTabs { - base::UmaHistogramCounts100("Tabs.InactiveCountAtStartup", numTabs); ++ (void)recordStartupInactiveTabCount:(int)tabCount { + base::UmaHistogramCounts100("Tabs.InactiveCountAtStartup", tabCount); } -+ (void)recordNumAbsoluteInactiveTabAtStartup:(int)numTabs { - base::UmaHistogramCounts100("Tabs.OldCountAtStartup", numTabs); ++ (void)recordStartupAbsoluteInactiveTabCount:(int)tabCount { + base::UmaHistogramCounts100("Tabs.OldCountAtStartup", tabCount); } -+ (void)recordNumTabAtStartup:(int)numTabs { - base::UmaHistogramCounts100("Tabs.CountAtStartup", numTabs); ++ (void)recordStartupTabCount:(int)tabCount { + base::UmaHistogramCounts100("Tabs.CountAtStartup", tabCount); } -+ (void)recordNumTabAtResume:(int)numTabs { - base::UmaHistogramCounts100("Tabs.CountAtResume", numTabs); ++ (void)recordResumeTabCount:(int)tabCount { + base::UmaHistogramCounts100("Tabs.CountAtResume", tabCount); } -+ (void)recordNumNTPTabAtStartup:(int)numTabs { - base::UmaHistogramCounts100("Tabs.NTPCountAtStartup", numTabs); ++ (void)recordStartupNTPTabCount:(int)tabCount { + base::UmaHistogramCounts100("Tabs.NTPCountAtStartup", tabCount); } -+ (void)recordNumNTPTabAtResume:(int)numTabs { - base::UmaHistogramCounts100("Tabs.NTPCountAtResume", numTabs); ++ (void)recordResumeNTPTabCount:(int)tabCount { + base::UmaHistogramCounts100("Tabs.NTPCountAtResume", tabCount); } -+ (void)recordNumLiveNTPTabAtResume:(int)numTabs { - base::UmaHistogramCounts100("Tabs.LiveNTPCountAtResume", numTabs); ++ (void)recordResumeLiveNTPTabCount:(int)tabCount { + base::UmaHistogramCounts100("Tabs.LiveNTPCountAtResume", tabCount); } -+ (void)recordNumOldTabAtStartup:(int)numTabs { - base::UmaHistogramCounts100("Tabs.UnusedCountAtStartup", numTabs); ++ (void)recordStartupOldTabCount:(int)tabCount { + base::UmaHistogramCounts100("Tabs.UnusedCountAtStartup", tabCount); } -+ (void)recordNumDuplicatedTabAtStartup:(int)numTabs { - base::UmaHistogramCounts100("Tabs.DuplicatesCountAtStartup", numTabs); ++ (void)recordStartupDuplicatedTabCount:(int)tabCount { + base::UmaHistogramCounts100("Tabs.DuplicatesCountAtStartup", tabCount); } + (void)recordTabsAgeAtStartup:(const std::vector<base::TimeDelta>&)tabsAge {
diff --git a/ios/chrome/app/application_delegate/metrics_mediator_testing.h b/ios/chrome/app/application_delegate/metrics_mediator_testing.h index 6bd97b5..9b56af25 100644 --- a/ios/chrome/app/application_delegate/metrics_mediator_testing.h +++ b/ios/chrome/app/application_delegate/metrics_mediator_testing.h
@@ -8,11 +8,11 @@ #include "net/base/network_change_notifier.h" @interface MetricsMediator (TestingAddition) -+ (void)recordNumTabAtStartup:(int)numTabs; -+ (void)recordNumTabAtResume:(int)numTabs; -+ (void)recordNumNTPTabAtStartup:(int)numTabs; -+ (void)recordNumNTPTabAtResume:(int)numTabs; -+ (void)recordNumLiveNTPTabAtResume:(int)numTabs; ++ (void)recordStartupTabCount:(int)tabCount; ++ (void)recordResumeTabCount:(int)tabCount; ++ (void)recordStartupNTPTabCount:(int)tabCount; ++ (void)recordResumeNTPTabCount:(int)tabCount; ++ (void)recordResumeLiveNTPTabCount:(int)tabCount; @end #endif // IOS_CHROME_APP_APPLICATION_DELEGATE_METRICS_MEDIATOR_TESTING_H_
diff --git a/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm b/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm index 98b1b09..7bbbc03 100644 --- a/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm +++ b/ios/chrome/app/application_delegate/metrics_mediator_unittest.mm
@@ -128,20 +128,20 @@ } copy]; if (coldStart) { tabs_uma_histogram_swizzler_.reset(new ScopedBlockSwizzler( - [MetricsMediator class], @selector(recordNumTabAtStartup:), + [MetricsMediator class], @selector(recordStartupTabCount:), num_tabs_swizzle_block_)); ntp_tabs_uma_histogram_swizzler_.reset(new ScopedBlockSwizzler( - [MetricsMediator class], @selector(recordNumNTPTabAtStartup:), + [MetricsMediator class], @selector(recordStartupNTPTabCount:), num_ntp_tabs_swizzle_block_)); } else { tabs_uma_histogram_swizzler_.reset(new ScopedBlockSwizzler( - [MetricsMediator class], @selector(recordNumTabAtResume:), + [MetricsMediator class], @selector(recordResumeTabCount:), num_tabs_swizzle_block_)); ntp_tabs_uma_histogram_swizzler_.reset(new ScopedBlockSwizzler( - [MetricsMediator class], @selector(recordNumNTPTabAtResume:), + [MetricsMediator class], @selector(recordResumeNTPTabCount:), num_ntp_tabs_swizzle_block_)); live_ntp_tabs_uma_histogram_swizzler_.reset(new ScopedBlockSwizzler( - [MetricsMediator class], @selector(recordNumLiveNTPTabAtResume:), + [MetricsMediator class], @selector(recordResumeLiveNTPTabCount:), num_live_ntp_tabs_swizzle_block_)); } }
diff --git a/ios/chrome/browser/crash_report/crash_report_helper.mm b/ios/chrome/browser/crash_report/crash_report_helper.mm index 4272182..4003504 100644 --- a/ios/chrome/browser/crash_report/crash_report_helper.mm +++ b/ios/chrome/browser/crash_report/crash_report_helper.mm
@@ -160,19 +160,26 @@ #pragma mark - WebStateListObserving protocol +- (void)didChangeWebStateList:(WebStateList*)webStateList + change:(const WebStateListChange&)change + selection:(const WebStateSelection&)selection { + switch (change.type()) { + case WebStateListChange::Type::kReplace: { + const WebStateListChangeReplace& replaceChange = + change.As<WebStateListChangeReplace>(); + [self removeTabId:replaceChange.replaced_web_state() + ->GetStableIdentifier()]; + break; + } + } +} + - (void)webStateList:(WebStateList*)webStateList didDetachWebState:(web::WebState*)webState atIndex:(int)atIndex { [self removeTabId:webState->GetStableIdentifier()]; } -- (void)webStateList:(WebStateList*)webStateList - didReplaceWebState:(web::WebState*)oldWebState - withWebState:(web::WebState*)newWebState - atIndex:(int)atIndex { - [self removeTabId:oldWebState->GetStableIdentifier()]; -} - #pragma mark - CRWWebStateObserver protocol - (void)webState:(web::WebState*)webState
diff --git a/ios/chrome/browser/flags/BUILD.gn b/ios/chrome/browser/flags/BUILD.gn index ca5638f..10569bd 100644 --- a/ios/chrome/browser/flags/BUILD.gn +++ b/ios/chrome/browser/flags/BUILD.gn
@@ -85,6 +85,7 @@ "//ios/chrome/browser/ui/post_restore_signin:features", "//ios/chrome/browser/ui/start_surface:feature_flags", "//ios/chrome/browser/ui/whats_new:feature_flags", + "//ios/chrome/browser/ui/whats_new:util", "//ios/chrome/browser/web:feature_flags", "//ios/components/security_interstitials/https_only_mode:feature", "//ios/public/provider/chrome/browser/app_utils:app_utils_api",
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 5e7462c..e1a5f696 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -98,6 +98,7 @@ #import "ios/chrome/browser/ui/post_restore_signin/features.h" #import "ios/chrome/browser/ui/start_surface/start_surface_features.h" #import "ios/chrome/browser/ui/whats_new/feature_flags.h" +#import "ios/chrome/browser/ui/whats_new/whats_new_util.h" #import "ios/chrome/browser/web/features.h" #import "ios/chrome/grit/ios_strings.h" #import "ios/components/security_interstitials/https_only_mode/feature.h" @@ -1238,6 +1239,9 @@ FEATURE_WITH_PARAMS_VALUE_TYPE(kWhatsNewIOS, kWhatsNewLayoutVariations, "WhatsNewLayoutVariations")}, + {"whats-new-ios-m116", flag_descriptions::kWhatsNewIOSM116Name, + flag_descriptions::kWhatsNewIOSM116Description, flags_ui::kOsIos, + FEATURE_VALUE_TYPE(kWhatsNewIOSM116)}, {"ios-autofill-branding", flag_descriptions::kAutofillBrandingIOSName, flag_descriptions::kAutofillBrandingIOSDescription, flags_ui::kOsIos, FEATURE_WITH_PARAMS_VALUE_TYPE(autofill::features::kAutofillBrandingIOS,
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index 042b2b6..241bc89 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -1091,6 +1091,10 @@ const char kWhatsNewIOSDescription[] = "When enabled, What's New will display new features and chrome tips."; +const char kWhatsNewIOSM116Name[] = "Enable What's New M116."; +const char kWhatsNewIOSM116Description[] = + "When enabled, What's New will display new features and a chrome tip."; + // Please insert your name/description above in alphabetical order. } // namespace flag_descriptions
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index ecafc21..9b12de4 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -956,6 +956,10 @@ extern const char kWhatsNewIOSName[]; extern const char kWhatsNewIOSDescription[]; +// Title and description for the flag to enable What's New version 2. +extern const char kWhatsNewIOSM116Name[]; +extern const char kWhatsNewIOSM116Description[]; + // Please add names and descriptions above in alphabetical order. } // namespace flag_descriptions
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/BUILD.gn b/ios/chrome/browser/infobars/overlays/browser_agent/BUILD.gn index d6f615ca..3d6a9d02 100644 --- a/ios/chrome/browser/infobars/overlays/browser_agent/BUILD.gn +++ b/ios/chrome/browser/infobars/overlays/browser_agent/BUILD.gn
@@ -34,9 +34,7 @@ "//components/safe_browsing/core/common", "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/autofill_address_profile", "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/confirm", - "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card", "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/sync_error", - "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/tailored_security", "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/translate", "//ios/chrome/browser/overlays/public/infobar_banner", "//ios/chrome/browser/shared/model/browser",
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/infobar_overlay_browser_agent_util.mm b/ios/chrome/browser/infobars/overlays/browser_agent/infobar_overlay_browser_agent_util.mm index 6c1afa3..1308d2e 100644 --- a/ios/chrome/browser/infobars/overlays/browser_agent/infobar_overlay_browser_agent_util.mm +++ b/ios/chrome/browser/infobars/overlays/browser_agent/infobar_overlay_browser_agent_util.mm
@@ -10,13 +10,9 @@ #import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/autofill_address_profile/save_address_profile_infobar_banner_interaction_handler.h" #import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/autofill_address_profile/save_address_profile_infobar_modal_interaction_handler.h" #import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/confirm/confirm_infobar_banner_interaction_handler.h" -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_interaction_handler.h" -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_interaction_handler.h" #import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/sync_error/sync_error_infobar_banner_interaction_handler.h" -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/tailored_security/tailored_security_infobar_banner_interaction_handler.h" #import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/translate/translate_infobar_banner_interaction_handler.h" #import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/translate/translate_infobar_modal_interaction_handler.h" -#import "ios/chrome/browser/overlays/public/infobar_banner/tailored_security_service_infobar_banner_overlay_request_config.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -27,10 +23,18 @@ InfobarOverlayBrowserAgent* browser_agent = InfobarOverlayBrowserAgent::FromBrowser(browser); + if (base::FeatureList::IsEnabled( + safe_browsing::kTailoredSecurityIntegration)) { + browser_agent->AddDefaultInfobarInteractionHandlerForInfobarType( + InfobarType::kInfobarTypeTailoredSecurityService); + } + browser_agent->AddDefaultInfobarInteractionHandlerForInfobarType( InfobarType::kInfobarTypePasswordSave); browser_agent->AddDefaultInfobarInteractionHandlerForInfobarType( InfobarType::kInfobarTypePasswordUpdate); + browser_agent->AddDefaultInfobarInteractionHandlerForInfobarType( + InfobarType::kInfobarTypeSaveCard); browser_agent->AddInfobarInteractionHandler( std::make_unique<InfobarInteractionHandler>( @@ -42,11 +46,6 @@ InfobarType::kInfobarTypeTranslate, std::make_unique<TranslateInfobarBannerInteractionHandler>(), std::make_unique<TranslateInfobarModalInteractionHandler>())); - browser_agent->AddInfobarInteractionHandler( - std::make_unique<InfobarInteractionHandler>( - InfobarType::kInfobarTypeSaveCard, - std::make_unique<SaveCardInfobarBannerInteractionHandler>(), - std::make_unique<SaveCardInfobarModalInteractionHandler>())); browser_agent->AddInfobarInteractionHandler(std::make_unique< InfobarInteractionHandler>( InfobarType::kInfobarTypeSaveAutofillAddressProfile, @@ -59,17 +58,4 @@ InfobarType::kInfobarTypeSyncError, std::make_unique<SyncErrorInfobarBannerInteractionHandler>(), /*modal_handler=*/nullptr)); - - if (base::FeatureList::IsEnabled( - safe_browsing::kTailoredSecurityIntegration)) { - const OverlayRequestSupport* support = - tailored_security_service_infobar_overlays:: - TailoredSecurityServiceBannerRequestConfig::RequestSupport(); - browser_agent->AddInfobarInteractionHandler( - std::make_unique<InfobarInteractionHandler>( - InfobarType::kInfobarTypeTailoredSecurityService, - std::make_unique<TailoredSecurityInfobarBannerInteractionHandler>( - support), - nil)); - } }
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/BUILD.gn b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/BUILD.gn deleted file mode 100644 index f3a1d30..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/BUILD.gn +++ /dev/null
@@ -1,65 +0,0 @@ -# Copyright 2020 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -source_set("save_card") { - configs += [ "//build/config/compiler:enable_arc" ] - sources = [ - "save_card_infobar_banner_interaction_handler.h", - "save_card_infobar_banner_interaction_handler.mm", - "save_card_infobar_banner_overlay_request_callback_installer.h", - "save_card_infobar_banner_overlay_request_callback_installer.mm", - "save_card_infobar_modal_interaction_handler.h", - "save_card_infobar_modal_interaction_handler.mm", - "save_card_infobar_modal_overlay_request_callback_installer.h", - "save_card_infobar_modal_overlay_request_callback_installer.mm", - ] - deps = [ - "//base", - "//components/autofill/core/browser", - "//ios/chrome/browser/infobars", - "//ios/chrome/browser/infobars:public", - "//ios/chrome/browser/infobars/overlays", - "//ios/chrome/browser/infobars/overlays:util", - "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers", - "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common", - "//ios/chrome/browser/overlays", - "//ios/chrome/browser/overlays/public/infobar_banner", - "//ios/chrome/browser/overlays/public/infobar_modal", - "//ios/chrome/browser/shared/model/browser", - "//ios/chrome/browser/shared/model/web_state_list", - ] -} - -source_set("unit_tests") { - configs += [ "//build/config/compiler:enable_arc" ] - testonly = true - sources = [ - "save_card_infobar_banner_interaction_handler_unittest.mm", - "save_card_infobar_banner_overlay_request_callback_installer_unittest.mm", - "save_card_infobar_modal_interaction_handler_unittest.mm", - "save_card_infobar_modal_overlay_request_callback_installer_unittest.mm", - ] - deps = [ - ":save_card", - "//base/test:test_support", - "//components/autofill/core/browser:test_support", - "//components/prefs", - "//ios/chrome/browser/infobars", - "//ios/chrome/browser/infobars/overlays", - "//ios/chrome/browser/infobars/overlays:util", - "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common", - "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test", - "//ios/chrome/browser/infobars/test", - "//ios/chrome/browser/overlays", - "//ios/chrome/browser/overlays/public/common", - "//ios/chrome/browser/overlays/public/infobar_banner", - "//ios/chrome/browser/overlays/public/infobar_modal", - "//ios/chrome/browser/overlays/test", - "//ios/chrome/browser/shared/model/browser/test:test_support", - "//ios/chrome/browser/shared/model/web_state_list", - "//ios/chrome/browser/ui/infobars/test", - "//ios/web/public/test/fakes", - "//testing/gtest", - ] -}
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_interaction_handler.h b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_interaction_handler.h deleted file mode 100644 index 6a3bbaa..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_interaction_handler.h +++ /dev/null
@@ -1,48 +0,0 @@ -// Copyright 2020 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_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_SAVE_CARD_SAVE_CARD_INFOBAR_BANNER_INTERACTION_HANDLER_H_ -#define IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_SAVE_CARD_SAVE_CARD_INFOBAR_BANNER_INTERACTION_HANDLER_H_ - -#include <string.h> - -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common/infobar_banner_interaction_handler.h" - -class InfobarBannerOverlayRequestCallbackInstaller; - -namespace autofill { -class AutofillSaveCardInfoBarDelegateMobile; -} - -// Helper object that updates the model layer for interaction events with the -// SaveCard infobar banner UI. -class SaveCardInfobarBannerInteractionHandler - : public InfobarBannerInteractionHandler { - public: - SaveCardInfobarBannerInteractionHandler(); - ~SaveCardInfobarBannerInteractionHandler() override; - - // Instructs the handler to update the credentials with `cardholder_name`, - // `expiration_date_month`, and `expiration_date_year`. This replaces - // MainButtonTapped. - virtual void SaveCredentials(InfoBarIOS* infobar, - std::u16string cardholder_name, - std::u16string expiration_date_month, - std::u16string expiration_date_year); - - // Overrides InfobarBannerInteractionHandler implementation because a banner - // dismissal should not call InfoBarDismissed(); - void BannerDismissedByUser(InfoBarIOS* infobar) override {} - - private: - // InfobarBannerInteractionHandler: - std::unique_ptr<InfobarBannerOverlayRequestCallbackInstaller> - CreateBannerInstaller() override; - - // Returns the SaveCard delegate from `infobar`. - autofill::AutofillSaveCardInfoBarDelegateMobile* GetInfobarDelegate( - InfoBarIOS* infobar); -}; - -#endif // IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_SAVE_CARD_SAVE_CARD_INFOBAR_BANNER_INTERACTION_HANDLER_H_
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_interaction_handler.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_interaction_handler.mm deleted file mode 100644 index d8ce553..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_interaction_handler.mm +++ /dev/null
@@ -1,58 +0,0 @@ -// Copyright 2020 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/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_interaction_handler.h" - -#import "base/check.h" -#import "components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.h" -#import "ios/chrome/browser/infobars/infobar_ios.h" -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_overlay_request_callback_installer.h" -#import "ios/chrome/browser/infobars/overlays/infobar_overlay_request_cancel_handler.h" -#import "ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter.h" -#import "ios/chrome/browser/overlays/public/infobar_banner/save_card_infobar_banner_overlay_request_config.h" -#import "ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_request_config.h" -#import "ios/chrome/browser/overlays/public/overlay_request_queue.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -using save_card_infobar_overlays::SaveCardBannerRequestConfig; - -#pragma mark - InfobarBannerInteractionHandler - -SaveCardInfobarBannerInteractionHandler:: - SaveCardInfobarBannerInteractionHandler() - : InfobarBannerInteractionHandler( - SaveCardBannerRequestConfig::RequestSupport()) {} - -SaveCardInfobarBannerInteractionHandler:: - ~SaveCardInfobarBannerInteractionHandler() = default; - -void SaveCardInfobarBannerInteractionHandler::SaveCredentials( - InfoBarIOS* infobar, - std::u16string cardholder_name, - std::u16string expiration_date_month, - std::u16string expiration_date_year) { - infobar->set_accepted(GetInfobarDelegate(infobar)->UpdateAndAccept( - cardholder_name, expiration_date_month, expiration_date_year)); -} - -#pragma mark - Private - -std::unique_ptr<InfobarBannerOverlayRequestCallbackInstaller> -SaveCardInfobarBannerInteractionHandler::CreateBannerInstaller() { - return std::make_unique<SaveCardInfobarBannerOverlayRequestCallbackInstaller>( - this); -} - -autofill::AutofillSaveCardInfoBarDelegateMobile* -SaveCardInfobarBannerInteractionHandler::GetInfobarDelegate( - InfoBarIOS* infobar) { - autofill::AutofillSaveCardInfoBarDelegateMobile* delegate = - autofill::AutofillSaveCardInfoBarDelegateMobile::FromInfobarDelegate( - infobar->delegate()); - DCHECK(delegate); - return delegate; -}
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_interaction_handler_unittest.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_interaction_handler_unittest.mm deleted file mode 100644 index 8d23b919..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_interaction_handler_unittest.mm +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2020 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/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_interaction_handler.h" - -#import "base/strings/sys_string_conversions.h" -#import "base/uuid.h" -#import "components/autofill/core/browser/autofill_test_utils.h" -#import "components/autofill/core/browser/data_model/credit_card.h" -#import "ios/chrome/browser/infobars/infobar_ios.h" -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common/infobar_banner_interaction_handler.h" -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_autofill_save_card_infobar_delegate_mobile.h" -#import "testing/platform_test.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -// Test fixture for SaveCardInfobarBannerInteractionHandler. -class SaveCardInfobarBannerInteractionHandlerTest : public PlatformTest { - public: - SaveCardInfobarBannerInteractionHandlerTest() - : delegate_factory_(), - card_(base::Uuid::GenerateRandomV4().AsLowercaseString(), - "https://www.example.com/") { - infobar_ = std::make_unique<InfoBarIOS>( - InfobarType::kInfobarTypeSaveCard, - MockAutofillSaveCardInfoBarDelegateMobileFactory:: - CreateMockAutofillSaveCardInfoBarDelegateMobileFactory(false, - card_)); - } - - MockAutofillSaveCardInfoBarDelegateMobile& mock_delegate() { - return *static_cast<MockAutofillSaveCardInfoBarDelegateMobile*>( - infobar_->delegate()); - } - - protected: - SaveCardInfobarBannerInteractionHandler handler_; - MockAutofillSaveCardInfoBarDelegateMobileFactory delegate_factory_; - autofill::CreditCard card_; - std::unique_ptr<InfoBarIOS> infobar_; -}; - -TEST_F(SaveCardInfobarBannerInteractionHandlerTest, SaveCredentials) { - std::u16string cardholder_name = base::SysNSStringToUTF16(@"test name"); - std::u16string expiration_date_month = base::SysNSStringToUTF16(@"06"); - std::u16string expiration_date_year = base::SysNSStringToUTF16(@"2023"); - EXPECT_CALL(mock_delegate(), - UpdateAndAccept(cardholder_name, expiration_date_month, - expiration_date_year)); - handler_.SaveCredentials(infobar_.get(), cardholder_name, - expiration_date_month, expiration_date_year); -} - -// Test that dismissing the banner does not call -// InfobarDelegate::InfobarDismissed(), which is a behavior for the other -// Infobars. -TEST_F(SaveCardInfobarBannerInteractionHandlerTest, DismissalNoDelegateCall) { - EXPECT_CALL(mock_delegate(), InfoBarDismissed()).Times(0); - handler_.BannerDismissedByUser(infobar_.get()); -}
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_overlay_request_callback_installer.h b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_overlay_request_callback_installer.h deleted file mode 100644 index 06e42a7..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_overlay_request_callback_installer.h +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2020 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_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_SAVE_CARD_SAVE_CARD_INFOBAR_BANNER_OVERLAY_REQUEST_CALLBACK_INSTALLER_H_ -#define IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_SAVE_CARD_SAVE_CARD_INFOBAR_BANNER_OVERLAY_REQUEST_CALLBACK_INSTALLER_H_ - -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common/infobar_banner_overlay_request_callback_installer.h" - -class SaveCardInfobarBannerInteractionHandler; - -// Callback installer for SaveCard banner interaction events. -class SaveCardInfobarBannerOverlayRequestCallbackInstaller - : public InfobarBannerOverlayRequestCallbackInstaller { - public: - // Constructor for an instance that installs callbacks that forward - // interaction events to `interaction_handler`. - explicit SaveCardInfobarBannerOverlayRequestCallbackInstaller( - SaveCardInfobarBannerInteractionHandler* interaction_handler); - ~SaveCardInfobarBannerOverlayRequestCallbackInstaller() override; - - private: - // Used as a callback for OverlayResponses dispatched through `request`'s - // callback manager. The OverlayDispatchCallback is created with an - // OverlayResponseSupport that guarantees that `response` is created with an - // save_card_infobar_modal_responses::SaveCardMainAction. - void SaveCredentialsCallback(OverlayRequest* request, - OverlayResponse* response); - - // OverlayRequestCallbackInstaller: - void InstallCallbacksInternal(OverlayRequest* request) override; - - // The handler for received responses. - SaveCardInfobarBannerInteractionHandler* interaction_handler_ = nullptr; - - base::WeakPtrFactory<SaveCardInfobarBannerOverlayRequestCallbackInstaller> - weak_factory_{this}; -}; - -#endif // IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_SAVE_CARD_SAVE_CARD_INFOBAR_BANNER_OVERLAY_REQUEST_CALLBACK_INSTALLER_H_
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_overlay_request_callback_installer.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_overlay_request_callback_installer.mm deleted file mode 100644 index b750a2f..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_overlay_request_callback_installer.mm +++ /dev/null
@@ -1,68 +0,0 @@ -// Copyright 2020 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/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_overlay_request_callback_installer.h" - -#import "base/check.h" -#import "base/strings/sys_string_conversions.h" -#import "ios/chrome/browser/infobars/infobar_ios.h" -#import "ios/chrome/browser/infobars/infobar_manager_impl.h" -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_interaction_handler.h" -#import "ios/chrome/browser/infobars/overlays/infobar_overlay_util.h" -#import "ios/chrome/browser/overlays/public/infobar_banner/save_card_infobar_banner_overlay_request_config.h" -#import "ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_responses.h" -#import "ios/chrome/browser/overlays/public/overlay_callback_manager.h" -#import "ios/chrome/browser/overlays/public/overlay_response.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -using save_card_infobar_overlays::SaveCardMainAction; -using save_card_infobar_overlays::SaveCardBannerRequestConfig; - -SaveCardInfobarBannerOverlayRequestCallbackInstaller:: - SaveCardInfobarBannerOverlayRequestCallbackInstaller( - SaveCardInfobarBannerInteractionHandler* interaction_handler) - : InfobarBannerOverlayRequestCallbackInstaller( - SaveCardBannerRequestConfig::RequestSupport(), - interaction_handler), - interaction_handler_(interaction_handler) { - DCHECK(interaction_handler_); -} - -SaveCardInfobarBannerOverlayRequestCallbackInstaller:: - ~SaveCardInfobarBannerOverlayRequestCallbackInstaller() = default; - -#pragma mark - Private - -void SaveCardInfobarBannerOverlayRequestCallbackInstaller:: - SaveCredentialsCallback(OverlayRequest* request, - OverlayResponse* response) { - InfoBarIOS* infobar = GetOverlayRequestInfobar(request); - if (!infobar) - return; - - SaveCardMainAction* info = response->GetInfo<SaveCardMainAction>(); - interaction_handler_->SaveCredentials( - GetOverlayRequestInfobar(request), - base::SysNSStringToUTF16(info->cardholder_name()), - base::SysNSStringToUTF16(info->expiration_month()), - base::SysNSStringToUTF16(info->expiration_year())); -} - -#pragma mark - OverlayRequestCallbackInstaller - -void SaveCardInfobarBannerOverlayRequestCallbackInstaller:: - InstallCallbacksInternal(OverlayRequest* request) { - InfobarBannerOverlayRequestCallbackInstaller::InstallCallbacksInternal( - request); - OverlayCallbackManager* manager = request->GetCallbackManager(); - manager->AddDispatchCallback(OverlayDispatchCallback( - base::BindRepeating( - &SaveCardInfobarBannerOverlayRequestCallbackInstaller:: - SaveCredentialsCallback, - weak_factory_.GetWeakPtr(), request), - SaveCardMainAction::ResponseSupport())); -}
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_overlay_request_callback_installer_unittest.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_overlay_request_callback_installer_unittest.mm deleted file mode 100644 index f2d8f961..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_overlay_request_callback_installer_unittest.mm +++ /dev/null
@@ -1,98 +0,0 @@ -// Copyright 2020 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/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_overlay_request_callback_installer.h" - -#import "base/strings/sys_string_conversions.h" -#import "base/uuid.h" -#import "components/autofill/core/browser/autofill_test_utils.h" -#import "components/autofill/core/browser/data_model/credit_card.h" -#import "ios/chrome/browser/infobars/infobar_ios.h" -#import "ios/chrome/browser/infobars/infobar_manager_impl.h" -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_autofill_save_card_infobar_delegate_mobile.h" -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_save_card_banner_infobar_interaction_handler.h" -#import "ios/chrome/browser/overlays/public/infobar_banner/save_card_infobar_banner_overlay_request_config.h" -#import "ios/chrome/browser/overlays/public/infobar_modal/infobar_modal_overlay_responses.h" -#import "ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_responses.h" -#import "ios/chrome/browser/overlays/public/overlay_callback_manager.h" -#import "ios/chrome/browser/overlays/public/overlay_request.h" -#import "ios/chrome/browser/overlays/public/overlay_request_queue.h" -#import "ios/chrome/browser/overlays/public/overlay_response.h" -#import "ios/web/public/test/fakes/fake_navigation_manager.h" -#import "ios/web/public/test/fakes/fake_web_state.h" -#import "testing/gmock/include/gmock/gmock.h" -#import "testing/platform_test.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -using save_card_infobar_overlays::SaveCardBannerRequestConfig; - -// Test fixture for SaveCardInfobarBannerOverlayRequestCallbackInstaller. -class SaveCardInfobarBannerOverlayRequestCallbackInstallerTest - : public PlatformTest { - public: - SaveCardInfobarBannerOverlayRequestCallbackInstallerTest() - : card_(base::Uuid::GenerateRandomV4().AsLowercaseString(), - "https://www.example.com/"), - installer_(&mock_handler_), - delegate_factory_() { - // Create the infobar and add it to the WebState's manager. - web_state_.SetNavigationManager( - std::make_unique<web::FakeNavigationManager>()); - InfoBarManagerImpl::CreateForWebState(&web_state_); - std::unique_ptr<MockAutofillSaveCardInfoBarDelegateMobile> delegate = - delegate_factory_ - .CreateMockAutofillSaveCardInfoBarDelegateMobileFactory(false, - card_); - delegate_ = delegate.get(); - std::unique_ptr<InfoBarIOS> infobar = std::make_unique<InfoBarIOS>( - InfobarType::kInfobarTypeTranslate, std::move(delegate)); - - infobar_ = infobar.get(); - manager()->AddInfoBar(std::move(infobar)); - // Create the request and add it to the WebState's queue. - std::unique_ptr<OverlayRequest> added_request = - OverlayRequest::CreateWithConfig<SaveCardBannerRequestConfig>(infobar_); - request_ = added_request.get(); - queue()->AddRequest(std::move(added_request)); - // Install the callbacks on the added request. - installer_.InstallCallbacks(request_); - } - - InfoBarManagerImpl* manager() { - return InfoBarManagerImpl::FromWebState(&web_state_); - } - OverlayRequestQueue* queue() { - return OverlayRequestQueue::FromWebState(&web_state_, - OverlayModality::kInfobarModal); - } - - protected: - autofill::CreditCard card_; - web::FakeWebState web_state_; - InfoBarIOS* infobar_ = nullptr; - OverlayRequest* request_ = nullptr; - MockSaveCardInfobarBannerInteractionHandler mock_handler_; - SaveCardInfobarBannerOverlayRequestCallbackInstaller installer_; - MockAutofillSaveCardInfoBarDelegateMobileFactory delegate_factory_; - MockAutofillSaveCardInfoBarDelegateMobile* delegate_; -}; - -TEST_F(SaveCardInfobarBannerOverlayRequestCallbackInstallerTest, - SaveCardCredentials) { - NSString* cardholder_name = @"test name"; - NSString* expiration_date_month = @"06"; - NSString* expiration_date_year = @"2023"; - EXPECT_CALL( - mock_handler_, - SaveCredentials(infobar_, base::SysNSStringToUTF16(cardholder_name), - base::SysNSStringToUTF16(expiration_date_month), - base::SysNSStringToUTF16(expiration_date_year))); - request_->GetCallbackManager()->DispatchResponse( - OverlayResponse::CreateWithInfo< - save_card_infobar_overlays::SaveCardMainAction>( - cardholder_name, expiration_date_month, expiration_date_year)); -}
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_interaction_handler.h b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_interaction_handler.h deleted file mode 100644 index 62a5d94..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_interaction_handler.h +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2020 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_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_SAVE_CARD_SAVE_CARD_INFOBAR_MODAL_INTERACTION_HANDLER_H_ -#define IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_SAVE_CARD_SAVE_CARD_INFOBAR_MODAL_INTERACTION_HANDLER_H_ - -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common/infobar_modal_interaction_handler.h" - -class InfoBarIOS; -class GURL; - -namespace autofill { -class AutofillSaveCardInfoBarDelegateMobile; -} - -// Helper object that updates the model layer for interaction events with the -// SaveCard infobar modal UI. -class SaveCardInfobarModalInteractionHandler - : public InfobarModalInteractionHandler { - public: - SaveCardInfobarModalInteractionHandler(); - ~SaveCardInfobarModalInteractionHandler() override; - - // Instructs the handler to update the credentials with `cardholder_name`, - // `expiration_date_month`, and `expiration_date_year`. Replaces - // MainButtonTapped. - virtual void UpdateCredentials(InfoBarIOS* infobar, - std::u16string cardholder_name, - std::u16string expiration_date_month, - std::u16string expiration_date_year); - - // Instructs the handler to load `url` through the delegate. - virtual void LoadURL(InfoBarIOS* infobar, GURL url); - - // InfobarModalInteractionHandler: - void PerformMainAction(InfoBarIOS* infobar) override; - void InfobarVisibilityChanged(InfoBarIOS* infobar, bool visible) override {} - - private: - // InfobarModalInteractionHandler: - std::unique_ptr<InfobarModalOverlayRequestCallbackInstaller> - CreateModalInstaller() override; - - // Returns the SaveCard delegate from `infobar`. - autofill::AutofillSaveCardInfoBarDelegateMobile* GetInfoBarDelegate( - InfoBarIOS* infobar); -}; - -#endif // IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_SAVE_CARD_SAVE_CARD_INFOBAR_MODAL_INTERACTION_HANDLER_H_
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_interaction_handler.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_interaction_handler.mm deleted file mode 100644 index 41686863..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_interaction_handler.mm +++ /dev/null
@@ -1,59 +0,0 @@ -// Copyright 2020 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/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_interaction_handler.h" - -#import "components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.h" -#import "ios/chrome/browser/infobars/infobar_ios.h" -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_overlay_request_callback_installer.h" -#import "ios/chrome/browser/shared/model/browser/browser.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -SaveCardInfobarModalInteractionHandler:: - SaveCardInfobarModalInteractionHandler() = default; - -SaveCardInfobarModalInteractionHandler:: - ~SaveCardInfobarModalInteractionHandler() = default; - -#pragma mark - Public - -void SaveCardInfobarModalInteractionHandler::UpdateCredentials( - InfoBarIOS* infobar, - std::u16string cardholder_name, - std::u16string expiration_date_month, - std::u16string expiration_date_year) { - infobar->set_accepted(GetInfoBarDelegate(infobar)->UpdateAndAccept( - cardholder_name, expiration_date_month, expiration_date_year)); -} - -void SaveCardInfobarModalInteractionHandler::LoadURL(InfoBarIOS* infobar, - GURL url) { - GetInfoBarDelegate(infobar)->OnLegalMessageLinkClicked(url); -} - -void SaveCardInfobarModalInteractionHandler::PerformMainAction( - InfoBarIOS* infobar) { - NOTREACHED() << "SaveCard does not use standard Infobar Accept action."; -} - -#pragma mark - Private - -std::unique_ptr<InfobarModalOverlayRequestCallbackInstaller> -SaveCardInfobarModalInteractionHandler::CreateModalInstaller() { - return std::make_unique<SaveCardInfobarModalOverlayRequestCallbackInstaller>( - this); -} - -autofill::AutofillSaveCardInfoBarDelegateMobile* -SaveCardInfobarModalInteractionHandler::GetInfoBarDelegate( - InfoBarIOS* infobar) { - autofill::AutofillSaveCardInfoBarDelegateMobile* delegate = - autofill::AutofillSaveCardInfoBarDelegateMobile::FromInfobarDelegate( - infobar->delegate()); - DCHECK(delegate); - return delegate; -}
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_interaction_handler_unittest.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_interaction_handler_unittest.mm deleted file mode 100644 index 65e6b8b..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_interaction_handler_unittest.mm +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright 2020 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/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_interaction_handler.h" - -#import <string> - -#import "base/strings/sys_string_conversions.h" -#import "base/uuid.h" -#import "components/autofill/core/browser/autofill_test_utils.h" -#import "components/autofill/core/browser/data_model/credit_card.h" -#import "ios/chrome/browser/infobars/infobar_ios.h" -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common/infobar_banner_interaction_handler.h" -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_autofill_save_card_infobar_delegate_mobile.h" -#import "testing/platform_test.h" -#import "url/gurl.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -// Test fixture for SaveCardInfobarModalInteractionHandler. -class SaveCardInfobarModalInteractionHandlerTest : public PlatformTest { - public: - SaveCardInfobarModalInteractionHandlerTest() - : delegate_factory_(), - card_(base::Uuid::GenerateRandomV4().AsLowercaseString(), - "https://www.example.com/") { - infobar_ = std::make_unique<InfoBarIOS>( - InfobarType::kInfobarTypeSaveCard, - MockAutofillSaveCardInfoBarDelegateMobileFactory:: - CreateMockAutofillSaveCardInfoBarDelegateMobileFactory(false, - card_)); - } - - MockAutofillSaveCardInfoBarDelegateMobile& mock_delegate() { - return *static_cast<MockAutofillSaveCardInfoBarDelegateMobile*>( - infobar_->delegate()); - } - - protected: - SaveCardInfobarModalInteractionHandler handler_; - MockAutofillSaveCardInfoBarDelegateMobileFactory delegate_factory_; - autofill::CreditCard card_; - std::unique_ptr<InfoBarIOS> infobar_; -}; - -TEST_F(SaveCardInfobarModalInteractionHandlerTest, UpdateCredentials) { - std::u16string cardholder_name = base::SysNSStringToUTF16(@"test name"); - std::u16string expiration_date_month = base::SysNSStringToUTF16(@"06"); - std::u16string expiration_date_year = base::SysNSStringToUTF16(@"2023"); - EXPECT_CALL(mock_delegate(), - UpdateAndAccept(cardholder_name, expiration_date_month, - expiration_date_year)); - handler_.UpdateCredentials(infobar_.get(), cardholder_name, - expiration_date_month, expiration_date_year); -} - -TEST_F(SaveCardInfobarModalInteractionHandlerTest, LoadURL) { - GURL url("https://test-example.com"); - EXPECT_CALL(mock_delegate(), OnLegalMessageLinkClicked(url)); - handler_.LoadURL(infobar_.get(), url); -}
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_overlay_request_callback_installer.h b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_overlay_request_callback_installer.h deleted file mode 100644 index a26bb99..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_overlay_request_callback_installer.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2020 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_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_SAVE_CARD_SAVE_CARD_INFOBAR_MODAL_OVERLAY_REQUEST_CALLBACK_INSTALLER_H_ -#define IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_SAVE_CARD_SAVE_CARD_INFOBAR_MODAL_OVERLAY_REQUEST_CALLBACK_INSTALLER_H_ - -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common/infobar_modal_overlay_request_callback_installer.h" - -#include "base/memory/weak_ptr.h" - -class SaveCardInfobarModalInteractionHandler; - -// Callback installer for SaveCard infobar modal interaction events. -class SaveCardInfobarModalOverlayRequestCallbackInstaller - : public InfobarModalOverlayRequestCallbackInstaller { - public: - // Constructor for an instance that installs callbacks that forward - // interaction events to `interaction_handler`. - explicit SaveCardInfobarModalOverlayRequestCallbackInstaller( - SaveCardInfobarModalInteractionHandler* interaction_handler); - ~SaveCardInfobarModalOverlayRequestCallbackInstaller() override; - - private: - // Used as a callback for OverlayResponses dispatched through `request`'s - // callback manager. The OverlayDispatchCallback is created with an - // OverlayResponseSupport that guarantees that `response` is created with an - // save_card_infobar_modal_responses::SaveCardMainAction. - void SaveCardCredentialsCallback(OverlayRequest* request, - OverlayResponse* response); - // Used as a callback for OverlayResponses dispatched through `request`'s - // callback manager. The OverlayDispatchCallback is created with an - // OverlayResponseSupport that guarantees that `response` is created with a - // save_card_infobar_modal_responses::SaveCardLoadURL. - void LoadURLCallback(OverlayRequest* request, OverlayResponse* response); - - // OverlayRequestCallbackInstaller: - void InstallCallbacksInternal(OverlayRequest* request) override; - - // The handler for received responses. - SaveCardInfobarModalInteractionHandler* interaction_handler_ = nullptr; - - base::WeakPtrFactory<SaveCardInfobarModalOverlayRequestCallbackInstaller> - weak_factory_{this}; -}; - -#endif // IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_SAVE_CARD_SAVE_CARD_INFOBAR_MODAL_OVERLAY_REQUEST_CALLBACK_INSTALLER_H_
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_overlay_request_callback_installer.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_overlay_request_callback_installer.mm deleted file mode 100644 index f1414b0..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_overlay_request_callback_installer.mm +++ /dev/null
@@ -1,81 +0,0 @@ -// Copyright 2020 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/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_overlay_request_callback_installer.h" - -#import "base/check.h" -#import "base/strings/sys_string_conversions.h" -#import "ios/chrome/browser/infobars/infobar_ios.h" -#import "ios/chrome/browser/infobars/infobar_manager_impl.h" -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_interaction_handler.h" -#import "ios/chrome/browser/infobars/overlays/infobar_overlay_util.h" -#import "ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_request_config.h" -#import "ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_responses.h" -#import "ios/chrome/browser/overlays/public/overlay_callback_manager.h" -#import "ios/chrome/browser/overlays/public/overlay_response.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -using save_card_infobar_overlays::SaveCardMainAction; -using save_card_infobar_overlays::SaveCardModalRequestConfig; -using save_card_infobar_overlays::SaveCardLoadURL; - -SaveCardInfobarModalOverlayRequestCallbackInstaller:: - SaveCardInfobarModalOverlayRequestCallbackInstaller( - SaveCardInfobarModalInteractionHandler* interaction_handler) - : InfobarModalOverlayRequestCallbackInstaller( - SaveCardModalRequestConfig::RequestSupport(), - interaction_handler), - interaction_handler_(interaction_handler) { - DCHECK(interaction_handler_); -} - -SaveCardInfobarModalOverlayRequestCallbackInstaller:: - ~SaveCardInfobarModalOverlayRequestCallbackInstaller() = default; - -#pragma mark - Private - -void SaveCardInfobarModalOverlayRequestCallbackInstaller:: - SaveCardCredentialsCallback(OverlayRequest* request, - OverlayResponse* response) { - InfoBarIOS* infobar = GetOverlayRequestInfobar(request); - if (!infobar) - return; - - SaveCardMainAction* info = response->GetInfo<SaveCardMainAction>(); - interaction_handler_->UpdateCredentials( - GetOverlayRequestInfobar(request), - base::SysNSStringToUTF16(info->cardholder_name()), - base::SysNSStringToUTF16(info->expiration_month()), - base::SysNSStringToUTF16(info->expiration_year())); -} - -void SaveCardInfobarModalOverlayRequestCallbackInstaller::LoadURLCallback( - OverlayRequest* request, - OverlayResponse* response) { - SaveCardLoadURL* info = response->GetInfo<SaveCardLoadURL>(); - interaction_handler_->LoadURL(GetOverlayRequestInfobar(request), - info->link_url()); -} - -#pragma mark - OverlayRequestCallbackInstaller - -void SaveCardInfobarModalOverlayRequestCallbackInstaller:: - InstallCallbacksInternal(OverlayRequest* request) { - InfobarModalOverlayRequestCallbackInstaller::InstallCallbacksInternal( - request); - OverlayCallbackManager* manager = request->GetCallbackManager(); - manager->AddDispatchCallback(OverlayDispatchCallback( - base::BindRepeating(&SaveCardInfobarModalOverlayRequestCallbackInstaller:: - SaveCardCredentialsCallback, - weak_factory_.GetWeakPtr(), request), - SaveCardMainAction::ResponseSupport())); - manager->AddDispatchCallback(OverlayDispatchCallback( - base::BindRepeating( - &SaveCardInfobarModalOverlayRequestCallbackInstaller::LoadURLCallback, - weak_factory_.GetWeakPtr(), request), - SaveCardLoadURL::ResponseSupport())); -}
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_overlay_request_callback_installer_unittest.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_overlay_request_callback_installer_unittest.mm deleted file mode 100644 index 0bda550..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_overlay_request_callback_installer_unittest.mm +++ /dev/null
@@ -1,106 +0,0 @@ -// Copyright 2020 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/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_overlay_request_callback_installer.h" - -#import "base/strings/sys_string_conversions.h" -#import "base/uuid.h" -#import "components/autofill/core/browser/autofill_test_utils.h" -#import "components/autofill/core/browser/data_model/credit_card.h" -#import "ios/chrome/browser/infobars/infobar_ios.h" -#import "ios/chrome/browser/infobars/infobar_manager_impl.h" -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_autofill_save_card_infobar_delegate_mobile.h" -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_save_card_modal_infobar_interaction_handler.h" -#import "ios/chrome/browser/overlays/public/infobar_modal/infobar_modal_overlay_responses.h" -#import "ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_request_config.h" -#import "ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_responses.h" -#import "ios/chrome/browser/overlays/public/overlay_callback_manager.h" -#import "ios/chrome/browser/overlays/public/overlay_request.h" -#import "ios/chrome/browser/overlays/public/overlay_request_queue.h" -#import "ios/chrome/browser/overlays/public/overlay_response.h" -#import "ios/web/public/test/fakes/fake_navigation_manager.h" -#import "ios/web/public/test/fakes/fake_web_state.h" -#import "testing/gmock/include/gmock/gmock.h" -#import "testing/platform_test.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -using save_card_infobar_overlays::SaveCardModalRequestConfig; - -// Test fixture for SaveCardInfobarModalOverlayRequestCallbackInstaller. -class SaveCardInfobarModalOverlayRequestCallbackInstallerTest - : public PlatformTest { - public: - SaveCardInfobarModalOverlayRequestCallbackInstallerTest() - : card_(base::Uuid::GenerateRandomV4().AsLowercaseString(), - "https://www.example.com/"), - installer_(&mock_handler_), - delegate_factory_() { - // Create the infobar and add it to the WebState's manager. - web_state_.SetNavigationManager( - std::make_unique<web::FakeNavigationManager>()); - InfoBarManagerImpl::CreateForWebState(&web_state_); - std::unique_ptr<MockAutofillSaveCardInfoBarDelegateMobile> delegate = - delegate_factory_ - .CreateMockAutofillSaveCardInfoBarDelegateMobileFactory(false, - card_); - delegate_ = delegate.get(); - std::unique_ptr<InfoBarIOS> infobar = std::make_unique<InfoBarIOS>( - InfobarType::kInfobarTypeTranslate, std::move(delegate)); - - infobar_ = infobar.get(); - manager()->AddInfoBar(std::move(infobar)); - // Create the request and add it to the WebState's queue. - std::unique_ptr<OverlayRequest> added_request = - OverlayRequest::CreateWithConfig<SaveCardModalRequestConfig>(infobar_); - request_ = added_request.get(); - queue()->AddRequest(std::move(added_request)); - // Install the callbacks on the added request. - installer_.InstallCallbacks(request_); - } - - InfoBarManagerImpl* manager() { - return InfoBarManagerImpl::FromWebState(&web_state_); - } - OverlayRequestQueue* queue() { - return OverlayRequestQueue::FromWebState(&web_state_, - OverlayModality::kInfobarModal); - } - - protected: - autofill::CreditCard card_; - web::FakeWebState web_state_; - InfoBarIOS* infobar_ = nullptr; - OverlayRequest* request_ = nullptr; - MockSaveCardInfobarModalInteractionHandler mock_handler_; - SaveCardInfobarModalOverlayRequestCallbackInstaller installer_; - MockAutofillSaveCardInfoBarDelegateMobileFactory delegate_factory_; - MockAutofillSaveCardInfoBarDelegateMobile* delegate_; -}; - -TEST_F(SaveCardInfobarModalOverlayRequestCallbackInstallerTest, - UpdateCredentials) { - NSString* cardholder_name = @"test name"; - NSString* expiration_date_month = @"06"; - NSString* expiration_date_year = @"2023"; - EXPECT_CALL( - mock_handler_, - UpdateCredentials(infobar_, base::SysNSStringToUTF16(cardholder_name), - base::SysNSStringToUTF16(expiration_date_month), - base::SysNSStringToUTF16(expiration_date_year))); - request_->GetCallbackManager()->DispatchResponse( - OverlayResponse::CreateWithInfo< - save_card_infobar_overlays::SaveCardMainAction>( - cardholder_name, expiration_date_month, expiration_date_year)); -} - -TEST_F(SaveCardInfobarModalOverlayRequestCallbackInstallerTest, LoadURL) { - GURL url("https://test-example.com"); - EXPECT_CALL(mock_handler_, LoadURL(infobar_, url)); - request_->GetCallbackManager()->DispatchResponse( - OverlayResponse::CreateWithInfo< - save_card_infobar_overlays::SaveCardLoadURL>(url)); -}
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/tailored_security/BUILD.gn b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/tailored_security/BUILD.gn deleted file mode 100644 index 224f09b..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/tailored_security/BUILD.gn +++ /dev/null
@@ -1,47 +0,0 @@ -# Copyright 2022 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -source_set("tailored_security") { - configs += [ "//build/config/compiler:enable_arc" ] - sources = [ - "tailored_security_infobar_banner_interaction_handler.h", - "tailored_security_infobar_banner_interaction_handler.mm", - ] - deps = [ - "//base", - "//ios/chrome/browser/infobars", - "//ios/chrome/browser/infobars:public", - "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers", - "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common", - "//ios/chrome/browser/overlays/public/infobar_banner", - "//ios/chrome/browser/safe_browsing/tailored_security:infobar_delegates", - ] -} - -source_set("unit_tests") { - configs += [ "//build/config/compiler:enable_arc" ] - testonly = true - sources = - [ "tailored_security_infobar_banner_interaction_handler_unittest.mm" ] - deps = [ - ":tailored_security", - "//base", - "//components/safe_browsing/core/common:safe_browsing_prefs", - "//components/sync_preferences", - "//components/sync_preferences:test_support", - "//ios/chrome/browser/infobars", - "//ios/chrome/browser/infobars/overlays", - "//ios/chrome/browser/infobars/test", - "//ios/chrome/browser/overlays/public/infobar_banner", - "//ios/chrome/browser/safe_browsing", - "//ios/chrome/browser/safe_browsing/tailored_security/test", - "//ios/chrome/browser/shared/model/browser_state:test_support", - "//ios/chrome/browser/shared/model/prefs:browser_prefs", - "//ios/components/security_interstitials/safe_browsing", - "//ios/web/public/test", - "//ios/web/public/test/fakes", - "//testing/gmock", - "//testing/gtest", - ] -}
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/tailored_security/tailored_security_infobar_banner_interaction_handler.h b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/tailored_security/tailored_security_infobar_banner_interaction_handler.h deleted file mode 100644 index 712c459..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/tailored_security/tailored_security_infobar_banner_interaction_handler.h +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_TAILORED_SECURITY_TAILORED_SECURITY_INFOBAR_BANNER_INTERACTION_HANDLER_H_ -#define IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_TAILORED_SECURITY_TAILORED_SECURITY_INFOBAR_BANNER_INTERACTION_HANDLER_H_ - -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common/infobar_banner_interaction_handler.h" - -namespace safe_browsing { -class TailoredSecurityServiceInfobarDelegate; -} // namespace safe_browsing - -// Helper object that updates the model layer for interaction events with the -// tailored security infobar banner UI. -class TailoredSecurityInfobarBannerInteractionHandler - : public InfobarBannerInteractionHandler { - public: - TailoredSecurityInfobarBannerInteractionHandler( - const OverlayRequestSupport* request_support); - ~TailoredSecurityInfobarBannerInteractionHandler() override; - - // InfobarBannerInteractionHandler: - void MainButtonTapped(InfoBarIOS* infobar) override; - - private: - // Returns the tailored security delegate from `infobar`. - safe_browsing::TailoredSecurityServiceInfobarDelegate* GetInfobarDelegate( - InfoBarIOS* infobar); -}; - -#endif // IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_TAILORED_SECURITY_TAILORED_SECURITY_INFOBAR_BANNER_INTERACTION_HANDLER_H_
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/tailored_security/tailored_security_infobar_banner_interaction_handler.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/tailored_security/tailored_security_infobar_banner_interaction_handler.mm deleted file mode 100644 index 05dafff9..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/tailored_security/tailored_security_infobar_banner_interaction_handler.mm +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/tailored_security/tailored_security_infobar_banner_interaction_handler.h" - -#import "ios/chrome/browser/infobars/infobar_ios.h" -#import "ios/chrome/browser/safe_browsing/tailored_security/tailored_security_service_infobar_delegate.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -using safe_browsing::TailoredSecurityServiceInfobarDelegate; - -#pragma mark - InfobarBannerInteractionHandler - -TailoredSecurityInfobarBannerInteractionHandler:: - TailoredSecurityInfobarBannerInteractionHandler( - const OverlayRequestSupport* request_support) - : InfobarBannerInteractionHandler(request_support) {} - -TailoredSecurityInfobarBannerInteractionHandler:: - ~TailoredSecurityInfobarBannerInteractionHandler() = default; - -void TailoredSecurityInfobarBannerInteractionHandler::MainButtonTapped( - InfoBarIOS* infobar) { - infobar->set_accepted(GetInfobarDelegate(infobar)->Accept()); -} -#pragma mark - Private - -TailoredSecurityServiceInfobarDelegate* -TailoredSecurityInfobarBannerInteractionHandler::GetInfobarDelegate( - InfoBarIOS* infobar) { - TailoredSecurityServiceInfobarDelegate* delegate = - TailoredSecurityServiceInfobarDelegate::FromInfobarDelegate( - infobar->delegate()); - DCHECK(delegate); - return delegate; -}
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/tailored_security/tailored_security_infobar_banner_interaction_handler_unittest.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/tailored_security/tailored_security_infobar_banner_interaction_handler_unittest.mm deleted file mode 100644 index bbf0dd0..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/tailored_security/tailored_security_infobar_banner_interaction_handler_unittest.mm +++ /dev/null
@@ -1,113 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/tailored_security/tailored_security_infobar_banner_interaction_handler.h" - -#import "components/safe_browsing/core/common/safe_browsing_prefs.h" -#import "components/sync_preferences/pref_service_mock_factory.h" -#import "components/sync_preferences/pref_service_syncable.h" -#import "ios/chrome/browser/infobars/infobar_manager_impl.h" -#import "ios/chrome/browser/infobars/overlays/default_infobar_overlay_request_factory.h" -#import "ios/chrome/browser/infobars/overlays/infobar_overlay_request_inserter.h" -#import "ios/chrome/browser/infobars/test/fake_infobar_ios.h" -#import "ios/chrome/browser/overlays/public/infobar_banner/tailored_security_service_infobar_banner_overlay_request_config.h" -#import "ios/chrome/browser/safe_browsing/safe_browsing_client_factory.h" -#import "ios/chrome/browser/safe_browsing/tailored_security/test/mock_tailored_security_service_infobar_delegate.h" -#import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h" -#import "ios/chrome/browser/shared/model/prefs/browser_prefs.h" -#import "ios/components/security_interstitials/safe_browsing/safe_browsing_client.h" -#import "ios/components/security_interstitials/safe_browsing/safe_browsing_query_manager.h" -#import "ios/components/security_interstitials/safe_browsing/safe_browsing_tab_helper.h" -#import "ios/web/public/test/fakes/fake_navigation_manager.h" -#import "ios/web/public/test/fakes/fake_web_state.h" -#import "ios/web/public/test/web_task_environment.h" -#import "testing/platform_test.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -// Test fixture for TailoredSecurityInfobarBannerInteractionHandlerTest. -class TailoredSecurityInfobarBannerInteractionHandlerTest - : public PlatformTest { - public: - TailoredSecurityInfobarBannerInteractionHandlerTest() - : task_environment_(web::WebTaskEnvironment::IO_MAINLOOP), - handler_( - tailored_security_service_infobar_overlays:: - TailoredSecurityServiceBannerRequestConfig::RequestSupport()) { - scoped_refptr<user_prefs::PrefRegistrySyncable> registry = - base::MakeRefCounted<user_prefs::PrefRegistrySyncable>(); - RegisterBrowserStatePrefs(registry.get()); - sync_preferences::PrefServiceMockFactory factory; - - web_state_.SetNavigationManager( - std::make_unique<web::FakeNavigationManager>()); - InfobarOverlayRequestInserter::CreateForWebState( - &web_state_, &DefaultInfobarOverlayRequestFactory); - InfoBarManagerImpl::CreateForWebState(&web_state_); - - TestChromeBrowserState::Builder test_cbs_builder; - test_cbs_builder.SetPrefService(factory.CreateSyncable(registry.get())); - chrome_browser_state_ = test_cbs_builder.Build(); - web_state_.SetBrowserState(chrome_browser_state_.get()); - - SafeBrowsingClient* client = SafeBrowsingClientFactory::GetForBrowserState( - chrome_browser_state_.get()); - SafeBrowsingQueryManager::CreateForWebState(&web_state_, client); - SafeBrowsingTabHelper::CreateForWebState(&web_state_, client); - } - - safe_browsing::MockTailoredSecurityServiceInfobarDelegate& mock_delegate() { - return *static_cast< - safe_browsing::MockTailoredSecurityServiceInfobarDelegate*>( - infobar_->delegate()); - } - - // Creates an infobar with a specific TailoredSecurityServiceMessageState. - void CreateInfobarWithMessageState( - safe_browsing::TailoredSecurityServiceMessageState message_state) { - std::unique_ptr<InfoBarIOS> infobar = std::make_unique<InfoBarIOS>( - InfobarType::kInfobarTypeTailoredSecurityService, - safe_browsing::MockTailoredSecurityServiceInfobarDelegate::Create( - message_state, &web_state_)); - infobar_ = infobar.get(); - InfoBarManagerImpl::FromWebState(&web_state_) - ->AddInfoBar(std::move(infobar)); - } - - protected: - web::WebTaskEnvironment task_environment_; - TailoredSecurityInfobarBannerInteractionHandler handler_; - web::FakeWebState web_state_; - InfoBarIOS* infobar_; - std::unique_ptr<TestChromeBrowserState> chrome_browser_state_; -}; - -// Tests MainButtonTapped() calls Accept() on the mock delegate and resets -// the infobar to be accepted for consented message prompt. -TEST_F(TailoredSecurityInfobarBannerInteractionHandlerTest, - ConsentedMessagePromptButtonTapped) { - CreateInfobarWithMessageState( - safe_browsing::TailoredSecurityServiceMessageState:: - kConsentedAndFlowEnabled); - ASSERT_FALSE(infobar_->accepted()); - handler_.MainButtonTapped(infobar_); - EXPECT_TRUE(infobar_->accepted()); -} - -// Tests MainButtonTapped() calls Accept() on the mock delegate and resets -// the infobar to be accepted for unconsented message prompt. -TEST_F(TailoredSecurityInfobarBannerInteractionHandlerTest, - UnconsentedMessagePromptButtonTapped) { - CreateInfobarWithMessageState( - safe_browsing::TailoredSecurityServiceMessageState:: - kUnconsentedAndFlowEnabled); - ASSERT_FALSE(infobar_->accepted()); - handler_.MainButtonTapped(infobar_); - EXPECT_TRUE(infobar_->accepted()); - EXPECT_TRUE( - safe_browsing::GetSafeBrowsingState(*chrome_browser_state_->GetPrefs()) == - safe_browsing::SafeBrowsingState::ENHANCED_PROTECTION); -}
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/BUILD.gn b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/BUILD.gn index 86b42a7..1c6f0b8 100644 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/BUILD.gn +++ b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/BUILD.gn
@@ -13,10 +13,6 @@ "mock_infobar_interaction_handler.mm", "mock_save_address_profile_modal_infobar_interaction_handler.h", "mock_save_address_profile_modal_infobar_interaction_handler.mm", - "mock_save_card_banner_infobar_interaction_handler.h", - "mock_save_card_banner_infobar_interaction_handler.mm", - "mock_save_card_modal_infobar_interaction_handler.h", - "mock_save_card_modal_infobar_interaction_handler.mm", "mock_translate_infobar_interaction_handler.h", "mock_translate_infobar_interaction_handler.mm", ] @@ -33,7 +29,6 @@ "//ios/chrome/browser/infobars/overlays", "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers", "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/autofill_address_profile", - "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card", "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/translate", "//ios/chrome/browser/overlays", "//ios/chrome/browser/overlays/public/common/infobars",
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_autofill_save_card_infobar_delegate_mobile.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_autofill_save_card_infobar_delegate_mobile.mm index e376d3c..9e0cc7e 100644 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_autofill_save_card_infobar_delegate_mobile.mm +++ b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_autofill_save_card_infobar_delegate_mobile.mm
@@ -4,15 +4,16 @@ #import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_autofill_save_card_infobar_delegate_mobile.h" -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - #import "base/functional/bind.h" #import "base/uuid.h" #import "components/autofill/core/browser/autofill_test_utils.h" +#import "components/autofill/core/browser/payments/test_legal_message_line.h" #import "components/signin/public/identity_manager/account_info.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + MockAutofillSaveCardInfoBarDelegateMobile:: MockAutofillSaveCardInfoBarDelegateMobile( autofill::AutofillClient::SaveCreditCardOptions options, @@ -56,5 +57,7 @@ return std::make_unique<MockAutofillSaveCardInfoBarDelegateMobile>( autofill::AutofillClient::SaveCreditCardOptions(), card, upload ? Variant(std::move(upload_cb)) : Variant(std::move(local_cb)), - autofill::LegalMessageLines(), AccountInfo()); + autofill::LegalMessageLines( + {autofill::TestLegalMessageLine("Test message")}), + AccountInfo()); }
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_save_card_banner_infobar_interaction_handler.h b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_save_card_banner_infobar_interaction_handler.h deleted file mode 100644 index 32e6246..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_save_card_banner_infobar_interaction_handler.h +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2020 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_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_TEST_MOCK_SAVE_CARD_BANNER_INFOBAR_INTERACTION_HANDLER_H_ -#define IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_TEST_MOCK_SAVE_CARD_BANNER_INFOBAR_INTERACTION_HANDLER_H_ - -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_banner_interaction_handler.h" - -#include <string.h> - -#include "testing/gmock/include/gmock/gmock.h" - -class InfoBarIOS; - -// Mock version of SaveCardInfobarBannerInteractionHandler for use in tests. -class MockSaveCardInfobarBannerInteractionHandler - : public SaveCardInfobarBannerInteractionHandler { - public: - MockSaveCardInfobarBannerInteractionHandler(); - ~MockSaveCardInfobarBannerInteractionHandler() override; - - MOCK_METHOD4(SaveCredentials, - void(InfoBarIOS* infobar, - std::u16string cardholder_name, - std::u16string expiration_date_month, - std::u16string expiration_date_year)); -}; - -#endif // IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_TEST_MOCK_SAVE_CARD_BANNER_INFOBAR_INTERACTION_HANDLER_H_
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_save_card_banner_infobar_interaction_handler.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_save_card_banner_infobar_interaction_handler.mm deleted file mode 100644 index d0a38686..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_save_card_banner_infobar_interaction_handler.mm +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2020 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/infobars/overlays/browser_agent/interaction_handlers/test/mock_save_card_banner_infobar_interaction_handler.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -MockSaveCardInfobarBannerInteractionHandler:: - MockSaveCardInfobarBannerInteractionHandler() = default; - -MockSaveCardInfobarBannerInteractionHandler:: - ~MockSaveCardInfobarBannerInteractionHandler() = default;
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_save_card_modal_infobar_interaction_handler.h b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_save_card_modal_infobar_interaction_handler.h deleted file mode 100644 index ce444130..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_save_card_modal_infobar_interaction_handler.h +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2020 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_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_TEST_MOCK_SAVE_CARD_MODAL_INFOBAR_INTERACTION_HANDLER_H_ -#define IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_TEST_MOCK_SAVE_CARD_MODAL_INFOBAR_INTERACTION_HANDLER_H_ - -#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card/save_card_infobar_modal_interaction_handler.h" - -#include "testing/gmock/include/gmock/gmock.h" -#include "url/gurl.h" - -class InfoBarIOS; - -// Mock version of SaveCardInfobarModalInteractionHandler for use in tests. -class MockSaveCardInfobarModalInteractionHandler - : public SaveCardInfobarModalInteractionHandler { - public: - MockSaveCardInfobarModalInteractionHandler(); - ~MockSaveCardInfobarModalInteractionHandler() override; - - MOCK_METHOD4(UpdateCredentials, - void(InfoBarIOS* infobar, - std::u16string cardholder_name, - std::u16string expiration_date_month, - std::u16string expiration_date_year)); - MOCK_METHOD2(LoadURL, void(InfoBarIOS* infobar, GURL url)); -}; - -#endif // IOS_CHROME_BROWSER_INFOBARS_OVERLAYS_BROWSER_AGENT_INTERACTION_HANDLERS_TEST_MOCK_SAVE_CARD_MODAL_INFOBAR_INTERACTION_HANDLER_H_
diff --git a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_save_card_modal_infobar_interaction_handler.mm b/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_save_card_modal_infobar_interaction_handler.mm deleted file mode 100644 index 9a7ac43..0000000 --- a/ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_save_card_modal_infobar_interaction_handler.mm +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2020 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/infobars/overlays/browser_agent/interaction_handlers/test/mock_save_card_modal_infobar_interaction_handler.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -MockSaveCardInfobarModalInteractionHandler:: - MockSaveCardInfobarModalInteractionHandler() = default; - -MockSaveCardInfobarModalInteractionHandler:: - ~MockSaveCardInfobarModalInteractionHandler() = default;
diff --git a/ios/chrome/browser/infobars/overlays/default_infobar_overlay_request_factory.mm b/ios/chrome/browser/infobars/overlays/default_infobar_overlay_request_factory.mm index 21d4e49..a5c697fd 100644 --- a/ios/chrome/browser/infobars/overlays/default_infobar_overlay_request_factory.mm +++ b/ios/chrome/browser/infobars/overlays/default_infobar_overlay_request_factory.mm
@@ -11,12 +11,9 @@ #import "ios/chrome/browser/overlays/public/default/default_infobar_overlay_request_config.h" #import "ios/chrome/browser/overlays/public/infobar_banner/confirm_infobar_banner_overlay_request_config.h" #import "ios/chrome/browser/overlays/public/infobar_banner/save_address_profile_infobar_banner_overlay_request_config.h" -#import "ios/chrome/browser/overlays/public/infobar_banner/save_card_infobar_banner_overlay_request_config.h" #import "ios/chrome/browser/overlays/public/infobar_banner/sync_error_infobar_banner_overlay_request_config.h" -#import "ios/chrome/browser/overlays/public/infobar_banner/tailored_security_service_infobar_banner_overlay_request_config.h" #import "ios/chrome/browser/overlays/public/infobar_banner/translate_infobar_banner_overlay_request_config.h" #import "ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.h" -#import "ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_request_config.h" #import "ios/chrome/browser/overlays/public/infobar_modal/translate_infobar_modal_overlay_request_config.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -28,8 +25,11 @@ InfobarOverlayType overlay_type) { DCHECK(infobar_ios); switch (infobar_ios->infobar_type()) { + case InfobarType::kInfobarTypeTailoredSecurityService: case InfobarType::kInfobarTypePasswordSave: case InfobarType::kInfobarTypePasswordUpdate: + case InfobarType::kInfobarTypePermissions: + case InfobarType::kInfobarTypeSaveCard: return OverlayRequest::CreateWithConfig< DefaultInfobarOverlayRequestConfig>(infobar_ios, overlay_type); case InfobarType::kInfobarTypeTranslate: @@ -62,22 +62,6 @@ return nullptr; } - case InfobarType::kInfobarTypeSaveCard: - switch (overlay_type) { - case InfobarOverlayType::kBanner: - return OverlayRequest::CreateWithConfig< - save_card_infobar_overlays::SaveCardBannerRequestConfig>( - infobar_ios); - - case InfobarOverlayType::kModal: - return OverlayRequest::CreateWithConfig< - save_card_infobar_overlays::SaveCardModalRequestConfig>( - infobar_ios); - - default: - return nullptr; - } - case InfobarType::kInfobarTypeSaveAutofillAddressProfile: switch (overlay_type) { case InfobarOverlayType::kBanner: @@ -94,16 +78,6 @@ return nullptr; } - case InfobarType::kInfobarTypePermissions: - return OverlayRequest::CreateWithConfig< - DefaultInfobarOverlayRequestConfig>(infobar_ios, overlay_type); - case InfobarType::kInfobarTypeTailoredSecurityService: - if (overlay_type == InfobarOverlayType::kBanner) { - return OverlayRequest::CreateWithConfig< - tailored_security_service_infobar_overlays:: - TailoredSecurityServiceBannerRequestConfig>(infobar_ios); - } - return nullptr; case InfobarType::kInfobarTypeSyncError: if (overlay_type == InfobarOverlayType::kBanner) { return OverlayRequest::CreateWithConfig<
diff --git a/ios/chrome/browser/infobars/overlays/default_infobar_overlay_request_factory_unittest.mm b/ios/chrome/browser/infobars/overlays/default_infobar_overlay_request_factory_unittest.mm index e8a59049..c66662a 100644 --- a/ios/chrome/browser/infobars/overlays/default_infobar_overlay_request_factory_unittest.mm +++ b/ios/chrome/browser/infobars/overlays/default_infobar_overlay_request_factory_unittest.mm
@@ -20,11 +20,8 @@ #import "ios/chrome/browser/overlays/public/default/default_infobar_overlay_request_config.h" #import "ios/chrome/browser/overlays/public/infobar_banner/confirm_infobar_banner_overlay_request_config.h" #import "ios/chrome/browser/overlays/public/infobar_banner/save_address_profile_infobar_banner_overlay_request_config.h" -#import "ios/chrome/browser/overlays/public/infobar_banner/save_card_infobar_banner_overlay_request_config.h" -#import "ios/chrome/browser/overlays/public/infobar_banner/tailored_security_service_infobar_banner_overlay_request_config.h" #import "ios/chrome/browser/overlays/public/infobar_banner/translate_infobar_banner_overlay_request_config.h" #import "ios/chrome/browser/overlays/public/infobar_modal/save_address_profile_infobar_modal_overlay_request_config.h" -#import "ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_request_config.h" #import "ios/chrome/browser/overlays/public/infobar_modal/translate_infobar_modal_overlay_request_config.h" #import "ios/chrome/browser/passwords/ios_chrome_save_password_infobar_delegate.h" #import "ios/chrome/browser/passwords/test/mock_ios_chrome_save_passwords_infobar_delegate.h" @@ -45,10 +42,6 @@ using infobars::InfoBar; using infobars::InfoBarDelegate; using safe_browsing::TailoredSecurityServiceMessageState; -using save_card_infobar_overlays::SaveCardBannerRequestConfig; -using save_card_infobar_overlays::SaveCardModalRequestConfig; -using tailored_security_service_infobar_overlays:: - TailoredSecurityServiceBannerRequestConfig; using translate_infobar_overlays::TranslateBannerRequestConfig; using translate_infobar_overlays::TranslateModalRequestConfig; @@ -128,12 +121,12 @@ std::unique_ptr<OverlayRequest> banner_request = DefaultInfobarOverlayRequestFactory(&infobar, InfobarOverlayType::kBanner); - EXPECT_TRUE(banner_request->GetConfig<SaveCardBannerRequestConfig>()); + EXPECT_TRUE(banner_request->GetConfig<DefaultInfobarOverlayRequestConfig>()); // Test modal request creation. std::unique_ptr<OverlayRequest> modal_request = DefaultInfobarOverlayRequestFactory(&infobar, InfobarOverlayType::kModal); - EXPECT_TRUE(modal_request->GetConfig<SaveCardModalRequestConfig>()); + EXPECT_TRUE(modal_request->GetConfig<DefaultInfobarOverlayRequestConfig>()); } // Tests that the factory creates a translate request. @@ -194,6 +187,5 @@ std::unique_ptr<OverlayRequest> banner_request = DefaultInfobarOverlayRequestFactory(&infobar, InfobarOverlayType::kBanner); - EXPECT_TRUE( - banner_request->GetConfig<TailoredSecurityServiceBannerRequestConfig>()); + EXPECT_TRUE(banner_request->GetConfig<DefaultInfobarOverlayRequestConfig>()); }
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn b/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn index cd86e4e..0e81be4 100644 --- a/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn +++ b/ios/chrome/browser/overlays/public/infobar_banner/BUILD.gn
@@ -14,12 +14,8 @@ "infobar_banner_placeholder_request_config.mm", "save_address_profile_infobar_banner_overlay_request_config.h", "save_address_profile_infobar_banner_overlay_request_config.mm", - "save_card_infobar_banner_overlay_request_config.h", - "save_card_infobar_banner_overlay_request_config.mm", "sync_error_infobar_banner_overlay_request_config.h", "sync_error_infobar_banner_overlay_request_config.mm", - "tailored_security_service_infobar_banner_overlay_request_config.h", - "tailored_security_service_infobar_banner_overlay_request_config.mm", "translate_infobar_banner_overlay_request_config.h", "translate_infobar_banner_overlay_request_config.mm", ]
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/save_card_infobar_banner_overlay_request_config.h b/ios/chrome/browser/overlays/public/infobar_banner/save_card_infobar_banner_overlay_request_config.h deleted file mode 100644 index 19a9e42..0000000 --- a/ios/chrome/browser/overlays/public/infobar_banner/save_card_infobar_banner_overlay_request_config.h +++ /dev/null
@@ -1,72 +0,0 @@ -// Copyright 2020 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_OVERLAYS_PUBLIC_INFOBAR_BANNER_SAVE_CARD_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_ -#define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_SAVE_CARD_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_ - -#include <CoreFoundation/CoreFoundation.h> - -#include <string> - -#include "ios/chrome/browser/overlays/public/overlay_request_config.h" -#include "ios/chrome/browser/overlays/public/overlay_user_data.h" - -namespace infobars { -class InfoBar; -} - -namespace save_card_infobar_overlays { - -// Configuration object for OverlayRequests for the banner UI for an InfoBar -// with a AutofillSaveCardInfoBarDelegateMobile. -class SaveCardBannerRequestConfig - : public OverlayRequestConfig<SaveCardBannerRequestConfig> { - public: - ~SaveCardBannerRequestConfig() override; - - // The message text. - std::u16string message_text() const { return message_text_; } - - // The label for the card. - std::u16string card_label() const { return card_label_; } - - // The card holder name of the card. - std::u16string cardholder_name() const { return cardholder_name_; } - - // The expiration month of the card. - std::u16string expiration_date_month() const { - return expiration_date_month_; - } - - // The expiration year of the card. - std::u16string expiration_date_year() const { return expiration_date_year_; } - - // The button label text. - std::u16string button_label_text() const { return button_label_text_; } - - // Whether the action is an upload or a local save. - bool should_upload_credentials() const { return should_upload_credentials_; } - - private: - OVERLAY_USER_DATA_SETUP(SaveCardBannerRequestConfig); - explicit SaveCardBannerRequestConfig(infobars::InfoBar* infobar); - - // OverlayUserData: - void CreateAuxiliaryData(base::SupportsUserData* user_data) override; - - // The InfoBar causing this banner. - infobars::InfoBar* infobar_ = nullptr; - // Configuration data extracted from `infobar_`'s save card delegate. - std::u16string message_text_; - std::u16string card_label_; - std::u16string cardholder_name_; - std::u16string expiration_date_month_; - std::u16string expiration_date_year_; - std::u16string button_label_text_; - bool should_upload_credentials_ = false; -}; - -} // namespace save_card_infobar_overlays - -#endif // IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_SAVE_CARD_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/save_card_infobar_banner_overlay_request_config.mm b/ios/chrome/browser/overlays/public/infobar_banner/save_card_infobar_banner_overlay_request_config.mm deleted file mode 100644 index e5bf0d5..0000000 --- a/ios/chrome/browser/overlays/public/infobar_banner/save_card_infobar_banner_overlay_request_config.mm +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2020 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/overlays/public/infobar_banner/save_card_infobar_banner_overlay_request_config.h" - -#import "components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.h" -#import "components/infobars/core/infobar.h" -#import "ios/chrome/browser/infobars/infobar_ios.h" -#import "ios/chrome/browser/infobars/overlays/infobar_overlay_type.h" -#import "ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.h" -#import "ios/chrome/grit/ios_strings.h" -#import "ui/base/l10n/l10n_util.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace save_card_infobar_overlays { - -OVERLAY_USER_DATA_SETUP_IMPL(SaveCardBannerRequestConfig); - -SaveCardBannerRequestConfig::SaveCardBannerRequestConfig( - infobars::InfoBar* infobar) - : infobar_(infobar) { - DCHECK(infobar_); - autofill::AutofillSaveCardInfoBarDelegateMobile* delegate = - autofill::AutofillSaveCardInfoBarDelegateMobile::FromInfobarDelegate( - infobar_->delegate()); - message_text_ = delegate->GetMessageText(); - card_label_ = delegate->card_label(); - cardholder_name_ = delegate->cardholder_name(); - expiration_date_month_ = delegate->expiration_date_month(); - expiration_date_year_ = delegate->expiration_date_year(); - button_label_text_ = - delegate->is_for_upload() - ? l10n_util::GetStringUTF16(IDS_IOS_AUTOFILL_SAVE_ELLIPSIS) - : delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK); - should_upload_credentials_ = delegate->is_for_upload(); -} - -SaveCardBannerRequestConfig::~SaveCardBannerRequestConfig() = default; - -void SaveCardBannerRequestConfig::CreateAuxiliaryData( - base::SupportsUserData* user_data) { - InfobarOverlayRequestConfig::CreateForUserData( - user_data, static_cast<InfoBarIOS*>(infobar_), - InfobarOverlayType::kBanner, false); -} - -} // namespace save_card_infobar_overlays
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/tailored_security_service_infobar_banner_overlay_request_config.h b/ios/chrome/browser/overlays/public/infobar_banner/tailored_security_service_infobar_banner_overlay_request_config.h deleted file mode 100644 index 6d21129d..0000000 --- a/ios/chrome/browser/overlays/public/infobar_banner/tailored_security_service_infobar_banner_overlay_request_config.h +++ /dev/null
@@ -1,67 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_TAILORED_SECURITY_SERVICE_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_ -#define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_TAILORED_SECURITY_SERVICE_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_ - -#import <CoreFoundation/CoreFoundation.h> - -#import <string> - -#import "ios/chrome/browser/overlays/public/overlay_request_config.h" -#import "ios/chrome/browser/overlays/public/overlay_user_data.h" -#import "ios/chrome/browser/safe_browsing/tailored_security/tailored_security_service_infobar_delegate.h" - -namespace infobars { -class InfoBar; -} - -namespace tailored_security_service_infobar_overlays { - -// Configuration object for OverlayRequests for the banner UI for an InfoBar -// with a TailoredSecurityServiceInfobarDelegate. -class TailoredSecurityServiceBannerRequestConfig - : public OverlayRequestConfig<TailoredSecurityServiceBannerRequestConfig> { - public: - ~TailoredSecurityServiceBannerRequestConfig() override; - - // The message text. - std::u16string message_text() const { return message_text_; } - - // The button label text. - std::u16string button_label_text() const { return button_label_text_; } - - // The description. - std::u16string description() const { return description_; } - - // The badge of the infobar. - bool has_badge() const { return has_badge_; } - - // The message state. - safe_browsing::TailoredSecurityServiceMessageState message_state() const { - return message_state_; - } - - private: - OVERLAY_USER_DATA_SETUP(TailoredSecurityServiceBannerRequestConfig); - explicit TailoredSecurityServiceBannerRequestConfig( - infobars::InfoBar* infobar); - - // OverlayUserData: - void CreateAuxiliaryData(base::SupportsUserData* user_data) override; - - // The InfoBar causing this banner. - infobars::InfoBar* infobar_ = nullptr; - // Configuration data extracted from `infobar_`'s tailored security delegate. - std::u16string message_text_; - std::u16string description_; - std::u16string button_label_text_; - safe_browsing::TailoredSecurityServiceMessageState message_state_; - // Determines if the banner should show the gear icon. - bool has_badge_ = false; -}; - -} // namespace tailored_security_service_infobar_overlays - -#endif // IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_BANNER_TAILORED_SECURITY_SERVICE_INFOBAR_BANNER_OVERLAY_REQUEST_CONFIG_H_
diff --git a/ios/chrome/browser/overlays/public/infobar_banner/tailored_security_service_infobar_banner_overlay_request_config.mm b/ios/chrome/browser/overlays/public/infobar_banner/tailored_security_service_infobar_banner_overlay_request_config.mm deleted file mode 100644 index f2cfcf7..0000000 --- a/ios/chrome/browser/overlays/public/infobar_banner/tailored_security_service_infobar_banner_overlay_request_config.mm +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/overlays/public/infobar_banner/tailored_security_service_infobar_banner_overlay_request_config.h" - -#import "components/infobars/core/infobar.h" -#import "ios/chrome/browser/infobars/infobar_ios.h" -#import "ios/chrome/browser/infobars/overlays/infobar_overlay_type.h" -#import "ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.h" -#import "ios/chrome/grit/ios_strings.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace tailored_security_service_infobar_overlays { - -OVERLAY_USER_DATA_SETUP_IMPL(TailoredSecurityServiceBannerRequestConfig); - -TailoredSecurityServiceBannerRequestConfig:: - TailoredSecurityServiceBannerRequestConfig(infobars::InfoBar* infobar) - : infobar_(infobar) { - DCHECK(infobar_); - safe_browsing::TailoredSecurityServiceInfobarDelegate* delegate = - safe_browsing::TailoredSecurityServiceInfobarDelegate:: - FromInfobarDelegate(infobar_->delegate()); - message_text_ = delegate->GetMessageText(); - button_label_text_ = delegate->GetMessageActionText(); - description_ = delegate->GetDescription(); - message_state_ = delegate->message_state(); -} - -TailoredSecurityServiceBannerRequestConfig:: - ~TailoredSecurityServiceBannerRequestConfig() = default; - -void TailoredSecurityServiceBannerRequestConfig::CreateAuxiliaryData( - base::SupportsUserData* user_data) { - InfobarOverlayRequestConfig::CreateForUserData( - user_data, static_cast<InfoBarIOS*>(infobar_), - InfobarOverlayType::kBanner, false); -} - -} // namespace tailored_security_service_infobar_overlays
diff --git a/ios/chrome/browser/overlays/public/infobar_modal/BUILD.gn b/ios/chrome/browser/overlays/public/infobar_modal/BUILD.gn index 8e14eff..f4c8688 100644 --- a/ios/chrome/browser/overlays/public/infobar_modal/BUILD.gn +++ b/ios/chrome/browser/overlays/public/infobar_modal/BUILD.gn
@@ -10,10 +10,6 @@ "save_address_profile_infobar_modal_overlay_request_config.mm", "save_address_profile_infobar_modal_overlay_responses.h", "save_address_profile_infobar_modal_overlay_responses.mm", - "save_card_infobar_modal_overlay_request_config.h", - "save_card_infobar_modal_overlay_request_config.mm", - "save_card_infobar_modal_overlay_responses.h", - "save_card_infobar_modal_overlay_responses.mm", "translate_infobar_modal_overlay_request_config.h", "translate_infobar_modal_overlay_request_config.mm", "translate_infobar_modal_overlay_responses.h",
diff --git a/ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_request_config.h b/ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_request_config.h deleted file mode 100644 index 89825d5..0000000 --- a/ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_request_config.h +++ /dev/null
@@ -1,100 +0,0 @@ -// Copyright 2020 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_OVERLAYS_PUBLIC_INFOBAR_MODAL_SAVE_CARD_INFOBAR_MODAL_OVERLAY_REQUEST_CONFIG_H_ -#define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_MODAL_SAVE_CARD_INFOBAR_MODAL_OVERLAY_REQUEST_CONFIG_H_ - -#import <UIKit/UIKit.h> - -#include "ios/chrome/browser/overlays/public/overlay_request_config.h" - -#include "components/autofill/core/browser/payments/legal_message_line.h" -#include "ui/gfx/image/image.h" - -class InfoBarIOS; -@class SaveCardMessageWithLinks; - -namespace autofill { -class AutofillSaveCardInfoBarDelegateMobile; -} - -namespace save_card_infobar_overlays { - -// Configuration object for OverlayRequests for the modal UI for an infobar with -// a AutofillSaveCardInfoBarDelegateMobile. -class SaveCardModalRequestConfig - : public OverlayRequestConfig<SaveCardModalRequestConfig> { - public: - ~SaveCardModalRequestConfig() override; - - // The card holder name of the card. - const std::u16string& cardholder_name() const { return cardholder_name_; } - - // The expiration month of the card. - const std::u16string& expiration_date_month() const { - return expiration_date_month_; - } - - // The expiration year of the card. - const std::u16string& expiration_date_year() const { - return expiration_date_year_; - } - - // The last four digits of the card. - const std::u16string& card_last_four_digits() const { - return card_last_four_digits_; - } - - // The resource ID for the icon that identifies the issuer of the card. - int issuer_icon_id() const { return issuer_icon_id_; } - - // The legal disclaimer shown at the bottom of the modal. - NSArray<SaveCardMessageWithLinks*>* legal_message_lines() const { - return legal_message_lines_; - } - - // Whether the current card is already saved. - bool current_card_saved() const { return current_card_saved_; } - - // Whether the action is an upload or a local save. - bool should_upload_credentials() const { return should_upload_credentials_; } - - const std::u16string& displayed_target_account_email() const { - return displayed_target_account_email_; - } - - const gfx::Image& displayed_target_account_avatar() const { - return displayed_target_account_avatar_; - } - - private: - OVERLAY_USER_DATA_SETUP(SaveCardModalRequestConfig); - explicit SaveCardModalRequestConfig(InfoBarIOS* infobar); - - // OverlayUserData: - void CreateAuxiliaryData(base::SupportsUserData* user_data) override; - - // Return an array of UI SaveCardMessageWithLinks model objects for - // `delegate`'s legal_message_lines_. - NSMutableArray<SaveCardMessageWithLinks*>* LegalMessagesForModal( - autofill::AutofillSaveCardInfoBarDelegateMobile* delegate); - - // The InfoBar causing this modal. - InfoBarIOS* infobar_ = nullptr; - // Configuration data extracted from `infobar_`'s save card delegate. - std::u16string cardholder_name_; - std::u16string expiration_date_month_; - std::u16string expiration_date_year_; - std::u16string card_last_four_digits_; - int issuer_icon_id_; - NSArray<SaveCardMessageWithLinks*>* legal_message_lines_; - bool current_card_saved_ = false; - bool should_upload_credentials_ = false; - std::u16string displayed_target_account_email_; - gfx::Image displayed_target_account_avatar_; -}; - -} // namespace save_card_infobar_overlays - -#endif // IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_MODAL_SAVE_CARD_INFOBAR_MODAL_OVERLAY_REQUEST_CONFIG_H_
diff --git a/ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_request_config.mm b/ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_request_config.mm deleted file mode 100644 index 778736a..0000000 --- a/ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_request_config.mm +++ /dev/null
@@ -1,76 +0,0 @@ -// Copyright 2020 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/overlays/public/infobar_modal/save_card_infobar_modal_overlay_request_config.h" - -#import "base/check.h" -#import "base/strings/sys_string_conversions.h" -#import "components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.h" -#import "ios/chrome/browser/autofill/message/save_card_message_with_links.h" -#import "ios/chrome/browser/infobars/infobar_ios.h" -#import "ios/chrome/browser/overlays/public/common/infobars/infobar_overlay_request_config.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace save_card_infobar_overlays { - -OVERLAY_USER_DATA_SETUP_IMPL(SaveCardModalRequestConfig); - -SaveCardModalRequestConfig::SaveCardModalRequestConfig(InfoBarIOS* infobar) - : infobar_(infobar) { - DCHECK(infobar_); - autofill::AutofillSaveCardInfoBarDelegateMobile* delegate = - static_cast<autofill::AutofillSaveCardInfoBarDelegateMobile*>( - infobar_->delegate()); - - cardholder_name_ = delegate->cardholder_name(); - expiration_date_month_ = delegate->expiration_date_month(); - expiration_date_year_ = delegate->expiration_date_year(); - card_last_four_digits_ = delegate->card_last_four_digits(); - issuer_icon_id_ = delegate->issuer_icon_id(); - legal_message_lines_ = LegalMessagesForModal(delegate); - current_card_saved_ = infobar->accepted(); - should_upload_credentials_ = delegate->is_for_upload(); - displayed_target_account_email_ = delegate->displayed_target_account_email(); - displayed_target_account_avatar_ = - delegate->displayed_target_account_avatar(); -} - -SaveCardModalRequestConfig::~SaveCardModalRequestConfig() = default; - -void SaveCardModalRequestConfig::CreateAuxiliaryData( - base::SupportsUserData* user_data) { - InfobarOverlayRequestConfig::CreateForUserData( - user_data, infobar_, InfobarOverlayType::kModal, false); -} - -NSMutableArray<SaveCardMessageWithLinks*>* -SaveCardModalRequestConfig::LegalMessagesForModal( - autofill::AutofillSaveCardInfoBarDelegateMobile* delegate) { - NSMutableArray<SaveCardMessageWithLinks*>* legalMessages = - [[NSMutableArray alloc] init]; - // Only display legal Messages if the card is being uploaded and there are - // any. - if (delegate->is_for_upload() && !delegate->legal_message_lines().empty()) { - for (const auto& line : delegate->legal_message_lines()) { - SaveCardMessageWithLinks* message = - [[SaveCardMessageWithLinks alloc] init]; - message.messageText = base::SysUTF16ToNSString(line.text()); - NSMutableArray* linkRanges = [[NSMutableArray alloc] init]; - std::vector<GURL> linkURLs; - for (const auto& link : line.links()) { - [linkRanges addObject:[NSValue valueWithRange:link.range.ToNSRange()]]; - linkURLs.push_back(link.url); - } - message.linkRanges = linkRanges; - message.linkURLs = linkURLs; - [legalMessages addObject:message]; - } - } - return legalMessages; -} - -} // namespace save_card_infobar_overlays
diff --git a/ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_responses.h b/ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_responses.h deleted file mode 100644 index 9b37d481f..0000000 --- a/ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_responses.h +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2020 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_OVERLAYS_PUBLIC_INFOBAR_MODAL_SAVE_CARD_INFOBAR_MODAL_OVERLAY_RESPONSES_H_ -#define IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_MODAL_SAVE_CARD_INFOBAR_MODAL_OVERLAY_RESPONSES_H_ - -#import <Foundation/Foundation.h> - -#include "ios/chrome/browser/overlays/public/overlay_response_info.h" -#include "url/gurl.h" - -namespace save_card_infobar_overlays { - -// Main action response config for Save Card that passes the information of a -// card to be saved. -class SaveCardMainAction : public OverlayResponseInfo<SaveCardMainAction> { - public: - ~SaveCardMainAction() override; - - // The cardholder name of the card to be saved. - NSString* cardholder_name() const { return cardholder_name_; } - // The expiration month of the card to be saved. - NSString* expiration_month() const { return expiration_month_; } - // The expiration year of the card to be saved. - NSString* expiration_year() const { return expiration_year_; } - - private: - OVERLAY_USER_DATA_SETUP(SaveCardMainAction); - SaveCardMainAction(NSString* cardholder_name, - NSString* expiration_month, - NSString* expiration_year); - - NSString* cardholder_name_ = nil; - NSString* expiration_month_ = nil; - NSString* expiration_year_ = nil; -}; - -// Response config to load a URL tapped in the modal. -class SaveCardLoadURL : public OverlayResponseInfo<SaveCardLoadURL> { - public: - ~SaveCardLoadURL() override; - - const GURL& link_url() const { return link_url_; } - - private: - OVERLAY_USER_DATA_SETUP(SaveCardLoadURL); - SaveCardLoadURL(const GURL& link_url); - - GURL link_url_; -}; - -} // namespace save_card_infobar_overlays -#endif // IOS_CHROME_BROWSER_OVERLAYS_PUBLIC_INFOBAR_MODAL_SAVE_CARD_INFOBAR_MODAL_OVERLAY_RESPONSES_H_
diff --git a/ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_responses.mm b/ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_responses.mm deleted file mode 100644 index 0e90b31..0000000 --- a/ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_responses.mm +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2020 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/overlays/public/infobar_modal/save_card_infobar_modal_overlay_responses.h" - -#import "url/gurl.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace save_card_infobar_overlays { - -#pragma mark - SaveCardMainAction - -OVERLAY_USER_DATA_SETUP_IMPL(SaveCardMainAction); - -SaveCardMainAction::SaveCardMainAction(NSString* cardholder_name, - NSString* expiration_month, - NSString* expiration_year) - : cardholder_name_(cardholder_name), - expiration_month_(expiration_month), - expiration_year_(expiration_year) {} - -SaveCardMainAction::~SaveCardMainAction() = default; - -#pragma mark - SaveCardLoadURL - -OVERLAY_USER_DATA_SETUP_IMPL(SaveCardLoadURL); - -SaveCardLoadURL::SaveCardLoadURL(const GURL& link_url) : link_url_(link_url) {} - -SaveCardLoadURL::~SaveCardLoadURL() = default; - -} // namespace save_card_infobar_overlays
diff --git a/ios/chrome/browser/shared/model/prefs/browser_prefs.mm b/ios/chrome/browser/shared/model/prefs/browser_prefs.mm index 46656c2..2315626e 100644 --- a/ios/chrome/browser/shared/model/prefs/browser_prefs.mm +++ b/ios/chrome/browser/shared/model/prefs/browser_prefs.mm
@@ -404,6 +404,9 @@ // Register pref used to determine if Browser Lockdown Mode is enabled. registry->RegisterBooleanPref(prefs::kBrowserLockdownModeEnabled, false); + // Register pref used to determine if OS Lockdown Mode is enabled. + registry->RegisterBooleanPref(prefs::kOSLockdownModeEnabled, false); + ntp_snippets::prefs::RegisterProfilePrefsForMigrationApril2023(registry); registry->RegisterBooleanPref(kDeprecatedReadingListHasUnseenEntries, false);
diff --git a/ios/chrome/browser/shared/model/prefs/pref_names.cc b/ios/chrome/browser/shared/model/prefs/pref_names.cc index f078e9b..1c5821a 100644 --- a/ios/chrome/browser/shared/model/prefs/pref_names.cc +++ b/ios/chrome/browser/shared/model/prefs/pref_names.cc
@@ -241,6 +241,10 @@ const char kDefaultFollowingFeedSortTypeChanged[] = "ios.ntp.following_feed_default_sort_type_changed"; +// Boolean that is true when OS Lockdown Mode is enabled for their entire device +// through native iOS settings. +const char kOSLockdownModeEnabled[] = "ios.os_lockdown_mode_enabled"; + // Dictionary preference which tracks day(s) a given destination is clicked from // the new overflow menu carousel. const char kOverflowMenuDestinationUsageHistory[] =
diff --git a/ios/chrome/browser/shared/model/prefs/pref_names.h b/ios/chrome/browser/shared/model/prefs/pref_names.h index 5b4119e..32f30cb 100644 --- a/ios/chrome/browser/shared/model/prefs/pref_names.h +++ b/ios/chrome/browser/shared/model/prefs/pref_names.h
@@ -60,6 +60,7 @@ extern const char kNTPContentSuggestionsForSupervisedUserEnabled[]; extern const char kNTPFollowingFeedSortType[]; extern const char kDefaultFollowingFeedSortTypeChanged[]; +extern const char kOSLockdownModeEnabled[]; extern const char kOverflowMenuDestinationUsageHistory[]; extern const char kOverflowMenuNewDestinations[]; extern const char kOverflowMenuDestinationsOrder[];
diff --git a/ios/chrome/browser/shared/model/web_state_list/web_state_list_observer_bridge.h b/ios/chrome/browser/shared/model/web_state_list/web_state_list_observer_bridge.h index 60129a0..1927633 100644 --- a/ios/chrome/browser/shared/model/web_state_list/web_state_list_observer_bridge.h +++ b/ios/chrome/browser/shared/model/web_state_list/web_state_list_observer_bridge.h
@@ -15,6 +15,11 @@ @optional +// Invoked after the WebStateList is updated. +- (void)didChangeWebStateList:(WebStateList*)webStateList + change:(const WebStateListChange&)change + selection:(const WebStateSelection&)selection; + // Invoked after a new WebState has been added to the WebStateList at the // specified index. `activating` will be YES if the WebState will become // the new active WebState after the insertion. @@ -29,13 +34,6 @@ fromIndex:(int)fromIndex toIndex:(int)toIndex; -// Invoked after the WebState at the specified index is replaced by another -// WebState. -- (void)webStateList:(WebStateList*)webStateList - didReplaceWebState:(web::WebState*)oldWebState - withWebState:(web::WebState*)newWebState - atIndex:(int)atIndex; - // Invoked before the specified WebState is detached from the WebStateList. // The WebState is still valid and still in the WebStateList. - (void)webStateList:(WebStateList*)webStateList
diff --git a/ios/chrome/browser/shared/model/web_state_list/web_state_list_observer_bridge.mm b/ios/chrome/browser/shared/model/web_state_list/web_state_list_observer_bridge.mm index 16bd15b..6fe069a 100644 --- a/ios/chrome/browser/shared/model/web_state_list/web_state_list_observer_bridge.mm +++ b/ios/chrome/browser/shared/model/web_state_list/web_state_list_observer_bridge.mm
@@ -18,26 +18,14 @@ WebStateList* web_state_list, const WebStateListChange& change, const WebStateSelection& selection) { - switch (change.type()) { - case WebStateListChange::Type::kReplace: { - const WebStateListChangeReplace& replace_change = - change.As<WebStateListChangeReplace>(); - const SEL selector = @selector(webStateList: - didReplaceWebState:withWebState:atIndex:); - if (![observer_ respondsToSelector:selector]) { - return; - } - - // TODO(crbug.com/1442546): Introduce -webStateList:didWebStateListChanged - // to WebStateListObserverBridge and replace - // -webStateList:didReplaceWebState with it. - [observer_ webStateList:web_state_list - didReplaceWebState:replace_change.replaced_web_state() - withWebState:replace_change.inserted_web_state() - atIndex:selection.index]; - break; - } + const SEL selector = @selector(didChangeWebStateList:change:selection:); + if (![observer_ respondsToSelector:selector]) { + return; } + + [observer_ didChangeWebStateList:web_state_list + change:change + selection:selection]; } void WebStateListObserverBridge::WebStateInsertedAt(
diff --git a/ios/chrome/browser/shared/ui/util/pasteboard_util.h b/ios/chrome/browser/shared/ui/util/pasteboard_util.h index 34b3c16..ee7e27a 100644 --- a/ios/chrome/browser/shared/ui/util/pasteboard_util.h +++ b/ios/chrome/browser/shared/ui/util/pasteboard_util.h
@@ -19,9 +19,8 @@ // Stores `url` in the pasteboard. `url` must be valid. void StoreURLInPasteboard(const GURL& url); -// Stores `urls` in the pasteboard. `urls` must not be empty and each url -// within `urls` must be valid. (Use `ClearPasteboard()` explicitly to clear -// existing items.) +// Stores `urls` in the pasteboard. +// (Use `ClearPasteboard()` explicitly to clear existing items.) void StoreURLsInPasteboard(const std::vector<const GURL>& urls); // Stores `text` and `url` into the pasteboard.
diff --git a/ios/chrome/browser/shared/ui/util/pasteboard_util.mm b/ios/chrome/browser/shared/ui/util/pasteboard_util.mm index a0bebaf..8bf5935 100644 --- a/ios/chrome/browser/shared/ui/util/pasteboard_util.mm +++ b/ios/chrome/browser/shared/ui/util/pasteboard_util.mm
@@ -26,14 +26,11 @@ } void StoreURLsInPasteboard(const std::vector<const GURL>& urls) { - DCHECK(!urls.empty()); - NSMutableArray* pasteboard_items = [[NSMutableArray alloc] init]; for (const GURL& URL : urls) { - DCHECK(URL.is_valid()); - // Although this breaks the API contract, invalid URLs arrive here in - // production. Prevent crashing by continuing and early returning below if - // no valid URLs were passed in `urls`. (crbug.com/880525) + // Invalid URLs arrive here in production. Prevent crashing by continuing + // and early returning below if no valid URLs were passed in `urls`. + // (crbug.com/880525) if (!URL.is_valid()) { continue; }
diff --git a/ios/chrome/browser/sync/BUILD.gn b/ios/chrome/browser/sync/BUILD.gn index 2b5a77c..9394233f 100644 --- a/ios/chrome/browser/sync/BUILD.gn +++ b/ios/chrome/browser/sync/BUILD.gn
@@ -74,6 +74,7 @@ "//ios/chrome/browser/search_engines", "//ios/chrome/browser/sessions", "//ios/chrome/browser/shared/model/application_context", + "//ios/chrome/browser/shared/model/browser", "//ios/chrome/browser/shared/model/browser_state", "//ios/chrome/browser/shared/model/prefs:pref_names", "//ios/chrome/browser/shared/model/url:constants",
diff --git a/ios/chrome/browser/sync/session_sync_service_factory.mm b/ios/chrome/browser/sync/session_sync_service_factory.mm index 0d3e96df..98499bb4 100644 --- a/ios/chrome/browser/sync/session_sync_service_factory.mm +++ b/ios/chrome/browser/sync/session_sync_service_factory.mm
@@ -23,6 +23,7 @@ #import "components/sync_sessions/synced_window_delegates_getter.h" #import "ios/chrome/browser/favicon/favicon_service_factory.h" #import "ios/chrome/browser/history/history_service_factory.h" +#import "ios/chrome/browser/shared/model/browser/browser_list_factory.h" #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/shared/model/url/chrome_url_constants.h" #import "ios/chrome/browser/sync/device_info_sync_service_factory.h" @@ -60,13 +61,14 @@ // might inherit from other interfaces with same methods. class SyncSessionsClientImpl : public sync_sessions::SyncSessionsClient { public: - explicit SyncSessionsClientImpl(ChromeBrowserState* browser_state) + SyncSessionsClientImpl(ChromeBrowserState* browser_state, + BrowserList* browser_list) : browser_state_(browser_state), window_delegates_getter_( std::make_unique<IOSSyncedWindowDelegatesGetter>()), local_session_event_router_( std::make_unique<IOSChromeLocalSessionEventRouter>( - browser_state_, + browser_list, this, ios::sync_start_util::GetFlareForSyncableService( browser_state_->GetStatePath()))), @@ -162,6 +164,9 @@ web::BrowserState* context) const { ChromeBrowserState* browser_state = ChromeBrowserState::FromBrowserState(context); + BrowserList* browser_list = + BrowserListFactory::GetForBrowserState(browser_state); return std::make_unique<sync_sessions::SessionSyncServiceImpl>( - ::GetChannel(), std::make_unique<SyncSessionsClientImpl>(browser_state)); + ::GetChannel(), + std::make_unique<SyncSessionsClientImpl>(browser_state, browser_list)); }
diff --git a/ios/chrome/browser/sync/sessions/ios_chrome_local_session_event_router.h b/ios/chrome/browser/sync/sessions/ios_chrome_local_session_event_router.h index 2428af6..7f597ced 100644 --- a/ios/chrome/browser/sync/sessions/ios_chrome_local_session_event_router.h +++ b/ios/chrome/browser/sync/sessions/ios_chrome_local_session_event_router.h
@@ -15,12 +15,12 @@ #include "ios/chrome/browser/shared/model/web_state_list/web_state_list_observer.h" #include "ios/web/public/web_state_observer.h" -class ChromeBrowserState; class AllWebStateListObservationRegistrar; +class BrowserList; namespace sync_sessions { class SyncSessionsClient; -} +} // namespace sync_sessions // A LocalEventRouter that drives session sync via observation of // web::WebState-related events. @@ -28,8 +28,7 @@ : public sync_sessions::LocalSessionEventRouter { public: IOSChromeLocalSessionEventRouter( - // TODO(crbug.com/1450909): Pass a BrowserList directly instead. - ChromeBrowserState* browser_state, + BrowserList* browser_list, sync_sessions::SyncSessionsClient* sessions_client_, const syncer::SyncableService::StartSyncFlare& flare);
diff --git a/ios/chrome/browser/sync/sessions/ios_chrome_local_session_event_router.mm b/ios/chrome/browser/sync/sessions/ios_chrome_local_session_event_router.mm index 364ab44..9a98993 100644 --- a/ios/chrome/browser/sync/sessions/ios_chrome_local_session_event_router.mm +++ b/ios/chrome/browser/sync/sessions/ios_chrome_local_session_event_router.mm
@@ -14,8 +14,7 @@ #import "components/sync_sessions/synced_tab_delegate.h" #import "ios/chrome/browser/history/history_service_factory.h" #import "ios/chrome/browser/shared/model/browser/all_web_state_list_observation_registrar.h" -#import "ios/chrome/browser/shared/model/browser/browser_list_factory.h" -#import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h" +#import "ios/chrome/browser/shared/model/browser/browser_list.h" #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h" #import "ios/chrome/browser/sync/glue/sync_start_util.h" #import "ios/chrome/browser/sync/ios_chrome_synced_tab_delegate.h" @@ -37,11 +36,11 @@ } // namespace IOSChromeLocalSessionEventRouter::IOSChromeLocalSessionEventRouter( - ChromeBrowserState* browser_state, + BrowserList* browser_list, sync_sessions::SyncSessionsClient* sessions_client, const syncer::SyncableService::StartSyncFlare& flare) : registrar_(std::make_unique<AllWebStateListObservationRegistrar>( - BrowserListFactory::GetForBrowserState(browser_state), + browser_list, std::make_unique<Observer>(this), AllWebStateListObservationRegistrar::Mode::REGULAR)), sessions_client_(sessions_client),
diff --git a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h index 9127b22..cf99a2e 100644 --- a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h +++ b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.h
@@ -21,6 +21,7 @@ #include "components/autofill/core/browser/ui/payments/card_name_fix_flow_controller_impl.h" #include "components/autofill/core/browser/ui/payments/card_unmask_prompt_controller_impl.h" #include "components/autofill/core/browser/ui/payments/card_unmask_prompt_options.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #import "components/autofill/ios/browser/autofill_client_ios_bridge.h" #include "components/infobars/core/infobar_manager.h" @@ -138,7 +139,7 @@ void DidFillOrPreviewField(const std::u16string& autofilled_value, const std::u16string& profile_full_name) override; bool IsContextSecure() const override; - void ExecuteCommand(Suggestion::FrontendId id) override; + void ExecuteCommand(PopupItemId popup_item_id) override; void OpenPromoCodeOfferDetailsURL(const GURL& url) override; FormInteractionsFlowId GetCurrentFormInteractionsFlowId() override; LogManager* GetLogManager() const override;
diff --git a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm index 09125ab..02181ae5 100644 --- a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm +++ b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
@@ -24,6 +24,7 @@ #import "components/autofill/core/browser/payments/credit_card_otp_authenticator.h" #import "components/autofill/core/browser/payments/payments_client.h" #import "components/autofill/core/browser/ui/payments/card_unmask_prompt_view.h" +#import "components/autofill/core/browser/ui/popup_item_ids.h" #import "components/autofill/core/common/autofill_features.h" #import "components/autofill/core/common/autofill_prefs.h" #import "components/autofill/ios/browser/autofill_driver_ios.h" @@ -490,7 +491,7 @@ return IsContextSecureForWebState(web_state_); } -void ChromeAutofillClientIOS::ExecuteCommand(Suggestion::FrontendId id) { +void ChromeAutofillClientIOS::ExecuteCommand(PopupItemId popup_item_id) { NOTIMPLEMENTED(); }
diff --git a/ios/chrome/browser/ui/badges/badge_mediator.mm b/ios/chrome/browser/ui/badges/badge_mediator.mm index 0bed93f..789560f 100644 --- a/ios/chrome/browser/ui/badges/badge_mediator.mm +++ b/ios/chrome/browser/ui/badges/badge_mediator.mm
@@ -390,13 +390,20 @@ #pragma mark - WebStateListObserver -- (void)webStateList:(WebStateList*)webStateList - didReplaceWebState:(web::WebState*)oldWebState - withWebState:(web::WebState*)newWebState - atIndex:(int)atIndex { - DCHECK_EQ(self.webStateList, webStateList); - if (atIndex == webStateList->active_index()) - self.webState = newWebState; +- (void)didChangeWebStateList:(WebStateList*)webStateList + change:(const WebStateListChange&)change + selection:(const WebStateSelection&)selection { + switch (change.type()) { + case WebStateListChange::Type::kReplace: { + DCHECK_EQ(self.webStateList, webStateList); + const WebStateListChangeReplace& replaceChange = + change.As<WebStateListChangeReplace>(); + if (selection.index == webStateList->active_index()) { + self.webState = replaceChange.inserted_web_state(); + } + break; + } + } } - (void)webStateList:(WebStateList*)webStateList
diff --git a/ios/chrome/browser/ui/browser_view/tab_events_mediator.mm b/ios/chrome/browser/ui/browser_view/tab_events_mediator.mm index 4f2f82fb..670705d 100644 --- a/ios/chrome/browser/ui/browser_view/tab_events_mediator.mm +++ b/ios/chrome/browser/ui/browser_view/tab_events_mediator.mm
@@ -124,6 +124,33 @@ #pragma mark - WebStateListObserving methods +- (void)didChangeWebStateList:(WebStateList*)webStateList + change:(const WebStateListChange&)change + selection:(const WebStateSelection&)selection { + switch (change.type()) { + case WebStateListChange::Type::kReplace: { + const WebStateListChangeReplace& replaceChange = + change.As<WebStateListChangeReplace>(); + NewTabPageTabHelper* NTPTabHelper = + NewTabPageTabHelper::FromWebState(replaceChange.replaced_web_state()); + if (NTPTabHelper->IsActive()) { + [self stopNTPIfNeeded]; + } + + web::WebState* currentWebState = _webStateList->GetActiveWebState(); + web::WebState* newWebState = replaceChange.inserted_web_state(); + // Add `newTab`'s view to the hierarchy if it's the current Tab. + if (currentWebState == newWebState) { + // Set this before triggering any of the possible page loads in + // displayTabViewIfActive. + newWebState->SetKeepRenderProcessAlive(true); + [self.consumer displayTabViewIfActive]; + } + break; + } + } +} + - (void)webStateList:(WebStateList*)webStateList willDetachWebState:(web::WebState*)webState atIndex:(int)atIndex { @@ -203,27 +230,6 @@ } } -// Observer method, WebState replaced in `webStateList`. -- (void)webStateList:(WebStateList*)webStateList - didReplaceWebState:(web::WebState*)oldWebState - withWebState:(web::WebState*)newWebState - atIndex:(int)atIndex { - NewTabPageTabHelper* NTPTabHelper = - NewTabPageTabHelper::FromWebState(oldWebState); - if (NTPTabHelper->IsActive()) { - [self stopNTPIfNeeded]; - } - - web::WebState* currentWebState = _webStateList->GetActiveWebState(); - // Add `newTab`'s view to the hierarchy if it's the current Tab. - if (currentWebState == newWebState) { - // Set this before triggering any of the possible page loads in - // displayTabViewIfActive. - newWebState->SetKeepRenderProcessAlive(true); - [self.consumer displayTabViewIfActive]; - } -} - #pragma mark - WebStateListObserving helpers (Private) - (void)startNTPIfNeededForActiveWebState:(web::WebState*)webState {
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn index c886dd8..478e279 100644 --- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn +++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -358,7 +358,9 @@ "//ios/chrome/browser/signin:system_identity_manager", "//ios/chrome/browser/ui/authentication:eg_test_support+eg2", "//ios/chrome/browser/ui/authentication/cells:constants", + "//ios/chrome/browser/ui/authentication/signin:constants", "//ios/chrome/browser/ui/content_suggestions/cells:constants", + "//ios/chrome/browser/ui/first_run:constants", "//ios/chrome/browser/ui/ntp:constants", "//ios/chrome/browser/ui/ntp:feature_flags", "//ios/chrome/browser/ui/popup_menu:constants", @@ -366,6 +368,8 @@ "//ios/chrome/browser/ui/start_surface:feature_flags", "//ios/chrome/browser/ui/toolbar/public:constants", "//ios/chrome/browser/ui/whats_new:feature_flags", + "//ios/chrome/common/ui/confirmation_alert:constants", + "//ios/chrome/common/ui/promo_style:constants", "//ios/chrome/test:eg_test_support+eg2", "//ios/chrome/test/earl_grey:eg_test_support+eg2", "//ios/testing/earl_grey:eg_test_support+eg2", @@ -414,10 +418,13 @@ "//components/keyed_service/ios", "//components/search_engines", "//ios/chrome/browser/flags:system_flags", + "//ios/chrome/browser/ntp:set_up_list_item_type", + "//ios/chrome/browser/ntp:set_up_list_prefs", "//ios/chrome/browser/search_engines", "//ios/chrome/browser/shared/model/application_context", "//ios/chrome/browser/shared/model/browser_state", "//ios/chrome/browser/shared/ui/util", + "//ios/chrome/browser/ui/content_suggestions/set_up_list", "//ios/chrome/browser/ui/ntp:constants", "//ios/chrome/test/app:test_support", "//ios/testing:block_swizzler",
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm index a19d0f6..09d4f4a 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm
@@ -13,14 +13,22 @@ #import "base/test/ios/wait_util.h" #import "components/strings/grit/components_strings.h" #import "ios/chrome/browser/ntp/features.h" +#import "ios/chrome/browser/shared/model/prefs/pref_names.h" +#import "ios/chrome/browser/signin/fake_system_identity.h" +#import "ios/chrome/browser/ui/authentication/signin/signin_constants.h" +#import "ios/chrome/browser/ui/authentication/signin_earl_grey.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h" #import "ios/chrome/browser/ui/content_suggestions/new_tab_page_app_interface.h" #import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h" +#import "ios/chrome/browser/ui/first_run/first_run_constants.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_constants.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_feature.h" +#import "ios/chrome/common/ui/confirmation_alert/constants.h" +#import "ios/chrome/common/ui/promo_style/constants.h" #import "ios/chrome/grit/ios_strings.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" +#import "ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h" #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" @@ -56,6 +64,78 @@ return std::move(http_response); } +// Matcher for the SetUpList. +id<GREYMatcher> SetUpList() { + return grey_allOf(grey_accessibilityID(@"kSetUpListAccessibilityID"), + grey_sufficientlyVisible(), nil); +} + +// Returns matcher for the secondary action button. +id<GREYMatcher> SetUpListAllSet() { + return grey_accessibilityID(@"kSetUpListAllSetID"); +} + +// Scrolls to the SetUpList, if it is off-screen. +void ScrollToSetUpList() { + [[[EarlGrey selectElementWithMatcher:SetUpList()] + usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 200) + onElementWithMatcher:chrome_test_util::NTPCollectionView()] + assertWithMatcher:grey_notNil()]; +} + +// Taps the view with the given `accessibility_id`. +void TapView(NSString* accessibility_id) { + id<GREYMatcher> matcher = grey_accessibilityID(accessibility_id); + [[EarlGrey selectElementWithMatcher:matcher] assertWithMatcher:grey_notNil()]; + [[EarlGrey selectElementWithMatcher:matcher] performAction:grey_tap()]; +} + +// Tap the PromoStylePrimaryActionButton. +void TapPromoStylePrimaryActionButton() { + id<GREYMatcher> button = + grey_accessibilityID(kPromoStylePrimaryActionAccessibilityIdentifier); + [[EarlGrey selectElementWithMatcher:button] assertWithMatcher:grey_notNil()]; + [[EarlGrey selectElementWithMatcher:button] performAction:grey_tap()]; +} + +// Tap the PromoStyleSecondaryActionButton. +void TapPromoStyleSecondaryActionButton() { + id<GREYMatcher> button = + grey_accessibilityID(kPromoStyleSecondaryActionAccessibilityIdentifier); + [[EarlGrey selectElementWithMatcher:button] assertWithMatcher:grey_notNil()]; + [[EarlGrey selectElementWithMatcher:button] performAction:grey_tap()]; +} + +// Tap the ConfirmationAlertSecondaryAction Button. +void TapSecondaryActionButton() { + id<GREYMatcher> button = grey_accessibilityID( + kConfirmationAlertSecondaryActionAccessibilityIdentifier); + [[EarlGrey selectElementWithMatcher:button] assertWithMatcher:grey_notNil()]; + [[EarlGrey selectElementWithMatcher:button] performAction:grey_tap()]; +} + +// Tap the SetUpList button to expand the list. +void TapSetUpListExpand() { + id<GREYMatcher> expandButton = + grey_accessibilityID(@"kSetUpListExpandButtonID"); + [[EarlGrey selectElementWithMatcher:expandButton] + assertWithMatcher:grey_notNil()]; + [[EarlGrey selectElementWithMatcher:expandButton] performAction:grey_tap()]; +} + +// Tap the "More" button if it is visible. +void TapMoreButtonIfVisible() { + id<GREYInteraction> button = + [EarlGrey selectElementWithMatcher: + grey_accessibilityID( + @"PromoStyleReadMoreActionAccessibilityIdentifier")]; + NSError* error; + [button assertWithMatcher:grey_notNil() error:&error]; + if (!error) { + [button performAction:grey_tap()]; + } +} + } // namespace #pragma mark - TestCase @@ -71,7 +151,9 @@ - (AppLaunchConfiguration)appConfigurationForTestCase { AppLaunchConfiguration config; + config.features_disabled.push_back(kMagicStack); config.features_enabled.push_back(kEnableFeedAblation); + config.features_enabled.push_back(kIOSSetUpList); return config; } @@ -96,6 +178,7 @@ - (void)tearDown { [ChromeEarlGrey clearBrowsingHistory]; + [ChromeEarlGreyAppInterface removeFirstRunSentinel]; [super tearDown]; } @@ -228,8 +311,154 @@ assertWithMatcher:grey_nil()]; } +#pragma mark - Set Up List tests + +// Tests that the SetUpList can be expanded and unexpanded by touching the +// "expand" button at the bottom of the list. +- (void)testSetUpListExpands { + [self prepareToTestSetUpList]; + + id<GREYMatcher> signinItem = grey_accessibilityID(@"kSetUpListItemSignInID"); + id<GREYMatcher> defaultBrowserItem = + grey_accessibilityID(@"kSetUpListItemDefaultBrowserID"); + id<GREYMatcher> autofillItem = + grey_accessibilityID(@"kSetUpListItemAutofillID"); + [[EarlGrey selectElementWithMatcher:signinItem] + assertWithMatcher:grey_notNil()]; + [[EarlGrey selectElementWithMatcher:defaultBrowserItem] + assertWithMatcher:grey_notNil()]; + [[EarlGrey selectElementWithMatcher:autofillItem] + assertWithMatcher:grey_nil()]; + + TapSetUpListExpand(); + ScrollToSetUpList(); + + // Autofill item should appear. + [[EarlGrey selectElementWithMatcher:autofillItem] + assertWithMatcher:grey_notNil()]; + + TapSetUpListExpand(); + + // Autofill item should disappear. + [[EarlGrey selectElementWithMatcher:autofillItem] + assertWithMatcher:grey_nil()]; +} + +// Tests that each item opens the appropriate UI flow and that dismissing that +// UI marks the item complete. Also tests that the "All Set" view appears when +// all items are complete. +- (void)testSetUpListDismissItems { + [self prepareToTestSetUpList]; + + // Tap the signin item. + TapView(@"kSetUpListItemSignInID"); + // Verify the signin screen appears and touch "Don't Sign In". + id<GREYMatcher> signinView = grey_accessibilityID( + first_run::kFirstRunSignInScreenAccessibilityIdentifier); + [[EarlGrey selectElementWithMatcher:signinView] + assertWithMatcher:grey_notNil()]; + // Dismiss the signin view. + TapPromoStyleSecondaryActionButton(); + // Verify the signin item is complete. + GREYAssertTrue([NewTabPageAppInterface setUpListItemSignInSyncIsComplete], + @"SetUpList item SignIn not completed."); + + // Tap the default browser item. + TapView(@"kSetUpListItemDefaultBrowserID"); + // Ensure the Default Browser Promo is displayed. + id<GREYMatcher> defaultBrowserView = grey_accessibilityID( + first_run::kFirstRunDefaultBrowserScreenAccessibilityIdentifier); + [[EarlGrey selectElementWithMatcher:defaultBrowserView] + assertWithMatcher:grey_notNil()]; + // Dismiss Default Browser Promo. + TapPromoStyleSecondaryActionButton(); + // Verify the default browser item is complete. + GREYAssertTrue([NewTabPageAppInterface setUpListItemDefaultBrowserIsComplete], + @"SetUpList item Default Browser not completed."); + + TapSetUpListExpand(); + ScrollToSetUpList(); + + // Tap the autofill item. + TapView(@"kSetUpListItemAutofillID"); + // TODO - verify the CPE promo is displayed. + id<GREYMatcher> CPEPromoView = + grey_accessibilityID(@"kCredentialProviderPromoAccessibilityId"); + [[EarlGrey selectElementWithMatcher:CPEPromoView] + assertWithMatcher:grey_notNil()]; + // Dismiss the CPE promo. + TapSecondaryActionButton(); + // Verify the Autofill item is complete. + GREYAssertTrue([NewTabPageAppInterface setUpListItemAutofillIsComplete], + @"SetUpList item Autofill not completed."); + + // Verify All Set view appears. + [ChromeEarlGrey waitForUIElementToAppearWithMatcher:SetUpListAllSet()]; + + // Close NTP and reopen. + [ChromeEarlGrey closeAllTabs]; + [ChromeEarlGrey openNewTab]; + // SetUpList is still visible. + [[EarlGrey selectElementWithMatcher:SetUpList()] + assertWithMatcher:grey_notNil()]; + + // Close NTP and reopen. SetUpList should not be visible. + [ChromeEarlGrey closeAllTabs]; + [ChromeEarlGrey openNewTab]; + // SetUpList is not visible. + [[EarlGrey selectElementWithMatcher:SetUpList()] + assertWithMatcher:grey_nil()]; +} + +// Tests that the signin UI flow works and that the signin item is marked +// complete when signin is completed. +- (void)testSetUpListSignin { + [self prepareToTestSetUpList]; + [SigninEarlGrey addFakeIdentity:[FakeSystemIdentity fakeIdentity1]]; + + // Tap the signin item. + TapView(@"kSetUpListItemSignInID"); + // Verify the signin screen appears and touch "Continue as ...". + id<GREYMatcher> signinView = grey_accessibilityID( + first_run::kFirstRunSignInScreenAccessibilityIdentifier); + [[EarlGrey selectElementWithMatcher:signinView] + assertWithMatcher:grey_notNil()]; + // Tap "Continue as ...". + TapPromoStylePrimaryActionButton(); + + // Verify the tangible sync screen appears. + id<GREYMatcher> syncView = + grey_accessibilityID(kTangibleSyncViewAccessibilityIdentifier); + [[EarlGrey selectElementWithMatcher:syncView] + assertWithMatcher:grey_notNil()]; + // On small screens, we may need to tap the "More" button. + TapMoreButtonIfVisible(); + // Tap "Yes, I'm in". + TapPromoStylePrimaryActionButton(); + + // Verify the signin item is complete. + GREYAssertTrue([NewTabPageAppInterface setUpListItemSignInSyncIsComplete], + @"SetUpList item SignIn not completed."); +} + #pragma mark - Test utils +// Sets up the test case to test SetUpList. +- (void)prepareToTestSetUpList { + [ChromeEarlGreyAppInterface writeFirstRunSentinel]; + [ChromeEarlGreyAppInterface clearDefaultBrowserPromoData]; + [ChromeEarlGrey resetDataForLocalStatePref: + prefs::kIosCredentialProviderPromoLastActionTaken]; + [NewTabPageAppInterface resetSetUpListPrefs]; + [ChromeEarlGrey closeAllTabs]; + [ChromeEarlGrey openNewTab]; + ScrollToSetUpList(); + + // SetUpList is visible + [[EarlGrey selectElementWithMatcher:SetUpList()] + assertWithMatcher:grey_notNil()]; +} + // Setup a most visited tile, and open the context menu by long pressing on it. - (void)setupMostVisitedTileLongPress { self.testServer->RegisterRequestHandler(
diff --git a/ios/chrome/browser/ui/content_suggestions/new_tab_page_app_interface.h b/ios/chrome/browser/ui/content_suggestions/new_tab_page_app_interface.h index 80ca1443..b5c34d7 100644 --- a/ios/chrome/browser/ui/content_suggestions/new_tab_page_app_interface.h +++ b/ios/chrome/browser/ui/content_suggestions/new_tab_page_app_interface.h
@@ -29,6 +29,18 @@ // Returns the Discover header label. + (UILabel*)discoverHeaderLabel; +// Resets SetUpList prefs to clear any completed items. ++ (void)resetSetUpListPrefs; + +// Returns YES if the SetUpListItemView for SignInSync is complete. ++ (BOOL)setUpListItemSignInSyncIsComplete; + +// Returns YES if the SetUpListItemView for DefaultBrowser is complete. ++ (BOOL)setUpListItemDefaultBrowserIsComplete; + +// Returns YES if the SetUpListItemView for Autofill is complete. ++ (BOOL)setUpListItemAutofillIsComplete; + @end #endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_NEW_TAB_PAGE_APP_INTERFACE_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/new_tab_page_app_interface.mm b/ios/chrome/browser/ui/content_suggestions/new_tab_page_app_interface.mm index 009ed47..2e1ee05 100644 --- a/ios/chrome/browser/ui/content_suggestions/new_tab_page_app_interface.mm +++ b/ios/chrome/browser/ui/content_suggestions/new_tab_page_app_interface.mm
@@ -9,12 +9,15 @@ #import "base/strings/utf_string_conversions.h" #import "components/keyed_service/ios/browser_state_keyed_service_factory.h" #import "ios/chrome/browser/flags/system_flags.h" +#import "ios/chrome/browser/ntp/set_up_list_item_type.h" +#import "ios/chrome/browser/ntp/set_up_list_prefs.h" #import "ios/chrome/browser/search_engines/template_url_service_factory.h" #import "ios/chrome/browser/shared/model/application_context/application_context.h" #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h" #import "ios/chrome/browser/ui/content_suggestions/ntp_home_test_utils.h" +#import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view.h" #import "ios/chrome/test/app/chrome_test_util.h" #import "net/base/mac/url_conversions.h" @@ -23,6 +26,7 @@ #endif using content_suggestions::SearchFieldWidth; +using set_up_list_prefs::SetUpListItemState; @implementation NewTabPageAppInterface @@ -49,4 +53,33 @@ return ntp_home::DiscoverHeaderLabel(); } ++ (void)resetSetUpListPrefs { + PrefService* localState = GetApplicationContext()->GetLocalState(); + SetUpListItemState unknown = SetUpListItemState::kUnknown; + set_up_list_prefs::SetItemState(localState, SetUpListItemType::kSignInSync, + unknown); + set_up_list_prefs::SetItemState(localState, + SetUpListItemType::kDefaultBrowser, unknown); + set_up_list_prefs::SetItemState(localState, SetUpListItemType::kAutofill, + unknown); +} + ++ (BOOL)setUpListItemSignInSyncIsComplete { + return ntp_home::SetUpListItemViewWithAccessibilityId( + @"kSetUpListItemSignInID") + .complete; +} + ++ (BOOL)setUpListItemDefaultBrowserIsComplete { + return ntp_home::SetUpListItemViewWithAccessibilityId( + @"kSetUpListItemDefaultBrowserID") + .complete; +} + ++ (BOOL)setUpListItemAutofillIsComplete { + return ntp_home::SetUpListItemViewWithAccessibilityId( + @"kSetUpListItemAutofillID") + .complete; +} + @end
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_test_utils.h b/ios/chrome/browser/ui/content_suggestions/ntp_home_test_utils.h index c9dd4a7..be85d508 100644 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_test_utils.h +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_test_utils.h
@@ -10,6 +10,7 @@ #include "url/gurl.h" @protocol GREYMatcher; +@class SetUpListItemView; namespace ntp_home { // Returns the primary collection view of the new tab page. Returns nil if it is @@ -27,6 +28,11 @@ // Returns the label corresponding to the Discover header label. Returns nil if // it is not in the view hierarchy. UILabel* DiscoverHeaderLabel(); + +// Returns the SetUpListItemView with the given `accessibility_id`. +SetUpListItemView* SetUpListItemViewWithAccessibilityId( + NSString* accessibility_id); + } // namespace ntp_home #endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_NTP_HOME_TEST_UTILS_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_test_utils.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_test_utils.mm index a4403ccf..17d8d38 100644 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_test_utils.mm +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_test_utils.mm
@@ -11,6 +11,8 @@ #import "base/strings/utf_string_conversions.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h" #import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h" +#import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view.h" +#import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_view.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_constants.h" #import "ios/testing/earl_grey/earl_grey_app.h" #import "ios/web/common/uikit_ui_util.h" @@ -39,6 +41,12 @@ return nil; } +// Returns the SetUpListView, if present. +SetUpListView* GetSetUpListView() { + return base::mac::ObjCCast<SetUpListView>(SubviewWithAccessibilityIdentifier( + @"kSetUpListAccessibilityID", GetAnyKeyWindow())); +} + } // namespace namespace ntp_home { @@ -65,4 +73,10 @@ DiscoverHeaderTitleAccessibilityID(), GetAnyKeyWindow())); } +SetUpListItemView* SetUpListItemViewWithAccessibilityId( + NSString* accessibility_id) { + return base::mac::ObjCCast<SetUpListItemView>( + SubviewWithAccessibilityIdentifier(accessibility_id, GetSetUpListView())); +} + } // namespace ntp_home
diff --git a/ios/chrome/browser/ui/infobars/coordinators/BUILD.gn b/ios/chrome/browser/ui/infobars/coordinators/BUILD.gn index 0da8db37..cdd5e505 100644 --- a/ios/chrome/browser/ui/infobars/coordinators/BUILD.gn +++ b/ios/chrome/browser/ui/infobars/coordinators/BUILD.gn
@@ -15,6 +15,7 @@ "//components/infobars/core", "//ios/chrome/browser/infobars:public", "//ios/chrome/browser/shared/coordinator/chrome_coordinator", + "//ios/chrome/browser/shared/coordinator/layout_guide", "//ios/chrome/browser/shared/model/browser", "//ios/chrome/browser/shared/public/commands", "//ios/chrome/browser/shared/ui/util",
diff --git a/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinator.mm b/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinator.mm index ff666a03..0980d38 100644 --- a/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinator.mm +++ b/ios/chrome/browser/ui/infobars/coordinators/infobar_coordinator.mm
@@ -9,8 +9,10 @@ #import "base/metrics/user_metrics.h" #import "base/metrics/user_metrics_action.h" #import "base/timer/timer.h" +#import "ios/chrome/browser/shared/coordinator/layout_guide/layout_guide_util.h" #import "ios/chrome/browser/shared/model/browser/browser.h" -#import "ios/chrome/browser/shared/ui/util/named_guide.h" +#import "ios/chrome/browser/shared/ui/util/layout_guide_names.h" +#import "ios/chrome/browser/shared/ui/util/util_swift.h" #import "ios/chrome/browser/ui/fullscreen/animated_scoped_fullscreen_disabler.h" #import "ios/chrome/browser/ui/fullscreen/fullscreen_controller.h" #import "ios/chrome/browser/ui/infobars/banners/infobar_banner_accessibility_util.h" @@ -230,12 +232,10 @@ #pragma mark InfobarBannerPositioner - (CGFloat)bannerYPosition { - NamedGuide* omniboxGuide = - [NamedGuide guideWithName:kOmniboxGuide - view:self.baseViewController.view]; - UIView* omniboxView = omniboxGuide.owningView; - CGRect omniboxFrame = [omniboxView convertRect:omniboxGuide.layoutFrame - toView:omniboxView.window]; + LayoutGuideCenter* layoutGuideCenter = + LayoutGuideCenterForBrowser(self.browser); + UIView* omnibox = [layoutGuideCenter referencedViewUnderName:kOmniboxGuide]; + CGRect omniboxFrame = [omnibox convertRect:omnibox.bounds toView:nil]; return CGRectGetMaxY(omniboxFrame); }
diff --git a/ios/chrome/browser/ui/main_content/web_scroll_view_main_content_ui_forwarder.mm b/ios/chrome/browser/ui/main_content/web_scroll_view_main_content_ui_forwarder.mm index cd3edbd4..0106de3 100644 --- a/ios/chrome/browser/ui/main_content/web_scroll_view_main_content_ui_forwarder.mm +++ b/ios/chrome/browser/ui/main_content/web_scroll_view_main_content_ui_forwarder.mm
@@ -179,12 +179,20 @@ #pragma mark - WebStateListObserving -- (void)webStateList:(WebStateList*)webStateList - didReplaceWebState:(web::WebState*)oldWebState - withWebState:(web::WebState*)newWebState - atIndex:(int)atIndex { - if (newWebState == webStateList->GetActiveWebState()) - self.webState = newWebState; +- (void)didChangeWebStateList:(WebStateList*)webStateList + change:(const WebStateListChange&)change + selection:(const WebStateSelection&)selection { + switch (change.type()) { + case WebStateListChange::Type::kReplace: { + const WebStateListChangeReplace& replaceChange = + change.As<WebStateListChangeReplace>(); + web::WebState* insertedWebState = replaceChange.inserted_web_state(); + if (insertedWebState == webStateList->GetActiveWebState()) { + self.webState = insertedWebState; + } + break; + } + } } - (void)webStateList:(WebStateList*)webStateList
diff --git a/ios/chrome/browser/ui/ntp/metrics/BUILD.gn b/ios/chrome/browser/ui/ntp/metrics/BUILD.gn index cd7bd60..bd2047e0 100644 --- a/ios/chrome/browser/ui/ntp/metrics/BUILD.gn +++ b/ios/chrome/browser/ui/ntp/metrics/BUILD.gn
@@ -7,6 +7,8 @@ sources = [ "feed_metrics_constants.h", "feed_metrics_constants.mm", + "feed_metrics_provider.h", + "feed_metrics_provider.mm", "feed_metrics_recorder+testing.h", "feed_metrics_recorder.h", "feed_metrics_recorder.mm", @@ -25,6 +27,7 @@ "//base", "//components/favicon_base", "//components/feed/core/v2/public:common", + "//components/metrics", "//components/ntp_tiles", "//ios/chrome/browser/discover_feed:constants", "//ios/chrome/browser/discover_feed:discover_feed_refresher", @@ -44,6 +47,7 @@ configs += [ "//build/config/compiler:enable_arc" ] testonly = true sources = [ + "feed_metrics_provider_unittest.mm", "feed_metrics_recorder_unittest.mm", "feed_session_recorder_unittest.mm", ]
diff --git a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.h b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.h index 69ca250..74dd1980 100644 --- a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.h +++ b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.h
@@ -250,6 +250,9 @@ // Histogram name for the feed activity bucket metric. extern const char kAllFeedsActivityBucketsHistogram[]; +// Histogram name for the feed activity bucket filter. +extern const char kAllFeedsActivityBucketsByProviderHistogram[]; + // Histogram name for a Discover feed card shown at index. extern const char kDiscoverFeedCardShownAtIndex[];
diff --git a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.mm b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.mm index e4ecd9e..b4dc58f 100644 --- a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.mm +++ b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.mm
@@ -57,6 +57,8 @@ "ContentSuggestions.Feed.WebFeed.Shown"; const char kAllFeedsActivityBucketsHistogram[] = "ContentSuggestions.Feed.AllFeeds.Activity"; +const char kAllFeedsActivityBucketsByProviderHistogram[] = + "ContentSuggestions.Feed.AllFeeds.Activity.ByProvider"; const char kDiscoverFeedNoticeCardFulfilled[] = "ContentSuggestions.Feed.NoticeCardFulfilled2"; const char kDiscoverFeedArticlesFetchNetworkDurationSuccess[] =
diff --git a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_provider.h b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_provider.h new file mode 100644 index 0000000..ce80aaf --- /dev/null +++ b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_provider.h
@@ -0,0 +1,23 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_NTP_METRICS_FEED_METRICS_PROVIDER_H_ +#define IOS_CHROME_BROWSER_UI_NTP_METRICS_FEED_METRICS_PROVIDER_H_ + +#import "components/metrics/metrics_provider.h" + +class FeedMetricsProvider : public metrics::MetricsProvider { + public: + explicit FeedMetricsProvider(); + FeedMetricsProvider(const FeedMetricsProvider&) = delete; + FeedMetricsProvider& operator=(const FeedMetricsProvider&) = delete; + + ~FeedMetricsProvider() override; + + // metrics::MetricsProvider + void ProvideCurrentSessionData( + metrics::ChromeUserMetricsExtension* uma_proto) override; +}; + +#endif // IOS_CHROME_BROWSER_UI_NTP_METRICS_FEED_METRICS_PROVIDER_H_
diff --git a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_provider.mm b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_provider.mm new file mode 100644 index 0000000..c62d77d --- /dev/null +++ b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_provider.mm
@@ -0,0 +1,25 @@ +// 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. + +#import "ios/chrome/browser/ui/ntp/metrics/feed_metrics_provider.h" + +#import "base/metrics/histogram_functions.h" +#import "ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +FeedMetricsProvider::FeedMetricsProvider() {} + +FeedMetricsProvider::~FeedMetricsProvider() {} + +void FeedMetricsProvider::ProvideCurrentSessionData( + metrics::ChromeUserMetricsExtension* uma_proto) { + // Retrieve activity bucket from storage. + FeedActivityBucket activityBucket = (FeedActivityBucket) + [[NSUserDefaults standardUserDefaults] integerForKey:kActivityBucketKey]; + base::UmaHistogramEnumeration(kAllFeedsActivityBucketsByProviderHistogram, + activityBucket); +}
diff --git a/ios/chrome/browser/ui/ntp/metrics/feed_metrics_provider_unittest.mm b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_provider_unittest.mm new file mode 100644 index 0000000..d7154fa7 --- /dev/null +++ b/ios/chrome/browser/ui/ntp/metrics/feed_metrics_provider_unittest.mm
@@ -0,0 +1,37 @@ +// 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. + +#import "ios/chrome/browser/ui/ntp/metrics/feed_metrics_provider.h" + +#import "base/test/metrics/histogram_tester.h" +#import "ios/chrome/browser/ui/ntp/metrics/feed_metrics_constants.h" +#import "testing/platform_test.h" +#import "third_party/ocmock/OCMock/OCMock.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +// Tests metrics that are recorded and uploaded by +// FeedMetricsProvider. +class FeedMetricsProviderTest : public PlatformTest { + public: + FeedMetricsProviderTest() { + histogram_tester_.reset(new base::HistogramTester()); + } + + protected: + void TearDown() override { PlatformTest::TearDown(); } + std::unique_ptr<base::HistogramTester> histogram_tester_; +}; + +// Tests the implementation of ProvideCurrentSessionData +TEST_F(FeedMetricsProviderTest, ProvideCurrentSessionData) { + FeedMetricsProvider provider; + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; + [defaults setInteger:1 forKey:kActivityBucketKey]; + provider.ProvideCurrentSessionData(nullptr /* uma_proto */); + histogram_tester_->ExpectBucketCount( + kAllFeedsActivityBucketsByProviderHistogram, 1, 1); +}
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm b/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm index 1ba3b92..5360c30 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_header_view_controller.mm
@@ -21,7 +21,6 @@ #import "ios/chrome/browser/shared/public/features/features.h" #import "ios/chrome/browser/shared/ui/symbols/symbols.h" #import "ios/chrome/browser/shared/ui/util/layout_guide_names.h" -#import "ios/chrome/browser/shared/ui/util/named_guide.h" #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h" #import "ios/chrome/browser/shared/ui/util/util_swift.h" #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h" @@ -145,11 +144,10 @@ self.fakeOmniboxWidthConstraint.constant = self.headerView.bounds.size.width; [self.headerView layoutIfNeeded]; - NamedGuide* omniboxGuide = [NamedGuide guideWithName:kOmniboxGuide - view:self.headerView]; - CGRect omniboxFrameInFakebox = - [[omniboxGuide owningView] convertRect:[omniboxGuide layoutFrame] - toView:self.fakeOmnibox]; + UIView* omnibox = + [self.layoutGuideCenter referencedViewUnderName:kOmniboxGuide]; + CGRect omniboxFrameInFakebox = [omnibox convertRect:omnibox.bounds + toView:self.fakeOmnibox]; self.headerView.fakeLocationBarLeadingConstraint.constant = omniboxFrameInFakebox.origin.x; self.headerView.fakeLocationBarTrailingConstraint.constant =
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm index 3a2c8eb..783a657 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm
@@ -168,6 +168,7 @@ self.mediator.presenter = [[OmniboxPopupPresenter alloc] initWithPopupPresenterDelegate:self.presenterDelegate popupViewController:self.popupViewController + layoutGuideCenter:LayoutGuideCenterForBrowser(self.browser) incognito:isIncognito]; _popupView->SetMediator(self.mediator);
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h index 038fdf7..02ad132 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h
@@ -8,6 +8,7 @@ #import <UIKit/UIKit.h> @protocol ContentProviding; +@class LayoutGuideCenter; @class OmniboxPopupPresenter; @protocol OmniboxPopupPresenterDelegate @@ -43,12 +44,13 @@ /// Tells the presenter to update, following a trait collection change. - (void)updatePopupAfterTraitCollectionChange; -- (instancetype)initWithPopupPresenterDelegate: - (id<OmniboxPopupPresenterDelegate>)presenterDelegate - popupViewController: - (UIViewController<ContentProviding>*) - viewController - incognito:(BOOL)incognito; +- (instancetype) + initWithPopupPresenterDelegate: + (id<OmniboxPopupPresenterDelegate>)presenterDelegate + popupViewController: + (UIViewController<ContentProviding>*)viewController + layoutGuideCenter:(LayoutGuideCenter*)layoutGuideCenter + incognito:(BOOL)incognito; @end
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm index 047bcc872..8e72ba1 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm
@@ -5,8 +5,9 @@ #import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h" #import "ios/chrome/browser/shared/public/features/features.h" -#import "ios/chrome/browser/shared/ui/util/named_guide.h" +#import "ios/chrome/browser/shared/ui/util/layout_guide_names.h" #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h" +#import "ios/chrome/browser/shared/ui/util/util_swift.h" #import "ios/chrome/browser/ui/omnibox/omnibox_ui_features.h" #import "ios/chrome/browser/ui/omnibox/popup/content_providing.h" #import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_container_view.h" @@ -39,6 +40,9 @@ /// Separator for the bottom edge of the popup on iPad. @property(nonatomic, strong) UIView* bottomSeparator; +// The layout guide center to use to refer to the omnibox. +@property(nonatomic, strong) LayoutGuideCenter* layoutGuideCenter; + @end @implementation OmniboxPopupPresenter @@ -47,11 +51,13 @@ initWithPopupPresenterDelegate:(id<OmniboxPopupPresenterDelegate>)delegate popupViewController: (UIViewController<ContentProviding>*)viewController + layoutGuideCenter:(LayoutGuideCenter*)layoutGuideCenter incognito:(BOOL)incognito { self = [super init]; if (self) { _delegate = delegate; _viewController = viewController; + _layoutGuideCenter = layoutGuideCenter; // Popup uses same colors as the toolbar, so the ToolbarConfiguration is // used to get the style. @@ -199,13 +205,14 @@ constraintGreaterThanOrEqualToAnchor:popup.bottomAnchor constant:kPopupBottomPaddingTablet]; - // Position the top anchor of the popup relatively to the layout guide - // positioned on the omnibox. - UILayoutGuide* omniboxGuide = [NamedGuide guideWithName:kOmniboxGuide - view:popup]; + // Install in the superview the guide tracking the omnibox. + UILayoutGuide* omniboxGuide = + [self.layoutGuideCenter makeLayoutGuideNamed:kOmniboxGuide]; + [[popup superview] addLayoutGuide:omniboxGuide]; + // Position the top anchor of the popup relatively to that layout guide. NSLayoutConstraint* topConstraint = - [popup.topAnchor constraintEqualToAnchor:omniboxGuide.bottomAnchor]; - topConstraint.constant = kVerticalOffset; + [popup.topAnchor constraintEqualToAnchor:omniboxGuide.bottomAnchor + constant:kVerticalOffset]; NSMutableArray<NSLayoutConstraint*>* constraintsToActivate = [NSMutableArray arrayWithObject:topConstraint];
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm index f49921e6..25d3e89 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm
@@ -16,8 +16,8 @@ #import "ios/chrome/browser/shared/ui/elements/self_sizing_table_view.h" #import "ios/chrome/browser/shared/ui/util/keyboard_observer_helper.h" #import "ios/chrome/browser/shared/ui/util/layout_guide_names.h" -#import "ios/chrome/browser/shared/ui/util/named_guide.h" #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h" +#import "ios/chrome/browser/shared/ui/util/util_swift.h" #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_tile_layout_util.h" #import "ios/chrome/browser/ui/favicon/favicon_attributes_provider.h" #import "ios/chrome/browser/ui/favicon/favicon_attributes_with_payload.h" @@ -130,10 +130,17 @@ /// content inset. @property(nonatomic, assign) CGFloat cachedContentHeight; +/// Layout guide that tracks the position of the omnibox. +/// This is useful to add constraints to, or to derive manual layout values off +/// of. +@property(nonatomic, readonly) UILayoutGuide* omniboxGuide; + @end @implementation OmniboxPopupViewController +@synthesize omniboxGuide = _omniboxGuide; + - (instancetype)init { if (self = [super initWithNibName:nil bundle:nil]) { _forwardsScrollEvents = YES; @@ -316,15 +323,11 @@ } - (void)adjustMarginsToMatchOmniboxWidth { - NamedGuide* layoutGuide = [NamedGuide guideWithName:kOmniboxGuide - view:self.view]; - if (!layoutGuide) { + if (!self.omniboxGuide) { return; } - CGRect omniboxFrame = [layoutGuide.constrainedView - convertRect:layoutGuide.constrainedView.bounds - toView:self.view]; + CGRect omniboxFrame = self.omniboxGuide.layoutFrame; CGFloat leftMargin = IsRegularXRegularSizeClass(self) ? omniboxFrame.origin.x : 0; CGFloat rightMargin = IsRegularXRegularSizeClass(self) @@ -767,13 +770,8 @@ // Inset the header to match the omnibox width, similar to // `adjustMarginsToMatchOmniboxWidth` method. if (IsRegularXRegularSizeClass(self)) { - NamedGuide* layoutGuide = [NamedGuide guideWithName:kOmniboxGuide - view:self.view]; - if (layoutGuide) { - CGRect omniboxFrame = [layoutGuide.constrainedView - convertRect:layoutGuide.constrainedView.bounds - toView:self.view]; - CGFloat leftMargin = omniboxFrame.origin.x; + if (self.omniboxGuide) { + CGFloat leftMargin = CGRectGetMinX(self.omniboxGuide.layoutFrame); contentConfiguration.directionalLayoutMargins = NSDirectionalEdgeInsetsMake(kHeaderTopPadding, @@ -1099,4 +1097,12 @@ completion:nil]; } +- (UILayoutGuide*)omniboxGuide { + if (!_omniboxGuide) { + _omniboxGuide = [self.layoutGuideCenter makeLayoutGuideNamed:kOmniboxGuide]; + [self.view addLayoutGuide:_omniboxGuide]; + } + return _omniboxGuide; +} + @end
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn b/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn index f738434..29e85fe 100644 --- a/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn +++ b/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn
@@ -18,6 +18,7 @@ "//ios/chrome/browser/overlays", "//ios/chrome/browser/overlays/public/common/infobars", "//ios/chrome/browser/overlays/public/default", + "//ios/chrome/browser/shared/coordinator/layout_guide", "//ios/chrome/browser/shared/ui/util", "//ios/chrome/browser/ui/infobars:constants", "//ios/chrome/browser/ui/infobars/banners",
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.mm index 46b5b267..8a6eb995 100644 --- a/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.mm +++ b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.mm
@@ -13,7 +13,9 @@ #import "ios/chrome/browser/overlays/public/overlay_request.h" #import "ios/chrome/browser/overlays/public/overlay_request_support.h" #import "ios/chrome/browser/overlays/public/overlay_response.h" -#import "ios/chrome/browser/shared/ui/util/named_guide.h" +#import "ios/chrome/browser/shared/coordinator/layout_guide/layout_guide_util.h" +#import "ios/chrome/browser/shared/ui/util/layout_guide_names.h" +#import "ios/chrome/browser/shared/ui/util/util_swift.h" #import "ios/chrome/browser/ui/infobars/banners/infobar_banner_accessibility_util.h" #import "ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.h" #import "ios/chrome/browser/ui/infobars/infobar_constants.h" @@ -76,12 +78,10 @@ #pragma mark - InfobarBannerPositioner - (CGFloat)bannerYPosition { - NamedGuide* omniboxGuide = - [NamedGuide guideWithName:kOmniboxGuide - view:self.baseViewController.view]; - UIView* owningView = omniboxGuide.owningView; - CGRect omniboxFrame = [owningView convertRect:omniboxGuide.layoutFrame - toView:owningView.window]; + LayoutGuideCenter* layoutGuideCenter = + LayoutGuideCenterForBrowser(self.browser); + UIView* omnibox = [layoutGuideCenter referencedViewUnderName:kOmniboxGuide]; + CGRect omniboxFrame = [omnibox convertRect:omnibox.bounds toView:nil]; return CGRectGetMaxY(omniboxFrame); } @@ -211,6 +211,12 @@ case InfobarType::kInfobarTypePermissions: mediatorClass = [PermissionsBannerOverlayMediator class]; break; + case InfobarType::kInfobarTypeTailoredSecurityService: + mediatorClass = [TailoredSecurityInfobarBannerOverlayMediator class]; + break; + case InfobarType::kInfobarTypeSaveCard: + mediatorClass = [SaveCardInfobarBannerOverlayMediator class]; + break; default: NOTREACHED_NORETURN() << "Received unsupported infobarType."; }
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/save_card/BUILD.gn b/ios/chrome/browser/ui/overlays/infobar_banner/save_card/BUILD.gn index ed91004..63618b5 100644 --- a/ios/chrome/browser/ui/overlays/infobar_banner/save_card/BUILD.gn +++ b/ios/chrome/browser/ui/overlays/infobar_banner/save_card/BUILD.gn
@@ -12,7 +12,11 @@ deps = [ "//base", + "//components/autofill/core/browser", + "//ios/chrome/app/strings", + "//ios/chrome/browser/infobars/overlays:util", "//ios/chrome/browser/overlays", + "//ios/chrome/browser/overlays/public/default", "//ios/chrome/browser/overlays/public/infobar_banner", "//ios/chrome/browser/overlays/public/infobar_modal", "//ios/chrome/browser/shared/ui/symbols", @@ -38,16 +42,21 @@ "//components/prefs", "//components/signin/public/identity_manager", "//ios/chrome/browser/infobars", + "//ios/chrome/browser/infobars:public", + "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test", "//ios/chrome/browser/infobars/test", "//ios/chrome/browser/overlays", + "//ios/chrome/browser/overlays/public/default", "//ios/chrome/browser/overlays/public/infobar_banner", "//ios/chrome/browser/overlays/public/infobar_modal", "//ios/chrome/browser/overlays/test", + "//ios/chrome/browser/ui/infobars/banners", "//ios/chrome/browser/ui/infobars/banners/test", "//ios/chrome/browser/ui/infobars/test", "//ios/chrome/browser/ui/overlays/test", "//testing/gmock", "//testing/gtest", + "//third_party/ocmock", "//ui/base", ] }
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/save_card/save_card_infobar_banner_overlay_mediator.mm b/ios/chrome/browser/ui/overlays/infobar_banner/save_card/save_card_infobar_banner_overlay_mediator.mm index 2dc56e4..92c72b83 100644 --- a/ios/chrome/browser/ui/overlays/infobar_banner/save_card/save_card_infobar_banner_overlay_mediator.mm +++ b/ios/chrome/browser/ui/overlays/infobar_banner/save_card/save_card_infobar_banner_overlay_mediator.mm
@@ -5,63 +5,69 @@ #import "ios/chrome/browser/ui/overlays/infobar_banner/save_card/save_card_infobar_banner_overlay_mediator.h" #import "base/strings/sys_string_conversions.h" +#import "components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.h" +#import "ios/chrome/browser/infobars/overlays/infobar_overlay_util.h" +#import "ios/chrome/browser/overlays/public/default/default_infobar_overlay_request_config.h" #import "ios/chrome/browser/overlays/public/infobar_banner/infobar_banner_overlay_responses.h" -#import "ios/chrome/browser/overlays/public/infobar_banner/save_card_infobar_banner_overlay_request_config.h" -#import "ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_responses.h" -#import "ios/chrome/browser/overlays/public/overlay_response.h" #import "ios/chrome/browser/shared/ui/symbols/symbols.h" #import "ios/chrome/browser/ui/infobars/banners/infobar_banner_consumer.h" #import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator+consumer_support.h" #import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.h" #import "ios/chrome/browser/ui/overlays/overlay_request_mediator+subclassing.h" +#import "ios/chrome/grit/ios_strings.h" #import "ui/base/l10n/l10n_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif -using save_card_infobar_overlays::SaveCardBannerRequestConfig; -using save_card_infobar_overlays::SaveCardMainAction; - @interface SaveCardInfobarBannerOverlayMediator () + // The save card banner config from the request. -@property(nonatomic, readonly) SaveCardBannerRequestConfig* config; +@property(nonatomic, readonly) DefaultInfobarOverlayRequestConfig* config; + @end @implementation SaveCardInfobarBannerOverlayMediator #pragma mark - Accessors -- (SaveCardBannerRequestConfig*)config { - return self.request ? self.request->GetConfig<SaveCardBannerRequestConfig>() - : nullptr; +- (DefaultInfobarOverlayRequestConfig*)config { + return self.request + ? self.request->GetConfig<DefaultInfobarOverlayRequestConfig>() + : nullptr; +} + +// Returns the delegate attached to the config. +- (autofill::AutofillSaveCardInfoBarDelegateMobile*)saveCardDelegate { + return static_cast<autofill::AutofillSaveCardInfoBarDelegateMobile*>( + self.config->delegate()); } #pragma mark - OverlayRequestMediator + (const OverlayRequestSupport*)requestSupport { - return SaveCardBannerRequestConfig::RequestSupport(); + return DefaultInfobarOverlayRequestConfig::RequestSupport(); } #pragma mark - InfobarOverlayRequestMediator - (void)bannerInfobarButtonWasPressed:(UIButton*)sender { + autofill::AutofillSaveCardInfoBarDelegateMobile* delegate = + self.saveCardDelegate; + // Display the modal (thus the ToS) if the card will be uploaded, this is a // legal requirement and shouldn't be changed. - if (self.config->should_upload_credentials()) { - [self dispatchResponse:OverlayResponse::CreateWithInfo< - InfobarBannerShowModalResponse>()]; + if (delegate->is_for_upload()) { + [self presentInfobarModalFromBanner]; return; } - // Notify the model layer to perform the infobar's main action before - // dismissing the banner. - [self dispatchResponse:OverlayResponse::CreateWithInfo<SaveCardMainAction>( - base::SysUTF16ToNSString( - self.config->cardholder_name()), - base::SysUTF16ToNSString( - self.config->expiration_date_month()), - base::SysUTF16ToNSString( - self.config->expiration_date_year()))]; + + InfoBarIOS* infobar = GetOverlayRequestInfobar(self.request); + infobar->set_accepted(delegate->UpdateAndAccept( + delegate->cardholder_name(), delegate->expiration_date_month(), + delegate->expiration_date_year())); + [self dismissOverlay]; } @@ -70,19 +76,30 @@ @implementation SaveCardInfobarBannerOverlayMediator (ConsumerSupport) - (void)configureConsumer { - SaveCardBannerRequestConfig* config = self.config; + DefaultInfobarOverlayRequestConfig* config = self.config; if (!self.consumer || !config) return; - [self.consumer - setButtonText:base::SysUTF16ToNSString(self.config->button_label_text())]; + autofill::AutofillSaveCardInfoBarDelegateMobile* delegate = + self.saveCardDelegate; + if (!delegate) { + return; + } + + std::u16string buttonLabelText = + delegate->is_for_upload() + ? l10n_util::GetStringUTF16(IDS_IOS_AUTOFILL_SAVE_ELLIPSIS) + : delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK); + [self.consumer setButtonText:base::SysUTF16ToNSString(buttonLabelText)]; + UIImage* iconImage = DefaultSymbolTemplateWithPointSize( kCreditCardSymbol, kInfobarSymbolPointSize); [self.consumer setIconImage:iconImage]; + [self.consumer - setTitleText:base::SysUTF16ToNSString(self.config->message_text())]; + setTitleText:base::SysUTF16ToNSString(delegate->GetMessageText())]; [self.consumer - setSubtitleText:base::SysUTF16ToNSString(self.config->card_label())]; + setSubtitleText:base::SysUTF16ToNSString(delegate->card_label())]; } @end
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/save_card/save_card_infobar_banner_overlay_mediator_unittest.mm b/ios/chrome/browser/ui/overlays/infobar_banner/save_card/save_card_infobar_banner_overlay_mediator_unittest.mm index 5074d8a3..316cf14e 100644 --- a/ios/chrome/browser/ui/overlays/infobar_banner/save_card/save_card_infobar_banner_overlay_mediator_unittest.mm +++ b/ios/chrome/browser/ui/overlays/infobar_banner/save_card/save_card_infobar_banner_overlay_mediator_unittest.mm
@@ -11,133 +11,86 @@ #import "components/autofill/core/browser/autofill_client.h" #import "components/autofill/core/browser/autofill_test_utils.h" #import "components/autofill/core/browser/data_model/credit_card.h" -#import "components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.h" #import "components/signin/public/identity_manager/account_info.h" #import "ios/chrome/browser/infobars/infobar_ios.h" -#import "ios/chrome/browser/overlays/public/infobar_banner/infobar_banner_overlay_responses.h" -#import "ios/chrome/browser/overlays/public/infobar_banner/save_card_infobar_banner_overlay_request_config.h" -#import "ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_responses.h" -#import "ios/chrome/browser/overlays/test/fake_overlay_request_callback_installer.h" +#import "ios/chrome/browser/infobars/infobar_type.h" +#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_autofill_save_card_infobar_delegate_mobile.h" +#import "ios/chrome/browser/overlays/public/default/default_infobar_overlay_request_config.h" +#import "ios/chrome/browser/ui/infobars/banners/infobar_banner_delegate.h" #import "ios/chrome/browser/ui/infobars/banners/test/fake_infobar_banner_consumer.h" #import "testing/gtest_mac.h" #import "testing/platform_test.h" +#import "third_party/ocmock/OCMock/OCMock.h" +#import "third_party/ocmock/gtest_support.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif -using save_card_infobar_overlays::SaveCardBannerRequestConfig; -using save_card_infobar_overlays::SaveCardMainAction; - // Test fixture for SaveCardInfobarBannerOverlayMediator. class SaveCardInfobarBannerOverlayMediatorTest : public PlatformTest { public: - SaveCardInfobarBannerOverlayMediatorTest() - : callback_installer_(&callback_receiver_, - {InfobarBannerShowModalResponse::ResponseSupport(), - SaveCardMainAction::ResponseSupport()}) { + SaveCardInfobarBannerOverlayMediatorTest() {} + + void InitInfobar(const bool upload) { + autofill::CreditCard credit_card( + base::Uuid::GenerateRandomV4().AsLowercaseString(), + "https://www.example.com/"); + ; + std::unique_ptr<MockAutofillSaveCardInfoBarDelegateMobile> delegate = + MockAutofillSaveCardInfoBarDelegateMobileFactory:: + CreateMockAutofillSaveCardInfoBarDelegateMobileFactory(upload, + credit_card); + delegate_ = delegate.get(); + infobar_ = std::make_unique<InfoBarIOS>(InfobarType::kInfobarTypeSaveCard, + std::move(delegate)); + request_ = + OverlayRequest::CreateWithConfig<DefaultInfobarOverlayRequestConfig>( + infobar_.get(), InfobarOverlayType::kBanner); + consumer_ = [[FakeInfobarBannerConsumer alloc] init]; + mediator_ = [[SaveCardInfobarBannerOverlayMediator alloc] + initWithRequest:request_.get()]; + ; + mediator_.consumer = consumer_; } protected: - MockOverlayRequestCallbackReceiver callback_receiver_; - FakeOverlayRequestCallbackInstaller callback_installer_; + std::unique_ptr<InfoBarIOS> infobar_; + std::unique_ptr<OverlayRequest> request_; + MockAutofillSaveCardInfoBarDelegateMobile* delegate_ = nil; + FakeInfobarBannerConsumer* consumer_ = nil; + SaveCardInfobarBannerOverlayMediator* mediator_ = nil; }; -// Tests that a SaveCardInfobarBannerOverlayMediator correctly sets up its -// consumer. TEST_F(SaveCardInfobarBannerOverlayMediatorTest, SetUpConsumer) { - autofill::CreditCard credit_card( - base::Uuid::GenerateRandomV4().AsLowercaseString(), - "https://www.example.com/"); - std::unique_ptr<autofill::AutofillSaveCardInfoBarDelegateMobile> - passed_delegate = - autofill::AutofillSaveCardInfoBarDelegateMobile::CreateForLocalSave( - autofill::AutofillClient::SaveCreditCardOptions(), credit_card, - base::DoNothing()); - autofill::AutofillSaveCardInfoBarDelegateMobile* delegate = - passed_delegate.get(); - InfoBarIOS infobar(InfobarType::kInfobarTypeSaveCard, - std::move(passed_delegate)); + InitInfobar(false); - // Package the infobar into an OverlayRequest, then create a mediator that - // uses this request in order to set up a fake consumer. - std::unique_ptr<OverlayRequest> request = - OverlayRequest::CreateWithConfig<SaveCardBannerRequestConfig>(&infobar); - SaveCardInfobarBannerOverlayMediator* mediator = - [[SaveCardInfobarBannerOverlayMediator alloc] - initWithRequest:request.get()]; - FakeInfobarBannerConsumer* consumer = - [[FakeInfobarBannerConsumer alloc] init]; - mediator.consumer = consumer; // Verify that the infobar was set up properly. - NSString* title = base::SysUTF16ToNSString(delegate->GetMessageText()); - EXPECT_NSEQ(title, consumer.titleText); + NSString* title = base::SysUTF16ToNSString(delegate_->GetMessageText()); + EXPECT_NSEQ(title, consumer_.titleText); EXPECT_NSEQ(base::SysUTF16ToNSString( - delegate->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK)), - consumer.buttonText); - EXPECT_NSEQ(base::SysUTF16ToNSString(delegate->card_label()), - consumer.subtitleText); + delegate_->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK)), + consumer_.buttonText); + EXPECT_NSEQ(base::SysUTF16ToNSString(delegate_->card_label()), + consumer_.subtitleText); } // Tests that when upload is turned on, tapping on the banner action button // presents the modal. TEST_F(SaveCardInfobarBannerOverlayMediatorTest, PresentModalWhenUploadOn) { - // Create an InfoBarIOS with a ConfirmInfoBarDelegate. - autofill::CreditCard credit_card( - base::Uuid::GenerateRandomV4().AsLowercaseString(), - "https://www.example.com/"); - std::unique_ptr<autofill::AutofillSaveCardInfoBarDelegateMobile> - passed_delegate = - autofill::AutofillSaveCardInfoBarDelegateMobile::CreateForUploadSave( - autofill::AutofillClient::SaveCreditCardOptions(), credit_card, - base::DoNothing(), autofill::LegalMessageLines(), AccountInfo()); + InitInfobar(true); - InfoBarIOS infobar(InfobarType::kInfobarTypeSaveCard, - std::move(passed_delegate)); - - // Package the infobar into an OverlayRequest, then create a mediator that - // uses this request in order to set up a fake consumer. - std::unique_ptr<OverlayRequest> request = - OverlayRequest::CreateWithConfig<SaveCardBannerRequestConfig>(&infobar); - callback_installer_.InstallCallbacks(request.get()); - SaveCardInfobarBannerOverlayMediator* mediator = - [[SaveCardInfobarBannerOverlayMediator alloc] - initWithRequest:request.get()]; - - EXPECT_CALL( - callback_receiver_, - DispatchCallback(request.get(), - InfobarBannerShowModalResponse::ResponseSupport())); - [mediator bannerInfobarButtonWasPressed:nil]; + OCMExpect([mediator_ presentInfobarModalFromBanner]); + [mediator_ bannerInfobarButtonWasPressed:nil]; } // Tests that when upload is turned off, tapping on the banner action button // does not present the modal. TEST_F(SaveCardInfobarBannerOverlayMediatorTest, PresentModalWhenUploadOff) { - // Create an InfoBarIOS with a ConfirmInfoBarDelegate. - autofill::CreditCard credit_card( - base::Uuid::GenerateRandomV4().AsLowercaseString(), - "https://www.example.com/"); - std::unique_ptr<autofill::AutofillSaveCardInfoBarDelegateMobile> - passed_delegate = - autofill::AutofillSaveCardInfoBarDelegateMobile::CreateForLocalSave( - autofill::AutofillClient::SaveCreditCardOptions(), credit_card, - base::DoNothing()); + InitInfobar(false); - InfoBarIOS infobar(InfobarType::kInfobarTypeSaveCard, - std::move(passed_delegate)); - - // Package the infobar into an OverlayRequest, then create a mediator that - // uses this request in order to set up a fake consumer. - std::unique_ptr<OverlayRequest> request = - OverlayRequest::CreateWithConfig<SaveCardBannerRequestConfig>(&infobar); - callback_installer_.InstallCallbacks(request.get()); - SaveCardInfobarBannerOverlayMediator* mediator = - [[SaveCardInfobarBannerOverlayMediator alloc] - initWithRequest:request.get()]; - - EXPECT_CALL( - callback_receiver_, - DispatchCallback(request.get(), SaveCardMainAction::ResponseSupport())); - [mediator bannerInfobarButtonWasPressed:nil]; + EXPECT_CALL(*delegate_, UpdateAndAccept(delegate_->cardholder_name(), + delegate_->expiration_date_month(), + delegate_->expiration_date_year())); + [mediator_ bannerInfobarButtonWasPressed:nil]; }
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/tailored_security/BUILD.gn b/ios/chrome/browser/ui/overlays/infobar_banner/tailored_security/BUILD.gn index 9e9a824..4e5d1a58 100644 --- a/ios/chrome/browser/ui/overlays/infobar_banner/tailored_security/BUILD.gn +++ b/ios/chrome/browser/ui/overlays/infobar_banner/tailored_security/BUILD.gn
@@ -11,11 +11,14 @@ deps = [ "//base", "//components/infobars/core", + "//ios/chrome/browser/infobars/overlays:util", + "//ios/chrome/browser/overlays/public/default", "//ios/chrome/browser/overlays/public/infobar_banner", "//ios/chrome/browser/safe_browsing/tailored_security:infobar_delegates", "//ios/chrome/browser/shared/ui/symbols", "//ios/chrome/browser/shared/ui/symbols:buildflags", "//ios/chrome/browser/ui/infobars/banners", + "//ios/chrome/browser/ui/overlays:coordinators", "//ios/chrome/browser/ui/overlays/infobar_banner:mediators", ] } @@ -28,6 +31,7 @@ ":tailored_security", "//ios/chrome/browser/infobars", "//ios/chrome/browser/overlays", + "//ios/chrome/browser/overlays/public/default", "//ios/chrome/browser/overlays/public/infobar_banner", "//ios/chrome/browser/safe_browsing/tailored_security/test", "//ios/chrome/browser/shared/ui/symbols",
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/tailored_security/tailored_security_infobar_banner_overlay_mediator.mm b/ios/chrome/browser/ui/overlays/infobar_banner/tailored_security/tailored_security_infobar_banner_overlay_mediator.mm index 6128a0f..7d31bd8 100644 --- a/ios/chrome/browser/ui/overlays/infobar_banner/tailored_security/tailored_security_infobar_banner_overlay_mediator.mm +++ b/ios/chrome/browser/ui/overlays/infobar_banner/tailored_security/tailored_security_infobar_banner_overlay_mediator.mm
@@ -6,13 +6,15 @@ #import "base/strings/sys_string_conversions.h" #import "components/infobars/core/confirm_infobar_delegate.h" -#import "ios/chrome/browser/overlays/public/infobar_banner/tailored_security_service_infobar_banner_overlay_request_config.h" +#import "ios/chrome/browser/infobars/overlays/infobar_overlay_util.h" +#import "ios/chrome/browser/overlays/public/default/default_infobar_overlay_request_config.h" #import "ios/chrome/browser/safe_browsing/tailored_security/tailored_security_service_infobar_delegate.h" #import "ios/chrome/browser/shared/ui/symbols/buildflags.h" #import "ios/chrome/browser/shared/ui/symbols/symbols.h" #import "ios/chrome/browser/ui/infobars/banners/infobar_banner_consumer.h" #import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator+consumer_support.h" #import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.h" +#import "ios/chrome/browser/ui/overlays/overlay_request_mediator+subclassing.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -20,9 +22,6 @@ namespace { -// The size of the symbol image. -CGFloat kSymbolImagePointSize = 18.; - // Returns the branded version of the Google shield symbol. NSString* GetBrandedGoogleShieldSymbol() { #if BUILDFLAG(IOS_USE_BRANDED_SYMBOLS) @@ -34,30 +33,40 @@ } // namespace -using tailored_security_service_infobar_overlays:: - TailoredSecurityServiceBannerRequestConfig; - @interface TailoredSecurityInfobarBannerOverlayMediator () // The tailored security banner config from the request. -@property(nonatomic, readonly) - TailoredSecurityServiceBannerRequestConfig* config; +@property(nonatomic, readonly) DefaultInfobarOverlayRequestConfig* config; @end @implementation TailoredSecurityInfobarBannerOverlayMediator #pragma mark - Accessors -- (TailoredSecurityServiceBannerRequestConfig*)config { +- (DefaultInfobarOverlayRequestConfig*)config { return self.request - ? self.request - ->GetConfig<TailoredSecurityServiceBannerRequestConfig>() + ? self.request->GetConfig<DefaultInfobarOverlayRequestConfig>() : nullptr; } +// Returns the delegate attached to the config. +- (safe_browsing::TailoredSecurityServiceInfobarDelegate*)tailoredDelegate { + return static_cast<safe_browsing::TailoredSecurityServiceInfobarDelegate*>( + self.config->delegate()); +} + #pragma mark - OverlayRequestMediator + (const OverlayRequestSupport*)requestSupport { - return TailoredSecurityServiceBannerRequestConfig::RequestSupport(); + return DefaultInfobarOverlayRequestConfig::RequestSupport(); +} + +#pragma mark - InfobarOverlayRequestMediator + +- (void)bannerInfobarButtonWasPressed:(UIButton*)sender { + InfoBarIOS* infobar = GetOverlayRequestInfobar(self.request); + infobar->set_accepted(self.tailoredDelegate->Accept()); + + [self dismissOverlay]; } @end @@ -65,33 +74,40 @@ @implementation TailoredSecurityInfobarBannerOverlayMediator (ConsumerSupport) - (void)configureConsumer { - TailoredSecurityServiceBannerRequestConfig* config = self.config; - if (!self.consumer || !config) + DefaultInfobarOverlayRequestConfig* config = self.config; + if (!self.consumer || !config) { return; + } - NSString* title = base::SysUTF16ToNSString(config->message_text()); - NSString* subtitle = base::SysUTF16ToNSString(config->description()); - NSString* buttonText = base::SysUTF16ToNSString(config->button_label_text()); + safe_browsing::TailoredSecurityServiceInfobarDelegate* delegate = + self.tailoredDelegate; + if (!delegate) { + return; + } + + NSString* title = base::SysUTF16ToNSString(delegate->GetMessageText()); + NSString* subtitle = base::SysUTF16ToNSString(delegate->GetDescription()); + NSString* buttonText = + base::SysUTF16ToNSString(delegate->GetMessageActionText()); NSString* bannerAccessibilityLabel = [NSString stringWithFormat:@"%@,%@", title, subtitle]; - NSString* icon_image_name = [self chooseIconImageName:config]; + NSString* iconImageName = + [self iconImageNameForState:delegate->message_state()]; + [self.consumer setBannerAccessibilityLabel:bannerAccessibilityLabel]; [self.consumer setButtonText:buttonText]; - [self.consumer setIconImage:CustomSymbolWithPointSize(icon_image_name, - kSymbolImagePointSize)]; - [self.consumer setPresentsModal:config->has_badge()]; + [self.consumer setIconImage:CustomSymbolWithPointSize( + iconImageName, kInfobarSymbolPointSize)]; [self.consumer setTitleText:title]; [self.consumer setSubtitleText:subtitle]; } #pragma mark - Private methods -// Conversion function to choose NSString needed for UIImage. -- (NSString*)chooseIconImageName: - (TailoredSecurityServiceBannerRequestConfig*)config { - safe_browsing::TailoredSecurityServiceMessageState message_state = - config->message_state(); - switch (message_state) { +// Returns the icon image name corresponding to the given `state`. +- (NSString*)iconImageNameForState: + (safe_browsing::TailoredSecurityServiceMessageState)state { + switch (state) { case safe_browsing::TailoredSecurityServiceMessageState:: kConsentedAndFlowEnabled: case safe_browsing::TailoredSecurityServiceMessageState::
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/tailored_security/tailored_security_infobar_banner_overlay_mediator_unittest.mm b/ios/chrome/browser/ui/overlays/infobar_banner/tailored_security/tailored_security_infobar_banner_overlay_mediator_unittest.mm index 768ea58..e0e7429 100644 --- a/ios/chrome/browser/ui/overlays/infobar_banner/tailored_security/tailored_security_infobar_banner_overlay_mediator_unittest.mm +++ b/ios/chrome/browser/ui/overlays/infobar_banner/tailored_security/tailored_security_infobar_banner_overlay_mediator_unittest.mm
@@ -6,7 +6,7 @@ #import "base/strings/sys_string_conversions.h" #import "ios/chrome/browser/infobars/infobar_ios.h" -#import "ios/chrome/browser/overlays/public/infobar_banner/tailored_security_service_infobar_banner_overlay_request_config.h" +#import "ios/chrome/browser/overlays/public/default/default_infobar_overlay_request_config.h" #import "ios/chrome/browser/overlays/public/overlay_request.h" #import "ios/chrome/browser/safe_browsing/tailored_security/test/mock_tailored_security_service_infobar_delegate.h" #import "ios/chrome/browser/shared/ui/symbols/symbols.h" @@ -37,100 +37,79 @@ using safe_browsing::MockTailoredSecurityServiceInfobarDelegate; using safe_browsing::TailoredSecurityServiceInfobarDelegate; using safe_browsing::TailoredSecurityServiceMessageState; -using tailored_security_service_infobar_overlays:: - TailoredSecurityServiceBannerRequestConfig; // Test fixture for TailoredSecurityInfobarBannerOverlayMediator. -using TailoredSecurityInfobarBannerOverlayMediatorTest = PlatformTest; +class TailoredSecurityInfobarBannerOverlayMediatorTest : public PlatformTest { + public: + TailoredSecurityInfobarBannerOverlayMediatorTest() {} + + void InitInfobar(const TailoredSecurityServiceMessageState state) { + std::unique_ptr<TailoredSecurityServiceInfobarDelegate> delegate = + MockTailoredSecurityServiceInfobarDelegate::Create(state, nullptr); + delegate_ = delegate.get(); + infobar_ = std::make_unique<InfoBarIOS>( + InfobarType::kInfobarTypeTailoredSecurityService, std::move(delegate)); + request_ = + OverlayRequest::CreateWithConfig<DefaultInfobarOverlayRequestConfig>( + infobar_.get(), InfobarOverlayType::kBanner); + consumer_ = [[FakeInfobarBannerConsumer alloc] init]; + mediator_ = [[TailoredSecurityInfobarBannerOverlayMediator alloc] + initWithRequest:request_.get()]; + ; + mediator_.consumer = consumer_; + } + + protected: + std::unique_ptr<InfoBarIOS> infobar_; + std::unique_ptr<OverlayRequest> request_; + TailoredSecurityServiceInfobarDelegate* delegate_ = nil; + FakeInfobarBannerConsumer* consumer_ = nil; + TailoredSecurityInfobarBannerOverlayMediator* mediator_ = nil; +}; // Tests that a TailoredSecurityInfobarBannerOverlayMediatorTest correctly sets // up its consumer. TEST_F(TailoredSecurityInfobarBannerOverlayMediatorTest, SetUpConsumer) { - // Create an InfoBarIOS with a TailoredSecurityServiceInfobarDelegate. - std::unique_ptr<TailoredSecurityServiceInfobarDelegate> passed_delegate = - MockTailoredSecurityServiceInfobarDelegate::Create( - /*message_state*/ TailoredSecurityServiceMessageState:: - kConsentedAndFlowEnabled, - nullptr); - TailoredSecurityServiceInfobarDelegate* delegate = passed_delegate.get(); - InfoBarIOS infobar(InfobarType::kInfobarTypeTailoredSecurityService, - std::move(passed_delegate)); - // Package the infobar into an OverlayRequest, then create a mediator that - // uses this request in order to set up a fake consumer. - std::unique_ptr<OverlayRequest> request = OverlayRequest::CreateWithConfig< - TailoredSecurityServiceBannerRequestConfig>(&infobar); - TailoredSecurityInfobarBannerOverlayMediator* mediator = - [[TailoredSecurityInfobarBannerOverlayMediator alloc] - initWithRequest:request.get()]; - FakeInfobarBannerConsumer* consumer = - [[FakeInfobarBannerConsumer alloc] init]; - mediator.consumer = consumer; + InitInfobar(TailoredSecurityServiceMessageState::kConsentedAndFlowEnabled); + // Verify that the infobar was set up properly. - NSString* title = base::SysUTF16ToNSString(delegate->GetMessageText()); - NSString* subtitle = base::SysUTF16ToNSString(delegate->GetDescription()); + NSString* title = base::SysUTF16ToNSString(delegate_->GetMessageText()); + NSString* subtitle = base::SysUTF16ToNSString(delegate_->GetDescription()); NSString* buttonText = - base::SysUTF16ToNSString(delegate->GetMessageActionText()); + base::SysUTF16ToNSString(delegate_->GetMessageActionText()); NSString* bannerAccessibilityLabel = [NSString stringWithFormat:@"%@,%@", title, subtitle]; - EXPECT_NSEQ(bannerAccessibilityLabel, consumer.bannerAccessibilityLabel); - EXPECT_NSEQ(buttonText, consumer.buttonText); - EXPECT_NSEQ(title, consumer.titleText); - EXPECT_NSEQ(subtitle, consumer.subtitleText); - EXPECT_NSEQ(GetBrandedGoogleShieldSymbol(), consumer.iconImage); + EXPECT_NSEQ(bannerAccessibilityLabel, consumer_.bannerAccessibilityLabel); + EXPECT_NSEQ(buttonText, consumer_.buttonText); + EXPECT_NSEQ(title, consumer_.titleText); + EXPECT_NSEQ(subtitle, consumer_.subtitleText); + EXPECT_NSEQ(GetBrandedGoogleShieldSymbol(), consumer_.iconImage); EXPECT_TRUE(TailoredSecurityServiceMessageState::kConsentedAndFlowEnabled == - delegate->message_state()); - EXPECT_FALSE(consumer.presentsModal); + delegate_->message_state()); + EXPECT_FALSE(consumer_.presentsModal); } // Tests that a TailoredSecurityInfobarBannerOverlayMediatorTest correctly // creates a consented and flow disabled message prompt. TEST_F(TailoredSecurityInfobarBannerOverlayMediatorTest, CheckConsentedAndFlowDisabledMessagePrompt) { - std::unique_ptr<TailoredSecurityServiceInfobarDelegate> passed_delegate = - MockTailoredSecurityServiceInfobarDelegate::Create( - /*message_state*/ TailoredSecurityServiceMessageState:: - kConsentedAndFlowDisabled, - nullptr); - TailoredSecurityServiceInfobarDelegate* delegate = passed_delegate.get(); - InfoBarIOS infobar(InfobarType::kInfobarTypeTailoredSecurityService, - std::move(passed_delegate)); - std::unique_ptr<OverlayRequest> request = OverlayRequest::CreateWithConfig< - TailoredSecurityServiceBannerRequestConfig>(&infobar); - TailoredSecurityInfobarBannerOverlayMediator* mediator = - [[TailoredSecurityInfobarBannerOverlayMediator alloc] - initWithRequest:request.get()]; - FakeInfobarBannerConsumer* consumer = - [[FakeInfobarBannerConsumer alloc] init]; - mediator.consumer = consumer; + InitInfobar(TailoredSecurityServiceMessageState::kConsentedAndFlowDisabled); + // Verify that the infobar was set up properly. EXPECT_NSEQ(CustomSymbolWithPointSize(kShieldSymbol, kSymbolImagePointSize), - consumer.iconImage); + consumer_.iconImage); EXPECT_TRUE(TailoredSecurityServiceMessageState::kConsentedAndFlowDisabled == - delegate->message_state()); + delegate_->message_state()); } // Tests that a TailoredSecurityInfobarBannerOverlayMediatorTest correctly // creates an unconsented and flow enabled message prompt. TEST_F(TailoredSecurityInfobarBannerOverlayMediatorTest, CheckUnconsentedAndFlowEnabledMessagePrompt) { - std::unique_ptr<TailoredSecurityServiceInfobarDelegate> passed_delegate = - MockTailoredSecurityServiceInfobarDelegate::Create( - /*message_state*/ TailoredSecurityServiceMessageState:: - kUnconsentedAndFlowEnabled, - nullptr); - TailoredSecurityServiceInfobarDelegate* delegate = passed_delegate.get(); - InfoBarIOS infobar(InfobarType::kInfobarTypeTailoredSecurityService, - std::move(passed_delegate)); - std::unique_ptr<OverlayRequest> request = OverlayRequest::CreateWithConfig< - TailoredSecurityServiceBannerRequestConfig>(&infobar); - TailoredSecurityInfobarBannerOverlayMediator* mediator = - [[TailoredSecurityInfobarBannerOverlayMediator alloc] - initWithRequest:request.get()]; - FakeInfobarBannerConsumer* consumer = - [[FakeInfobarBannerConsumer alloc] init]; - mediator.consumer = consumer; + InitInfobar(TailoredSecurityServiceMessageState::kUnconsentedAndFlowEnabled); + // Verify that the infobar was set up properly. - EXPECT_NSEQ(GetBrandedGoogleShieldSymbol(), consumer.iconImage); + EXPECT_NSEQ(GetBrandedGoogleShieldSymbol(), consumer_.iconImage); EXPECT_TRUE(TailoredSecurityServiceMessageState::kUnconsentedAndFlowEnabled == - delegate->message_state()); + delegate_->message_state()); }
diff --git a/ios/chrome/browser/ui/overlays/infobar_modal/save_card/BUILD.gn b/ios/chrome/browser/ui/overlays/infobar_modal/save_card/BUILD.gn index e24ef58..cc7bcab 100644 --- a/ios/chrome/browser/ui/overlays/infobar_modal/save_card/BUILD.gn +++ b/ios/chrome/browser/ui/overlays/infobar_modal/save_card/BUILD.gn
@@ -15,11 +15,14 @@ deps = [ "//base", + "//components/autofill/core/browser", "//components/autofill/core/common", "//ios/chrome/app/strings", "//ios/chrome/browser/autofill/message", + "//ios/chrome/browser/infobars/overlays:util", "//ios/chrome/browser/overlays", "//ios/chrome/browser/overlays/public/common/infobars", + "//ios/chrome/browser/overlays/public/default", "//ios/chrome/browser/overlays/public/infobar_modal", "//ios/chrome/browser/shared/ui/util", "//ios/chrome/browser/ui/infobars/modals", @@ -46,8 +49,11 @@ "//components/signin/public/identity_manager", "//ios/chrome/browser/autofill/message", "//ios/chrome/browser/infobars", + "//ios/chrome/browser/infobars:public", + "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test", "//ios/chrome/browser/infobars/test", "//ios/chrome/browser/overlays", + "//ios/chrome/browser/overlays/public/default", "//ios/chrome/browser/overlays/public/infobar_modal", "//ios/chrome/browser/overlays/test", "//ios/chrome/browser/ui/infobars/modals",
diff --git a/ios/chrome/browser/ui/overlays/infobar_modal/save_card/save_card_infobar_modal_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/infobar_modal/save_card/save_card_infobar_modal_overlay_coordinator.mm index 994fe787..bb1380d 100644 --- a/ios/chrome/browser/ui/overlays/infobar_modal/save_card/save_card_infobar_modal_overlay_coordinator.mm +++ b/ios/chrome/browser/ui/overlays/infobar_modal/save_card/save_card_infobar_modal_overlay_coordinator.mm
@@ -5,10 +5,8 @@ #import "ios/chrome/browser/ui/overlays/infobar_modal/save_card/save_card_infobar_modal_overlay_coordinator.h" #import "base/check.h" -#import "ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_request_config.h" -#import "ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_responses.h" -#import "ios/chrome/browser/overlays/public/overlay_callback_manager.h" -#import "ios/chrome/browser/overlays/public/overlay_response.h" +#import "components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.h" +#import "ios/chrome/browser/overlays/public/default/default_infobar_overlay_request_config.h" #import "ios/chrome/browser/ui/infobars/modals/infobar_save_card_table_view_controller.h" #import "ios/chrome/browser/ui/overlays/infobar_modal/infobar_modal_overlay_coordinator+modal_configuration.h" #import "ios/chrome/browser/ui/overlays/infobar_modal/save_card/save_card_infobar_modal_overlay_mediator.h" @@ -19,15 +17,13 @@ #error "This file requires ARC support." #endif -using save_card_infobar_overlays::SaveCardModalRequestConfig; -using save_card_infobar_overlays::SaveCardLoadURL; - @interface SaveCardInfobarModalOverlayCoordinator () // Redefine ModalConfiguration properties as readwrite. @property(nonatomic, strong, readwrite) OverlayRequestMediator* modalMediator; @property(nonatomic, strong, readwrite) UIViewController* modalViewController; // The request's config. -@property(nonatomic, assign, readonly) SaveCardModalRequestConfig* config; +@property(nonatomic, assign, readonly) + DefaultInfobarOverlayRequestConfig* config; // URL to load when the modal UI finishes dismissing. @property(nonatomic, assign) GURL pendingURLToLoad; @end @@ -36,15 +32,16 @@ #pragma mark - Accessors -- (SaveCardModalRequestConfig*)config { - return self.request ? self.request->GetConfig<SaveCardModalRequestConfig>() - : nullptr; +- (DefaultInfobarOverlayRequestConfig*)config { + return self.request + ? self.request->GetConfig<DefaultInfobarOverlayRequestConfig>() + : nullptr; } #pragma mark - Public + (const OverlayRequestSupport*)requestSupport { - return SaveCardModalRequestConfig::RequestSupport(); + return DefaultInfobarOverlayRequestConfig::RequestSupport(); } #pragma mark - SaveCardInfobarModalOverlayMediatorDelegate @@ -79,9 +76,12 @@ DCHECK(self.modalMediator); DCHECK(self.modalViewController); if (!self.pendingURLToLoad.is_empty() && self.request) { - self.request->GetCallbackManager()->DispatchResponse( - OverlayResponse::CreateWithInfo<SaveCardLoadURL>( - self.pendingURLToLoad)); + autofill::AutofillSaveCardInfoBarDelegateMobile* delegate = + static_cast<autofill::AutofillSaveCardInfoBarDelegateMobile*>( + self.config->delegate()); + if (delegate) { + delegate->OnLegalMessageLinkClicked(self.pendingURLToLoad); + } } self.modalMediator = nil; self.modalViewController = nil;
diff --git a/ios/chrome/browser/ui/overlays/infobar_modal/save_card/save_card_infobar_modal_overlay_mediator.mm b/ios/chrome/browser/ui/overlays/infobar_modal/save_card/save_card_infobar_modal_overlay_mediator.mm index 59980dc5..edd15b5 100644 --- a/ios/chrome/browser/ui/overlays/infobar_modal/save_card/save_card_infobar_modal_overlay_mediator.mm +++ b/ios/chrome/browser/ui/overlays/infobar_modal/save_card/save_card_infobar_modal_overlay_mediator.mm
@@ -5,9 +5,11 @@ #import "ios/chrome/browser/ui/overlays/infobar_modal/save_card/save_card_infobar_modal_overlay_mediator.h" #import "base/strings/sys_string_conversions.h" +#import "components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.h" #import "components/autofill/core/common/autofill_payments_features.h" -#import "ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_request_config.h" -#import "ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_responses.h" +#import "ios/chrome/browser/autofill/message/save_card_message_with_links.h" +#import "ios/chrome/browser/infobars/overlays/infobar_overlay_util.h" +#import "ios/chrome/browser/overlays/public/default/default_infobar_overlay_request_config.h" #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h" #import "ios/chrome/browser/ui/infobars/modals/infobar_save_card_modal_consumer.h" #import "ios/chrome/browser/ui/overlays/infobar_modal/infobar_modal_overlay_coordinator+modal_configuration.h" @@ -19,61 +21,72 @@ #error "This file requires ARC support." #endif -using save_card_infobar_overlays::SaveCardModalRequestConfig; -using save_card_infobar_overlays::SaveCardMainAction; - @interface SaveCardInfobarModalOverlayMediator () // The save card modal config from the request. -@property(nonatomic, assign, readonly) SaveCardModalRequestConfig* config; +@property(nonatomic, assign, readonly) + DefaultInfobarOverlayRequestConfig* config; @end @implementation SaveCardInfobarModalOverlayMediator #pragma mark - Accessors -- (SaveCardModalRequestConfig*)config { - return self.request ? self.request->GetConfig<SaveCardModalRequestConfig>() - : nullptr; +- (DefaultInfobarOverlayRequestConfig*)config { + return self.request + ? self.request->GetConfig<DefaultInfobarOverlayRequestConfig>() + : nullptr; +} + +// Returns the delegate attached to the config. +- (autofill::AutofillSaveCardInfoBarDelegateMobile*)saveCardDelegate { + return static_cast<autofill::AutofillSaveCardInfoBarDelegateMobile*>( + self.config->delegate()); } - (void)setConsumer:(id<InfobarSaveCardModalConsumer>)consumer { if (_consumer == consumer) return; - _consumer = consumer; - SaveCardModalRequestConfig* config = self.config; + DefaultInfobarOverlayRequestConfig* config = self.config; if (!_consumer || !config) return; + autofill::AutofillSaveCardInfoBarDelegateMobile* delegate = + self.saveCardDelegate; + if (!delegate) { + return; + } + + InfoBarIOS* infobar = GetOverlayRequestInfobar(self.request); NSString* cardNumber = [NSString stringWithFormat:@"•••• %@", base::SysUTF16ToNSString( - config->card_last_four_digits())]; + delegate->card_last_four_digits())]; + // Only allow editing if the card will be uploaded and it hasn't been // previously saved. - BOOL supportsEditing = - config->should_upload_credentials() && !config->current_card_saved(); + BOOL supportsEditing = delegate->is_for_upload() && !infobar->accepted(); // Convert gfx::Image to UIImage. The NSDictionary below doesn't support nil, // so NSNull must be used. - const gfx::Image& avatar_gfx = config->displayed_target_account_avatar(); + const gfx::Image& avatarGfx = delegate->displayed_target_account_avatar(); NSObject* avatar = - avatar_gfx.IsEmpty() ? [NSNull null] : avatar_gfx.ToUIImage(); + avatarGfx.IsEmpty() ? [NSNull null] : avatarGfx.ToUIImage(); NSDictionary* prefs = @{ kCardholderNamePrefKey : - base::SysUTF16ToNSString(config->cardholder_name()), - kCardIssuerIconNamePrefKey : NativeImage(config->issuer_icon_id()), + base::SysUTF16ToNSString(delegate->cardholder_name()), + kCardIssuerIconNamePrefKey : NativeImage(delegate->issuer_icon_id()), kCardNumberPrefKey : cardNumber, kExpirationMonthPrefKey : - base::SysUTF16ToNSString(config->expiration_date_month()), + base::SysUTF16ToNSString(delegate->expiration_date_month()), kExpirationYearPrefKey : - base::SysUTF16ToNSString(config->expiration_date_year()), - kLegalMessagesPrefKey : config->legal_message_lines(), - kCurrentCardSavedPrefKey : @(config->current_card_saved()), + base::SysUTF16ToNSString(delegate->expiration_date_year()), + kLegalMessagesPrefKey : [self legalMessages], + kCurrentCardSavedPrefKey : @(infobar->accepted()), kSupportsEditingPrefKey : @(supportsEditing), kDisplayedTargetAccountEmailPrefKey : - base::SysUTF16ToNSString(config->displayed_target_account_email()), + base::SysUTF16ToNSString(delegate->displayed_target_account_email()), kDisplayedTargetAccountAvatarPrefKey : avatar, }; [_consumer setupModalViewControllerWithPrefs:prefs]; @@ -82,7 +95,7 @@ #pragma mark - OverlayRequestMediator + (const OverlayRequestSupport*)requestSupport { - return SaveCardModalRequestConfig::RequestSupport(); + return DefaultInfobarOverlayRequestConfig::RequestSupport(); } #pragma mark - InfobarSaveCardModalDelegate @@ -90,8 +103,13 @@ - (void)saveCardWithCardholderName:(NSString*)cardholderName expirationMonth:(NSString*)month expirationYear:(NSString*)year { - [self dispatchResponse:OverlayResponse::CreateWithInfo<SaveCardMainAction>( - cardholderName, month, year)]; + autofill::AutofillSaveCardInfoBarDelegateMobile* delegate = + self.saveCardDelegate; + InfoBarIOS* infobar = GetOverlayRequestInfobar(self.request); + infobar->set_accepted(delegate->UpdateAndAccept( + base::SysNSStringToUTF16(cardholderName), base::SysNSStringToUTF16(month), + base::SysNSStringToUTF16(year))); + [self dismissOverlay]; } @@ -100,4 +118,34 @@ [self dismissOverlay]; } +#pragma mark - Private + +// Returns an array of UI SaveCardMessageWithLinks model objects. +- (NSMutableArray<SaveCardMessageWithLinks*>*)legalMessages { + autofill::AutofillSaveCardInfoBarDelegateMobile* delegate = + self.saveCardDelegate; + + NSMutableArray<SaveCardMessageWithLinks*>* legalMessages = + [[NSMutableArray alloc] init]; + // Only display legal Messages if the card is being uploaded and there are + // any. + if (delegate->is_for_upload() && !delegate->legal_message_lines().empty()) { + for (const auto& line : delegate->legal_message_lines()) { + SaveCardMessageWithLinks* message = + [[SaveCardMessageWithLinks alloc] init]; + message.messageText = base::SysUTF16ToNSString(line.text()); + NSMutableArray* linkRanges = [[NSMutableArray alloc] init]; + std::vector<GURL> linkURLs; + for (const auto& link : line.links()) { + [linkRanges addObject:[NSValue valueWithRange:link.range.ToNSRange()]]; + linkURLs.push_back(link.url); + } + message.linkRanges = linkRanges; + message.linkURLs = linkURLs; + [legalMessages addObject:message]; + } + } + return legalMessages; +} + @end
diff --git a/ios/chrome/browser/ui/overlays/infobar_modal/save_card/save_card_infobar_modal_overlay_mediator_unittest.mm b/ios/chrome/browser/ui/overlays/infobar_modal/save_card/save_card_infobar_modal_overlay_mediator_unittest.mm index a860e9b..7e4bd4e5 100644 --- a/ios/chrome/browser/ui/overlays/infobar_modal/save_card/save_card_infobar_modal_overlay_mediator_unittest.mm +++ b/ios/chrome/browser/ui/overlays/infobar_modal/save_card/save_card_infobar_modal_overlay_mediator_unittest.mm
@@ -11,13 +11,13 @@ #import "components/autofill/core/browser/autofill_client.h" #import "components/autofill/core/browser/autofill_test_utils.h" #import "components/autofill/core/browser/data_model/credit_card.h" -#import "components/autofill/core/browser/payments/autofill_save_card_infobar_delegate_mobile.h" #import "components/autofill/core/browser/payments/test_legal_message_line.h" #import "components/signin/public/identity_manager/account_info.h" #import "ios/chrome/browser/autofill/message/save_card_message_with_links.h" #import "ios/chrome/browser/infobars/infobar_ios.h" -#import "ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_request_config.h" -#import "ios/chrome/browser/overlays/public/infobar_modal/save_card_infobar_modal_overlay_responses.h" +#import "ios/chrome/browser/infobars/infobar_type.h" +#import "ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/test/mock_autofill_save_card_infobar_delegate_mobile.h" +#import "ios/chrome/browser/overlays/public/default/default_infobar_overlay_request_config.h" #import "ios/chrome/browser/overlays/test/fake_overlay_request_callback_installer.h" #import "ios/chrome/browser/ui/infobars/modals/infobar_save_card_modal_consumer.h" #import "ios/chrome/browser/ui/overlays/infobar_modal/save_card/save_card_infobar_modal_overlay_mediator_delegate.h" @@ -30,9 +30,6 @@ #error "This file requires ARC support." #endif -using save_card_infobar_overlays::SaveCardModalRequestConfig; -using save_card_infobar_overlays::SaveCardMainAction; - @interface FakeSaveCardMediatorDelegate : NSObject <SaveCardInfobarModalOverlayMediatorDelegate> @property(nonatomic, assign) GURL pendingURLToLoad; @@ -74,44 +71,35 @@ class SaveCardInfobarModalOverlayMediatorTest : public PlatformTest { public: SaveCardInfobarModalOverlayMediatorTest() - : callback_installer_(&callback_receiver_, - {SaveCardMainAction::ResponseSupport()}), - mediator_delegate_( + : mediator_delegate_( OCMStrictProtocolMock(@protocol(OverlayRequestMediatorDelegate))) { - autofill::LegalMessageLines legal_message_lines = - autofill::LegalMessageLines( - {autofill::TestLegalMessageLine("Test message")}); - std::unique_ptr<autofill::AutofillSaveCardInfoBarDelegateMobile> delegate = - autofill::AutofillSaveCardInfoBarDelegateMobile::CreateForUploadSave( - autofill::AutofillClient::SaveCreditCardOptions(), - autofill::CreditCard( - base::Uuid::GenerateRandomV4().AsLowercaseString(), - "https://www.example.com/"), - base::DoNothing(), legal_message_lines, AccountInfo()); + autofill::CreditCard credit_card( + base::Uuid::GenerateRandomV4().AsLowercaseString(), + "https://www.example.com/"); + std::unique_ptr<MockAutofillSaveCardInfoBarDelegateMobile> delegate = + MockAutofillSaveCardInfoBarDelegateMobileFactory:: + CreateMockAutofillSaveCardInfoBarDelegateMobileFactory(true, + credit_card); delegate_ = delegate.get(); infobar_ = std::make_unique<InfoBarIOS>(InfobarType::kInfobarTypeSaveCard, std::move(delegate)); - request_ = OverlayRequest::CreateWithConfig<SaveCardModalRequestConfig>( - infobar_.get()); - callback_installer_.InstallCallbacks(request_.get()); - + request_ = + OverlayRequest::CreateWithConfig<DefaultInfobarOverlayRequestConfig>( + infobar_.get(), InfobarOverlayType::kModal); mediator_ = [[SaveCardInfobarModalOverlayMediator alloc] initWithRequest:request_.get()]; mediator_.delegate = mediator_delegate_; } ~SaveCardInfobarModalOverlayMediatorTest() override { - EXPECT_CALL(callback_receiver_, CompletionCallback(request_.get())); EXPECT_OCMOCK_VERIFY(mediator_delegate_); } protected: - autofill::AutofillSaveCardInfoBarDelegateMobile* delegate_; std::unique_ptr<InfoBarIOS> infobar_; - MockOverlayRequestCallbackReceiver callback_receiver_; - FakeOverlayRequestCallbackInstaller callback_installer_; std::unique_ptr<OverlayRequest> request_; + MockAutofillSaveCardInfoBarDelegateMobile* delegate_ = nil; SaveCardInfobarModalOverlayMediator* mediator_ = nil; id<OverlayRequestMediatorDelegate> mediator_delegate_ = nil; }; @@ -141,15 +129,20 @@ } // Tests that calling saveCardWithCardholderName:expirationMonth:expirationYear: -// triggers a SaveCardMainAction response. +// calls UpdateAndAccept(). TEST_F(SaveCardInfobarModalOverlayMediatorTest, MainAction) { - EXPECT_CALL( - callback_receiver_, - DispatchCallback(request_.get(), SaveCardMainAction::ResponseSupport())); + NSString* cardholderName = @"name"; + NSString* month = @"3"; + NSString* year = @"23"; + + EXPECT_CALL(*delegate_, + UpdateAndAccept(base::SysNSStringToUTF16(cardholderName), + base::SysNSStringToUTF16(month), + base::SysNSStringToUTF16(year))); OCMExpect([mediator_delegate_ stopOverlayForMediator:mediator_]); - [mediator_ saveCardWithCardholderName:@"name" - expirationMonth:@"3" - expirationYear:@"23"]; + [mediator_ saveCardWithCardholderName:cardholderName + expirationMonth:month + expirationYear:year]; } // Tests that calling dismissModalAndOpenURL: sends the passed URL to the
diff --git a/ios/chrome/browser/ui/overlays/overlay_coordinator_factory.mm b/ios/chrome/browser/ui/overlays/overlay_coordinator_factory.mm index 172e2c3f..30a0fd9 100644 --- a/ios/chrome/browser/ui/overlays/overlay_coordinator_factory.mm +++ b/ios/chrome/browser/ui/overlays/overlay_coordinator_factory.mm
@@ -87,10 +87,6 @@ } return [InfobarBannerOverlayCoordinator class]; case OverlayModality::kInfobarModal: - if ([SaveCardInfobarModalOverlayCoordinator requestSupport] - ->IsRequestSupported(request)) { - return [SaveCardInfobarModalOverlayCoordinator class]; - } if ([SaveAddressProfileInfobarModalOverlayCoordinator requestSupport] ->IsRequestSupported(request)) { return [SaveAddressProfileInfobarModalOverlayCoordinator class]; @@ -125,6 +121,8 @@ return [PasswordInfobarModalOverlayCoordinator class]; case InfobarType::kInfobarTypePermissions: return [PermissionsInfobarModalOverlayCoordinator class]; + case InfobarType::kInfobarTypeSaveCard: + return [SaveCardInfobarModalOverlayCoordinator class]; default: break; }
diff --git a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator.mm b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator.mm index 9e0970d..5cd8b64 100644 --- a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator.mm +++ b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_mediator.mm
@@ -297,14 +297,18 @@ #pragma mark - WebStateListObserving -- (void)webStateList:(WebStateList*)webStateList - didReplaceWebState:(web::WebState*)oldWebState - withWebState:(web::WebState*)newWebState - atIndex:(int)atIndex { +- (void)didChangeWebStateList:(WebStateList*)webStateList + change:(const WebStateListChange&)change + selection:(const WebStateSelection&)selection { DCHECK_EQ(_webStateList, webStateList); - if (atIndex == webStateList->active_index()) { - [self disableRefocus]; - [self.consumer dismiss]; + switch (change.type()) { + case WebStateListChange::Type::kReplace: { + if (selection.index == webStateList->active_index()) { + [self disableRefocus]; + [self.consumer dismiss]; + } + break; + } } }
diff --git a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_view_controller.mm b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_view_controller.mm index 299046fd..180d016 100644 --- a/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_view_controller.mm +++ b/ios/chrome/browser/ui/passwords/bottom_sheet/password_suggestion_bottom_sheet_view_controller.mm
@@ -58,9 +58,6 @@ UIGestureRecognizerDelegate, UITableViewDataSource, UITableViewDelegate> { - // Row in the table of suggestions of the use selectesd suggestion. - NSInteger _row; - // If YES: the table view is currently showing a single suggestion // If NO: the table view is currently showing all suggestions BOOL _tableViewIsMinimized; @@ -195,10 +192,14 @@ - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath { - _row = indexPath.row; + if (_suggestions.count <= 1) { + return; + } if (_tableViewIsMinimized) { _tableViewIsMinimized = NO; + [_tableView cellForRowAtIndexPath:indexPath].accessoryView = nil; + [self addSuggestionsToTableView]; // Update table view height. __weak __typeof(self) weakSelf = self; @@ -210,8 +211,14 @@ [self expand]; } - // Refresh cells to show the checkmark icon next to the selected suggestion. - [_tableView reloadData]; + [_tableView cellForRowAtIndexPath:indexPath].accessoryType = + UITableViewCellAccessoryCheckmark; +} + +- (void)tableView:(UITableView*)tableView + didDeselectRowAtIndexPath:(NSIndexPath*)indexPath { + [_tableView cellForRowAtIndexPath:indexPath].accessoryType = + UITableViewCellAccessoryNone; } // Long press open context menu. @@ -286,17 +293,6 @@ initWithImage:DefaultSymbolTemplateWithPointSize( kChevronDownSymbol, kSymbolAccessoryPointSize)]; cell.accessoryView.tintColor = [UIColor colorNamed:kTextQuaternaryColor]; - } else if (_row == indexPath.row) { - // The table view is showing all suggestions, and this cell contains the - // currently selected suggestion, so we display a checkmark on this cell. - cell.accessoryView = [[UIImageView alloc] - initWithImage:DefaultSymbolTemplateWithPointSize( - kCheckmarkSymbol, kSymbolAccessoryPointSize)]; - cell.accessoryView.tintColor = [UIColor colorNamed:kBlueColor]; - } else { - // The table view is showing all suggestions, and this cell does not contain - // the currently selected suggestion. - cell.accessoryView = nil; } [self loadFaviconAtIndexPath:indexPath forCell:cell]; return cell; @@ -403,6 +399,10 @@ _tableView.translatesAutoresizingMaskIntoConstraints = NO; + [_tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] + animated:NO + scrollPosition:UITableViewScrollPositionNone]; + return _tableView; } @@ -450,7 +450,7 @@ // Notifies the delegate that a password suggestion was selected by the user. - (void)didSelectSuggestion { - [self.delegate didSelectSuggestion:_row]; + [self.delegate didSelectSuggestion:_tableView.indexPathForSelectedRow.row]; } // Returns whether the provided index path points to the last row of the table @@ -548,6 +548,20 @@ } } +// Starting with a table view containing a single suggestion, add all other +// suggestions to the table view. +- (void)addSuggestionsToTableView { + [_tableView beginUpdates]; + NSMutableArray<NSIndexPath*>* indexPaths = + [NSMutableArray arrayWithCapacity:_suggestions.count - 1]; + for (NSUInteger i = 1; i < _suggestions.count; i++) { + [indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]]; + } + [_tableView insertRowsAtIndexPaths:indexPaths + withRowAnimation:UITableViewRowAnimationNone]; + [_tableView endUpdates]; +} + // Creates the UI action used to open the password manager. - (UIAction*)openPasswordManagerAction { __weak __typeof(self) weakSelf = self;
diff --git a/ios/chrome/browser/ui/safe_browsing/safe_browsing_coordinator.mm b/ios/chrome/browser/ui/safe_browsing/safe_browsing_coordinator.mm index f77cc1ff2..945e939 100644 --- a/ios/chrome/browser/ui/safe_browsing/safe_browsing_coordinator.mm +++ b/ios/chrome/browser/ui/safe_browsing/safe_browsing_coordinator.mm
@@ -65,6 +65,20 @@ #pragma mark - WebStateListObserving +- (void)didChangeWebStateList:(WebStateList*)webStateList + change:(const WebStateListChange&)change + selection:(const WebStateSelection&)selection { + switch (change.type()) { + case WebStateListChange::Type::kReplace: { + const WebStateListChangeReplace& replaceChange = + change.As<WebStateListChangeReplace>(); + SafeBrowsingTabHelper::FromWebState(replaceChange.inserted_web_state()) + ->SetDelegate(self); + break; + } + } +} + - (void)webStateList:(WebStateList*)webStateList didInsertWebState:(web::WebState*)webState atIndex:(int)index @@ -73,14 +87,6 @@ } - (void)webStateList:(WebStateList*)webStateList - didReplaceWebState:(web::WebState*)oldWebState - withWebState:(web::WebState*)newWebState - atIndex:(int)atIndex { - DCHECK(newWebState); - SafeBrowsingTabHelper::FromWebState(newWebState)->SetDelegate(self); -} - -- (void)webStateList:(WebStateList*)webStateList didDetachWebState:(web::WebState*)webState atIndex:(int)atIndex { SafeBrowsingTabHelper::FromWebState(webState)->RemoveDelegate();
diff --git a/ios/chrome/browser/ui/screen_time/screen_time_mediator.mm b/ios/chrome/browser/ui/screen_time/screen_time_mediator.mm index 183738f..ccfd40d7 100644 --- a/ios/chrome/browser/ui/screen_time/screen_time_mediator.mm +++ b/ios/chrome/browser/ui/screen_time/screen_time_mediator.mm
@@ -73,12 +73,15 @@ #pragma mark - WebStateListObserver -- (void)webStateList:(WebStateList*)webStateList - didReplaceWebState:(web::WebState*)oldWebState - withWebState:(web::WebState*)newWebState - atIndex:(int)atIndex { +- (void)didChangeWebStateList:(WebStateList*)webStateList + change:(const WebStateListChange&)change + selection:(const WebStateSelection&)selection { DCHECK_EQ(self.webStateList, webStateList); - [self updateConsumer]; + switch (change.type()) { + case WebStateListChange::Type::kReplace: + [self updateConsumer]; + break; + } } - (void)webStateList:(WebStateList*)webStateList
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.h index fd48210..6ea8d23 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.h
@@ -185,6 +185,18 @@ // TabGridModeSelection. - (void)deselectAllItemsForEditing; +// Notifies the grid that all items will be closed. +- (void)willCloseAll; + +// Notifies the grid that all items have been closed. +- (void)didCloseAll; + +// Notifies the grid that all closed items will be restored. +- (void)willUndoCloseAll; + +// Notifies the grid that all closed items have been restored. +- (void)didUndoCloseAll; + @end #endif // IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_GRID_GRID_GRID_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm index 9969d8c..023a81d 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm
@@ -193,6 +193,9 @@ @property(nonatomic) BOOL localDragActionInProgress; // Tracks if the Inactive Tabs button is being animated out. @property(nonatomic) BOOL inactiveTabsHeaderHideAnimationInProgress; +// Tracks if the items are in a batch action, which are the "Close All" or +// "Undo" the close all. +@property(nonatomic) BOOL isClosingAllOrUndoRunning; @end @implementation GridViewController { @@ -553,6 +556,34 @@ self.currentLayout.animatesItemUpdates = NO; } +- (void)willCloseAll { + self.isClosingAllOrUndoRunning = YES; +} + +- (void)didCloseAll { + self.isClosingAllOrUndoRunning = NO; +} + +- (void)willUndoCloseAll { + self.isClosingAllOrUndoRunning = YES; +} + +- (void)didUndoCloseAll { + self.isClosingAllOrUndoRunning = NO; + + // Reload the button and ensure it is not hidden, as this is the only flow + // where the button can dynamically reappear when the app is running and the + // reappearance is not managed by default. + [self reloadInactiveTabsButtonHeader]; + NSIndexPath* indexPath = [NSIndexPath indexPathForItem:0 + inSection:kOpenTabsSectionIndex]; + InactiveTabsButtonHeader* header = + base::mac::ObjCCast<InactiveTabsButtonHeader>([self.collectionView + supplementaryViewForElementKind:UICollectionElementKindSectionHeader + atIndexPath:indexPath]); + header.hidden = NO; +} + #pragma mark - UICollectionViewDataSource - (NSInteger)numberOfSectionsInCollectionView: @@ -743,6 +774,9 @@ // `collectionViewLayout` should always be a flow layout. DCHECK( [collectionViewLayout isKindOfClass:[UICollectionViewFlowLayout class]]); + if (self.isClosingAllOrUndoRunning) { + return CGSizeZero; + } UICollectionViewFlowLayout* layout = (UICollectionViewFlowLayout*)collectionViewLayout; CGSize itemSize = layout.itemSize; @@ -770,6 +804,9 @@ if (!IsInactiveTabsAvailable()) { return CGSizeZero; } + if (self.isClosingAllOrUndoRunning) { + return CGSizeZero; + } if (self.inactiveTabsHeaderHideAnimationInProgress) { // The header is animated out to a height of 0.1. return CGSizeMake(collectionView.bounds.size.width, 0.1);
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button_mediator.mm index 4e77dbf..dabddd0 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button_mediator.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button_mediator.mm
@@ -101,6 +101,15 @@ #pragma mark - WebStateListObserving +- (void)didChangeWebStateList:(WebStateList*)webStateList + change:(const WebStateListChange&)change + selection:(const WebStateSelection&)selection { + switch (change.type()) { + case WebStateListChange::Type::kReplace: + NOTREACHED_NORETURN(); + } +} + - (void)webStateList:(WebStateList*)webStateList didInsertWebState:(web::WebState*)webState atIndex:(int)index @@ -120,13 +129,6 @@ } - (void)webStateList:(WebStateList*)webStateList - didReplaceWebState:(web::WebState*)oldWebState - withWebState:(web::WebState*)newWebState - atIndex:(int)index { - NOTREACHED(); -} - -- (void)webStateList:(WebStateList*)webStateList willDetachWebState:(web::WebState*)webState atIndex:(int)index { // No-op. `-webStateList:didDetachWebState:atIndex` will soon be called and
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_mediator.mm index 45251ddf..a1f83d6 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_mediator.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_mediator.mm
@@ -263,6 +263,15 @@ #pragma mark - WebStateListObserving +- (void)didChangeWebStateList:(WebStateList*)webStateList + change:(const WebStateListChange&)change + selection:(const WebStateSelection&)selection { + switch (change.type()) { + case WebStateListChange::Type::kReplace: + NOTREACHED_NORETURN(); + } +} + - (void)webStateList:(WebStateList*)webStateList didInsertWebState:(web::WebState*)webState atIndex:(int)index @@ -292,13 +301,6 @@ } - (void)webStateList:(WebStateList*)webStateList - didReplaceWebState:(web::WebState*)oldWebState - withWebState:(web::WebState*)newWebState - atIndex:(int)index { - NOTREACHED_NORETURN(); -} - -- (void)webStateList:(WebStateList*)webStateList willDetachWebState:(web::WebState*)webState atIndex:(int)index { DCHECK_EQ(_webStateList, webStateList);
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_mediator.mm index ddc8227..082011d 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_mediator.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_mediator.mm
@@ -125,6 +125,36 @@ #pragma mark - WebStateListObserving +- (void)didChangeWebStateList:(WebStateList*)webStateList + change:(const WebStateListChange&)change + selection:(const WebStateSelection&)selection { + DCHECK_EQ(_webStateList, webStateList); + switch (change.type()) { + case WebStateListChange::Type::kReplace: { + if (webStateList->IsBatchInProgress()) { + return; + } + + if (!webStateList->IsWebStatePinnedAt(selection.index)) { + return; + } + + const WebStateListChangeReplace& replaceChange = + change.As<WebStateListChangeReplace>(); + web::WebState* replacedWebState = replaceChange.replaced_web_state(); + web::WebState* insertedWebState = replaceChange.inserted_web_state(); + TabSwitcherItem* newItem = [[PinnedWebStateTabSwitcherItem alloc] + initWithWebState:insertedWebState]; + [self.consumer replaceItemID:replacedWebState->GetStableIdentifier() + withItem:newItem]; + + _scopedWebStateObservation->RemoveObservation(replacedWebState); + _scopedWebStateObservation->AddObservation(insertedWebState); + break; + } + } +} + - (void)webStateList:(WebStateList*)webStateList didInsertWebState:(web::WebState*)webState atIndex:(int)index @@ -177,29 +207,6 @@ } - (void)webStateList:(WebStateList*)webStateList - didReplaceWebState:(web::WebState*)oldWebState - withWebState:(web::WebState*)newWebState - atIndex:(int)index { - DCHECK_EQ(_webStateList, webStateList); - - if (webStateList->IsBatchInProgress()) { - return; - } - - if (!webStateList->IsWebStatePinnedAt(index)) { - return; - } - - TabSwitcherItem* newItem = - [[PinnedWebStateTabSwitcherItem alloc] initWithWebState:newWebState]; - [self.consumer replaceItemID:oldWebState->GetStableIdentifier() - withItem:newItem]; - - _scopedWebStateObservation->RemoveObservation(oldWebState); - _scopedWebStateObservation->AddObservation(newWebState); -} - -- (void)webStateList:(WebStateList*)webStateList willDetachWebState:(web::WebState*)webState atIndex:(int)index { DCHECK_EQ(_webStateList, webStateList);
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm index 19486c6..076faa8 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_coordinator.mm
@@ -522,7 +522,7 @@ bool thumbStripEnabled = self.isThumbStripEnabled; DCHECK(viewController || (thumbStripEnabled && self.bvcContainer)); - if (shouldCloseTabGrid) { + if (shouldCloseTabGrid && !self.tabGridEnterTime.is_null()) { // Record when the tab switcher is dismissed. base::RecordAction(base::UserMetricsAction("MobileTabGridExited"));
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_mediator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_mediator.mm index 0b18b32..2ecd035 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_mediator.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_mediator.mm
@@ -250,6 +250,37 @@ #pragma mark - WebStateListObserving +- (void)didChangeWebStateList:(WebStateList*)webStateList + change:(const WebStateListChange&)change + selection:(const WebStateSelection&)selection { + DCHECK_EQ(_webStateList, webStateList); + switch (change.type()) { + case WebStateListChange::Type::kReplace: { + if (webStateList->IsBatchInProgress()) { + return; + } + + if (IsPinnedTabsEnabled() && + webStateList->IsWebStatePinnedAt(selection.index)) { + return; + } + + const WebStateListChangeReplace& replaceChange = + change.As<WebStateListChangeReplace>(); + web::WebState* replacedWebState = replaceChange.replaced_web_state(); + web::WebState* insertedWebState = replaceChange.inserted_web_state(); + TabSwitcherItem* newItem = + [[WebStateTabSwitcherItem alloc] initWithWebState:insertedWebState]; + [self.consumer replaceItemID:replacedWebState->GetStableIdentifier() + withItem:newItem]; + + _scopedWebStateObservation->RemoveObservation(replacedWebState); + _scopedWebStateObservation->AddObservation(insertedWebState); + break; + } + } +} + - (void)webStateList:(WebStateList*)webStateList didInsertWebState:(web::WebState*)webState atIndex:(int)index @@ -302,28 +333,6 @@ } - (void)webStateList:(WebStateList*)webStateList - didReplaceWebState:(web::WebState*)oldWebState - withWebState:(web::WebState*)newWebState - atIndex:(int)index { - DCHECK_EQ(_webStateList, webStateList); - if (webStateList->IsBatchInProgress()) { - return; - } - - if (IsPinnedTabsEnabled() && webStateList->IsWebStatePinnedAt(index)) { - return; - } - - TabSwitcherItem* newItem = - [[WebStateTabSwitcherItem alloc] initWithWebState:newWebState]; - [self.consumer replaceItemID:oldWebState->GetStableIdentifier() - withItem:newItem]; - - _scopedWebStateObservation->RemoveObservation(oldWebState); - _scopedWebStateObservation->AddObservation(newWebState); -} - -- (void)webStateList:(WebStateList*)webStateList willDetachWebState:(web::WebState*)webState atIndex:(int)index { DCHECK_EQ(_webStateList, webStateList);
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm index ce1edbc9..004af74 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm
@@ -2800,23 +2800,37 @@ } - (void)undoCloseAllItemsForRegularTabs { + GridViewController* regularViewController = + [self gridViewControllerForPage:TabGridPageRegularTabs]; + + [regularViewController willUndoCloseAll]; + // This was saved as a stack: first save the inactive tabs, then the active // tabs. So undo in the reverse order: first undo the active tabs, then the // inactive tabs. [self.regularTabsDelegate undoCloseAllItems]; [self.inactiveTabsDelegate undoCloseAllItems]; + [regularViewController didUndoCloseAll]; + self.undoCloseAllAvailable = NO; [self configureCloseAllButtonForCurrentPageAndUndoAvailability]; } - (void)saveAndCloseAllItemsForRegularTabs { + GridViewController* regularViewController = + [self gridViewControllerForPage:TabGridPageRegularTabs]; + + [regularViewController willCloseAll]; + // This was saved as a stack: first save the inactive tabs, then the active // tabs. So undo in the reverse order: first undo the active tabs, then the // inactive tabs. [self.inactiveTabsDelegate saveAndCloseAllItems]; [self.regularTabsDelegate saveAndCloseAllItems]; + [regularViewController didCloseAll]; + self.undoCloseAllAvailable = YES; [self configureCloseAllButtonForCurrentPageAndUndoAvailability]; }
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm index 72623ae..10dfa061 100644 --- a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm +++ b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
@@ -1166,6 +1166,21 @@ #pragma mark - WebStateListObserving methods +- (void)didChangeWebStateList:(WebStateList*)webStateList + change:(const WebStateListChange&)change + selection:(const WebStateSelection&)selection { + switch (change.type()) { + case WebStateListChange::Type::kReplace: { + const WebStateListChangeReplace& replaceChange = + change.As<WebStateListChangeReplace>(); + web::WebState* insertedWebState = replaceChange.inserted_web_state(); + TabView* view = [self tabViewForWebState:insertedWebState]; + [self updateTabView:view withWebState:insertedWebState]; + break; + } + } +} + // Observer method, active WebState changed. - (void)webStateList:(WebStateList*)webStateList didChangeActiveWebState:(web::WebState*)newWebState @@ -1261,15 +1276,6 @@ [self updateContentOffsetForWebStateIndex:index isNewWebState:YES]; } -// Observer method, WebState replaced in `webStateList`. -- (void)webStateList:(WebStateList*)webStateList - didReplaceWebState:(web::WebState*)oldWebState - withWebState:(web::WebState*)newWebState - atIndex:(int)atIndex { - TabView* view = [self tabViewForWebState:newWebState]; - [self updateTabView:view withWebState:newWebState]; -} - #pragma mark - WebStateFaviconDriverObserver // Observer method. `webState` got a favicon update.
diff --git a/ios/chrome/browser/ui/text_zoom/text_zoom_mediator.mm b/ios/chrome/browser/ui/text_zoom/text_zoom_mediator.mm index e1032243..e6ec741 100644 --- a/ios/chrome/browser/ui/text_zoom/text_zoom_mediator.mm +++ b/ios/chrome/browser/ui/text_zoom/text_zoom_mediator.mm
@@ -85,14 +85,19 @@ #pragma mark - WebStateListObserver -- (void)webStateList:(WebStateList*)webStateList - didReplaceWebState:(web::WebState*)oldWebState - withWebState:(web::WebState*)newWebState - atIndex:(int)atIndex { +- (void)didChangeWebStateList:(WebStateList*)webStateList + change:(const WebStateListChange&)change + selection:(const WebStateSelection&)selection { DCHECK_EQ(_webStateList, webStateList); - if (atIndex == webStateList->active_index()) { - [self setActiveWebState:newWebState]; - [_commandHandler closeTextZoom]; + switch (change.type()) { + case WebStateListChange::Type::kReplace: + const WebStateListChangeReplace& replaceChange = + change.As<WebStateListChangeReplace>(); + if (selection.index == webStateList->active_index()) { + [self setActiveWebState:replaceChange.inserted_web_state()]; + [_commandHandler closeTextZoom]; + } + break; } }
diff --git a/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.mm index 2fdf2c3..31bcec8 100644 --- a/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.mm +++ b/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.mm
@@ -166,12 +166,16 @@ // set to topLayoutGuide after the view creation on iOS 10. [self.view setUp]; + [self.layoutGuideCenter referenceView:self.view.locationBarContainer + underName:kOmniboxGuide]; self.view.locationBarBottomConstraint.constant = [self verticalMarginForLocationBarForFullscreenProgress:1]; } - (void)didMoveToParentViewController:(UIViewController*)parent { [super didMoveToParentViewController:parent]; + // TODO(crbug.com/1450530): Remove once all usage of kOmniboxGuide has moved + // to LayoutGuideCenter. UIView* omniboxView = self.view.locationBarContainer; [NamedGuide guideWithName:kOmniboxGuide view:omniboxView].constrainedView = omniboxView;
diff --git a/ios/chrome/browser/ui/whats_new/whats_new_util.h b/ios/chrome/browser/ui/whats_new/whats_new_util.h index bb64c2f..f253765 100644 --- a/ios/chrome/browser/ui/whats_new/whats_new_util.h +++ b/ios/chrome/browser/ui/whats_new/whats_new_util.h
@@ -6,9 +6,13 @@ #define IOS_CHROME_BROWSER_UI_WHATS_NEW_WHATS_NEW_UTIL_H_ #import <Foundation/Foundation.h> +#include "base/feature_list.h" class PromosManager; +// Feature flag that enables version 2 of What's New. +BASE_DECLARE_FEATURE(kWhatsNewIOSM116); + // Key to store whether the What's New promo has been register. extern NSString* const kWhatsNewPromoRegistrationKey; @@ -40,4 +44,7 @@ // more than once. bool ShouldRegisterWhatsNewPromo(); +// Returns whether What's New M116 is enabled. +bool IsWhatsNewM116Enabled(); + #endif // IOS_CHROME_BROWSER_UI_WHATS_NEW_WHATS_NEW_UTIL_H_
diff --git a/ios/chrome/browser/ui/whats_new/whats_new_util.mm b/ios/chrome/browser/ui/whats_new/whats_new_util.mm index 6738277a..e815544 100644 --- a/ios/chrome/browser/ui/whats_new/whats_new_util.mm +++ b/ios/chrome/browser/ui/whats_new/whats_new_util.mm
@@ -66,6 +66,10 @@ } // namespace +BASE_FEATURE(kWhatsNewIOSM116, + "WhatsNewIOSM116", + base::FEATURE_DISABLED_BY_DEFAULT); + bool WasWhatsNewUsed() { return [[NSUserDefaults standardUserDefaults] boolForKey:kWhatsNewUsageEntryKey]; @@ -97,3 +101,7 @@ return !IsWhatsNewPromoRegistered() && (IsSixLaunchAfterFre() || IsSixDaysAfterFre()); } + +bool IsWhatsNewM116Enabled() { + return base::FeatureList::IsEnabled(kWhatsNewIOSM116); +}
diff --git a/ios/chrome/browser/web/chrome_web_client.h b/ios/chrome/browser/web/chrome_web_client.h index e0bace8..a6ca168 100644 --- a/ios/chrome/browser/web/chrome_web_client.h +++ b/ios/chrome/browser/web/chrome_web_client.h
@@ -67,6 +67,8 @@ bool IsMixedContentAutoupgradeEnabled( web::BrowserState* browser_state) const override; bool IsBrowserLockdownModeEnabled(web::BrowserState* browser_state) override; + void SetOSLockdownModeEnabled(web::BrowserState* browser_state, + bool enabled) override; private: // Reference to a view that is attached to a window.
diff --git a/ios/chrome/browser/web/chrome_web_client.mm b/ios/chrome/browser/web/chrome_web_client.mm index 7fa87b3e..ea0aa8e 100644 --- a/ios/chrome/browser/web/chrome_web_client.mm +++ b/ios/chrome/browser/web/chrome_web_client.mm
@@ -531,3 +531,13 @@ } return false; } + +void ChromeWebClient::SetOSLockdownModeEnabled(web::BrowserState* browser_state, + bool enabled) { + if (base::FeatureList::IsEnabled(web::kBrowserLockdownModeAvailable)) { + ChromeBrowserState* chrome_browser_state = + ChromeBrowserState::FromBrowserState(browser_state); + PrefService* prefs = chrome_browser_state->GetPrefs(); + prefs->SetBoolean(prefs::kOSLockdownModeEnabled, enabled); + } +}
diff --git a/ios/chrome/browser/web/session_state/web_session_state_cache_factory.mm b/ios/chrome/browser/web/session_state/web_session_state_cache_factory.mm index ba3655a..bc767bbd 100644 --- a/ios/chrome/browser/web/session_state/web_session_state_cache_factory.mm +++ b/ios/chrome/browser/web/session_state/web_session_state_cache_factory.mm
@@ -27,9 +27,8 @@ // allowing it bind it to an ChromeBrowserState as a KeyedService. class WebSessionStateCacheWrapper : public KeyedService { public: - explicit WebSessionStateCacheWrapper( - BrowserList* browser_list, - WebSessionStateCache* web_session_state_cache); + WebSessionStateCacheWrapper(BrowserList* browser_list, + WebSessionStateCache* web_session_state_cache); WebSessionStateCacheWrapper(const WebSessionStateCacheWrapper&) = delete; WebSessionStateCacheWrapper& operator=(const WebSessionStateCacheWrapper&) =
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn index 76fe9b5c..bf1e432 100644 --- a/ios/chrome/test/BUILD.gn +++ b/ios/chrome/test/BUILD.gn
@@ -227,9 +227,7 @@ "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/autofill_address_profile:unit_tests", "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/common:unit_tests", "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/confirm:unit_tests", - "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/save_card:unit_tests", "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/sync_error:unit_tests", - "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/tailored_security:unit_tests", "//ios/chrome/browser/infobars/overlays/browser_agent/interaction_handlers/translate:unit_tests", "//ios/chrome/browser/itunes_urls:unit_tests", "//ios/chrome/browser/json_parser:unit_tests",
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn index 02360381..4a370a13 100644 --- a/ios/chrome/test/earl_grey/BUILD.gn +++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -88,6 +88,7 @@ "//ios/chrome/browser/device_sharing:eg_app_support+eg2", "//ios/chrome/browser/find_in_page", "//ios/chrome/browser/find_in_page:eg_app_support+eg2", + "//ios/chrome/browser/first_run", "//ios/chrome/browser/https_upgrades:eg_app_support+eg2", "//ios/chrome/browser/metrics:eg_app_support+eg2", "//ios/chrome/browser/ntp:features",
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h index 5d759e9..df4a645 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h +++ b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h
@@ -682,6 +682,15 @@ // message. + (void)disableDefaultBrowserPromo; +#pragma mark - First Run Utilities + +// Writes the First Run Sentinel file, used to record that First Run has +// completed. ++ (void)writeFirstRunSentinel; + +// Remove the FirstRun sentinel file. ++ (void)removeFirstRunSentinel; + @end #endif // IOS_CHROME_TEST_EARL_GREY_CHROME_EARL_GREY_APP_INTERFACE_H_
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm index 3de781ca..cdd94f8e 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm +++ b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm
@@ -8,6 +8,7 @@ #import "base/command_line.h" #import "base/containers/contains.h" +#import "base/files/file.h" #import "base/files/file_util.h" #import "base/ios/ios_util.h" #import "base/json/json_string_value_serializer.h" @@ -35,6 +36,7 @@ #import "ios/chrome/browser/content_settings/host_content_settings_map_factory.h" #import "ios/chrome/browser/default_browser/utils.h" #import "ios/chrome/browser/default_browser/utils_test_support.h" +#import "ios/chrome/browser/first_run/first_run.h" #import "ios/chrome/browser/ntp/features.h" #import "ios/chrome/browser/search_engines/search_engines_util.h" #import "ios/chrome/browser/search_engines/template_url_service_factory.h" @@ -1455,4 +1457,21 @@ LogUserInteractionWithFullscreenPromo(); } +#pragma mark - First Run Utilities + ++ (void)writeFirstRunSentinel { + base::ScopedAllowBlockingForTesting allow_blocking; + FirstRun::RemoveSentinel(); + base::File::Error fileError; + FirstRun::CreateSentinel(&fileError); + FirstRun::LoadSentinelInfo(); +} + ++ (void)removeFirstRunSentinel { + base::ScopedAllowBlockingForTesting allow_blocking; + if (FirstRun::RemoveSentinel()) { + FirstRun::LoadSentinelInfo(); + } +} + @end
diff --git a/ios/web/navigation/crw_wk_navigation_handler.mm b/ios/web/navigation/crw_wk_navigation_handler.mm index e7b9265..22351569 100644 --- a/ios/web/navigation/crw_wk_navigation_handler.mm +++ b/ios/web/navigation/crw_wk_navigation_handler.mm
@@ -167,8 +167,19 @@ preferences:(WKWebpagePreferences*)preferences decisionHandler:(void (^)(WKNavigationActionPolicy, WKWebpagePreferences*))handler { - GURL requestURL = net::GURLWithNSURL(action.request.URL); + // Check if OS lockdown mode is enabled and update the preference value. + if (!self.beingDestroyed) { + static dispatch_once_t onceToken; + web::BrowserState* browser_state = self.webStateImpl->GetBrowserState(); + dispatch_once(&onceToken, ^{ + if (@available(iOS 16.0, *)) { + web::GetWebClient()->SetOSLockdownModeEnabled( + browser_state, preferences.lockdownModeEnabled); + } + }); + } + GURL requestURL = net::GURLWithNSURL(action.request.URL); const web::UserAgentType userAgentType = [self userAgentForNavigationAction:action webView:webView]; @@ -223,10 +234,11 @@ preferences.lockdownModeEnabled); } - if (self.webStateImpl) { + if (!self.beingDestroyed) { web::BrowserState* browser_state = self.webStateImpl->GetBrowserState(); - if (web::GetWebClient()->IsBrowserLockdownModeEnabled(browser_state)) + if (web::GetWebClient()->IsBrowserLockdownModeEnabled(browser_state)) { preferences.lockdownModeEnabled = true; + } } } #endif // defined (__IPHONE_16_0)
diff --git a/ios/web/navigation/navigation_manager_impl.mm b/ios/web/navigation/navigation_manager_impl.mm index 7d53211b..2f43c3a 100644 --- a/ios/web/navigation/navigation_manager_impl.mm +++ b/ios/web/navigation/navigation_manager_impl.mm
@@ -549,10 +549,9 @@ NavigationInitiationType initiation_type, bool has_user_gesture) { if (index < 0 || index >= GetItemCount()) { - // There are bugs in WKWebView where the back/forward list can fall out - // of sync with reality. In these situations, a navigation item that - // appears in the back or forward list might not actually exist. See - // crbug.com/1407244. + // Button actions are executed asynchronously, so it is possible for the + // client to call this with an invalid index if the user quickly taps the + // back or foward button mulitple times. See crbug.com/1407244. return; }
diff --git a/ios/web/public/web_client.h b/ios/web/public/web_client.h index 77d8a1f..0fc27a7 100644 --- a/ios/web/public/web_client.h +++ b/ios/web/public/web_client.h
@@ -212,6 +212,11 @@ // Returns true if browser lockdown mode is enabled. Default return value is // false. virtual bool IsBrowserLockdownModeEnabled(web::BrowserState* browser_state); + + // Sets OS lockdown mode preference value. By default, no preference value is + // set. + virtual void SetOSLockdownModeEnabled(web::BrowserState* browser_state, + bool enabled); }; } // namespace web
diff --git a/ios/web/web_client.mm b/ios/web/web_client.mm index 98eba05e1..6835ef3 100644 --- a/ios/web/web_client.mm +++ b/ios/web/web_client.mm
@@ -150,4 +150,7 @@ return false; } +void WebClient::SetOSLockdownModeEnabled(web::BrowserState* browser_state, + bool enabled) {} + } // namespace web
diff --git a/ios/web_view/internal/autofill/cwv_autofill_controller.mm b/ios/web_view/internal/autofill/cwv_autofill_controller.mm index 518e404..075599f 100644 --- a/ios/web_view/internal/autofill/cwv_autofill_controller.mm +++ b/ios/web_view/internal/autofill/cwv_autofill_controller.mm
@@ -323,11 +323,13 @@ delegate { // We only want Autofill suggestions. std::vector<autofill::Suggestion> filtered_suggestions; - base::ranges::copy_if( - suggestions, std::back_inserter(filtered_suggestions), - [](const autofill::Suggestion& suggestion) { - return suggestion.frontend_id.is_an_address_or_card_popup_item_id(); - }); + base::ranges::copy_if(suggestions, std::back_inserter(filtered_suggestions), + [](const autofill::Suggestion& suggestion) { + return suggestion.popup_item_id == + autofill::PopupItemId::kAddressEntry || + suggestion.popup_item_id == + autofill::PopupItemId::kCreditCardEntry; + }); [_autofillAgent showAutofillPopup:filtered_suggestions popupDelegate:delegate]; }
diff --git a/ios/web_view/internal/autofill/web_view_autofill_client_ios.h b/ios/web_view/internal/autofill/web_view_autofill_client_ios.h index be6b3290..3704cca7 100644 --- a/ios/web_view/internal/autofill/web_view_autofill_client_ios.h +++ b/ios/web_view/internal/autofill/web_view_autofill_client_ios.h
@@ -131,7 +131,7 @@ void DidFillOrPreviewField(const std::u16string& autofilled_value, const std::u16string& profile_full_name) override; bool IsContextSecure() const override; - void ExecuteCommand(Suggestion::FrontendId id) override; + void ExecuteCommand(PopupItemId popup_item_id) override; void OpenPromoCodeOfferDetailsURL(const GURL& url) override; autofill::FormInteractionsFlowId GetCurrentFormInteractionsFlowId() override; bool IsLastQueriedField(FieldGlobalId field_id) override;
diff --git a/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm b/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm index 8045495a..df8e5b8 100644 --- a/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm +++ b/ios/web_view/internal/autofill/web_view_autofill_client_ios.mm
@@ -7,31 +7,32 @@ #import <utility> #import <vector> -#include "base/check.h" -#include "base/functional/bind.h" -#include "base/functional/callback.h" -#include "base/memory/ptr_util.h" -#include "base/notreached.h" -#include "components/autofill/core/browser/form_data_importer.h" -#include "components/autofill/core/browser/logging/log_router.h" +#import "base/check.h" +#import "base/functional/bind.h" +#import "base/functional/callback.h" +#import "base/memory/ptr_util.h" +#import "base/notreached.h" +#import "components/autofill/core/browser/form_data_importer.h" +#import "components/autofill/core/browser/logging/log_router.h" #import "components/autofill/core/browser/payments/credit_card_cvc_authenticator.h" -#include "components/autofill/core/browser/payments/payments_client.h" -#include "components/autofill/core/common/autofill_prefs.h" +#import "components/autofill/core/browser/payments/payments_client.h" +#import "components/autofill/core/browser/ui/popup_item_ids.h" +#import "components/autofill/core/common/autofill_prefs.h" #import "components/autofill/ios/browser/autofill_driver_ios.h" -#include "components/autofill/ios/browser/autofill_util.h" -#include "components/password_manager/core/common/password_manager_pref_names.h" -#include "components/security_state/ios/security_state_utils.h" -#include "ios/web/public/browser_state.h" +#import "components/autofill/ios/browser/autofill_util.h" +#import "components/password_manager/core/common/password_manager_pref_names.h" +#import "components/security_state/ios/security_state_utils.h" +#import "ios/web/public/browser_state.h" #import "ios/web/public/web_state.h" -#include "ios/web_view/internal/app/application_context.h" -#include "ios/web_view/internal/autofill/web_view_autocomplete_history_manager_factory.h" +#import "ios/web_view/internal/app/application_context.h" +#import "ios/web_view/internal/autofill/web_view_autocomplete_history_manager_factory.h" #import "ios/web_view/internal/autofill/web_view_autofill_log_router_factory.h" -#include "ios/web_view/internal/autofill/web_view_personal_data_manager_factory.h" -#include "ios/web_view/internal/autofill/web_view_strike_database_factory.h" -#include "ios/web_view/internal/signin/web_view_identity_manager_factory.h" +#import "ios/web_view/internal/autofill/web_view_personal_data_manager_factory.h" +#import "ios/web_view/internal/autofill/web_view_strike_database_factory.h" +#import "ios/web_view/internal/signin/web_view_identity_manager_factory.h" #import "ios/web_view/internal/sync/web_view_sync_service_factory.h" -#include "services/network/public/cpp/shared_url_loader_factory.h" -#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#import "services/network/public/cpp/shared_url_loader_factory.h" +#import "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -360,7 +361,7 @@ return IsContextSecureForWebState(web_state_); } -void WebViewAutofillClientIOS::ExecuteCommand(Suggestion::FrontendId id) { +void WebViewAutofillClientIOS::ExecuteCommand(PopupItemId popup_item_id) { NOTIMPLEMENTED(); }
diff --git a/media/capture/video/win/video_capture_device_factory_win.cc b/media/capture/video/win/video_capture_device_factory_win.cc index 075f9927..40e663c1 100644 --- a/media/capture/video/win/video_capture_device_factory_win.cc +++ b/media/capture/video/win/video_capture_device_factory_win.cc
@@ -38,6 +38,7 @@ #include "media/base/media_switches.h" #include "media/base/win/mf_initializer.h" #include "media/capture/capture_switches.h" +#include "media/capture/video/video_capture_metrics.h" #include "media/capture/video/win/metrics.h" #include "media/capture/video/win/video_capture_device_mf_win.h" #include "media/capture/video/win/video_capture_device_win.h" @@ -418,6 +419,7 @@ DVLOG(1) << " MediaFoundation Device: " << device_descriptor.display_name(); if (device->Init()) { + LogCaptureDeviceHashedModelId(device_descriptor); return VideoCaptureErrorOrDevice(std::move(device)); } return VideoCaptureErrorOrDevice( @@ -443,8 +445,10 @@ auto device = std::make_unique<VideoCaptureDeviceWin>( device_descriptor, std::move(capture_filter)); DVLOG(1) << " DirectShow Device: " << device_descriptor.display_name(); - if (device->Init()) + if (device->Init()) { + LogCaptureDeviceHashedModelId(device_descriptor); return VideoCaptureErrorOrDevice(std::move(device)); + } return VideoCaptureErrorOrDevice( VideoCaptureError::kWinDirectShowDeviceInitializationFailed); }
diff --git a/media/gpu/windows/d3d11_video_decoder.cc b/media/gpu/windows/d3d11_video_decoder.cc index 8205f5e7..2ebefdf 100644 --- a/media/gpu/windows/d3d11_video_decoder.cc +++ b/media/gpu/windows/d3d11_video_decoder.cc
@@ -209,8 +209,11 @@ } if (set_accelerator_decoder_wrapper_cb_) { - set_accelerator_decoder_wrapper_cb_.Run( - CreateD3D11VideoDecoderWrapper(video_decoder)); + auto wrapper = CreateD3D11VideoDecoderWrapper(video_decoder); + if (!wrapper) { + return E_FAIL; + } + set_accelerator_decoder_wrapper_cb_.Run(std::move(wrapper)); } // Provide the initial video decoder object. @@ -693,9 +696,12 @@ return NotifyError(std::move(video_decoder_or_error).error()); } auto video_decoder = std::move(video_decoder_or_error).value(); + auto wrapper = CreateD3D11VideoDecoderWrapper(video_decoder); + if (!wrapper) { + return NotifyError(D3D11StatusCode::kDecoderCreationFailed); + } if (set_accelerator_decoder_wrapper_cb_) { - set_accelerator_decoder_wrapper_cb_.Run( - CreateD3D11VideoDecoderWrapper(video_decoder)); + set_accelerator_decoder_wrapper_cb_.Run(std::move(wrapper)); } DCHECK(set_accelerator_decoder_cb_); set_accelerator_decoder_cb_.Run(video_decoder);
diff --git a/media/gpu/windows/d3d_accelerator.cc b/media/gpu/windows/d3d_accelerator.cc index b78e627..504f12f 100644 --- a/media/gpu/windows/d3d_accelerator.cc +++ b/media/gpu/windows/d3d_accelerator.cc
@@ -49,6 +49,7 @@ void D3DAccelerator::SetVideoDecoderWrapper( std::unique_ptr<D3DVideoDecoderWrapper> video_decoder_wrapper) { + CHECK(video_decoder_wrapper); video_decoder_wrapper_ = std::move(video_decoder_wrapper); }
diff --git a/media/mojo/clients/mojo_video_decoder.h b/media/mojo/clients/mojo_video_decoder.h index 87fdd87..ecf7c02 100644 --- a/media/mojo/clients/mojo_video_decoder.h +++ b/media/mojo/clients/mojo_video_decoder.h
@@ -120,7 +120,8 @@ // Manages VideoFrame destruction callbacks. scoped_refptr<MojoVideoFrameHandleReleaser> mojo_video_frame_handle_releaser_; - raw_ptr<GpuVideoAcceleratorFactories> gpu_factories_ = nullptr; + raw_ptr<GpuVideoAcceleratorFactories, LeakedDanglingUntriaged> + gpu_factories_ = nullptr; // Raw pointer is safe since both `this` and the `media_log` are owned by // WebMediaPlayerImpl with the correct declaration order.
diff --git a/media/mojo/mojom/speech_recognition.mojom b/media/mojo/mojom/speech_recognition.mojom index 452cf30..11d70525 100644 --- a/media/mojo/mojom/speech_recognition.mojom +++ b/media/mojo/mojom/speech_recognition.mojom
@@ -9,6 +9,8 @@ import "mojo/public/mojom/base/unguessable_token.mojom"; import "ui/gfx/geometry/mojom/geometry.mojom"; +// Next MinVersion: 2 + // Corresponds to the LangIdEvent.ConfidenceInterval defined in // http://google3/speech/soda/public/soda_event.proto. [Stable, Extensible] @@ -19,6 +21,16 @@ kHighlyConfident, }; +// Corresponds to the LangIdEvent.AsrSwitchResult defined in +// http://google3/speech/soda/public/soda_event.proto. +[Stable, Extensible] +enum AsrSwitchResult { + [Default] kDefaultNoSwitch, + kSwitchSucceeded, + kSwitchFailed, + kSwitchSkipedNoLp, +}; + // The main interface a renderer client uses to interact with a speech // recognition service process. In web Live Caption, every renderer can own one // or more Remote<SpeechRecognitionContext>, with the receiver bound through the @@ -142,6 +154,10 @@ // The confidence interval. ConfidenceLevel confidence_level; + + // If multilang is enabled, describes the actions Automatic Speech Recognition + // took as a result of this event. + [MinVersion=1] AsrSwitchResult? asr_switch_result; }; // The interface used to notify the speech recognition client of events
diff --git a/media/mojo/services/mojo_video_decoder_service.h b/media/mojo/services/mojo_video_decoder_service.h index 9db66c61..ddc28db 100644 --- a/media/mojo/services/mojo_video_decoder_service.h +++ b/media/mojo/services/mojo_video_decoder_service.h
@@ -101,10 +101,11 @@ std::string codec_string_; // Decoder factory. - raw_ptr<MojoMediaClient> mojo_media_client_; + raw_ptr<MojoMediaClient, LeakedDanglingUntriaged> mojo_media_client_; // A helper object required to get the CDM from a CDM ID. - const raw_ptr<MojoCdmServiceContext> mojo_cdm_service_context_ = nullptr; + const raw_ptr<MojoCdmServiceContext, LeakedDanglingUntriaged> + mojo_cdm_service_context_ = nullptr; // Channel for sending async messages to the client. mojo::AssociatedRemote<mojom::VideoDecoderClient> client_;
diff --git a/media/renderers/video_renderer_impl.cc b/media/renderers/video_renderer_impl.cc index b452b47..dea05810 100644 --- a/media/renderers/video_renderer_impl.cc +++ b/media/renderers/video_renderer_impl.cc
@@ -1011,6 +1011,7 @@ algorithm_->Reset( VideoRendererAlgorithm::ResetFlag::kPreserveNextFrameEstimates); painted_first_frame_ = false; + paint_first_frame_cb_.Cancel(); // It's possible in the background rendering case for us to expire enough // frames that we need to transition from HAVE_ENOUGH => HAVE_NOTHING. Just @@ -1064,11 +1065,12 @@ void VideoRendererImpl::PaintFirstFrame() { DCHECK(task_runner_->RunsTasksInCurrentSequence()); - DCHECK(algorithm_->frames_queued()); if (painted_first_frame_ || sink_started_) { return; } + DCHECK(algorithm_->frames_queued()); + auto first_frame = algorithm_->Render(base::TimeTicks(), base::TimeTicks(), nullptr); DCHECK(first_frame);
diff --git a/net/dns/host_resolver_cache.cc b/net/dns/host_resolver_cache.cc index 40bb9530..3ffcb2dd 100644 --- a/net/dns/host_resolver_cache.cc +++ b/net/dns/host_resolver_cache.cc
@@ -226,8 +226,8 @@ lookup_name = canonicalized; } - auto range = - entries_.equal_range(KeyRef{lookup_name, network_anonymization_key}); + auto range = entries_.equal_range( + KeyRef{lookup_name, raw_ref(network_anonymization_key)}); if (range.first == entries_.cend() || range.second == entries_.cbegin()) { return matches; }
diff --git a/net/dns/host_resolver_cache.h b/net/dns/host_resolver_cache.h index 50030bb..5c7e9e89 100644 --- a/net/dns/host_resolver_cache.h +++ b/net/dns/host_resolver_cache.h
@@ -122,7 +122,7 @@ struct KeyRef { base::StringPiece domain_name; - const NetworkAnonymizationKey& network_anonymization_key; + const raw_ref<const NetworkAnonymizationKey> network_anonymization_key; }; // Allow comparing Key to KeyRef to allow refs for entry lookup. @@ -136,11 +136,11 @@ bool operator()(const Key& lhs, const KeyRef& rhs) const { return std::tie(lhs.domain_name, lhs.network_anonymization_key) < - std::tie(rhs.domain_name, rhs.network_anonymization_key); + std::tie(rhs.domain_name, *rhs.network_anonymization_key); } bool operator()(const KeyRef& lhs, const Key& rhs) const { - return std::tie(lhs.domain_name, lhs.network_anonymization_key) < + return std::tie(lhs.domain_name, *lhs.network_anonymization_key) < std::tie(rhs.domain_name, rhs.network_anonymization_key); } };
diff --git a/net/reporting/reporting_test_util.h b/net/reporting/reporting_test_util.h index 00dcaa5..6957eb5 100644 --- a/net/reporting/reporting_test_util.h +++ b/net/reporting/reporting_test_util.h
@@ -179,8 +179,9 @@ // Owned by the DeliveryAgent and GarbageCollector, respectively, but // referenced here to preserve type: - raw_ptr<base::MockOneShotTimer> delivery_timer_; - raw_ptr<base::MockOneShotTimer> garbage_collection_timer_; + raw_ptr<base::MockOneShotTimer, LeakedDanglingUntriaged> delivery_timer_; + raw_ptr<base::MockOneShotTimer, LeakedDanglingUntriaged> + garbage_collection_timer_; }; // A unit test base class that provides a TestReportingContext and shorthand
diff --git a/pdf/pdfium/pdfium_document.cc b/pdf/pdfium/pdfium_document.cc index 8616b31..5b61e721 100644 --- a/pdf/pdfium/pdfium_document.cc +++ b/pdf/pdfium/pdfium_document.cc
@@ -31,7 +31,7 @@ return file_avail->doc_loader_->IsDataAvailable(offset, size); } - raw_ptr<DocumentLoader> doc_loader_; + raw_ptr<DocumentLoader, LeakedDanglingUntriaged> doc_loader_; }; class DownloadHints : public FX_DOWNLOADHINTS { @@ -51,7 +51,7 @@ return download_hints->doc_loader_->RequestData(offset, size); } - raw_ptr<DocumentLoader> doc_loader_; + raw_ptr<DocumentLoader, LeakedDanglingUntriaged> doc_loader_; }; class FileAccess : public FPDF_FILEACCESS { @@ -73,7 +73,7 @@ return file_access->doc_loader_->GetBlock(position, size, buffer); } - raw_ptr<DocumentLoader> doc_loader_; + raw_ptr<DocumentLoader, LeakedDanglingUntriaged> doc_loader_; }; } // namespace
diff --git a/sandbox/policy/features.cc b/sandbox/policy/features.cc index 2b6bbc83..5d9678d 100644 --- a/sandbox/policy/features.cc +++ b/sandbox/policy/features.cc
@@ -72,6 +72,11 @@ "WinSboxHighRendererJobMemoryLimits", base::FEATURE_DISABLED_BY_DEFAULT); +// Emergency "off switch" for closing the KsecDD handle in cryptbase.dll just +// before sandbox lockdown in renderers. +BASE_FEATURE(kWinSboxRendererCloseKsecDD, + "WinSboxRendererCloseKsecDD", + base::FEATURE_ENABLED_BY_DEFAULT); #endif // BUILDFLAG(IS_WIN) #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/sandbox/policy/features.h b/sandbox/policy/features.h index 585f3ffd..e4abbc6b 100644 --- a/sandbox/policy/features.h +++ b/sandbox/policy/features.h
@@ -32,6 +32,7 @@ SANDBOX_POLICY_EXPORT BASE_DECLARE_FEATURE(kRendererAppContainer); SANDBOX_POLICY_EXPORT BASE_DECLARE_FEATURE(kWinSboxAllowSystemFonts); SANDBOX_POLICY_EXPORT BASE_DECLARE_FEATURE(kWinSboxHighRendererJobMemoryLimits); +SANDBOX_POLICY_EXPORT BASE_DECLARE_FEATURE(kWinSboxRendererCloseKsecDD); #endif // BUILDFLAG(IS_WIN) #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/sandbox/policy/win/sandbox_win.cc b/sandbox/policy/win/sandbox_win.cc index 4d566d8..490ecf0 100644 --- a/sandbox/policy/win/sandbox_win.cc +++ b/sandbox/policy/win/sandbox_win.cc
@@ -608,9 +608,17 @@ return result; if (process_type == switches::kRendererProcess) { + if (base::FeatureList::IsEnabled(features::kWinSboxRendererCloseKsecDD)) { + // TODO(crbug.com/74242) Remove if we can avoid loading cryptbase.dll. + result = config->AddKernelObjectToClose(L"File", L"\\Device\\KsecDD"); + if (result != SBOX_ALL_OK) { + return result; + } + } result = SandboxWin::AddWin32kLockdownPolicy(config); - if (result != SBOX_ALL_OK) + if (result != SBOX_ALL_OK) { return result; + } } if (!delegate->DisableDefaultPolicy()) {
diff --git a/services/network/public/cpp/server/web_socket.h b/services/network/public/cpp/server/web_socket.h index c173b02..1a6285a 100644 --- a/services/network/public/cpp/server/web_socket.h +++ b/services/network/public/cpp/server/web_socket.h
@@ -56,7 +56,7 @@ const std::string& message, const net::NetworkTrafficAnnotationTag traffic_annotation); - const raw_ptr<HttpServer> server_; + const raw_ptr<HttpServer, LeakedDanglingUntriaged> server_; const raw_ptr<HttpConnection> connection_; std::unique_ptr<WebSocketEncoder> encoder_; bool closed_;
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index d46da4d2..9684424 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -2486,7 +2486,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -2546,7 +2546,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -2607,7 +2607,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -2666,7 +2666,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -2718,7 +2718,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -2768,7 +2768,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -2827,7 +2827,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -2886,7 +2886,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -2945,7 +2945,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -3005,7 +3005,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -3065,7 +3065,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -3124,7 +3124,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -3184,7 +3184,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -3243,7 +3243,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -3303,7 +3303,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -3362,7 +3362,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -3432,7 +3432,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -3500,7 +3500,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -3565,7 +3565,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -3625,7 +3625,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -3686,7 +3686,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -3748,7 +3748,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -3810,7 +3810,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -3870,7 +3870,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -3931,7 +3931,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -3990,7 +3990,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -4049,7 +4049,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -4108,7 +4108,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -4168,7 +4168,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -4227,7 +4227,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -4286,7 +4286,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -4345,7 +4345,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -4404,7 +4404,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -4466,7 +4466,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -4525,7 +4525,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -4584,7 +4584,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -4643,7 +4643,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -4702,7 +4702,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -4761,7 +4761,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -4820,7 +4820,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -4880,7 +4880,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -4939,7 +4939,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -4998,7 +4998,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -5058,7 +5058,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -5117,7 +5117,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -5176,7 +5176,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -5235,7 +5235,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -5294,7 +5294,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -5354,7 +5354,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -5414,7 +5414,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -5473,7 +5473,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -5532,7 +5532,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -5591,7 +5591,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -5650,7 +5650,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -5709,7 +5709,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -5768,7 +5768,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -5827,7 +5827,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -5886,7 +5886,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -5945,7 +5945,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -6004,7 +6004,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -6064,7 +6064,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -6123,7 +6123,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -6182,7 +6182,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -6241,7 +6241,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -6301,7 +6301,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -6369,7 +6369,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -6441,7 +6441,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -6501,7 +6501,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -6560,7 +6560,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -11142,7 +11142,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -11202,7 +11202,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -11263,7 +11263,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -11322,7 +11322,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -11374,7 +11374,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -11425,7 +11425,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -11484,7 +11484,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -11543,7 +11543,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -11602,7 +11602,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -11662,7 +11662,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -11722,7 +11722,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -11781,7 +11781,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -11841,7 +11841,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -11900,7 +11900,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -11959,7 +11959,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -12018,7 +12018,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -12085,7 +12085,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -12153,7 +12153,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -12219,7 +12219,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -12279,7 +12279,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -12338,7 +12338,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -12399,7 +12399,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -12460,7 +12460,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -12520,7 +12520,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -12581,7 +12581,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -12640,7 +12640,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -12700,7 +12700,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -12759,7 +12759,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -12819,7 +12819,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -12878,7 +12878,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -12937,7 +12937,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -12996,7 +12996,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -13055,7 +13055,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -13117,7 +13117,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -13176,7 +13176,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -13235,7 +13235,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -13294,7 +13294,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -13353,7 +13353,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -13412,7 +13412,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -13471,7 +13471,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -13531,7 +13531,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -13590,7 +13590,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -13649,7 +13649,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -13709,7 +13709,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -13768,7 +13768,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -13827,7 +13827,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -13886,7 +13886,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -13945,7 +13945,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -14006,7 +14006,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -14065,7 +14065,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -14124,7 +14124,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -14183,7 +14183,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -14242,7 +14242,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -14301,7 +14301,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -14360,7 +14360,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -14419,7 +14419,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -14478,7 +14478,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -14537,7 +14537,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -14596,7 +14596,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -14655,7 +14655,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -14714,7 +14714,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -14774,7 +14774,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -14833,7 +14833,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -14892,7 +14892,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -14951,7 +14951,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -15011,7 +15011,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -15071,7 +15071,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -15130,7 +15130,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -15189,7 +15189,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -15252,7 +15252,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -15312,7 +15312,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -15373,7 +15373,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -15432,7 +15432,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -15484,7 +15484,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -15535,7 +15535,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -15594,7 +15594,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -15653,7 +15653,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -15712,7 +15712,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -15772,7 +15772,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -15832,7 +15832,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -15891,7 +15891,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -15951,7 +15951,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -16010,7 +16010,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -16069,7 +16069,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -16128,7 +16128,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -16195,7 +16195,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -16263,7 +16263,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -16329,7 +16329,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -16389,7 +16389,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -16448,7 +16448,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -16509,7 +16509,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -16570,7 +16570,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -16630,7 +16630,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -16691,7 +16691,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -16750,7 +16750,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -16810,7 +16810,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -16869,7 +16869,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -16929,7 +16929,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -16988,7 +16988,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -17047,7 +17047,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -17106,7 +17106,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -17165,7 +17165,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -17227,7 +17227,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -17286,7 +17286,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -17345,7 +17345,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -17404,7 +17404,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -17463,7 +17463,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -17522,7 +17522,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -17581,7 +17581,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -17641,7 +17641,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -17700,7 +17700,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -17759,7 +17759,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -17819,7 +17819,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -17878,7 +17878,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -17937,7 +17937,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -17996,7 +17996,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -18055,7 +18055,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -18116,7 +18116,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -18175,7 +18175,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -18234,7 +18234,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -18293,7 +18293,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -18352,7 +18352,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -18411,7 +18411,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -18470,7 +18470,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -18529,7 +18529,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -18588,7 +18588,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -18647,7 +18647,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -18706,7 +18706,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -18765,7 +18765,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -18824,7 +18824,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -18884,7 +18884,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -18943,7 +18943,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -19003,7 +19003,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -19071,7 +19071,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -19143,7 +19143,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -19213,7 +19213,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -19273,7 +19273,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -19332,7 +19332,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -19391,7 +19391,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -22707,7 +22707,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -22776,7 +22776,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -22844,7 +22844,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -22906,7 +22906,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -22969,7 +22969,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -23030,7 +23030,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -23093,7 +23093,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -23693,7 +23693,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -23752,7 +23752,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -23811,7 +23811,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -23870,7 +23870,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -23929,7 +23929,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -23988,7 +23988,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -24048,7 +24048,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -24112,7 +24112,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -24171,7 +24171,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -24230,7 +24230,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -24289,7 +24289,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -24348,7 +24348,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -24407,7 +24407,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -24466,7 +24466,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -24530,7 +24530,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -24589,7 +24589,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -24648,7 +24648,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -24707,7 +24707,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -24766,7 +24766,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -24825,7 +24825,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -24885,7 +24885,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -24949,7 +24949,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -25008,7 +25008,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -25067,7 +25067,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -25126,7 +25126,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -25185,7 +25185,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -25244,7 +25244,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -25303,7 +25303,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -25367,7 +25367,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -25426,7 +25426,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -25485,7 +25485,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -25544,7 +25544,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -25603,7 +25603,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -25662,7 +25662,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -25722,7 +25722,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -25786,7 +25786,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -25845,7 +25845,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -25904,7 +25904,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -25963,7 +25963,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -26022,7 +26022,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -26081,7 +26081,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -26141,7 +26141,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -26265,7 +26265,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -26324,7 +26324,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -26383,7 +26383,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -26442,7 +26442,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -26501,7 +26501,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -26560,7 +26560,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -26620,7 +26620,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -33321,7 +33321,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -33381,7 +33381,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -33442,7 +33442,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -33501,7 +33501,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -33553,7 +33553,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -33603,7 +33603,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -33662,7 +33662,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -33721,7 +33721,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -33780,7 +33780,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -33840,7 +33840,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -33900,7 +33900,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -33959,7 +33959,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -34019,7 +34019,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -34078,7 +34078,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -34138,7 +34138,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -34197,7 +34197,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -34256,7 +34256,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -34323,7 +34323,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -34391,7 +34391,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -34456,7 +34456,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -34516,7 +34516,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -34575,7 +34575,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -34636,7 +34636,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -34697,7 +34697,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -34757,7 +34757,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -34817,7 +34817,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -34876,7 +34876,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -34935,7 +34935,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -34994,7 +34994,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -35054,7 +35054,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -35113,7 +35113,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -35172,7 +35172,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -35231,7 +35231,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -35290,7 +35290,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -35352,7 +35352,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -35411,7 +35411,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -35470,7 +35470,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -35529,7 +35529,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -35588,7 +35588,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -35647,7 +35647,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -35706,7 +35706,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -35766,7 +35766,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -35825,7 +35825,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -35884,7 +35884,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -35943,7 +35943,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -36002,7 +36002,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -36061,7 +36061,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -36120,7 +36120,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -36179,7 +36179,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -36238,7 +36238,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -36298,7 +36298,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -36359,7 +36359,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -36418,7 +36418,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -36477,7 +36477,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -36536,7 +36536,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -36595,7 +36595,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -36654,7 +36654,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -36713,7 +36713,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -36772,7 +36772,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -36831,7 +36831,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -36890,7 +36890,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -36949,7 +36949,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -37009,7 +37009,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -37068,7 +37068,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -37127,7 +37127,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -37186,7 +37186,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -37252,7 +37252,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -37313,7 +37313,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -37373,7 +37373,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -37432,7 +37432,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -37491,7 +37491,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -37576,7 +37576,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ], @@ -37648,7 +37648,7 @@ "cpu": "x86-64", "device_os": null, "device_type": null, - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.avd" } ],
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json index 0fa5966c24..7eefa60 100644 --- a/testing/buildbot/chromium.coverage.json +++ b/testing/buildbot/chromium.coverage.json
@@ -8847,7 +8847,8 @@ "os": "Ubuntu-18.04" } ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 16 }, "test": "browser_tests", "test_id_prefix": "ninja://chrome/test:browser_tests/"
diff --git a/testing/buildbot/chromium.dawn.json b/testing/buildbot/chromium.dawn.json index 95ea115..bbee691c 100644 --- a/testing/buildbot/chromium.dawn.json +++ b/testing/buildbot/chromium.dawn.json
@@ -4430,7 +4430,6 @@ "--use-webgpu-power-preference=default-high-performance", "--jobs=4" ], - "ci_only": true, "isolate_name": "telemetry_gpu_integration_test", "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -4583,7 +4582,6 @@ "--use-webgpu-power-preference=default-high-performance", "--jobs=4" ], - "ci_only": true, "isolate_name": "telemetry_gpu_integration_test", "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -5594,7 +5592,6 @@ "--use-webgpu-power-preference=default-high-performance", "--jobs=4" ], - "ci_only": true, "isolate_name": "telemetry_gpu_integration_test", "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -5747,7 +5744,6 @@ "--use-webgpu-power-preference=default-high-performance", "--jobs=4" ], - "ci_only": true, "isolate_name": "telemetry_gpu_integration_test", "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 3892d0e4..bf8a41e7 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -3276,7 +3276,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.finch" } ], @@ -3342,7 +3342,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.finch" } ], @@ -3401,7 +3401,7 @@ "dimension_sets": [ { "cpu": "x86-64", - "os": "Ubuntu-18.04", + "os": "Ubuntu-22.04", "pool": "chromium.tests.finch" } ],
diff --git a/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter b/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter index d463b06..7db7cc46 100644 --- a/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter +++ b/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter
@@ -10,3 +10,6 @@ # ash-chrome < 116 checks the policy AttestationEnabledForUser when building a # response for a Verified Access challenge which leads to a different error. -KeystoreServiceLacrosBrowserTest.WrongFormattingUser + +# crbug.com/1451234 +-WebAppIntegration*
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 704d376..82f3067 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -4726,17 +4726,10 @@ 'Dawn Linux x64 Release (Intel UHD 630)': { 'ci_only': True, }, - 'Dawn Mac x64 DEPS Release (AMD)': { - 'ci_only': True, - }, # crbug.com/1450207 corrupt Metal shader cache 'Dawn Mac x64 DEPS Release (Intel)': { 'ci_only': True, }, - 'Dawn Mac x64 Release (AMD)': { - 'ci_only': True, - }, - # crbug.com/1450207 corrupt Metal shader cache 'Dawn Mac x64 Release (Intel)': { 'ci_only': True, }, @@ -4758,12 +4751,6 @@ 'Dawn Linux x64 Release (Intel UHD 630)': { 'ci_only': True, }, - 'Dawn Mac x64 DEPS Release (AMD)': { - 'ci_only': True, - }, - 'Dawn Mac x64 Release (AMD)': { - 'ci_only': True, - }, }, }, 'webkit_unit_tests': {
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index cede321c..4252f45 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -715,6 +715,9 @@ 'chromeos_js_code_coverage_browser_tests' : { 'chromeos_js_code_coverage_browser_tests': { 'args': [], + 'swarming': { + 'shards': 16, + }, 'test': 'browser_tests', } },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index 24e25f88..3494788 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -704,7 +704,7 @@ '11-x86-emulator', 'emulator-4-cores', 'has_native_resultdb_integration', - 'linux-bionic', + 'linux-jammy', 'x86-64', ], 'os_type': 'android', @@ -735,7 +735,7 @@ '12l-x64-emulator', 'emulator-8-cores', 'has_native_resultdb_integration', - 'linux-bionic', + 'linux-jammy', 'x86-64', ], 'os_type': 'android', @@ -748,7 +748,7 @@ '13-x64-emulator', 'emulator-8-cores', 'has_native_resultdb_integration', - 'linux-bionic', + 'linux-jammy', 'x86-64', ], 'os_type': 'android', @@ -776,7 +776,7 @@ 'has_native_resultdb_integration', 'nougat-x86-emulator', 'emulator-8-cores', - 'linux-bionic', + 'linux-jammy', 'x86-64', ], 'os_type': 'android', @@ -876,7 +876,7 @@ '10-x86-emulator', 'emulator-4-cores', 'has_native_resultdb_integration', - 'linux-bionic', + 'linux-jammy', 'x86-64', ], 'os_type': 'android', @@ -889,7 +889,7 @@ '11-x86-emulator', 'emulator-4-cores', 'has_native_resultdb_integration', - 'linux-bionic', + 'linux-jammy', 'x86-64', ], 'os_type': 'android', @@ -902,7 +902,7 @@ 'lollipop-x86-emulator', 'emulator-4-cores', 'has_native_resultdb_integration', - 'linux-bionic', + 'linux-jammy', 'x86-64', ], 'os_type': 'android', @@ -915,7 +915,7 @@ 'marshmallow-x86-emulator', 'emulator-4-cores', 'has_native_resultdb_integration', - 'linux-bionic', + 'linux-jammy', 'x86-64', ], 'os_type': 'android', @@ -928,7 +928,7 @@ 'oreo-x86-emulator', 'emulator-4-cores', 'has_native_resultdb_integration', - 'linux-bionic', + 'linux-jammy', 'x86-64', ], 'os_type': 'android', @@ -941,7 +941,7 @@ 'pie-x86-emulator', 'emulator-4-cores', 'has_native_resultdb_integration', - 'linux-bionic', + 'linux-jammy', 'x86-64', ], 'os_type': 'android', @@ -970,7 +970,7 @@ 'kitkat-x86-emulator', 'emulator-4-cores', 'has_native_resultdb_integration', - 'linux-bionic', + 'linux-jammy', 'x86-64', ], 'os_type': 'android', @@ -1035,7 +1035,7 @@ 'has_native_resultdb_integration', 'pie-x86-emulator', 'emulator-4-cores', - 'linux-bionic', + 'linux-jammy', 'x86-64', ], 'os_type': 'android', @@ -1049,7 +1049,7 @@ 'has_native_resultdb_integration', '10-x86-emulator', 'emulator-4-cores', - 'linux-bionic', + 'linux-jammy', 'x86-64', ], 'os_type': 'android', @@ -3264,7 +3264,7 @@ 'has_native_resultdb_integration', 'finch-chromium-swarming-pool', 'pie-x86-emulator', - 'linux-bionic', + 'linux-jammy', 'x86-64', ], 'os_type': 'android',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index d456680c..6d22cbc 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -3087,22 +3087,6 @@ ] } ], - "ChurnPrivateComputingCheckIn": [ - { - "platforms": [ - "chromeos" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "DeviceActiveClientChurnCohortCheckIn", - "DeviceActiveClientChurnObservationCheckIn" - ] - } - ] - } - ], "ClientSideDetectionModelOptimizationGuide": [ { "platforms": [ @@ -10328,10 +10312,10 @@ ], "experiments": [ { - "name": "XRequestedWithDeprecation_20230302", + "name": "XRequestedWithDeprecation_20230605", "enable_features": [ "PersistentOriginTrials", - "WebViewXRequestedWithDeprecation" + "WebViewXRequestedWithHeaderControl" ] } ]
diff --git a/third_party/androidx/build.gradle.template b/third_party/androidx/build.gradle.template index 75e19de..25c7356 100644 --- a/third_party/androidx/build.gradle.template +++ b/third_party/androidx/build.gradle.template
@@ -29,6 +29,8 @@ compile 'androidx.annotation:annotation-jvm:{{androidx_dependency_version}}' compile 'androidx.appcompat:appcompat:{{androidx_dependency_version}}' compile 'androidx.appcompat:appcompat-resources:{{androidx_dependency_version}}' + compile 'androidx.appsearch:appsearch:{{androidx_dependency_version}}' + compile 'androidx.appsearch:appsearch-platform-storage:{{androidx_dependency_version}}' compile 'androidx.asynclayoutinflater:asynclayoutinflater:{{androidx_dependency_version}}' compile 'androidx.asynclayoutinflater:asynclayoutinflater-appcompat:{{androidx_dependency_version}}' compile 'androidx.biometric:biometric:{{androidx_dependency_version}}'
diff --git a/third_party/blink/common/navigation/impression_mojom_traits.cc b/third_party/blink/common/navigation/impression_mojom_traits.cc index 39e5d427..46d8b4e 100644 --- a/third_party/blink/common/navigation/impression_mojom_traits.cc +++ b/third_party/blink/common/navigation/impression_mojom_traits.cc
@@ -13,7 +13,6 @@ blink::mojom::ImpressionDataView data, blink::Impression* out) { return data.ReadAttributionSrcToken(&out->attribution_src_token) && - data.ReadNavType(&out->nav_type) && data.ReadRuntimeFeatures(&out->runtime_features); }
diff --git a/third_party/blink/public/common/navigation/impression.h b/third_party/blink/public/common/navigation/impression.h index bfe1eb7c..36ea1c2d 100644 --- a/third_party/blink/public/common/navigation/impression.h +++ b/third_party/blink/public/common/navigation/impression.h
@@ -8,7 +8,6 @@ #include "services/network/public/cpp/attribution_reporting_runtime_features.h" #include "third_party/blink/public/common/common_export.h" #include "third_party/blink/public/common/tokens/tokens.h" -#include "third_party/blink/public/mojom/conversions/attribution_reporting.mojom.h" namespace blink { @@ -22,7 +21,6 @@ // Indicates the attributionsrc request associated with `this`. // Data parameters will be used from the attributionsrc response. AttributionSrcToken attribution_src_token; - blink::mojom::AttributionNavigationType nav_type; // TODO(crbug.com/1443561): Get rid of this when Runtime Feature State fully // supports runtime feature access from the browser process. network::AttributionReportingRuntimeFeatures runtime_features;
diff --git a/third_party/blink/public/common/navigation/impression_mojom_traits.h b/third_party/blink/public/common/navigation/impression_mojom_traits.h index 0b73f6c..7c56ec78 100644 --- a/third_party/blink/public/common/navigation/impression_mojom_traits.h +++ b/third_party/blink/public/common/navigation/impression_mojom_traits.h
@@ -10,7 +10,6 @@ #include "third_party/blink/public/common/common_export.h" #include "third_party/blink/public/common/navigation/impression.h" #include "third_party/blink/public/common/tokens/tokens.h" -#include "third_party/blink/public/mojom/conversions/attribution_reporting.mojom.h" #include "third_party/blink/public/mojom/conversions/conversions.mojom.h" namespace mojo { @@ -22,10 +21,6 @@ const blink::Impression& r) { return r.attribution_src_token; } - static blink::mojom::AttributionNavigationType nav_type( - const blink::Impression& r) { - return r.nav_type; - } static const network::AttributionReportingRuntimeFeatures& runtime_features( const blink::Impression& r) { return r.runtime_features;
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn index da44fc9..dea710d4 100644 --- a/third_party/blink/public/mojom/BUILD.gn +++ b/third_party/blink/public/mojom/BUILD.gn
@@ -47,7 +47,6 @@ "content_index/content_index.mojom", "context_menu/context_menu.mojom", "conversions/attribution_data_host.mojom", - "conversions/attribution_reporting.mojom", "conversions/conversions.mojom", "cookie_manager/cookie_manager_automation.mojom", "cookie_store/cookie_store.mojom",
diff --git a/third_party/blink/public/mojom/conversions/attribution_reporting.mojom b/third_party/blink/public/mojom/conversions/attribution_reporting.mojom deleted file mode 100644 index 3543f64..0000000 --- a/third_party/blink/public/mojom/conversions/attribution_reporting.mojom +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -module blink.mojom; - -// These values are persisted to logs. Entries should not be renumbered and -// numeric values should never be reused. -enum AttributionNavigationType { - kAnchor = 0, - kWindowOpen = 1, - kContextMenu = 2, -};
diff --git a/third_party/blink/public/mojom/conversions/conversions.mojom b/third_party/blink/public/mojom/conversions/conversions.mojom index effd6f64..f49d69a4 100644 --- a/third_party/blink/public/mojom/conversions/conversions.mojom +++ b/third_party/blink/public/mojom/conversions/conversions.mojom
@@ -6,7 +6,6 @@ import "components/attribution_reporting/registration_type.mojom"; import "third_party/blink/public/mojom/conversions/attribution_data_host.mojom"; -import "third_party/blink/public/mojom/conversions/attribution_reporting.mojom"; import "third_party/blink/public/mojom/tokens/tokens.mojom"; import "services/network/public/mojom/attribution.mojom"; @@ -16,7 +15,6 @@ // API parameters will be used from the the `AttributionDataHost` // that is associated with `attribution_src_token`. AttributionSrcToken attribution_src_token; - AttributionNavigationType nav_type; // Indicates whether Attribution Reporting API related runtime features are // enabled. network.mojom.AttributionReportingRuntimeFeatures runtime_features;
diff --git a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom index 1954d6f..187e8fe 100644 --- a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom +++ b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
@@ -3918,6 +3918,7 @@ kLongAnimationFrameRequested = 4578, kFedCmLoginHint = 4579, kFedCmRpContext = 4580, + kEventTimingArtificialPointerupOrClick = 4581, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/renderer/core/css/container_query_evaluator_test.cc b/third_party/blink/renderer/core/css/container_query_evaluator_test.cc index d8af88c9..9fd98d49 100644 --- a/third_party/blink/renderer/core/css/container_query_evaluator_test.cc +++ b/third_party/blink/renderer/core/css/container_query_evaluator_test.cc
@@ -21,7 +21,6 @@ #include "third_party/blink/renderer/core/dom/dom_token_list.h" #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" -#include "third_party/blink/renderer/core/dom/parent_node.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/execution_context/security_context.h" #include "third_party/blink/renderer/core/frame/local_frame.h" @@ -748,10 +747,10 @@ UpdateAllLifecyclePhasesForTest(); - Element* outer_size = ParentNode::firstElementChild(*GetDocument().body()); - Element* outer = ParentNode::firstElementChild(*outer_size); - Element* inner_size = ParentNode::firstElementChild(*outer); - Element* inner = ParentNode::firstElementChild(*inner_size); + Element* outer_size = GetDocument().body()->firstElementChild(); + Element* outer = outer_size->firstElementChild(); + Element* inner_size = outer->firstElementChild(); + Element* inner = inner_size->firstElementChild(); EXPECT_EQ(ContainerQueryEvaluator::FindContainer( inner, ParseContainer("style(--foo: bar)")->Selector(), @@ -792,11 +791,11 @@ UpdateAllLifecyclePhasesForTest(); - Element* sticky_size = ParentNode::firstElementChild(*GetDocument().body()); - Element* outer_sticky = ParentNode::firstElementChild(*sticky_size); - Element* outer = ParentNode::firstElementChild(*outer_sticky); - Element* inner_sticky = ParentNode::firstElementChild(*outer); - Element* inner = ParentNode::firstElementChild(*inner_sticky); + Element* sticky_size = GetDocument().body()->firstElementChild(); + Element* outer_sticky = sticky_size->firstElementChild(); + Element* outer = outer_sticky->firstElementChild(); + Element* inner_sticky = outer->firstElementChild(); + Element* inner = inner_sticky->firstElementChild(); EXPECT_EQ( ContainerQueryEvaluator::FindContainer(
diff --git a/third_party/blink/renderer/core/dom/build.gni b/third_party/blink/renderer/core/dom/build.gni index 38a5eb2..abee6a4 100644 --- a/third_party/blink/renderer/core/dom/build.gni +++ b/third_party/blink/renderer/core/dom/build.gni
@@ -50,7 +50,6 @@ "child_frame_disconnector.h", "child_list_mutation_scope.cc", "child_list_mutation_scope.h", - "child_node.h", "child_node_list.cc", "child_node_list.h", "class_collection.cc", @@ -220,11 +219,8 @@ "node_traversal.h", "node_traversal_strategy.h", "node_with_index.h", - "non_document_type_child_node.h", - "non_element_parent_node.h", "nth_index_cache.cc", "nth_index_cache.h", - "parent_node.h", "parser_content_policy.h", "popover_data.h", "presentation_attribute_style.cc",
diff --git a/third_party/blink/renderer/core/dom/child_node.h b/third_party/blink/renderer/core/dom/child_node.h deleted file mode 100644 index 7e50b90..0000000 --- a/third_party/blink/renderer/core/dom/child_node.h +++ /dev/null
@@ -1,45 +0,0 @@ -// Copyright 2014 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_CORE_DOM_CHILD_NODE_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_CHILD_NODE_H_ - -#include "third_party/blink/renderer/core/dom/node.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" - -namespace blink { - -class ChildNode { - STATIC_ONLY(ChildNode); - - public: - static void before( - Node& node, - const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes, - ExceptionState& exception_state) { - return node.Before(nodes, exception_state); - } - - static void after( - Node& node, - const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes, - ExceptionState& exception_state) { - return node.After(nodes, exception_state); - } - - static void replaceWith( - Node& node, - const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes, - ExceptionState& exception_state) { - return node.ReplaceWith(nodes, exception_state); - } - - static void remove(Node& node, ExceptionState& exception_state) { - return node.remove(exception_state); - } -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_CHILD_NODE_H_
diff --git a/third_party/blink/renderer/core/dom/child_node.idl b/third_party/blink/renderer/core/dom/child_node.idl index fd58ee2..b5fc1d1 100644 --- a/third_party/blink/renderer/core/dom/child_node.idl +++ b/third_party/blink/renderer/core/dom/child_node.idl
@@ -21,12 +21,9 @@ */ // https://dom.spec.whatwg.org/#interface-childnode - -[ - LegacyTreatAsPartialInterface -] interface mixin ChildNode { - [Unscopable, RaisesException, CEReactions] void before((Node or DOMString or TrustedScript) ... nodes); - [Unscopable, RaisesException, CEReactions] void after((Node or DOMString or TrustedScript)... nodes); - [Unscopable, RaisesException, CEReactions] void replaceWith((Node or DOMString or TrustedScript)... nodes); - [Unscopable, RaisesException, CEReactions] void remove(); +interface mixin ChildNode { + [Unscopable, RaisesException, CEReactions] void before((Node or DOMString or TrustedScript) ... nodes); + [Unscopable, RaisesException, CEReactions] void after((Node or DOMString or TrustedScript)... nodes); + [Unscopable, RaisesException, CEReactions] void replaceWith((Node or DOMString or TrustedScript)... nodes); + [Unscopable, RaisesException, CEReactions] void remove(); };
diff --git a/third_party/blink/renderer/core/dom/container_node.cc b/third_party/blink/renderer/core/dom/container_node.cc index 8b364ec..95c727e3 100644 --- a/third_party/blink/renderer/core/dom/container_node.cc +++ b/third_party/blink/renderer/core/dom/container_node.cc
@@ -1258,10 +1258,38 @@ this_element->PseudoStateChanged(CSSSelector::kPseudoDrag); } -HTMLCollection* ContainerNode::Children() { +HTMLCollection* ContainerNode::children() { return EnsureCachedCollection<HTMLCollection>(kNodeChildren); } +Element* ContainerNode::firstElementChild() { + return ElementTraversal::FirstChild(*this); +} + +Element* ContainerNode::lastElementChild() { + return ElementTraversal::LastChild(*this); +} + +unsigned ContainerNode::childElementCount() { + unsigned count = 0; + for (Element* child = ElementTraversal::FirstChild(*this); child; + child = ElementTraversal::NextSibling(*child)) { + ++count; + } + return count; +} + +Element* ContainerNode::querySelector(const AtomicString& selectors, + ExceptionState& exception_state) { + return QuerySelector(selectors, exception_state); +} + +StaticElementList* ContainerNode::querySelectorAll( + const AtomicString& selectors, + ExceptionState& exception_state) { + return QuerySelectorAll(selectors, exception_state); +} + unsigned ContainerNode::CountChildren() const { unsigned count = 0; for (Node* node = firstChild(); node; node = node->nextSibling())
diff --git a/third_party/blink/renderer/core/dom/container_node.h b/third_party/blink/renderer/core/dom/container_node.h index d840283..74003e3 100644 --- a/third_party/blink/renderer/core/dom/container_node.h +++ b/third_party/blink/renderer/core/dom/container_node.h
@@ -83,15 +83,25 @@ const int kInitialNodeVectorSize = 11; using NodeVector = HeapVector<Member<Node>, kInitialNodeVectorSize>; -// Note: while ContainerNode itself isn't web-exposed, a number of methods it -// implements (such as firstChild, lastChild) use web-style naming to shadow -// the corresponding methods on Node. This is a performance optimization, as it -// avoids a virtual dispatch if the type is statically known to be -// ContainerNode. +// ContainerNode itself isn't web-exposed exactly, but it maps closely to the +// ParentNode mixin interface. A number of methods it implements (such as +// firstChild, lastChild) use web-style naming to shadow the corresponding +// methods on Node. This is a performance optimization, as it avoids a virtual +// dispatch if the type is statically known to be ContainerNode. class CORE_EXPORT ContainerNode : public Node { public: ~ContainerNode() override; + // ParentNode web-exposed: + // Note that some of the ParentNode interface is implemented in Node. + HTMLCollection* children(); + Element* firstElementChild(); + Element* lastElementChild(); + unsigned childElementCount(); + Element* querySelector(const AtomicString& selectors, ExceptionState&); + StaticElementList* querySelectorAll(const AtomicString& selectors, + ExceptionState&); + Node* firstChild() const { return first_child_; } Node* lastChild() const { return last_child_; } bool hasChildren() const { return first_child_; } @@ -105,8 +115,6 @@ } bool HasChildCount(unsigned) const; - HTMLCollection* Children(); - unsigned CountChildren() const; Element* QuerySelector(const AtomicString& selectors, ExceptionState&);
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc index 3d11917..2e11bb19 100644 --- a/third_party/blink/renderer/core/dom/node.cc +++ b/third_party/blink/renderer/core/dom/node.cc
@@ -848,7 +848,7 @@ return fragment; } -void Node::Prepend( +void Node::prepend( const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes, ExceptionState& exception_state) { auto* this_node = DynamicTo<ContainerNode>(this); @@ -864,7 +864,7 @@ this_node->InsertBefore(node, this_node->firstChild(), exception_state); } -void Node::Append( +void Node::append( const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes, ExceptionState& exception_state) { auto* this_node = DynamicTo<ContainerNode>(this); @@ -880,7 +880,7 @@ this_node->AppendChild(node, exception_state); } -void Node::Before( +void Node::before( const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes, ExceptionState& exception_state) { ContainerNode* parent = parentNode(); @@ -897,7 +897,7 @@ } } -void Node::After( +void Node::after( const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes, ExceptionState& exception_state) { ContainerNode* parent = parentNode(); @@ -909,7 +909,7 @@ parent->InsertBefore(node, viable_next_sibling, exception_state); } -void Node::ReplaceWith( +void Node::replaceWith( const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes, ExceptionState& exception_state) { ContainerNode* parent = parentNode(); @@ -927,7 +927,7 @@ } // https://dom.spec.whatwg.org/#dom-parentnode-replacechildren -void Node::ReplaceChildren( +void Node::replaceChildren( const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes, ExceptionState& exception_state) { auto* this_node = DynamicTo<ContainerNode>(this); @@ -970,6 +970,14 @@ remove(ASSERT_NO_EXCEPTION); } +Element* Node::previousElementSibling() { + return ElementTraversal::PreviousSibling(*this); +} + +Element* Node::nextElementSibling() { + return ElementTraversal::NextSibling(*this); +} + Node* Node::cloneNode(bool deep, ExceptionState& exception_state) const { // https://dom.spec.whatwg.org/#dom-node-clonenode
diff --git a/third_party/blink/renderer/core/dom/node.h b/third_party/blink/renderer/core/dom/node.h index 6922be6..eee3dbb 100644 --- a/third_party/blink/renderer/core/dom/node.h +++ b/third_party/blink/renderer/core/dom/node.h
@@ -240,27 +240,38 @@ // https://dom.spec.whatwg.org/#concept-closed-shadow-hidden bool IsClosedShadowHiddenFrom(const Node&) const; - void Prepend( + // ParentNode interface. These functions are only actually web-exposed on + // interfaces that include ParentNode in their idl. + void prepend( const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes, ExceptionState& exception_state); - void Append( + void append( const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes, ExceptionState& exception_state); - void Before( + void replaceChildren( const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes, ExceptionState& exception_state); - void After( + + // ChildNode interface. These functions are only actually web-exposed on + // interfaces that include ChildNode in their idl. + void before( const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes, ExceptionState& exception_state); - void ReplaceWith( + void after( const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes, ExceptionState& exception_state); - void ReplaceChildren( + void replaceWith( const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes, ExceptionState& exception_state); void remove(ExceptionState&); void remove(); + // NonDocumentTypeChildNode interface. These functions are only actually + // web-exposed on interfaces that include NonDocumentTypeChildNode in their + // idl. + Element* previousElementSibling(); + Element* nextElementSibling(); + Node* PseudoAwareNextSibling() const; Node* PseudoAwarePreviousSibling() const; Node* PseudoAwareFirstChild() const;
diff --git a/third_party/blink/renderer/core/dom/non_document_type_child_node.h b/third_party/blink/renderer/core/dom/non_document_type_child_node.h deleted file mode 100644 index 47b8c369..0000000 --- a/third_party/blink/renderer/core/dom/non_document_type_child_node.h +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2014 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_CORE_DOM_NON_DOCUMENT_TYPE_CHILD_NODE_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_NON_DOCUMENT_TYPE_CHILD_NODE_H_ - -#include "third_party/blink/renderer/core/dom/element_traversal.h" -#include "third_party/blink/renderer/core/dom/node.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" - -namespace blink { - -class NonDocumentTypeChildNode { - STATIC_ONLY(NonDocumentTypeChildNode); - - public: - static Element* previousElementSibling(Node& node) { - return ElementTraversal::PreviousSibling(node); - } - - static Element* nextElementSibling(Node& node) { - return ElementTraversal::NextSibling(node); - } -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_NON_DOCUMENT_TYPE_CHILD_NODE_H_
diff --git a/third_party/blink/renderer/core/dom/non_document_type_child_node.idl b/third_party/blink/renderer/core/dom/non_document_type_child_node.idl index f11bc019..0980b47 100644 --- a/third_party/blink/renderer/core/dom/non_document_type_child_node.idl +++ b/third_party/blink/renderer/core/dom/non_document_type_child_node.idl
@@ -3,10 +3,7 @@ // found in the LICENSE file. // https://dom.spec.whatwg.org/#interface-nondocumenttypechildnode - -[ - LegacyTreatAsPartialInterface -] interface mixin NonDocumentTypeChildNode { - [PerWorldBindings] readonly attribute Element? previousElementSibling; - [PerWorldBindings] readonly attribute Element? nextElementSibling; +interface mixin NonDocumentTypeChildNode { + [PerWorldBindings] readonly attribute Element? previousElementSibling; + [PerWorldBindings] readonly attribute Element? nextElementSibling; };
diff --git a/third_party/blink/renderer/core/dom/non_element_parent_node.h b/third_party/blink/renderer/core/dom/non_element_parent_node.h deleted file mode 100644 index 8e5ae868..0000000 --- a/third_party/blink/renderer/core/dom/non_element_parent_node.h +++ /dev/null
@@ -1,27 +0,0 @@ -// Copyright 2015 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_NON_ELEMENT_PARENT_NODE_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_NON_ELEMENT_PARENT_NODE_H_ - -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/dom/document_fragment.h" - -namespace blink { - -class NonElementParentNode { - public: - static Element* getElementById(Document& document, const AtomicString& id) { - return document.getElementById(id); - } - - static Element* getElementById(DocumentFragment& fragment, - const AtomicString& id) { - return fragment.getElementById(id); - } -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_NON_ELEMENT_PARENT_NODE_H_
diff --git a/third_party/blink/renderer/core/dom/non_element_parent_node.idl b/third_party/blink/renderer/core/dom/non_element_parent_node.idl index e3a13d27..37bf01d 100644 --- a/third_party/blink/renderer/core/dom/non_element_parent_node.idl +++ b/third_party/blink/renderer/core/dom/non_element_parent_node.idl
@@ -3,9 +3,6 @@ // found in the LICENSE file. // https://dom.spec.whatwg.org/#interface-nonelementparentnode - -[ - LegacyTreatAsPartialInterface -] interface mixin NonElementParentNode { - [PerWorldBindings] Element? getElementById(DOMString elementId); +interface mixin NonElementParentNode { + [PerWorldBindings] Element? getElementById(DOMString elementId); };
diff --git a/third_party/blink/renderer/core/dom/parent_node.h b/third_party/blink/renderer/core/dom/parent_node.h deleted file mode 100644 index 3c24faa..0000000 --- a/third_party/blink/renderer/core/dom/parent_node.h +++ /dev/null
@@ -1,103 +0,0 @@ -/* - * Copyright (C) 2013 Samsung Electronics. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_PARENT_NODE_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_PARENT_NODE_H_ - -#include "third_party/blink/renderer/core/dom/container_node.h" -#include "third_party/blink/renderer/core/dom/element_traversal.h" -#include "third_party/blink/renderer/core/html/html_collection.h" -#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" -#include "third_party/blink/renderer/platform/heap/member.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" - -namespace blink { - -class ParentNode { - STATIC_ONLY(ParentNode); - - public: - static HTMLCollection* children(ContainerNode& node) { - return node.Children(); - } - - static Element* firstElementChild(ContainerNode& node) { - return ElementTraversal::FirstChild(node); - } - - static Element* lastElementChild(ContainerNode& node) { - return ElementTraversal::LastChild(node); - } - - static unsigned childElementCount(ContainerNode& node) { - unsigned count = 0; - for (Element* child = ElementTraversal::FirstChild(node); child; - child = ElementTraversal::NextSibling(*child)) - ++count; - return count; - } - - static void prepend( - Node& node, - const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes, - ExceptionState& exception_state) { - return node.Prepend(nodes, exception_state); - } - - static void append( - Node& node, - const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes, - ExceptionState& exception_state) { - return node.Append(nodes, exception_state); - } - - static void replaceChildren( - Node& node, - const HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>>& nodes, - ExceptionState& exception_state) { - return node.ReplaceChildren(nodes, exception_state); - } - - static Element* querySelector(ContainerNode& node, - const AtomicString& selectors, - ExceptionState& exception_state) { - return node.QuerySelector(selectors, exception_state); - } - - static StaticElementList* querySelectorAll(ContainerNode& node, - const AtomicString& selectors, - ExceptionState& exception_state) { - return node.QuerySelectorAll(selectors, exception_state); - } -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_PARENT_NODE_H_
diff --git a/third_party/blink/renderer/core/dom/parent_node.idl b/third_party/blink/renderer/core/dom/parent_node.idl index 2427e1ec..0ab7fa6 100644 --- a/third_party/blink/renderer/core/dom/parent_node.idl +++ b/third_party/blink/renderer/core/dom/parent_node.idl
@@ -29,21 +29,16 @@ */ // https://dom.spec.whatwg.org/#interface-parentnode +interface mixin ParentNode { + [SameObject, PerWorldBindings] readonly attribute HTMLCollection children; + [PerWorldBindings] readonly attribute Element? firstElementChild; + [PerWorldBindings] readonly attribute Element? lastElementChild; + readonly attribute unsigned long childElementCount; -[ - LegacyTreatAsPartialInterface -] interface mixin ParentNode { - [SameObject, PerWorldBindings] readonly attribute HTMLCollection children; - [PerWorldBindings] readonly attribute Element? firstElementChild; - [PerWorldBindings] readonly attribute Element? lastElementChild; - readonly attribute unsigned long childElementCount; + [Unscopable, RaisesException, CEReactions] void prepend((Node or DOMString or TrustedScript)... nodes); + [Unscopable, RaisesException, CEReactions] void append((Node or DOMString or TrustedScript)... nodes); + [Unscopable, RaisesException, CEReactions] void replaceChildren((Node or DOMString or TrustedScript)... nodes); - [Unscopable, RaisesException, CEReactions] void prepend((Node or DOMString or TrustedScript)... nodes); - [Unscopable, RaisesException, CEReactions] void append((Node or DOMString or TrustedScript)... nodes); - [Unscopable, RaisesException, CEReactions] void replaceChildren((Node or DOMString or TrustedScript)... nodes); - - // [Unscopable] Element? query(DOMString relativeSelectors); - // [NewObject, Unscopable] Elements queryAll(DOMString relativeSelectors); - [Affects=Nothing, RaisesException] Element? querySelector(DOMString selectors); - [Affects=Nothing, NewObject, RaisesException] NodeList querySelectorAll(DOMString selectors); + [Affects=Nothing, RaisesException] Element? querySelector(DOMString selectors); + [Affects=Nothing, NewObject, RaisesException] NodeList querySelectorAll(DOMString selectors); };
diff --git a/third_party/blink/renderer/core/editing/commands/insert_list_command_test.cc b/third_party/blink/renderer/core/editing/commands/insert_list_command_test.cc index bb1706c..0a54b5a9 100644 --- a/third_party/blink/renderer/core/editing/commands/insert_list_command_test.cc +++ b/third_party/blink/renderer/core/editing/commands/insert_list_command_test.cc
@@ -4,7 +4,6 @@ #include "third_party/blink/renderer/core/editing/commands/insert_list_command.h" -#include "third_party/blink/renderer/core/dom/parent_node.h" #include "third_party/blink/renderer/core/dom/text.h" #include "third_party/blink/renderer/core/editing/frame_selection.h" #include "third_party/blink/renderer/core/editing/selection_template.h"
diff --git a/third_party/blink/renderer/core/exported/web_image.cc b/third_party/blink/renderer/core/exported/web_image.cc index da0e43e1..42c4b59e 100644 --- a/third_party/blink/renderer/core/exported/web_image.cc +++ b/third_party/blink/renderer/core/exported/web_image.cc
@@ -78,8 +78,9 @@ } ImageFrame* frame = decoder->DecodeFrameBufferAtIndex(index); - if (!frame || decoder->Failed()) + if (!frame || decoder->Failed() || frame->Bitmap().drawsNothing()) { return {}; + } if (decoder->Orientation().Orientation() == ImageOrientationEnum::kDefault) return frame->Bitmap();
diff --git a/third_party/blink/renderer/core/frame/attribution_src_loader.cc b/third_party/blink/renderer/core/frame/attribution_src_loader.cc index 048857f..cd914936f 100644 --- a/third_party/blink/renderer/core/frame/attribution_src_loader.cc +++ b/third_party/blink/renderer/core/frame/attribution_src_loader.cc
@@ -36,7 +36,6 @@ #include "third_party/blink/public/common/navigation/impression.h" #include "third_party/blink/public/common/tokens/tokens.h" #include "third_party/blink/public/mojom/conversions/attribution_data_host.mojom-blink.h" -#include "third_party/blink/public/mojom/conversions/attribution_reporting.mojom-blink.h" #include "third_party/blink/public/mojom/conversions/conversions.mojom-blink.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" #include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom-blink.h" @@ -327,9 +326,6 @@ // operations and DevTools issues. const Impression impression{ - .nav_type = element - ? mojom::blink::AttributionNavigationType::kAnchor - : mojom::blink::AttributionNavigationType::kWindowOpen, .runtime_features = GetRuntimeFeatures(), };
diff --git a/third_party/blink/renderer/core/html/parser/html_document_parser.cc b/third_party/blink/renderer/core/html/parser/html_document_parser.cc index d4c06269..812927b 100644 --- a/third_party/blink/renderer/core/html/parser/html_document_parser.cc +++ b/third_party/blink/renderer/core/html/parser/html_document_parser.cc
@@ -643,6 +643,10 @@ ? task_runner_state_->GetDefaultBudget() : kInfiniteTokenizationBudget; + if (RuntimeEnabledFeatures::HTMLParserYieldAndDelayOftenForTestingEnabled()) { + budget = 2; + } + base::TimeDelta timed_budget; if (TimedParserBudgetEnabled()) timed_budget = GetTimedBudget(task_runner_state_->TimesYielded()); @@ -693,7 +697,9 @@ ConstructTreeFromToken(atomic_html_token); if (!should_run_until_completion && !IsPaused()) { DCHECK_EQ(task_runner_state_->GetMode(), kAllowDeferredParsing); - if (TimedParserBudgetEnabled()) { + if (TimedParserBudgetEnabled() && + !RuntimeEnabledFeatures:: + HTMLParserYieldAndDelayOftenForTestingEnabled()) { if (CheckParserBudgetLessOften()) { int newly_consumed_characters = input_.Current().NumberOfCharactersConsumed() - @@ -769,6 +775,7 @@ CHECK(!should_run_until_completion || !should_yield); if (should_yield) task_runner_state_->MarkYield(); + return should_yield; } @@ -781,11 +788,16 @@ // If the parser is already scheduled, there's no need to do anything. return; } - loading_task_runner_->PostTask( + base::TimeDelta delay = base::Milliseconds(0); + if (RuntimeEnabledFeatures::HTMLParserYieldAndDelayOftenForTestingEnabled()) { + delay = base::Milliseconds(1000); + } + loading_task_runner_->PostDelayedTask( FROM_HERE, WTF::BindOnce(&HTMLDocumentParser::DeferredPumpTokenizerIfPossible, WrapPersistent(this), from_finish_append, - base::TimeTicks::Now())); + base::TimeTicks::Now()), + delay); task_runner_state_->SetState( HTMLDocumentParserState::DeferredParserState::kScheduled);
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index 35aa33d9..1650a5c 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -465,7 +465,6 @@ : spanner_placeholder_(nullptr), // TODO(rego): We should store these based on physical direction. has_override_containing_block_content_logical_width_(false), - has_override_containing_block_content_logical_height_(false), has_previous_content_box_rect_(false), snap_container_(nullptr) {} @@ -2088,9 +2087,7 @@ LayoutUnit LayoutBox::OverrideContainingBlockContentLogicalHeight() const { NOT_DESTROYED(); DCHECK(HasOverrideContainingBlockContentLogicalHeight()); - if (extra_input_) - return extra_input_->containing_block_content_block_size; - return rare_data_->override_containing_block_content_logical_height_; + return extra_input_->containing_block_content_block_size; } // TODO (lajava) Shouldn't we implement these functions based on physical @@ -2107,10 +2104,7 @@ // direction ?. bool LayoutBox::HasOverrideContainingBlockContentLogicalHeight() const { NOT_DESTROYED(); - if (extra_input_) - return true; - return rare_data_ && - rare_data_->has_override_containing_block_content_logical_height_; + return extra_input_; } // TODO (lajava) Shouldn't we implement these functions based on physical @@ -2127,26 +2121,12 @@ // TODO (lajava) Shouldn't we implement these functions based on physical // direction ?. -void LayoutBox::SetOverrideContainingBlockContentLogicalHeight( - LayoutUnit logical_height) { - NOT_DESTROYED(); - DCHECK(!extra_input_); - DCHECK_GE(logical_height, LayoutUnit(-1)); - EnsureRareData().override_containing_block_content_logical_height_ = - logical_height; - EnsureRareData().has_override_containing_block_content_logical_height_ = true; -} - -// TODO (lajava) Shouldn't we implement these functions based on physical -// direction ?. void LayoutBox::ClearOverrideContainingBlockContentSize() { NOT_DESTROYED(); DCHECK(!extra_input_); if (!rare_data_) return; EnsureRareData().has_override_containing_block_content_logical_width_ = false; - EnsureRareData().has_override_containing_block_content_logical_height_ = - false; } LayoutUnit LayoutBox::OverrideAvailableInlineSize() const {
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h index d4ec614..444c734 100644 --- a/third_party/blink/renderer/core/layout/layout_box.h +++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -100,11 +100,9 @@ Member<LayoutMultiColumnSpannerPlaceholder> spanner_placeholder_; bool has_override_containing_block_content_logical_width_ : 1; - bool has_override_containing_block_content_logical_height_ : 1; bool has_previous_content_box_rect_ : 1; LayoutUnit override_containing_block_content_logical_width_; - LayoutUnit override_containing_block_content_logical_height_; // For snap area, the owning snap container. Member<LayoutBox> snap_container_; @@ -874,7 +872,6 @@ bool HasOverrideContainingBlockContentLogicalWidth() const; bool HasOverrideContainingBlockContentLogicalHeight() const; void SetOverrideContainingBlockContentLogicalWidth(LayoutUnit); - void SetOverrideContainingBlockContentLogicalHeight(LayoutUnit); void ClearOverrideContainingBlockContentSize(); // When an available inline size override has been set, we'll use that to fill
diff --git a/third_party/blink/renderer/core/layout/layout_inline.cc b/third_party/blink/renderer/core/layout/layout_inline.cc index 2cb0e5e..ce56ead 100644 --- a/third_party/blink/renderer/core/layout/layout_inline.cc +++ b/third_party/blink/renderer/core/layout/layout_inline.cc
@@ -403,7 +403,12 @@ void LayoutInline::CollectLineBoxRects( const PhysicalRectCollector& yield) const { NOT_DESTROYED(); - DCHECK(IsInLayoutNGInlineFormattingContext()); +#if DCHECK_IS_ON() + if (!IsInLayoutNGInlineFormattingContext()) { + ShowLayoutTreeForThis(); + DCHECK(IsInLayoutNGInlineFormattingContext()); + } +#endif NGInlineCursor cursor; cursor.MoveToIncludingCulledInline(*this); for (; cursor; cursor.MoveToNextForSameLayoutObject()) {
diff --git a/third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.cc b/third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.cc index 457a5c7..54ad9f1 100644 --- a/third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.cc +++ b/third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.cc
@@ -44,15 +44,6 @@ (style.ResolvedIsRowFlexDirection() && is_wrap_reverse)); } -void LayoutNGFlexibleBox::UpdateBlockLayout() { - if (IsOutOfFlowPositioned()) { - UpdateOutOfFlowBlockLayout(); - return; - } - - UpdateInFlowBlockLayout(); -} - namespace { void MergeAnonymousFlexItems(LayoutObject* remove_child) {
diff --git a/third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.h b/third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.h index 0d07e5a8..96927c12 100644 --- a/third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.h +++ b/third_party/blink/renderer/core/layout/ng/flex/layout_ng_flexible_box.h
@@ -24,7 +24,10 @@ bool HasTopOverflow() const override; bool HasLeftOverflow() const override; - void UpdateBlockLayout() override; + void UpdateBlockLayout() final { + NOT_DESTROYED(); + NOTREACHED_NORETURN(); + } bool IsFlexibleBoxIncludingNG() const final { NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/ng/grid/layout_ng_grid.cc b/third_party/blink/renderer/core/layout/ng/grid/layout_ng_grid.cc index e30f0b2..bcc6fe84 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/layout_ng_grid.cc +++ b/third_party/blink/renderer/core/layout/ng/grid/layout_ng_grid.cc
@@ -11,14 +11,6 @@ LayoutNGGrid::LayoutNGGrid(Element* element) : LayoutNGMixin<LayoutBlock>(element) {} -void LayoutNGGrid::UpdateBlockLayout() { - if (IsOutOfFlowPositioned()) { - UpdateOutOfFlowBlockLayout(); - return; - } - UpdateInFlowBlockLayout(); -} - void LayoutNGGrid::AddChild(LayoutObject* new_child, LayoutObject* before_child) { NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/ng/grid/layout_ng_grid.h b/third_party/blink/renderer/core/layout/ng/grid/layout_ng_grid.h index fc9eef77..9ff1699 100644 --- a/third_party/blink/renderer/core/layout/ng/grid/layout_ng_grid.h +++ b/third_party/blink/renderer/core/layout/ng/grid/layout_ng_grid.h
@@ -16,7 +16,10 @@ public: explicit LayoutNGGrid(Element*); - void UpdateBlockLayout() override; + void UpdateBlockLayout() final { + NOT_DESTROYED(); + NOTREACHED_NORETURN(); + } const char* GetName() const override { NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/ng/layout_box_utils.cc b/third_party/blink/renderer/core/layout/ng/layout_box_utils.cc index 7d7c0070..84e3499 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_box_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/layout_box_utils.cc
@@ -72,103 +72,6 @@ return box.ContainingBlockLogicalWidthForContent(); } -NGLogicalStaticPosition LayoutBoxUtils::ComputeStaticPositionFromLegacy( - const LayoutBox& box, - const NGBoxStrut& container_border_scrollbar, - const NGBoxFragmentBuilder* container_builder) { - const auto* css_container = To<LayoutBoxModelObject>(box.Container()); - const TextDirection parent_direction = box.Parent()->StyleRef().Direction(); - - // These two values represent the available-size for the OOF-positioned - // descandant, in the *descendant's* writing mode. - LayoutUnit containing_block_logical_width = - box.ContainingBlockLogicalWidthForPositioned(css_container); - LayoutUnit containing_block_logical_height = - box.ContainingBlockLogicalHeightForPositioned(css_container); - - Length logical_left; - Length logical_right; - Length logical_top; - Length logical_bottom; - box.ComputeInlineStaticDistance(logical_left, logical_right, &box, - css_container, containing_block_logical_width, - container_builder); - box.ComputeBlockStaticDistance(logical_top, logical_bottom, &box, - css_container, container_builder); - - // Determine the static-position. - LayoutUnit static_line; - LayoutUnit static_block; - if (IsLtr(parent_direction)) { - if (!logical_left.IsAuto()) { - static_line = - MinimumValueForLength(logical_left, containing_block_logical_width); - } - } else { - if (!logical_right.IsAuto()) { - static_line = - MinimumValueForLength(logical_right, containing_block_logical_width); - } - - // |logical_right| is an adjustment from the right edge, to keep this - // relative to the line-left edge account for the - // |containing_block_logical_width|. - static_line = containing_block_logical_width - static_line; - } - if (!logical_top.IsAuto()) { - static_block = - MinimumValueForLength(logical_top, containing_block_logical_height); - } - - NGLogicalStaticPosition::BlockEdge block_edge = - box.Layer()->StaticBlockEdge(); - NGLogicalStaticPosition::InlineEdge inline_edge = - box.Layer()->StaticInlineEdge(); - - if (!IsLtr(parent_direction)) { - if (inline_edge == NGLogicalStaticPosition::InlineEdge::kInlineStart) - inline_edge = NGLogicalStaticPosition::InlineEdge::kInlineEnd; - else if (inline_edge == NGLogicalStaticPosition::InlineEdge::kInlineEnd) - inline_edge = NGLogicalStaticPosition::InlineEdge::kInlineStart; - } - - NGLogicalStaticPosition logical_static_position{ - {static_line, static_block}, inline_edge, block_edge}; - - // Determine the physical available-size, remember that the available-size is - // currently in the *descendant's* writing-mode. - PhysicalSize container_size = - ToPhysicalSize(LogicalSize(containing_block_logical_width, - containing_block_logical_height), - box.StyleRef().GetWritingMode()); - - const LayoutBox* container = css_container->IsBox() - ? To<LayoutBox>(css_container) - : box.ContainingBlock(); - const WritingMode container_writing_mode = - container->StyleRef().GetWritingMode(); - const TextDirection container_direction = container->StyleRef().Direction(); - - // We perform a logical-physical-logical conversion to convert the - // static-position into the correct writing-mode, and direction combination. - // - // At the moment the static-position is in line-relative coordinates which is - // why we use |TextDirection::kLtr| for the first conversion. - logical_static_position = - logical_static_position - .ConvertToPhysical( - {{container_writing_mode, TextDirection::kLtr}, container_size}) - .ConvertToLogical( - {{container_writing_mode, container_direction}, container_size}); - - // Finally we shift the static-position from being relative to the - // padding-box, to the border-box. - logical_static_position.offset += - LogicalOffset{container_border_scrollbar.inline_start, - container_border_scrollbar.block_start}; - return logical_static_position; -} - bool LayoutBoxUtils::SkipContainingBlockForPercentHeightCalculation( const LayoutBlock* cb) { return LayoutBox::SkipContainingBlockForPercentHeightCalculation(cb);
diff --git a/third_party/blink/renderer/core/layout/ng/layout_box_utils.h b/third_party/blink/renderer/core/layout/ng/layout_box_utils.h index 9ec609f..bdc9c02 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_box_utils.h +++ b/third_party/blink/renderer/core/layout/ng/layout_box_utils.h
@@ -13,10 +13,7 @@ class LayoutBlock; class LayoutPoint; class NGBlockBreakToken; -class NGBoxFragmentBuilder; class NGPhysicalBoxFragment; -struct NGBoxStrut; -struct NGLogicalStaticPosition; struct PhysicalOffset; // This static class should be used for querying information from a |LayoutBox|, @@ -33,14 +30,6 @@ static LayoutUnit AvailableLogicalHeight(const LayoutBox& box, const LayoutBlock* cb); - // Produces a |NGLogicalStaticPosition| for |box| from the layout-tree. - // |container_builder| is needed as not all the information from current NG - // layout is copied to the layout-tree yet. - static NGLogicalStaticPosition ComputeStaticPositionFromLegacy( - const LayoutBox& box, - const NGBoxStrut& container_border_scrollbar, - const NGBoxFragmentBuilder* container_builder = nullptr); - static bool SkipContainingBlockForPercentHeightCalculation( const LayoutBlock* cb);
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.cc index 286d5a03..5dfae2a 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.cc +++ b/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.cc
@@ -18,8 +18,4 @@ LayoutNGMixin<LayoutBlockFlow>::IsOfType(type); } -void LayoutNGBlockFlow::UpdateBlockLayout() { - UpdateNGBlockLayout(); -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h b/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h index 8529c4c4..9dbfbdc 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h +++ b/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h
@@ -23,7 +23,10 @@ explicit LayoutNGBlockFlow(ContainerNode*); ~LayoutNGBlockFlow() override; - void UpdateBlockLayout() override; + void UpdateBlockLayout() final { + NOT_DESTROYED(); + NOTREACHED_NORETURN(); + } const char* GetName() const override { NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.cc index e9e020b..64a83e2 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.cc +++ b/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.cc
@@ -189,18 +189,6 @@ } template <typename Base> -void LayoutNGBlockFlowMixin<Base>::UpdateNGBlockLayout() { - Base::CheckIsNotDestroyed(); - - if (Base::IsOutOfFlowPositioned()) { - LayoutNGMixin<Base>::UpdateOutOfFlowBlockLayout(); - return; - } - - LayoutNGMixin<Base>::UpdateInFlowBlockLayout(); -} - -template <typename Base> void LayoutNGBlockFlowMixin<Base>::Trace(Visitor* visitor) const { visitor->Trace(ng_inline_node_data_); LayoutNGMixin<Base>::Trace(visitor);
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.h b/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.h index e19cc50..bc788e2e 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.h +++ b/third_party/blink/renderer/core/layout/ng/layout_ng_block_flow_mixin.h
@@ -65,10 +65,6 @@ void DirtyLinesFromChangedChild(LayoutObject* child, MarkingBehavior marking_behavior) final; - // Intended to be called from UpdateLayout() for subclasses that want the same - // behavior as LayoutNGBlockFlow. - void UpdateNGBlockLayout(); - Member<NGInlineNodeData> ng_inline_node_data_; friend class NGBaseLayoutAlgorithmTest;
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_frame_set.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_frame_set.cc index 07c5768..4a521015 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_ng_frame_set.cc +++ b/third_party/blink/renderer/core/layout/ng/layout_ng_frame_set.cc
@@ -43,13 +43,6 @@ To<HTMLFrameSetElement>(GetNode())->DirtyEdgeInfoAndFullPaintInvalidation(); } -void LayoutNGFrameSet::UpdateBlockLayout() { - if (IsOutOfFlowPositioned()) - UpdateOutOfFlowBlockLayout(); - else - UpdateInFlowBlockLayout(); -} - CursorDirective LayoutNGFrameSet::GetCursor(const PhysicalOffset& point, ui::Cursor& cursor) const { NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_frame_set.h b/third_party/blink/renderer/core/layout/ng/layout_ng_frame_set.h index 92f2b00..51d77a2 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_ng_frame_set.h +++ b/third_party/blink/renderer/core/layout/ng/layout_ng_frame_set.h
@@ -19,7 +19,6 @@ bool IsChildAllowed(LayoutObject* child, const ComputedStyle&) const override; void AddChild(LayoutObject* new_child, LayoutObject* before_child) override; void RemoveChild(LayoutObject* child) override; - void UpdateBlockLayout() override; CursorDirective GetCursor(const PhysicalOffset& point, ui::Cursor& cursor) const override; };
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc index 3e0438b..c402ff3 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc +++ b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.cc
@@ -28,26 +28,6 @@ namespace blink { -namespace { - -bool CanUseConstraintSpaceForCaching(const NGLayoutResult* previous_result, - const LayoutBox& box) { - if (!previous_result) - return false; - const auto& space = previous_result->GetConstraintSpaceForCaching(); - if (space.IsFixedInlineSize() && box.HasOverrideLogicalWidth()) { - if (space.AvailableSize().inline_size != box.OverrideLogicalWidth()) - return false; - } - if (space.IsFixedBlockSize() && box.HasOverrideLogicalHeight()) { - if (space.AvailableSize().block_size != box.OverrideLogicalHeight()) - return false; - } - return space.GetWritingMode() == box.StyleRef().GetWritingMode(); -} - -} // namespace - template <typename Base> LayoutNGMixin<Base>::LayoutNGMixin(ContainerNode* node) : Base(node) { Base::CheckIsNotDestroyed(); @@ -171,178 +151,6 @@ return builder.ToConstraintSpace(); } -template <typename Base> -void LayoutNGMixin<Base>::UpdateOutOfFlowBlockLayout() { - Base::CheckIsNotDestroyed(); - - auto* css_container = To<LayoutBoxModelObject>(Base::Container()); - DCHECK(!css_container->IsBox() || css_container->IsLayoutBlock()); - auto* container = DynamicTo<LayoutBlock>(css_container); - if (!container) - container = Base::ContainingBlock(); - const ComputedStyle* container_style = container->Style(); - NGConstraintSpace constraint_space = - NGConstraintSpace::CreateFromLayoutObject(*container); - - // As this is part of the Legacy->NG bridge, the container_builder is used - // for indicating the resolved size of the OOF-positioned containing-block - // and not used for caching purposes. - // When we produce a layout result from it, we access its child fragments - // which must contain *at least* this node. We use the child fragments for - // copying back position information. - NGBlockNode container_node(container); - NGBoxFragmentBuilder container_builder( - container_node, scoped_refptr<const ComputedStyle>(container_style), - constraint_space, container_style->GetWritingDirection()); - container_builder.SetIsNewFormattingContext( - container_node.CreatesNewFormattingContext()); - - NGFragmentGeometry fragment_geometry; - fragment_geometry.border = ComputeBorders(constraint_space, container_node); - fragment_geometry.scrollbar = - ComputeScrollbars(constraint_space, container_node); - fragment_geometry.padding = - ComputePadding(constraint_space, *container_style); - - NGBoxStrut border_scrollbar = - fragment_geometry.border + fragment_geometry.scrollbar; - - // Calculate the border-box size of the object that's the containing block of - // this out-of-flow positioned descendant. Note that this is not to be used as - // the containing block size to resolve sizes and positions for the - // descendant, since we're dealing with the border box here (not the padding - // box, which is where the containing block is established). These sizes are - // just used to do a fake/partial NG layout pass of the containing block (that - // object is really managed by legacy layout). - LayoutUnit container_border_box_logical_width; - LayoutUnit container_border_box_logical_height; - if (Base::HasOverrideContainingBlockContentLogicalWidth()) { - container_border_box_logical_width = - Base::OverrideContainingBlockContentLogicalWidth() + - border_scrollbar.InlineSum(); - } else { - container_border_box_logical_width = container->LogicalWidth(); - } - if (Base::HasOverrideContainingBlockContentLogicalHeight()) { - container_border_box_logical_height = - Base::OverrideContainingBlockContentLogicalHeight() + - border_scrollbar.BlockSum(); - } else { - container_border_box_logical_height = container->LogicalHeight(); - } - - fragment_geometry.border_box_size = {container_border_box_logical_width, - container_border_box_logical_height}; - container_builder.SetInitialFragmentGeometry(fragment_geometry); - - // TODO(1229581): Remove this call to determine the static position. - NGLogicalStaticPosition static_position = - LayoutBoxUtils::ComputeStaticPositionFromLegacy(*this, border_scrollbar); - - // Set correct container for inline containing blocks. - container_builder.AddOutOfFlowLegacyCandidate( - NGBlockNode(this), static_position, - DynamicTo<LayoutInline>(css_container)); - - absl::optional<LogicalSize> initial_containing_block_fixed_size = - NGOutOfFlowLayoutPart::InitialContainingBlockFixedSize( - NGBlockNode(container)); - // We really only want to lay out ourselves here, so we pass |this| to - // Run(). Otherwise, NGOutOfFlowLayoutPart may also lay out other objects - // it discovers that are part of the same containing block, but those - // should get laid out by the actual containing block. - NGOutOfFlowLayoutPart(css_container->CanContainAbsolutePositionObjects(), - css_container->CanContainFixedPositionObjects(), - /* is_grid_container */ false, constraint_space, - &container_builder, initial_containing_block_fixed_size) - .Run(/* only_layout */ this); - const NGLayoutResult* result = container_builder.ToBoxFragment(); - - const auto& fragment = result->PhysicalFragment(); - DCHECK_GT(fragment.Children().size(), 0u); - - // Handle the unpositioned OOF descendants of the current OOF block. - if (fragment.HasOutOfFlowPositionedDescendants()) { - LayoutBlock* oof_container = - LayoutObject::FindNonAnonymousContainingBlock(container); - for (const auto& descendant : fragment.OutOfFlowPositionedDescendants()) - descendant.Node().InsertIntoLegacyPositionedObjectsOf(oof_container); - } - - // Copy sizes of all child fragments to Legacy. - // There could be multiple fragments, when this node has descendants whose - // container is this node's container. - // Example: fixed descendant of fixed element. - for (auto& child : fragment.Children()) { - const NGPhysicalFragment* child_fragment = child.get(); - DCHECK(child_fragment->GetLayoutObject()->IsBox()); - auto* child_legacy_box = - To<LayoutBox>(child_fragment->GetMutableLayoutObject()); - PhysicalOffset child_offset = child.Offset(); - if (container_style->IsFlippedBlocksWritingMode()) { - child_offset.left = container_border_box_logical_height - - child_offset.left - child_fragment->Size().width; - } - child_legacy_box->SetLocation(child_offset.ToLayoutPoint()); - } - DCHECK_EQ(fragment.Children()[0]->GetLayoutObject(), this); -} - -template <typename Base> -const NGLayoutResult* LayoutNGMixin<Base>::UpdateInFlowBlockLayout() { - Base::CheckIsNotDestroyed(); - - // This is an entry-point for LayoutNG from the legacy engine. This means that - // we need to be at a formatting context boundary, since NG and legacy don't - // cooperate on e.g. margin collapsing. - DCHECK(this->CreatesNewFormattingContext()); - - const NGLayoutResult* previous_result = Base::GetSingleCachedLayoutResult(); - - // If we are a layout root, use the previous space if available. This will - // include any stretched sizes if applicable. - NGConstraintSpace constraint_space = - CanUseConstraintSpaceForCaching(previous_result, *this) - ? previous_result->GetConstraintSpaceForCaching() - : NGConstraintSpace::CreateFromLayoutObject(*this); - - const NGLayoutResult* result = NGBlockNode(this).Layout(constraint_space); - - const auto& physical_fragment = - To<NGPhysicalBoxFragment>(result->PhysicalFragment()); - - for (const auto& descendant : - physical_fragment.OutOfFlowPositionedDescendants()) { - descendant.Node().InsertIntoLegacyPositionedObjectsOf( - descendant.box->ContainingBlock()); - } - - // Even if we are a layout root, our baseline may have shifted. In this - // (rare) case, mark our containing-block for layout. - if (previous_result) { - if (To<NGPhysicalBoxFragment>(previous_result->PhysicalFragment()) - .FirstBaseline() != physical_fragment.FirstBaseline()) { - if (auto* containing_block = Base::ContainingBlock()) { - // Baselines inside replaced elements don't affect other boxes. - bool is_in_replaced = false; - for (auto* parent = Base::Parent(); - parent && parent != containing_block; parent = parent->Parent()) { - if (parent->IsLayoutReplaced()) { - is_in_replaced = true; - break; - } - } - if (!is_in_replaced) { - containing_block->SetNeedsLayout( - layout_invalidation_reason::kChildChanged, kMarkContainerChain); - } - } - } - } - - return result; -} - template class CORE_TEMPLATE_EXPORT LayoutNGMixin<LayoutBlock>; template class CORE_TEMPLATE_EXPORT LayoutNGMixin<LayoutBlockFlow>; template class CORE_TEMPLATE_EXPORT LayoutNGMixin<LayoutSVGBlock>;
diff --git a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h index ff4dd677..0897745a 100644 --- a/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h +++ b/third_party/blink/renderer/core/layout/ng/layout_ng_mixin.h
@@ -44,9 +44,6 @@ protected: MinMaxSizes ComputeIntrinsicLogicalWidths() const override; NGConstraintSpace ConstraintSpaceForMinMaxSizes() const; - - void UpdateOutOfFlowBlockLayout(); - const NGLayoutResult* UpdateInFlowBlockLayout(); }; } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.cc b/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.cc index 1b6dc5c..c298da4 100644 --- a/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.cc +++ b/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.cc
@@ -14,15 +14,6 @@ : LayoutNGMixin<LayoutBlock>(element) { } -void LayoutNGMathMLBlock::UpdateBlockLayout() { - if (IsOutOfFlowPositioned()) { - UpdateOutOfFlowBlockLayout(); - return; - } - - UpdateInFlowBlockLayout(); -} - bool LayoutNGMathMLBlock::IsOfType(LayoutObjectType type) const { return type == kLayoutObjectMathML || (type == kLayoutObjectMathMLRoot && GetNode() &&
diff --git a/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.h b/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.h index b3e942a..d1da740b 100644 --- a/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.h +++ b/third_party/blink/renderer/core/layout/ng/mathml/layout_ng_mathml_block.h
@@ -19,7 +19,10 @@ } private: - void UpdateBlockLayout() final; + void UpdateBlockLayout() final { + NOT_DESTROYED(); + NOTREACHED_NORETURN(); + } bool IsOfType(LayoutObjectType) const final; bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const final;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc index 9bdf982..1ffa247 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc
@@ -273,16 +273,6 @@ has_inflow_child_break_inside_ |= !is_in_parallel_flow; } -void NGBoxFragmentBuilder::AddOutOfFlowLegacyCandidate( - NGBlockNode node, - const NGLogicalStaticPosition& static_position, - const LayoutInline* inline_container) { - oof_positioned_candidates_.emplace_back( - node, static_position, - NGInlineContainer<LogicalOffset>(inline_container, - /* relative_offset */ LogicalOffset())); -} - void NGBoxFragmentBuilder::PropagateSpaceShortage( absl::optional<LayoutUnit> space_shortage) { // Space shortage should only be reported when we already have a tentative
diff --git a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h index 7f8920a..23d3c03 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h +++ b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h
@@ -223,10 +223,6 @@ // this break token is for content in the same flow as this parent. void AddBreakToken(const NGBreakToken*, bool is_in_parallel_flow = false); - void AddOutOfFlowLegacyCandidate(NGBlockNode, - const NGLogicalStaticPosition&, - const LayoutInline* inline_container); - // Before layout we'll determine whether we can tell for sure that the node // (or what's left of it to lay out, in case we've already broken) will fit in // the current fragmentainer. If this is the case, we'll know that any
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc index 221fb7a..88f8380 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -177,7 +177,7 @@ default_containing_block_info_for_fixed_.rect.offset = container_offset; } -void NGOutOfFlowLayoutPart::Run(const LayoutBox* only_layout) { +void NGOutOfFlowLayoutPart::Run() { HandleFragmentation(); const LayoutObject* current_container = container_builder_->GetLayoutObject(); if (!container_builder_->HasOutOfFlowPositionedCandidates() && @@ -198,7 +198,7 @@ clear_scope(&candidates); container_builder_->SwapOutOfFlowPositionedCandidates(&candidates); - LayoutCandidates(&candidates, only_layout); + LayoutCandidates(&candidates); } void NGOutOfFlowLayoutPart::HandleFragmentation( @@ -682,8 +682,7 @@ } void NGOutOfFlowLayoutPart::LayoutCandidates( - HeapVector<NGLogicalOutOfFlowPositionedNode>* candidates, - const LayoutBox* only_layout) { + HeapVector<NGLogicalOutOfFlowPositionedNode>* candidates) { const WritingModeConverter conainer_converter( container_builder_->GetWritingDirection(), container_builder_->Size()); const NGFragmentItemsBuilder::ItemWithOffsetList* items = nullptr; @@ -696,18 +695,14 @@ LayoutBox* layout_box = candidate.box; if (!container_builder_->IsBlockFragmentationContextRoot()) SaveStaticPositionOnPaintLayer(layout_box, candidate.static_position); - if (IsContainingBlockForCandidate(candidate) && - (!only_layout || layout_box == only_layout)) { + if (IsContainingBlockForCandidate(candidate)) { if (has_block_fragmentation_) { container_builder_->SetHasOutOfFlowInFragmentainerSubtree(true); if (!container_builder_->IsInitialColumnBalancingPass()) { // As an optimization, only populate legacy positioned objects lists // when inside a fragmentation context root, since otherwise we can // just look at the children in the fragment tree. - if (layout_box != only_layout) { - container_builder_->InsertLegacyPositionedObject( - candidate.Node()); - } + container_builder_->InsertLegacyPositionedObject(candidate.Node()); NGLogicalOOFNodeForFragmentation fragmentainer_descendant( candidate); container_builder_->AdjustFragmentainerDescendant( @@ -738,10 +733,9 @@ NodeInfo node_info = SetupNodeInfo(candidate); NodeToLayout node_to_layout = { node_info, - CalculateOffset(node_info, only_layout, /* is_first_run */ false, + CalculateOffset(node_info, /* is_first_run */ false, needs_anchor_queries ? &*anchor_queries : nullptr)}; - const NGLayoutResult* result = - LayoutOOFNode(node_to_layout, only_layout); + const NGLayoutResult* result = LayoutOOFNode(node_to_layout); container_builder_->AddResult( *result, result->OutOfFlowPositionedOffset(), /* relative_offset */ absl::nullopt, &candidate.inline_container); @@ -1214,9 +1208,8 @@ NodeInfo node_info = SetupNodeInfo(descendant); NodeToLayout node_to_layout = { - node_info, - CalculateOffset(node_info, /* only_layout */ nullptr, - /* is_first_run */ true, &stitched_anchor_queries)}; + node_info, CalculateOffset(node_info, /* is_first_run */ true, + &stitched_anchor_queries)}; node_to_layout.containing_block_fragment = descendant.containing_block.Fragment(); node_to_layout.offset_info.original_offset = @@ -1465,7 +1458,6 @@ const NGLayoutResult* NGOutOfFlowLayoutPart::LayoutOOFNode( NodeToLayout& oof_node_to_layout, - const LayoutBox* only_layout, const NGConstraintSpace* fragmentainer_constraint_space, bool is_last_fragmentainer_so_far) { const NodeInfo& node_info = oof_node_to_layout.node_info; @@ -1539,8 +1531,7 @@ // token, causing major confusion everywhere. // // [1] https://drafts.csswg.org/css-break/#varying-size-boxes - offset_info = CalculateOffset(node_info, only_layout, - /* is_first_run */ false); + offset_info = CalculateOffset(node_info, /* is_first_run */ false); } layout_result = Layout(oof_node_to_layout, fragmentainer_constraint_space, @@ -1557,7 +1548,6 @@ NGOutOfFlowLayoutPart::OffsetInfo NGOutOfFlowLayoutPart::CalculateOffset( const NodeInfo& node_info, - const LayoutBox* only_layout, bool is_first_run, const NGLogicalAnchorQueryMap* anchor_queries) { const ComputedStyle* style = &node_info.node.Style(); @@ -1598,9 +1588,9 @@ const bool try_fit_available_space = next_fallback_style; PhysicalScrollRange non_overflowing_range; - offset_info = TryCalculateOffset( - node_info, *style, only_layout, anchor_queries, implicit_anchor, - try_fit_available_space, is_first_run, &non_overflowing_range); + offset_info = TryCalculateOffset(node_info, *style, anchor_queries, + implicit_anchor, try_fit_available_space, + is_first_run, &non_overflowing_range); // Also check if it fits the containing block after applying scroll offset. if (offset_info && next_fallback_style) { @@ -1630,7 +1620,6 @@ NGOutOfFlowLayoutPart::TryCalculateOffset( const NodeInfo& node_info, const ComputedStyle& candidate_style, - const LayoutBox* only_layout, const NGLogicalAnchorQueryMap* anchor_queries, const LayoutObject* implicit_anchor, bool try_fit_available_space, @@ -1781,7 +1770,7 @@ offset_info.offset.inline_offset += inset.inline_start; offset_info.offset.block_offset += inset.block_start; - if (!only_layout && !container_builder_->IsBlockFragmentationContextRoot()) { + if (!container_builder_->IsBlockFragmentationContextRoot()) { // OOFs contained by an inline that's been split into continuations are // special, as their offset is relative to a fragment that's not the same as // their containing NG fragment; take a look inside @@ -2063,9 +2052,8 @@ bool* has_actual_break_inside, NGSimplifiedOOFLayoutAlgorithm* algorithm, HeapVector<NodeToLayout>* fragmented_descendants) { - const NGLayoutResult* result = - LayoutOOFNode(descendant, /* only_layout */ nullptr, fragmentainer_space, - is_last_fragmentainer_so_far); + const NGLayoutResult* result = LayoutOOFNode(descendant, fragmentainer_space, + is_last_fragmentainer_so_far); if (result->Status() != NGLayoutResult::kSuccess) { DCHECK_EQ(result->Status(), NGLayoutResult::kOutOfFragmentainerSpace);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h index 2cf5674..6e3b14a7 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h +++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h
@@ -61,13 +61,7 @@ NGBoxFragmentBuilder* container_builder, absl::optional<LogicalSize> initial_containing_block_fixed_size); - // Normally this function lays out and positions all out-of-flow objects from - // the container_builder and additional ones it discovers through laying out - // those objects. However, if only_layout is specified, only that object will - // get laid out; any additional ones will be stored as out-of-flow - // descendants in the builder for use via - // LayoutResult::OutOfFlowPositionedDescendants. - void Run(const LayoutBox* only_layout = nullptr); + void Run(); struct ColumnBalancingInfo { DISALLOW_NEW(); @@ -299,8 +293,7 @@ bool adjust_for_fragmentation = false); void LayoutCandidates( - HeapVector<NGLogicalOutOfFlowPositionedNode>* candidates, - const LayoutBox* only_layout); + HeapVector<NGLogicalOutOfFlowPositionedNode>* candidates); void HandleMulticolsWithPendingOOFs(NGBoxFragmentBuilder* container_builder); void LayoutOOFsInMulticol( @@ -320,7 +313,6 @@ const NGLayoutResult* LayoutOOFNode( NodeToLayout& oof_node_to_layout, - const LayoutBox* only_layout, const NGConstraintSpace* fragmentainer_constraint_space = nullptr, bool is_last_fragmentainer_so_far = false); @@ -328,7 +320,6 @@ // changing this to a more accurate name. OffsetInfo CalculateOffset( const NodeInfo& node_info, - const LayoutBox* only_layout, bool is_first_run = true, const NGLogicalAnchorQueryMap* anchor_queries = nullptr); // Calculates offsets with the given ComputedStyle. Returns nullopt if @@ -337,7 +328,6 @@ absl::optional<OffsetInfo> TryCalculateOffset( const NodeInfo& node_info, const ComputedStyle& style, - const LayoutBox* only_layout, const NGLogicalAnchorQueryMap* anchor_queries, const LayoutObject* implicit_anchor, bool try_fit_available_space,
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc index 60d5c70..ada6ab3 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.cc
@@ -252,16 +252,6 @@ return false; } -void LayoutNGTable::UpdateBlockLayout() { - NOT_DESTROYED(); - - if (IsOutOfFlowPositioned()) { - UpdateOutOfFlowBlockLayout(); - return; - } - UpdateInFlowBlockLayout(); -} - void LayoutNGTable::AddChild(LayoutObject* child, LayoutObject* before_child) { NOT_DESTROYED(); TableGridStructureChanged();
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h index 4bdddc33..6b91de3 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h
@@ -146,8 +146,6 @@ return "LayoutNGTable"; } - void UpdateBlockLayout() override; - void AddChild(LayoutObject* child, LayoutObject* before_child = nullptr) override;
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_caption.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_caption.cc index 8b03809..3aaaba3 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_caption.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_caption.cc
@@ -19,48 +19,4 @@ LayoutNGTableCaption::LayoutNGTableCaption(Element* element) : LayoutNGBlockFlow(element) {} -// Legacy method. -// TODO(1229581): Remove. -void LayoutNGTableCaption::CalculateAndSetMargins( - const NGConstraintSpace& constraint_space, - const NGPhysicalFragment& physical_fragment) { - NOT_DESTROYED(); - const ComputedStyle& containing_block_style = ContainingBlock()->StyleRef(); - - NGBoxFragment box_fragment(containing_block_style.GetWritingDirection(), - To<NGPhysicalBoxFragment>(physical_fragment)); - - NGPhysicalBoxStrut physical_margins = - ComputePhysicalMargins(constraint_space, StyleRef()); - - NGBoxStrut logical_margins = physical_margins.ConvertToLogical( - containing_block_style.GetWritingDirection()); - - LayoutUnit caption_inline_size_in_cb_writing_mode = box_fragment.InlineSize(); - - LayoutUnit available_inline_size_in_cb_writing_mode = - ToPhysicalSize(constraint_space.AvailableSize(), - constraint_space.GetWritingMode()) - .ConvertToLogical(containing_block_style.GetWritingMode()) - .inline_size; - - ResolveInlineMargins(StyleRef(), containing_block_style, - available_inline_size_in_cb_writing_mode, - caption_inline_size_in_cb_writing_mode, - &logical_margins); - SetMargin(logical_margins.ConvertToPhysical( - containing_block_style.GetWritingDirection())); -} - -// TODO(1229581): Remove. -void LayoutNGTableCaption::UpdateBlockLayout() { - NOT_DESTROYED(); - - DCHECK(!IsOutOfFlowPositioned()) << "Out of flow captions are blockified."; - - const NGLayoutResult* result = UpdateInFlowBlockLayout(); - CalculateAndSetMargins(result->GetConstraintSpaceForCaching(), - result->PhysicalFragment()); -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_caption.h b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_caption.h index d1eb0dec..ae7a23d 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_caption.h +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_caption.h
@@ -10,14 +10,10 @@ namespace blink { -class NGPhysicalFragment; - class CORE_EXPORT LayoutNGTableCaption final : public LayoutNGBlockFlow { public: explicit LayoutNGTableCaption(Element*); - void UpdateBlockLayout() override; - const char* GetName() const override { NOT_DESTROYED(); return "LayoutNGTableCaption"; @@ -33,11 +29,6 @@ return type == kLayoutObjectTableCaption || LayoutNGBlockFlow::IsOfType(type); } - - private: - // Legacy-only API. - void CalculateAndSetMargins(const NGConstraintSpace&, - const NGPhysicalFragment&); }; // wtf/casting.h helper.
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc index 9384e45..651b3427 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.cc
@@ -128,16 +128,6 @@ return nullptr; } -void LayoutNGTableCell::UpdateBlockLayout() { - NOT_DESTROYED(); - - if (IsOutOfFlowPositioned()) { - UpdateOutOfFlowBlockLayout(); - return; - } - UpdateInFlowBlockLayout(); -} - void LayoutNGTableCell::StyleDidChange(StyleDifference diff, const ComputedStyle* old_style) { NOT_DESTROYED();
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h index 625fdee..4dc0d49 100644 --- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h +++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h
@@ -68,8 +68,6 @@ // LayoutBlockFlow methods start. - void UpdateBlockLayout() override; - void StyleDidChange(StyleDifference diff, const ComputedStyle* old_style) final;
diff --git a/third_party/blink/renderer/core/page/context_menu_controller.cc b/third_party/blink/renderer/core/page/context_menu_controller.cc index 1b47060..61edf7e 100644 --- a/third_party/blink/renderer/core/page/context_menu_controller.cc +++ b/third_party/blink/renderer/core/page/context_menu_controller.cc
@@ -39,7 +39,6 @@ #include "third_party/blink/public/common/input/web_menu_source_type.h" #include "third_party/blink/public/common/navigation/impression.h" #include "third_party/blink/public/mojom/context_menu/context_menu.mojom-blink.h" -#include "third_party/blink/public/mojom/conversions/attribution_reporting.mojom-blink.h" #include "third_party/blink/public/web/web_local_frame_client.h" #include "third_party/blink/public/web/web_plugin.h" #include "third_party/blink/public/web/web_text_check_client.h" @@ -762,7 +761,6 @@ /*element=*/anchor, /*request_id=*/absl::nullopt)) { data.impression = blink::Impression{ - .nav_type = mojom::blink::AttributionNavigationType::kContextMenu, .runtime_features = attribution_src_loader->GetRuntimeFeatures(), }; }
diff --git a/third_party/blink/renderer/core/page/context_menu_controller_test.cc b/third_party/blink/renderer/core/page/context_menu_controller_test.cc index a20dc60..cc9f900 100644 --- a/third_party/blink/renderer/core/page/context_menu_controller_test.cc +++ b/third_party/blink/renderer/core/page/context_menu_controller_test.cc
@@ -1950,10 +1950,6 @@ EXPECT_EQ(context_menu_data.impression.has_value(), test_case.impression_expected); - if (context_menu_data.impression.has_value()) { - EXPECT_EQ(context_menu_data.impression->nav_type, - mojom::blink::AttributionNavigationType::kContextMenu); - } } }
diff --git a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc index 325af55..b9e80ac4 100644 --- a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
@@ -203,7 +203,7 @@ HeapVector<Member<V8UnionNodeOrStringOrTrustedScript>> nodes; nodes.push_back( MakeGarbageCollected<V8UnionNodeOrStringOrTrustedScript>(iframe)); - document->documentElement()->ReplaceWith(nodes, ASSERT_NO_EXCEPTION); + document->documentElement()->replaceWith(nodes, ASSERT_NO_EXCEPTION); UpdateAllLifecyclePhases(MainFrameView());
diff --git a/third_party/blink/renderer/core/timing/window_performance.cc b/third_party/blink/renderer/core/timing/window_performance.cc index af87166..389e97f 100644 --- a/third_party/blink/renderer/core/timing/window_performance.cc +++ b/third_party/blink/renderer/core/timing/window_performance.cc
@@ -572,8 +572,22 @@ base::TimeDelta time_to_next_paint = base::Milliseconds(entry_end_time - entry->processingEnd()); - if (last_visibility_change_timestamp_ > event_timestamp && - last_visibility_change_timestamp_ < presentation_timestamp) { + const bool is_artificial_pointerup_or_click = + (entry->name() == event_type_names::kPointerup || + entry->name() == event_type_names::kClick) && + entry->startTime() == pending_pointer_down_start_time_; + + if (is_artificial_pointerup_or_click) { + UseCounter::Count(GetExecutionContext(), + WebFeature::kEventTimingArtificialPointerupOrClick); + } + + if ((last_visibility_change_timestamp_ > event_timestamp && + last_visibility_change_timestamp_ < presentation_timestamp) +#if BUILDFLAG(IS_MAC) + || is_artificial_pointerup_or_click +#endif // BUILDFLAG(IS_MAC) + ) { // The page visibility was changed. Ignore the presentation_timestamp and // fallback to processingEnd (as if there was no next paint needed). entry_end_time = entry->processingEnd(); @@ -592,6 +606,7 @@ entry->SetUnsafePresentationTimestamp(entry_presentation_timestamp); if (entry->name() == "pointerdown") { + pending_pointer_down_start_time_ = entry->startTime(); pending_pointer_down_input_delay_ = input_delay; pending_pointer_down_processing_time_ = processing_time; pending_pointer_down_time_to_next_paint_ = time_to_next_paint;
diff --git a/third_party/blink/renderer/core/timing/window_performance.h b/third_party/blink/renderer/core/timing/window_performance.h index 74c0689..2dd0bc6 100644 --- a/third_party/blink/renderer/core/timing/window_performance.h +++ b/third_party/blink/renderer/core/timing/window_performance.h
@@ -262,6 +262,7 @@ mutable Member<PerformanceNavigation> navigation_; mutable Member<PerformanceTiming> timing_; mutable Member<PerformanceTimingForReporting> timing_for_reporting_; + DOMHighResTimeStamp pending_pointer_down_start_time_; absl::optional<base::TimeDelta> pending_pointer_down_input_delay_; absl::optional<base::TimeDelta> pending_pointer_down_processing_time_; absl::optional<base::TimeDelta> pending_pointer_down_time_to_next_paint_;
diff --git a/third_party/blink/renderer/core/timing/window_performance_test.cc b/third_party/blink/renderer/core/timing/window_performance_test.cc index 8db636a..1ab47af7 100644 --- a/third_party/blink/renderer/core/timing/window_performance_test.cc +++ b/third_party/blink/renderer/core/timing/window_performance_test.cc
@@ -1029,6 +1029,72 @@ EXPECT_EQ(0u, entries.size()); } +#if BUILDFLAG(IS_MAC) +// Test artificial pointerup and click on MacOS fall back to use processingEnd +// as event duration ending time. +// See crbug.com/1321819 +TEST_P(WindowPerformanceTest, ArtificialPointerupOrClick) { + // Random keycode picked for testing + PointerId pointer_id = 4; + + // Pointerdown + base::TimeTicks pointerdown_timestamp = GetTimeOrigin(); + base::TimeTicks processing_start_pointerdown = GetTimeStamp(1); + base::TimeTicks processing_end_pointerdown = GetTimeStamp(2); + base::TimeTicks presentation_time_pointerdown = GetTimeStamp(3); + RegisterPointerEvent("pointerdown", pointerdown_timestamp, + processing_start_pointerdown, processing_end_pointerdown, + pointer_id); + SimulatePaintAndResolvePresentationPromise(presentation_time_pointerdown); + // Artificial Pointerup + base::TimeTicks pointerup_timestamp = pointerdown_timestamp; + base::TimeTicks processing_start_pointerup = GetTimeStamp(5); + base::TimeTicks processing_end_pointerup = GetTimeStamp(6); + base::TimeTicks presentation_time_pointerup = GetTimeStamp(10); + RegisterPointerEvent("pointerup", pointerup_timestamp, + processing_start_pointerup, processing_end_pointerup, + pointer_id); + SimulatePaintAndResolvePresentationPromise(presentation_time_pointerup); + // Artificial Click + base::TimeTicks click_timestamp = pointerup_timestamp; + base::TimeTicks processing_start_click = GetTimeStamp(11); + base::TimeTicks processing_end_click = GetTimeStamp(12); + base::TimeTicks presentation_time_click = GetTimeStamp(20); + RegisterPointerEvent("click", click_timestamp, processing_start_click, + processing_end_click, pointer_id); + SimulatePaintAndResolvePresentationPromise(presentation_time_click); + + // Flush UKM logging mojo request. + RunPendingTasks(); + + // Check UKM recording. + auto entries = GetUkmRecorder()->GetEntriesByName( + ukm::builders::Responsiveness_UserInteraction::kEntryName); + EXPECT_EQ(1u, entries.size()); + const ukm::mojom::UkmEntry* ukm_entry = entries[0]; + GetUkmRecorder()->ExpectEntryMetric( + ukm_entry, + ukm::builders::Responsiveness_UserInteraction::kMaxEventDurationName, 12); + GetUkmRecorder()->ExpectEntryMetric( + ukm_entry, + ukm::builders::Responsiveness_UserInteraction::kTotalEventDurationName, + 12); + GetUkmRecorder()->ExpectEntryMetric( + ukm_entry, + ukm::builders::Responsiveness_UserInteraction::kInteractionTypeName, 1); + + // Check UMA recording. + GetHistogramTester().ExpectTotalCount( + "Blink.Responsiveness.UserInteraction.MaxEventDuration.AllTypes", 1); + GetHistogramTester().ExpectTotalCount( + "Blink.Responsiveness.UserInteraction.MaxEventDuration.Keyboard", 0); + GetHistogramTester().ExpectTotalCount( + "Blink.Responsiveness.UserInteraction.MaxEventDuration.TapOrClick", 1); + GetHistogramTester().ExpectTotalCount( + "Blink.Responsiveness.UserInteraction.MaxEventDuration.Drag", 0); +} +#endif // BUILDFLAG(IS_MAC) + TEST_P(WindowPerformanceTest, ElementTimingTraceEvent) { using trace_analyzer::Query; trace_analyzer::Start("*");
diff --git a/third_party/blink/renderer/modules/websockets/dom_websocket.cc b/third_party/blink/renderer/modules/websockets/dom_websocket.cc index 556e5ae..47ce748 100644 --- a/third_party/blink/renderer/modules/websockets/dom_websocket.cc +++ b/third_party/blink/renderer/modules/websockets/dom_websocket.cc
@@ -403,8 +403,9 @@ // needs to fix the size of the File at this point. For this reason, // construct a new BlobDataHandle here with the size that this method // observed. - channel_->Send( - BlobDataHandle::Create(binary_data->Uuid(), binary_data->type(), size)); + channel_->Send(BlobDataHandle::Create(binary_data->Uuid(), + binary_data->type(), size, + binary_data->AsMojoBlob())); } void DOMWebSocket::close(uint16_t code,
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 5e189476..e5aba46 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1956,6 +1956,13 @@ status: "stable", }, { + // A flag, just for local testing to make the + // HTML parser yield more often and take longer to resume. + // This helps when debugging flaky tests caused by parser + // yielding heuristics. + name: "HTMLParserYieldAndDelayOftenForTesting", + }, + { // A kill-switch for crbug.com/1412729 // (enabling the `v` flag for `pattern` RegExps). name: "HTMLPatternRegExpUnicodeSets",
diff --git a/third_party/blink/tools/blinkpy/common/net/results_fetcher.py b/third_party/blink/tools/blinkpy/common/net/results_fetcher.py index fd676845..f19cdae 100644 --- a/third_party/blink/tools/blinkpy/common/net/results_fetcher.py +++ b/third_party/blink/tools/blinkpy/common/net/results_fetcher.py
@@ -88,7 +88,7 @@ def gather_results(self, build: Build, step_name: str, - exclude_exonerated: bool = True, + exclude_exonerated: bool = False, only_unexpected: bool = True) -> WebTestResults: """Gather all web test results on a given build step from ResultDB.""" assert build.build_id, '%s must set a build ID' % build
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index c74fa804dd..156e3a6 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -2845,6 +2845,11 @@ # unblock roll wpt crbug.com/626703 external/wpt/service-workers/service-worker/worker-interception.https.html [ Failure ] +# Disable certain requestIdleCallback tests pending spec or test changes. +crbug.com/1316344 virtual/threaded/external/wpt/requestidlecallback/deadline-max-timeout-dynamic.html [ Failure ] +crbug.com/1329296 virtual/threaded/external/wpt/requestidlecallback/deadline-max-rAF-dynamic.html [ Failure Pass ] +crbug.com/1329290 virtual/threaded/external/wpt/requestidlecallback/deadline-max-rAF.html [ Failure Pass ] + # ====== Test expectations added to unblock wpt-importer ====== crbug.com/626703 external/wpt/fetch/api/crashtests/body-window-destroy.html [ Crash ] crbug.com/626703 external/wpt/fetch/metadata/generated/worker-dedicated-constructor.sub.html [ Failure ] @@ -2852,7 +2857,6 @@ crbug.com/626703 [ Linux ] external/wpt/web-bundle/subresource-loading/reuse-web-bundle-resource.https.tentative.html [ Failure ] crbug.com/626703 [ Linux ] virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/worker-interception.https.html [ Failure ] crbug.com/626703 [ Mac ] external/wpt/web-bundle/subresource-loading/reuse-web-bundle-resource.https.tentative.html [ Failure ] -crbug.com/626703 virtual/threaded/external/wpt/requestidlecallback/deadline-max-timeout-dynamic.html [ Failure ] crbug.com/626703 external/wpt/service-workers/service-worker/navigation-timing-extended.https.html [ Failure ] crbug.com/626703 virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/navigation-timing-extended.https.html [ Failure ] crbug.com/626703 external/wpt/preload/preload-resource-match.https.html [ Failure ] @@ -5670,7 +5674,6 @@ crbug.com/1339291 [ Mac12-arm64 Release ] external/wpt/webaudio/the-audio-api/the-convolvernode-interface/realtime-conv.html [ Failure Pass ] crbug.com/1339293 [ Linux ] http/tests/devtools/network/network-initiator.js [ Failure Pass ] crbug.com/1339293 [ Linux ] external/wpt/html/semantics/embedded-content/the-img-element/invisible-image.html [ Failure Pass ] -crbug.com/1339293 virtual/threaded/external/wpt/requestidlecallback/deadline-max-rAF-dynamic.html [ Failure Pass ] crbug.com/webrtc/14228 external/wpt/webrtc/protocol/h264-profile-levels.https.html [ Failure Pass ] external/wpt/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-networkState.html [ Crash Failure Pass Timeout ] @@ -6590,9 +6593,6 @@ # Sheriff 2023-04-21 crbug.com/1426534 wpt_internal/content-security-policy/reporting-api/reporting-api-works-on-frame-ancestors.https.sub.html [ Failure Pass ] -# Flake suppressor for Mac12 Tests (dbg) builder 2023-04-26 -crbug.com/1446992 [ Mac ] virtual/threaded/external/wpt/requestidlecallback/deadline-max-rAF.html [ Failure ] - # Sheriff 2023-05-01 crbug.com/1432145 [ Mac10.14 ] virtual/feature-policy-permissions/external/wpt/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-video-is-black.https.html [ Failure Timeout ] crbug.com/1441416 [ Linux ] external/wpt/js-self-profiling/max-buffer-size.window.html [ Crash Pass ] @@ -6683,5 +6683,13 @@ # Sheriff 2023-05-30 crbug.com/1450020 [ Mac ] compositing/geometry/preserve-3d-switching.html [ Failure Pass ] +# Re-enable after adding changes https://bit.ly/3w5hn7y +crbug.com/1450344 http/tests/devtools/application-panel/resources-panel-on-navigation.js [ Failure Pass ] +crbug.com/1450344 http/tests/devtools/application-panel/resources-panel-resource-preview.js [ Failure Pass ] +crbug.com/1450344 http/tests/devtools/application-panel/resources-panel-selection-on-reload.js [ Failure Pass ] +crbug.com/1450344 http/tests/devtools/application-panel/resources-panel-websql.js [ Failure Pass ] +crbug.com/1450344 http/tests/devtools/bindings/suspendtarget-bindings.js [ Failure Pass ] +crbug.com/1450344 http/tests/devtools/resource-tree/resource-tree-non-unique-url.js [ Failure Pass ] + # Temporarily disabled to unblock https://crrev.com/c/4580489 -crbug.com/1422552 http/tests/devtools/tracing/timeline-misc/timeline-window-filter.js [ Failure Pass ] \ No newline at end of file +crbug.com/1422552 http/tests/devtools/tracing/timeline-misc/timeline-window-filter.js [ Failure Pass ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 992c1ed..a45d0d2 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -995,7 +995,7 @@ "--enable-blink-features=PrivateStateTokens,PrivateStateTokensAlwaysAllowIssuance", "--additional-private-state-token-key-commitments={\"https://web-platform.test:8444\":{\"PrivateStateTokenV3VOPRF\":{\"protocol_version\":\"PrivateStateTokenV3VOPRF\",\"id\":1,\"batchsize\":1,\"keys\":{\"0\":{\"Y\":\"AAAAAASqh8oivosFN46xxx7zIK10bh07Younm5hZ90HgglQqOFUC8l2/VSlsOlReOHJ2CrfJ6CG1adnTkKJhZ0BtbSPWBwviQtdl64MWJc7sSg9HPvWfTjDigX5ihbzihG8V8aA=\",\"expiry\":\"253402300799000000\"}}}}}" ], - "expires": "Jul 1, 2023" + "expires": "Jul 1, 2024" }, { "prefix": "offsetparent-old-behavior",
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 1349474..99e5fd3 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
@@ -273088,6 +273088,16 @@ } }, "support": { + ".cache": { + "gitignore2.json": [ + "93a0a07250beb02c97bf584f5557fb82ceff850c", + [] + ], + "mtime.json": [ + "d4b901e30e68b23104c30c01dd073f227cb662fd", + [] + ] + }, ".gitignore": [ "d93e645d547894b50149d3726de2654957b6e06f", [] @@ -314441,7 +314451,7 @@ [] ], "OWNERS": [ - "1d83d3d366d28815eb47da2822550e2185d9cca8", + "62cd9f61ce8ef70159268b40d05237aa08ea504f", [] ], "README": [ @@ -327523,7 +327533,7 @@ [] ], "css-transform-3d-transform-style.html.ini": [ - "3584653fa3bc04d5ff272f19c4126e83ec83501c", + "c49ba92bf37c77522db19791b9fe95a2e87e3926", [] ], "css-transform-animate-translate-implied-y-ref.html": [ @@ -341080,7 +341090,7 @@ [] ], "OWNERS": [ - "167a625063bc31c6e7d58df13f8561ed28931b29", + "561efe79c015fe27b136facc852015d5336a63df", [] ], "README.md": [ @@ -381390,7 +381400,7 @@ [] ], "modulepreload-as.html.ini": [ - "2c0f0a40c06d1df7e019c94e337bb21e76e51943", + "5302dddde319b678136c25e8e0c067b233fdf3a1", [] ], "modulepreload-expected.txt": [ @@ -388872,7 +388882,7 @@ [] ], "single-face-detection.https.html.ini": [ - "7d0ccf1b6bacb32298c108cff5c4395744404958", + "1c255288e78c9b5f3ac3beafa3440cc425edde92", [] ], "single-text-detection.https.html.ini": [ @@ -396158,7 +396168,7 @@ [] ], "full-cycle-test.https.any.js.ini": [ - "32114a16db46455a5aaae321e722fb60c96c1783", + "78a68a53fb6812f1722c4c9aae69ce0e38d3a84c", [] ], "h264.annexb": [ @@ -396194,7 +396204,7 @@ [] ], "reconfiguring-encoder.https.any.js.ini": [ - "bdea86ee7cc56b7294b42ebb3c01d44e8abfd4ee", + "ef20bdfdc19d0af65500d157392a2b820a73fe9c", [] ], "sfx-aac.mp4": [ @@ -557269,7 +557279,14 @@ ] ], "pattern_attribute.html": [ - "93cbd2caeca80c51a1b0627b85c7a0b0cc536748", + "ec093425f71e8298a9e139e568032b2e504601b6", + [ + null, + {} + ] + ], + "pattern_attribute_v_flag.html": [ + "5246421e8bd0fdb9c76316b9384b452239b8898c", [ null, {}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/css-transform-3d-transform-style.html.ini b/third_party/blink/web_tests/external/wpt/css/css-transforms/css-transform-3d-transform-style.html.ini index 3584653..c49ba92b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transforms/css-transform-3d-transform-style.html.ini +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/css-transform-3d-transform-style.html.ini
@@ -1,3 +1,4 @@ [css-transform-3d-transform-style.html] expected: + if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/pattern_attribute.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/pattern_attribute.html index 93cbd2c..ec093425 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/pattern_attribute.html +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/pattern_attribute.html
@@ -16,40 +16,6 @@ <input pattern="\p{ASCII_Hex_Digit}+" value="c0ff33" id="unicode-property"> <input pattern="\p{RGI_Emoji}+" value="😘💋" id="unicode-property-of-strings"> - <input pattern="[\p{ASCII_Hex_Digit}--[Ff]]" value="0123456789abcdefABCDEF" id="set-difference"> - <input pattern="[_\q{a|bc|def}]" value="q" id="string-literal"> - - <div class="breaking-changes-from-u-to-v"> - <!-- Unescaped special characters in character classes. --> - <input pattern="[(]" value="foo"> - <input pattern="[)]" value="foo"> - <input pattern="[[]" value="foo"> - <input pattern="[{]" value="foo"> - <input pattern="[}]" value="foo"> - <input pattern="[/]" value="foo"> - <input pattern="[-]" value="foo"> - <input pattern="[|]" value="foo"> - <!-- Double punctuators in character classes. --> - <input pattern="[&&]" value="foo"> - <input pattern="[!!]" value="foo"> - <input pattern="[##]" value="foo"> - <input pattern="[$$]" value="foo"> - <input pattern="[%%]" value="foo"> - <input pattern="[**]" value="foo"> - <input pattern="[++]" value="foo"> - <input pattern="[,,]" value="foo"> - <input pattern="[..]" value="foo"> - <input pattern="[::]" value="foo"> - <input pattern="[;;]" value="foo"> - <input pattern="[<<]" value="foo"> - <input pattern="[==]" value="foo"> - <input pattern="[>>]" value="foo"> - <input pattern="[??]" value="foo"> - <input pattern="[@@]" value="foo"> - <input pattern="[``]" value="foo"> - <input pattern="[~~]" value="foo"> - <input pattern="[_^^]" value="foo"> - </div> </div> <div id="log"></div> <script> @@ -86,32 +52,4 @@ assert_true(input.matches(":valid")); assert_false(input.validity.patternMismatch); }, "<input pattern> supports Unicode property escape syntax for properties of strings"); - - test(() => { - const input = document.querySelector("#set-difference"); - assert_false(input.validity.valid); - assert_false(input.matches(":valid")); - assert_true(input.validity.patternMismatch); - }, "<input pattern> supports set difference syntax"); - - test(() => { - const input = document.querySelector("#string-literal"); - assert_false(input.validity.valid); - assert_true(input.validity.patternMismatch); - assert_true(input.matches(":invalid")); - }, "<input pattern> supports string literal syntax"); - - test(() => { - const inputs = document.querySelectorAll(".breaking-changes-from-u-to-v input"); - // These examples are all written such that they’re all `:invalid` - // when using `u`, but would become `:valid` when using `v` because - // the pattern would error, in turn resulting in - // `validity.valid === true`. - for (const input of inputs) { - const html = input.outerHTML; - assert_true(input.validity.valid, `${html} should be valid`); - assert_true(input.matches(":valid"), `${html} should match \`:valid\``); - assert_false(input.validity.patternMismatch, `${html} should not trigger a pattern mismatch`); - } - }, "<input pattern> enables the RegExp v flag"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/pattern_attribute_v_flag.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/pattern_attribute_v_flag.html new file mode 100644 index 0000000..5246421 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-input-element/pattern_attribute_v_flag.html
@@ -0,0 +1,77 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>pattern attribute: v flag</title> +<meta name=viewport content="width=device-width"> +<link rel="author" title="Fabrice Clari" href="mailto:f.clari@inno-group.com"> +<link rel="author" title="Dimitri Bocquet" href="mailto:Dimitri.Bocquet@mosquito-fp7.eu"> +<link rel="author" title="Mathias Bynens" href="https://mathiasbynens.be/"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-input-pattern"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<h1><code>pattern</code> attribute: v flag</h1> +<div style="display: none"> + <input pattern="[\p{ASCII_Hex_Digit}--[Ff]]" value="0123456789abcdefABCDEF" id="set-difference"> + <input pattern="[_\q{a|bc|def}]" value="q" id="string-literal"> + + <div class="breaking-changes-from-u-to-v"> + <!-- Unescaped special characters in character classes. --> + <input pattern="[(]" value="foo"> + <input pattern="[)]" value="foo"> + <input pattern="[[]" value="foo"> + <input pattern="[{]" value="foo"> + <input pattern="[}]" value="foo"> + <input pattern="[/]" value="foo"> + <input pattern="[-]" value="foo"> + <input pattern="[|]" value="foo"> + <!-- Double punctuators in character classes. --> + <input pattern="[&&]" value="foo"> + <input pattern="[!!]" value="foo"> + <input pattern="[##]" value="foo"> + <input pattern="[$$]" value="foo"> + <input pattern="[%%]" value="foo"> + <input pattern="[**]" value="foo"> + <input pattern="[++]" value="foo"> + <input pattern="[,,]" value="foo"> + <input pattern="[..]" value="foo"> + <input pattern="[::]" value="foo"> + <input pattern="[;;]" value="foo"> + <input pattern="[<<]" value="foo"> + <input pattern="[==]" value="foo"> + <input pattern="[>>]" value="foo"> + <input pattern="[??]" value="foo"> + <input pattern="[@@]" value="foo"> + <input pattern="[``]" value="foo"> + <input pattern="[~~]" value="foo"> + <input pattern="[_^^]" value="foo"> + </div> +</div> +<div id="log"></div> +<script> + test(() => { + const input = document.querySelector("#set-difference"); + assert_false(input.validity.valid); + assert_false(input.matches(":valid")); + assert_true(input.validity.patternMismatch); + }, "<input pattern> supports set difference syntax"); + + test(() => { + const input = document.querySelector("#string-literal"); + assert_false(input.validity.valid); + assert_true(input.validity.patternMismatch); + assert_true(input.matches(":invalid")); + }, "<input pattern> supports string literal syntax"); + + test(() => { + const inputs = document.querySelectorAll(".breaking-changes-from-u-to-v input"); + // These examples are all written such that they’re all `:invalid` + // when using `u`, but would become `:valid` when using `v` because + // the pattern would error, in turn resulting in + // `validity.valid === true`. + for (const input of inputs) { + const html = input.outerHTML; + assert_true(input.validity.valid, `${html} should be valid`); + assert_true(input.matches(":valid"), `${html} should match \`:valid\``); + assert_false(input.validity.patternMismatch, `${html} should not trigger a pattern mismatch`); + } + }, "<input pattern> enables the RegExp v flag"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/preload/modulepreload-as.html.ini b/third_party/blink/web_tests/external/wpt/preload/modulepreload-as.html.ini index 2c0f0a4..5302ddd 100644 --- a/third_party/blink/web_tests/external/wpt/preload/modulepreload-as.html.ini +++ b/third_party/blink/web_tests/external/wpt/preload/modulepreload-as.html.ini
@@ -1,9 +1,9 @@ [modulepreload-as.html] expected: + if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): TIMEOUT if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): OK - if (product == "content_shell") and (os == "mac") and (port == "mac12"): OK if (product == "content_shell") and (os == "mac") and (port == "mac11"): OK - if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): [TIMEOUT, ERROR] + if (product == "content_shell") and (os == "mac") and (port == "mac12"): OK if (product == "content_shell") and (os == "win"): TIMEOUT if product == "chrome": TIMEOUT ERROR @@ -21,44 +21,41 @@ [Modulepreload with as="document"] expected: if (product == "content_shell") and (os == "win") and (port == "win10.20h2"): PASS - if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [FAIL, PASS] if product == "chrome": NOTRUN FAIL [Modulepreload with as="embed"] expected: - if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [FAIL, PASS] if (product == "content_shell") and (os == "win"): PASS if product == "chrome": NOTRUN FAIL [Modulepreload with as="fetch"] expected: + if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL + if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL - if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL - if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL if product == "chrome": NOTRUN [Modulepreload with as="font"] expected: - if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): PASS - if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [FAIL, PASS] if (product == "content_shell") and (os == "win") and (port == "win10.20h2"): PASS + if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): PASS if product == "chrome": NOTRUN FAIL [Modulepreload with as="frame"] expected: - if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): PASS - if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [FAIL, PASS] if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): PASS + if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): PASS if (product == "content_shell") and (os == "win"): PASS if product == "chrome": NOTRUN FAIL [Modulepreload with as="iMaGe"] expected: + if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL @@ -66,21 +63,21 @@ [Modulepreload with as="iframe"] expected: - if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [FAIL, PASS] + if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL + if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL - if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL - if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL + if (product == "content_shell") and (os == "linux") and (flag_specific == ""): FAIL if product == "chrome": NOTRUN [Modulepreload with as="image"] expected: - if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [PASS, FAIL] - if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): PASS - if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): PASS - if (product == "content_shell") and (os == "win"): PASS + if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL + if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): FAIL + if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL + if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL + if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL if product == "chrome": NOTRUN - FAIL [Modulepreload with as="invalid-dest"] expected: @@ -89,19 +86,19 @@ [Modulepreload with as="manifest"] expected: - if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [PASS, FAIL] if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): PASS + if (product == "content_shell") and (os == "linux") and (flag_specific == ""): PASS if (product == "content_shell") and (os == "win"): PASS if product == "chrome": NOTRUN FAIL [Modulepreload with as="object"] expected: - if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL + if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): FAIL if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL + if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL - if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): FAIL if product == "chrome": NOTRUN [Modulepreload with as="paintworklet"] @@ -136,7 +133,6 @@ [Modulepreload with as="style"] expected: - if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [FAIL, PASS] if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): PASS if (product == "content_shell") and (os == "win"): PASS if product == "chrome": NOTRUN @@ -145,14 +141,12 @@ [Modulepreload with as="track"] expected: if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): PASS - if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [FAIL, PASS] if (product == "content_shell") and (os == "win"): PASS if product == "chrome": NOTRUN FAIL [Modulepreload with as="video"] expected: - if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [FAIL, PASS] if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): PASS if (product == "content_shell") and (os == "win"): PASS if product == "chrome": NOTRUN @@ -160,11 +154,11 @@ [Modulepreload with as="webidentity"] expected: - if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [FAIL, PASS] if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL - if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL - if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL + if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL + if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL + if (product == "content_shell") and (os == "linux") and (flag_specific == ""): FAIL if product == "chrome": NOTRUN [Modulepreload with as="worker"] @@ -174,9 +168,9 @@ [Modulepreload with as="xslt"] expected: - if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): PASS - if (product == "content_shell") and (os == "linux") and (flag_specific == ""): [PASS, FAIL] - if (product == "content_shell") and (os == "linux") and (flag_specific == "disable-site-isolation-trials"): PASS - if (product == "content_shell") and (os == "win"): PASS + if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL + if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL + if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): FAIL + if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL + if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL if product == "chrome": NOTRUN - FAIL
diff --git a/third_party/blink/web_tests/external/wpt/shape-detection/single-face-detection.https.html.ini b/third_party/blink/web_tests/external/wpt/shape-detection/single-face-detection.https.html.ini index 7d0ccf1b..1c25528 100644 --- a/third_party/blink/web_tests/external/wpt/shape-detection/single-face-detection.https.html.ini +++ b/third_party/blink/web_tests/external/wpt/shape-detection/single-face-detection.https.html.ini
@@ -1,24 +1,21 @@ [single-face-detection.https.html] expected: - if (product == "content_shell") and (os == "mac") and (port == "mac11"): [OK, TIMEOUT] if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): TIMEOUT - if (product == "content_shell") and (os == "mac") and (port == "mac13"): [OK, TIMEOUT] - if (product == "content_shell") and (os == "mac") and (port == "mac12"): [OK, TIMEOUT] [Blob] expected: FAIL [HTMLCanvasElement] expected: - if (product == "content_shell") and (os == "mac") and (port == "mac11"): PASS - if (product == "content_shell") and (os == "mac") and (port == "mac13"): PASS if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): PASS + if (product == "content_shell") and (os == "mac") and (port == "mac13"): PASS + if (product == "content_shell") and (os == "mac") and (port == "mac11"): PASS FAIL [HTMLImageElement] expected: + if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): PASS if (product == "content_shell") and (os == "mac") and (port == "mac13"): PASS if (product == "content_shell") and (os == "mac") and (port == "mac11"): PASS - if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): PASS FAIL [HTMLVideoElement] @@ -26,25 +23,23 @@ [ImageBitmap] expected: - if (product == "content_shell") and (os == "mac") and (port == "mac12"): PASS - if (product == "content_shell") and (os == "mac") and (port == "mac13"): PASS if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): PASS + if (product == "content_shell") and (os == "mac") and (port == "mac13"): PASS if (product == "content_shell") and (os == "mac") and (port == "mac11"): PASS FAIL [ImageData] expected: - if (product == "content_shell") and (os == "mac") and (port == "mac11"): PASS if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): PASS if (product == "content_shell") and (os == "mac") and (port == "mac13"): PASS - if (product == "content_shell") and (os == "mac") and (port == "mac12"): PASS + if (product == "content_shell") and (os == "mac") and (port == "mac11"): PASS FAIL [OffscreenCanvas] expected: - if (product == "content_shell") and (os == "mac") and (port == "mac11"): PASS if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): PASS if (product == "content_shell") and (os == "mac") and (port == "mac13"): PASS + if (product == "content_shell") and (os == "mac") and (port == "mac11"): PASS FAIL [VideoFrame]
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/full-cycle-test.https.any.js.ini b/third_party/blink/web_tests/external/wpt/webcodecs/full-cycle-test.https.any.js.ini index 32114a1..78a68a5 100644 --- a/third_party/blink/web_tests/external/wpt/webcodecs/full-cycle-test.https.any.js.ini +++ b/third_party/blink/web_tests/external/wpt/webcodecs/full-cycle-test.https.any.js.ini
@@ -1,27 +1,24 @@ [full-cycle-test.https.any.html?h264_annexb] expected: + if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): ERROR + if (product == "content_shell") and (os == "mac") and (port == "mac13"): ERROR if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): TIMEOUT if (product == "content_shell") and (os == "mac") and (port == "mac11"): ERROR - if (product == "content_shell") and (os == "mac") and (port == "mac13"): ERROR - if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): ERROR if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): ERROR + if (product == "content_shell") and (os == "mac") and (port == "mac12"): ERROR [Encoding and decoding cycle] expected: - if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL - if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL - if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL - if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): FAIL - if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): FAIL - PRECONDITION_FAILED + if (product == "content_shell") and (os == "win"): PRECONDITION_FAILED + if (product == "content_shell") and (os == "linux"): PRECONDITION_FAILED + if product == "chrome": PRECONDITION_FAILED + FAIL [Encoding and decoding cycle w/ stripped color space] expected: - if (product == "content_shell") and (os == "mac") and (port == "mac11"): FAIL - if (product == "content_shell") and (os == "mac") and (port == "mac10.15"): FAIL - if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL - if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): FAIL - if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): FAIL - PRECONDITION_FAILED + if (product == "content_shell") and (os == "win"): PRECONDITION_FAILED + if (product == "content_shell") and (os == "linux"): PRECONDITION_FAILED + if product == "chrome": PRECONDITION_FAILED + FAIL [full-cycle-test.https.any.html?h264_avc]
diff --git a/third_party/blink/web_tests/external/wpt/webcodecs/reconfiguring-encoder.https.any.js.ini b/third_party/blink/web_tests/external/wpt/webcodecs/reconfiguring-encoder.https.any.js.ini index bdea86e..ef20bdf 100644 --- a/third_party/blink/web_tests/external/wpt/webcodecs/reconfiguring-encoder.https.any.js.ini +++ b/third_party/blink/web_tests/external/wpt/webcodecs/reconfiguring-encoder.https.any.js.ini
@@ -18,11 +18,13 @@ if (product == "content_shell") and (os == "mac") and (port == "mac13"): ERROR if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): ERROR if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): ERROR + if (product == "content_shell") and (os == "mac") and (port == "mac12"): ERROR [Reconfiguring encoder] expected: - if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL if (product == "content_shell") and (os == "mac") and (port == "mac12-arm64"): FAIL + if (product == "content_shell") and (os == "mac") and (port == "mac12"): FAIL if (product == "content_shell") and (os == "mac") and (port == "mac13-arm64"): FAIL + if (product == "content_shell") and (os == "mac") and (port == "mac13"): FAIL PRECONDITION_FAILED
diff --git a/third_party/qcms/OWNERS b/third_party/qcms/OWNERS index 5489c5f5..4eb0cb4 100644 --- a/third_party/qcms/OWNERS +++ b/third_party/qcms/OWNERS
@@ -1,2 +1 @@ -noel@chromium.org ccameron@chromium.org
diff --git a/third_party/zlib/OWNERS b/third_party/zlib/OWNERS index ecffb59..3a82157 100644 --- a/third_party/zlib/OWNERS +++ b/third_party/zlib/OWNERS
@@ -1,5 +1,4 @@ agl@chromium.org cavalcantii@chromium.org cblume@chromium.org -noel@chromium.org scroggo@google.com
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index e78ac3a..75cf7f2 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -29808,6 +29808,25 @@ </description> </action> +<action name="Settings.PrivacySandbox.RestrictedNotice.ClosedNoInteraction" + not_user_triggered="true"> + <owner>tommasin@chromium.org</owner> + <owner>kartoffel-core@google.com</owner> + <owner>kartoffel-core-eng@google.com</owner> + <description> + Restricted Notice closed with no interaction (e.g. browser shutdown). + </description> +</action> + +<action name="Settings.PrivacySandbox.RestrictedNotice.MoreButtonClicked"> + <owner>tommasin@chromium.org</owner> + <owner>kartoffel-core@google.com</owner> + <owner>kartoffel-core-eng@google.com</owner> + <description> + User clicked on the More button in the Privacy Sandbox Restricted Notice. + </description> +</action> + <action name="Settings.PrivacySandbox.RestrictedNotice.OpenedSettings"> <owner>djmitche@chromium.org</owner> <owner>kartoffel-core@google.com</owner> @@ -29817,6 +29836,14 @@ </description> </action> +<action name="Settings.PrivacySandbox.RestrictedNotice.Shown" + not_user_triggered="true"> + <owner>tommasin@chromium.org</owner> + <owner>kartoffel-core@google.com</owner> + <owner>kartoffel-core-eng@google.com</owner> + <description>Restricted Privacy Sandbox notice is shown.</description> +</action> + <action name="Settings.PrivacySandbox.SpamFraud.Opened"> <owner>dullweber@google.com</owner> <owner>sauski@google.com</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 6ec96d7e..404d343 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -42686,6 +42686,7 @@ <int value="4578" label="LongAnimationFrameRequested"/> <int value="4579" label="FedCmLoginHint"/> <int value="4580" label="FedCmRpContext"/> + <int value="4581" label="EventTimingArtificialPointerupOrClick"/> </enum> <enum name="FeaturePolicyAllowlistType"> @@ -62485,6 +62486,7 @@ <int value="-236433493" label="ArcKeyboardShortcutHelperIntegration:enabled"/> <int value="-236310717" label="AccessibilityDeprecateChromeVoxTabs:disabled"/> <int value="-236071174" label="NearbyShareVisibilityReminder:disabled"/> + <int value="-236058937" label="UseGpuSchedulerDfs:disabled"/> <int value="-235949168" label="DrawPredictedInkPoint:enabled"/> <int value="-235843754" label="OmniboxGroupingFrameworkForNonZPS:disabled"/> <int value="-234966279" label="PointerEvent:disabled"/> @@ -66197,6 +66199,7 @@ label="OmniboxUIExperimentBoldUserTextOnSearchSuggestions:enabled"/> <int value="1743151811" label="CommerceLocalPDPDetection:disabled"/> <int value="1743603853" label="CameraAppDocScanDlc:disabled"/> + <int value="1744034696" label="UseGpuSchedulerDfs:enabled"/> <int value="1745053254" label="ClickToCallOpenDialerDirectly:enabled"/> <int value="1747279677" label="disable-delegated-renderer"/> <int value="1748481830" label="AppManagement:enabled"/> @@ -103069,6 +103072,7 @@ <int value="2" label="Reauthentication failed"/> <int value="3" label="'Manage Passwords' was selected"/> <int value="4" label="Passkey was selected"/> + <int value="5" label="Hybrid passkey sign-in was selected"/> </enum> <enum name="TouchToFill.SubmissionReadiness"> @@ -103088,6 +103092,7 @@ <int value="1" label="Dismissed"/> <int value="2" label="Selected Manage Passwords"/> <int value="3" label="Selected WebAuthn Credential"/> + <int value="4" label="Selected Hybrid"/> </enum> <enum name="TouchType"> @@ -111519,18 +111524,6 @@ <int value="11" label="Delete all site entries for a FPS owner"/> </enum> -<enum name="WebsiteSettingsDiscoverabilityAction"> - <int value="0" label="Permission icon shown in omnibox"/> - <int value="1" - label="Page info opened while permission icon was shown in omnibox"/> - <int value="2" label="Permissions opened after click on permissions icon"/> - <int value="3" label="Permission changed after click on permissions icon"/> - <int value="4" label="Store icon shown in omnibox"/> - <int value="5" - label="Page info opened while store icon was shown in omnibox"/> - <int value="6" label="Store info opened after click on store icon"/> -</enum> - <enum name="WebSocketCloseCode"> <int value="0" label="Normal Closure">1000</int> <int value="1" label="Going Away">1001</int>
diff --git a/tools/metrics/histograms/metadata/accessibility/histograms.xml b/tools/metrics/histograms/metadata/accessibility/histograms.xml index e81b13d..a0954ca 100644 --- a/tools/metrics/histograms/metadata/accessibility/histograms.xml +++ b/tools/metrics/histograms/metadata/accessibility/histograms.xml
@@ -1824,6 +1824,35 @@ </summary> </histogram> +<histogram name="Accessibility.ReadAnything.MergedDistillationTime.{Result}" + units="ms" expires_after="2023-11-30"> + <owner>abigailbklein@google.com</owner> + <owner>chrome-a11y-core@google.com</owner> + <summary> + Records the time taken to distill a web page using the merged algorithm that + combines results from the rules based algorithm and the ML model. Refer to + AXTreeDistiller::Distill for details. + </summary> + <token key="Result"> + <variant name="Failure" summary="has failed"/> + <variant name="Success" summary="has succeeded"/> + </token> +</histogram> + +<histogram name="Accessibility.ReadAnything.RulesDistillationTime.{Result}" + units="ms" expires_after="2023-11-30"> + <owner>abigailbklein@google.com</owner> + <owner>chrome-a11y-core@google.com</owner> + <summary> + Records the time taken to distill a web page using the rules based + algorithm. Refer to AXTreeDistiller::DistillViaAlgorithm for details. + </summary> + <token key="Result"> + <variant name="Failure" summary="has failed"/> + <variant name="Success" summary="has succeeded"/> + </token> +</histogram> + <histogram name="Accessibility.ReadAnything.ScrollEvent" enum="ReadAnythingScrollEvent" expires_after="2023-11-30"> <owner>abigailbklein@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/content/histograms.xml b/tools/metrics/histograms/metadata/content/histograms.xml index 1c7dd2c..b11107d 100644 --- a/tools/metrics/histograms/metadata/content/histograms.xml +++ b/tools/metrics/histograms/metadata/content/histograms.xml
@@ -2012,6 +2012,25 @@ </token> </histogram> +<histogram name="ContentSuggestions.{FeedType}.Activity.ByProvider" + enum="FeedActivityBucket" expires_after="2023-11-24"> + <owner>guiperez@google.com</owner> + <owner>feed@chromium.org</owner> + <summary> + Tracks user activity buckets for the filter. Reported every time a metric is + reported through the MetricsProvider to allow filtering. The histogram used + for analysis is ContentSuggestions.{FeedType}.Activity, whilst this one will + only be used for the filter. Any changes to + ContentSuggestions.{FeedType}.Activity will also change how this metric is + reported. + </summary> + <token key="FeedType"> + <variant name="Feed" summary="the For-You feed"/> + <variant name="Feed.AllFeeds" summary="All Feeds combined"/> + <variant name="Feed.WebFeed" summary="the Following/Web Feed"/> + </token> +</histogram> + <histogram name="ContentSuggestions.{FeedType}.CardIndexOnSwitch" units="index" expires_after="2023-04-21"> <owner>adamta@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/ios/histograms.xml b/tools/metrics/histograms/metadata/ios/histograms.xml index 4ce29de4..93fe119f 100644 --- a/tools/metrics/histograms/metadata/ios/histograms.xml +++ b/tools/metrics/histograms/metadata/ios/histograms.xml
@@ -1735,7 +1735,7 @@ </histogram> <histogram name="IOS.PostRestoreSignin.Choice" - enum="IOSPostRestoreSigninChoice" expires_after="2023-06-15"> + enum="IOSPostRestoreSigninChoice" expires_after="2023-10-15"> <owner>scottyoder@google.com</owner> <owner>bling-get-set-up@google.com</owner> <summary> @@ -1744,7 +1744,7 @@ </histogram> <histogram name="IOS.PostRestoreSignin.Displayed" enum="Boolean" - expires_after="2023-06-15"> + expires_after="2023-10-15"> <owner>scottyoder@google.com</owner> <owner>bling-get-set-up@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/optimization/histograms.xml b/tools/metrics/histograms/metadata/optimization/histograms.xml index bc81611..8b7d5a6 100644 --- a/tools/metrics/histograms/metadata/optimization/histograms.xml +++ b/tools/metrics/histograms/metadata/optimization/histograms.xml
@@ -167,7 +167,7 @@ </variants> <histogram name="OptimizationGuide.ApplyDecision.{OptimizationType}" - enum="OptimizationGuideOptimizationTypeDecision" expires_after="M117"> + enum="OptimizationGuideOptimizationTypeDecision" expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>mcrouse@chromium.org</owner> <summary> @@ -178,7 +178,7 @@ </histogram> <histogram name="OptimizationGuide.ApplyDecisionAsync.{OptimizationType}" - enum="OptimizationGuideOptimizationTypeDecision" expires_after="M117"> + enum="OptimizationGuideOptimizationTypeDecision" expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>mcrouse@chromium.org</owner> <summary> @@ -192,7 +192,7 @@ </histogram> <histogram name="OptimizationGuide.ClearFetchedHints.StoreAvailable" - enum="BooleanAvailable" expires_after="M117"> + enum="BooleanAvailable" expires_after="M121"> <owner>mcrouse@chromium.org</owner> <owner>sophiechang@chromium.org</owner> <summary> @@ -226,7 +226,7 @@ </histogram> <histogram name="OptimizationGuide.HintCache.HintType.Loaded" - enum="HintCacheStoreEntryType" expires_after="M117"> + enum="HintCacheStoreEntryType" expires_after="M121"> <owner>mcrouse@chromium.org</owner> <owner>sophiechang@chromium.org</owner> <summary> @@ -258,7 +258,7 @@ <histogram name="OptimizationGuide.HintsFetcher.GetHintsRequest.ActiveRequestCanceled.{RequestContext}" - units="counts" expires_after="M117"> + units="counts" expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>mcrouse@chromium.org</owner> <summary> @@ -270,7 +270,7 @@ <histogram name="OptimizationGuide.HintsFetcher.GetHintsRequest.DroppedHosts.{RequestContext}" - units="counts" expires_after="M117"> + units="counts" expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>mcrouse@chromium.org</owner> <summary> @@ -283,7 +283,7 @@ <histogram name="OptimizationGuide.HintsFetcher.GetHintsRequest.DroppedUrls.{RequestContext}" - units="counts" expires_after="M117"> + units="counts" expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>mcrouse@chromium.org</owner> <summary> @@ -296,7 +296,7 @@ <histogram name="OptimizationGuide.HintsFetcher.GetHintsRequest.FetchLatency.{RequestContext}" - units="ms" expires_after="M117"> + units="ms" expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>mcrouse@chromium.org</owner> <summary> @@ -318,7 +318,7 @@ </histogram> <histogram name="OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount" - units="total host count" expires_after="M117"> + units="total host count" expires_after="M121"> <owner>mcrouse@chromium.org</owner> <owner>sophiechang@chromium.org</owner> <summary> @@ -358,7 +358,7 @@ </histogram> <histogram name="OptimizationGuide.HintsFetcher.RequestStatus.{RequestContext}" - enum="OptimizationGuideHintsFetcherRequestStatus" expires_after="M117"> + enum="OptimizationGuideHintsFetcherRequestStatus" expires_after="M121"> <owner>mcrouse@chromium.org</owner> <owner>sophiechang@chromium.org</owner> <summary> @@ -406,7 +406,7 @@ <histogram name="OptimizationGuide.HintsManager.PageNavigationHintsReturnedBeforeDataFlushed" - enum="BooleanStored" expires_after="M117"> + enum="BooleanStored" expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>mcrouse@chromium.org</owner> <summary> @@ -430,7 +430,7 @@ </histogram> <histogram name="OptimizationGuide.IsPredictionModelValid.{OptimizationTarget}" - enum="BooleanValid" expires_after="M117"> + enum="BooleanValid" expires_after="M121"> <owner>mcrouse@chromium.org</owner> <owner>sophiechang@chromium.org</owner> <summary> @@ -442,7 +442,7 @@ </histogram> <histogram name="OptimizationGuide.MetadataFetchValidation.Result" - enum="Boolean" expires_after="M117"> + enum="Boolean" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -453,7 +453,7 @@ <histogram name="OptimizationGuide.ModelExecutor.DidTimeout.{OptimizationTarget}" - enum="Boolean" expires_after="M117"> + enum="Boolean" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -466,7 +466,7 @@ <histogram name="OptimizationGuide.ModelExecutor.ExecutionLatency.{OptimizationTarget}" - units="ms" expires_after="M117"> + units="ms" expires_after="M121"> <owner>mcrouse@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -480,7 +480,7 @@ <histogram name="OptimizationGuide.ModelExecutor.ExecutionStatus.{OptimizationTarget}" - enum="OptimizationGuideExecutionStatus" expires_after="M117"> + enum="OptimizationGuideExecutionStatus" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -494,7 +494,7 @@ <histogram name="OptimizationGuide.ModelExecutor.ExecutionThreadTime.{OptimizationTarget}" - units="ms" expires_after="M117"> + units="ms" expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -510,7 +510,7 @@ <histogram name="OptimizationGuide.ModelExecutor.ExecutionThreadTimeMicroseconds.{OptimizationTarget}" - units="microseconds" expires_after="M117"> + units="microseconds" expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -524,7 +524,7 @@ <histogram name="OptimizationGuide.ModelExecutor.ModelAvailableToLoad.{OptimizationTarget}" - enum="BooleanAvailable" expires_after="M117"> + enum="BooleanAvailable" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -541,7 +541,7 @@ <histogram name="OptimizationGuide.ModelExecutor.ModelLoadingDuration2.{OptimizationTarget}" - units="ms" expires_after="M117"> + units="ms" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -554,7 +554,7 @@ <histogram name="OptimizationGuide.ModelExecutor.TaskExecutionLatency.{OptimizationTarget}" - units="ms" expires_after="M117"> + units="ms" expires_after="M121"> <owner>mcrouse@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -572,7 +572,7 @@ <histogram name="OptimizationGuide.ModelExecutor.TaskSchedulingLatency.{OptimizationTarget}" - units="ms" expires_after="M117"> + units="ms" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -586,7 +586,7 @@ <histogram name="OptimizationGuide.ModelExecutor.TimeSincePreviousRun.{OptimizationTarget}" - units="ms" expires_after="M117"> + units="ms" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -598,7 +598,7 @@ </histogram> <histogram name="OptimizationGuide.ModelFilesVerified.{OptimizationTarget}" - enum="BooleanValid" expires_after="M117"> + enum="BooleanValid" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -613,7 +613,7 @@ <histogram name="OptimizationGuide.ModelHandler.HandlerCreated.{OptimizationTarget}" - enum="BooleanCreated" expires_after="M117"> + enum="BooleanCreated" expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -626,7 +626,7 @@ <histogram name="OptimizationGuide.ModelHandler.HandlerCreatedToModelAvailable.{OptimizationTarget}" - units="ms" expires_after="M117"> + units="ms" expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -638,7 +638,7 @@ </histogram> <histogram name="OptimizationGuide.OptimizationFilterStatus.{OptimizationType}" - enum="OptimizationGuideOptimizationFilterStatus" expires_after="M117"> + enum="OptimizationGuideOptimizationFilterStatus" expires_after="M121"> <owner>mcrouse@chromium.org</owner> <owner>sophiechang@chromium.org</owner> <summary> @@ -650,7 +650,7 @@ </histogram> <histogram name="OptimizationGuide.OptimizationHintsComponent.MajorVersion" - units="major version number" expires_after="M117"> + units="major version number" expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>mcrouse@chromium.org</owner> <summary> @@ -674,7 +674,7 @@ <histogram name="OptimizationGuide.PageContentAnnotations.BatchRequestedSize.{AnnotationType}" - units="counts" expires_after="M117"> + units="counts" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -686,7 +686,7 @@ <histogram name="OptimizationGuide.PageContentAnnotations.BatchSuccess.{AnnotationType}" - enum="BooleanSuccess" expires_after="M117"> + enum="BooleanSuccess" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -724,7 +724,7 @@ <histogram name="OptimizationGuide.PageContentAnnotations.JobExecutionTime.{AnnotationType}" - units="ms" expires_after="M117"> + units="ms" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -736,7 +736,7 @@ <histogram name="OptimizationGuide.PageContentAnnotations.JobScheduleTime.{AnnotationType}" - units="ms" expires_after="M117"> + units="ms" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -771,7 +771,7 @@ <histogram name="OptimizationGuide.PageContentAnnotationsService.ContentAnnotated" - enum="BooleanAnnotated" expires_after="M117"> + enum="BooleanAnnotated" expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>mcrouse@chromium.org</owner> <summary> @@ -801,7 +801,7 @@ <histogram name="OptimizationGuide.PageContentAnnotationsService.ContentAnnotationsStorageMinMagnitudeForVisitNotFound.{PageContentAnnotationsStorageType}" - units="ms" expires_after="M117"> + units="ms" expires_after="M121"> <obsolete> Obsolete as of 04/2023. </obsolete> @@ -835,7 +835,7 @@ <histogram name="OptimizationGuide.PageContentAnnotationsService.ContentAnnotationsStorageStatus.{PageContentAnnotationsStorageType}" enum="OptimizationGuidePageContentAnnotationsStorageStatus" - expires_after="M117"> + expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>mcrouse@chromium.org</owner> <summary> @@ -984,7 +984,7 @@ </histogram> <histogram name="OptimizationGuide.PageTextDump.AbandonedRequests" - units="count" expires_after="M117"> + units="count" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -996,7 +996,7 @@ <histogram name="OptimizationGuide.PageTextDump.FrameDumpLength.{PageTextDumpEvent}" - units="bytes" expires_after="M117"> + units="bytes" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -1009,7 +1009,7 @@ <histogram name="OptimizationGuide.PageTextDump.OutstandingRequests.DidFinishLoad" - units="count" expires_after="M117"> + units="count" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -1019,7 +1019,7 @@ <histogram name="OptimizationGuide.PageTextDump.TimeUntilFrameDisconnected.{PageTextDumpEvent}" - units="ms" expires_after="M117"> + units="ms" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -1032,7 +1032,7 @@ <histogram name="OptimizationGuide.PageTextDump.TimeUntilFrameDumpCompleted.{PageTextDumpEvent}" - units="ms" expires_after="M117"> + units="ms" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -1061,7 +1061,7 @@ </histogram> <histogram name="OptimizationGuide.PageTopicsOverrideList.GotFile" - enum="Boolean" expires_after="M117"> + enum="Boolean" expires_after="M121"> <obsolete> Removed in M115. </obsolete> @@ -1099,7 +1099,7 @@ <histogram name="OptimizationGuide.PredictionManager.FirstModelFetchSinceServiceInit" - units="ms" expires_after="M117"> + units="ms" expires_after="M121"> <owner>rajendrant@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -1125,7 +1125,7 @@ <histogram name="OptimizationGuide.PredictionManager.IsDownloadUrlValid.{OptimizationTarget}" - enum="BooleanValid" expires_after="M117"> + enum="BooleanValid" expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>mcrouse@chromium.org</owner> <summary> @@ -1137,7 +1137,7 @@ <histogram name="OptimizationGuide.PredictionManager.ModelAvailableAtRegistration.{OptimizationTarget}" - enum="BooleanAvailable" expires_after="M117"> + enum="BooleanAvailable" expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>mcrouse@chromium.org</owner> <summary> @@ -1151,7 +1151,7 @@ <histogram name="OptimizationGuide.PredictionManager.ModelDeliveryEvents.{OptimizationTarget}" - enum="OptimizationGuideModelDeliveryEvent" expires_after="M117"> + enum="OptimizationGuideModelDeliveryEvent" expires_after="M121"> <owner>rajendrant@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -1181,7 +1181,7 @@ <histogram name="OptimizationGuide.PredictionManager.RegistrationTimeSinceServiceInit.{OptimizationTarget}" - units="ms" expires_after="M117"> + units="ms" expires_after="M121"> <owner>rajendrant@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -1195,7 +1195,7 @@ <histogram name="OptimizationGuide.PredictionModelDownloadManager.DownloadStartLatency.{OptimizationTarget}" - units="ms" expires_after="M117"> + units="ms" expires_after="M121"> <owner>rajendrant@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -1232,7 +1232,7 @@ <histogram name="OptimizationGuide.PredictionModelDownloadManager.ReplaceFileError.{OptimizationTarget}" - enum="PlatformFileError" expires_after="M117"> + enum="PlatformFileError" expires_after="M121"> <owner>mcrouse@chromium.org</owner> <owner>sophiechang@chromium.org</owner> <summary> @@ -1246,7 +1246,7 @@ <histogram name="OptimizationGuide.PredictionModelDownloadManager.State.{OptimizationTarget}" - enum="OptimizationGuidePredictionModelDownloadState" expires_after="M117"> + enum="OptimizationGuidePredictionModelDownloadState" expires_after="M121"> <owner>rajendrant@chromium.org</owner> <owner>sophiechang@chromium.org</owner> <summary> @@ -1257,7 +1257,7 @@ </histogram> <histogram name="OptimizationGuide.PredictionModelExpired.{OptimizationTarget}" - enum="BooleanExpired" expires_after="M117"> + enum="BooleanExpired" expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -1271,7 +1271,7 @@ <histogram name="OptimizationGuide.PredictionModelExpiredVersion.{OptimizationTarget}" - units="version number" expires_after="M117"> + units="version number" expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -1299,7 +1299,7 @@ <histogram name="OptimizationGuide.PredictionModelFetcher.GetModelsResponse.NetErrorCode.{OptimizationTarget}" - enum="NetErrorCodes" expires_after="M117"> + enum="NetErrorCodes" expires_after="M121"> <owner>mcrouse@chromium.org</owner> <owner>sophiechang@chromium.org</owner> <summary> @@ -1329,7 +1329,7 @@ <histogram name="OptimizationGuide.PredictionModelFetcher.GetModelsResponse.Status.{OptimizationTarget}" - enum="HttpResponseCode" expires_after="M117"> + enum="HttpResponseCode" expires_after="M121"> <owner>mcrouse@chromium.org</owner> <owner>sophiechang@chromium.org</owner> <summary> @@ -1345,7 +1345,7 @@ <histogram name="OptimizationGuide.PredictionModelLoadedVersion.{OptimizationTarget}" - units="version number" expires_after="M117"> + units="version number" expires_after="M121"> <owner>mcrouse@chromium.org</owner> <owner>sophiechang@chromium.org</owner> <summary> @@ -1372,7 +1372,7 @@ <histogram name="OptimizationGuide.PredictionModelStore.ModelCount.{OptimizationTarget}" - units="counts" expires_after="M117"> + units="counts" expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>rajendrant@chromium.org</owner> <summary> @@ -1395,7 +1395,7 @@ <histogram name="OptimizationGuide.PredictionModelStore.TotalDirectorySize.{OptimizationTarget}" - units="MB" expires_after="M117"> + units="MB" expires_after="M121"> <owner>sophiechang@chromium.org</owner> <owner>rajendrant@chromium.org</owner> <summary> @@ -1407,7 +1407,7 @@ <histogram name="OptimizationGuide.PredictionModelUpdateVersion.{OptimizationTarget}" - units="version number" expires_after="M117"> + units="version number" expires_after="M121"> <owner>mcrouse@chromium.org</owner> <owner>sophiechang@chromium.org</owner> <summary> @@ -1419,7 +1419,7 @@ <histogram name="OptimizationGuide.PredictionModelValidationLatency.{OptimizationTarget}" - units="ms" expires_after="M117"> + units="ms" expires_after="M121"> <owner>mcrouse@chromium.org</owner> <owner>sophiechang@chromium.org</owner> <summary> @@ -1443,7 +1443,7 @@ </histogram> <histogram name="OptimizationGuide.ProcessingComponentAtShutdown" - enum="BooleanYesNo" expires_after="M117"> + enum="BooleanYesNo" expires_after="M121"> <owner>mcrouse@chromium.org</owner> <owner>sophiechang@chromium.org</owner> <summary> @@ -1453,7 +1453,7 @@ </histogram> <histogram name="OptimizationGuide.PushNotifications.CachedNotificationCount" - units="count" expires_after="M117"> + units="count" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -1465,7 +1465,7 @@ <histogram name="OptimizationGuide.PushNotifications.CachedNotificationsHandledSuccessfully" - enum="BooleanSuccess" expires_after="M117"> + enum="BooleanSuccess" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -1475,7 +1475,7 @@ </histogram> <histogram name="OptimizationGuide.PushNotifications.DidOverflow" - enum="Boolean" expires_after="M117"> + enum="Boolean" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -1485,7 +1485,7 @@ </histogram> <histogram name="OptimizationGuide.PushNotifications.GotPushNotification" - enum="Boolean" expires_after="M117"> + enum="Boolean" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary>Records a true sample for every incoming push notification.</summary> @@ -1493,7 +1493,7 @@ <histogram name="OptimizationGuide.PushNotifications.PushNotificationHandledSuccessfully" - enum="BooleanSuccess" expires_after="M117"> + enum="BooleanSuccess" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -1503,7 +1503,7 @@ </histogram> <histogram name="OptimizationGuide.PushNotifications.ReadCacheResult" - enum="OptimizationGuideReadCacheResult" expires_after="M117"> + enum="OptimizationGuideReadCacheResult" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary> @@ -1514,7 +1514,7 @@ </histogram> <histogram name="OptimizationGuide.PushNotifications.ReceivedNotificationType" - enum="OptimizationType" expires_after="M117"> + enum="OptimizationType" expires_after="M121"> <owner>robertogden@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/permissions/histograms.xml b/tools/metrics/histograms/metadata/permissions/histograms.xml index 85cfb93..c71f098 100644 --- a/tools/metrics/histograms/metadata/permissions/histograms.xml +++ b/tools/metrics/histograms/metadata/permissions/histograms.xml
@@ -1486,55 +1486,6 @@ </summary> </histogram> -<histogram name="WebsiteSettings.Discoverability.Action" - enum="WebsiteSettingsDiscoverabilityAction" expires_after="2023-06-18"> - <owner>eokoyomon@chromium.org</owner> - <owner>dullweber@chromium.org</owner> - <summary> - Tracks actions related to page info when discoverability has been activated. - </summary> -</histogram> - -<histogram name="WebsiteSettings.Discoverability.TimeToClickHighlight" - units="ms" expires_after="M98"> - <owner>eokoyomon@chromium.org</owner> - <owner>dullweber@chromium.org</owner> - <summary> - Records the amount of time between when the page info is opened and the - highlighted permissions section is clicked. - </summary> -</histogram> - -<histogram name="WebsiteSettings.Discoverability.TimeToClickHighlightStoreInfo" - units="ms" expires_after="2022-12-01"> - <owner>zhiyuancai@chromium.org</owner> - <owner>chrome-shopping@google.com</owner> - <summary> - Records the amount of time between when the page info is opened and the - highlighted store info section is clicked. - </summary> -</histogram> - -<histogram name="WebsiteSettings.Discoverability.TimeToOpen" units="ms" - expires_after="2023-02-19"> - <owner>eokoyomon@chromium.org</owner> - <owner>dullweber@chromium.org</owner> - <summary> - Records the amount of time the discoverability icon is shown in the omnibox - before the user clicks into page info. - </summary> -</histogram> - -<histogram name="WebsiteSettings.Discoverability.TimeToOpenFromStoreIcon" - units="ms" expires_after="2022-12-01"> - <owner>zhiyuancai@chromium.org</owner> - <owner>chrome-shopping@google.com</owner> - <summary> - Records the amount of time the store icon is shown in the omnibox before the - user clicks into page info. - </summary> -</histogram> - <histogram name="WebsiteSettings.GetAllSitesLoadTime" units="ms" expires_after="2023-10-22"> <owner>olesiamarukhno@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/tab/histograms.xml b/tools/metrics/histograms/metadata/tab/histograms.xml index 1465d3f..2ed2c18 100644 --- a/tools/metrics/histograms/metadata/tab/histograms.xml +++ b/tools/metrics/histograms/metadata/tab/histograms.xml
@@ -1160,6 +1160,26 @@ </token> </histogram> +<histogram name="Tabs.Active.AbsolutePosition" units="index" + expires_after="2023-12-31"> + <owner>emshack@chromium.org</owner> + <owner>chrome-desktop-ui-sea@google.com</owner> + <summary> + When a tab is activated, records the index of that tab in the tab strip, + starting at 1 (1-indexed). + </summary> +</histogram> + +<histogram name="Tabs.Active.RelativePosition" units="%" + expires_after="2023-12-31"> + <owner>emshack@chromium.org</owner> + <owner>chrome-desktop-ui-sea@google.com</owner> + <summary> + When a tab is activated, records the index of that tab in the tab strip as a + percentage of the total number of tabs. + </summary> +</histogram> + <histogram name="Tabs.ActiveCountAtStartup" units="tabs" expires_after="2023-10-01"> <owner>alionadangla@chromium.org</owner> @@ -1352,6 +1372,25 @@ </summary> </histogram> +<histogram name="Tabs.PageLoad.TimeSinceActive" units="ms" + expires_after="2023-12-31"> + <owner>emshack@chromium.org</owner> + <owner>chrome-desktop-ui-sea@google.com</owner> + <summary> + On page load, records the time since last active for each tab in the tab + strip. + </summary> +</histogram> + +<histogram name="Tabs.PageLoad.TimeSinceCreated" units="ms" + expires_after="2023-12-31"> + <owner>emshack@chromium.org</owner> + <owner>chrome-desktop-ui-sea@google.com</owner> + <summary> + On page load, records the time since creation for each tab in the tab strip. + </summary> +</histogram> + <histogram name="Tabs.PersistedTabData.Critical.Map.Success" enum="BooleanSuccess" expires_after="2024-01-08"> <owner>davidjm@chromium.org</owner>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 6214062..cea5d5a 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -176,6 +176,65 @@ </metric> </event> +<event name="Accessibility.ReadAnything"> + <owner>abigailbklein@google.com</owner> + <summary> + Records the time taken to distill a web page. + </summary> + <metric name="MergedDistillationTime.Failure"> + <summary> + The amount of time (ms) required to distill a web page with the merged + algorithm if distillation failed. + </summary> + <aggregation> + <history> + <statistics> + <quantiles type="std-percentiles"/> + </statistics> + </history> + </aggregation> + </metric> + <metric name="MergedDistillationTime.Success"> + <summary> + The amount of time (ms) required to distill a web page with the merged + algorithm if distillation succeeded. + </summary> + <aggregation> + <history> + <statistics> + <quantiles type="std-percentiles"/> + </statistics> + </history> + </aggregation> + </metric> + <metric name="RulesDistillationTime.Failure"> + <summary> + The amount of time (ms) required to distill a web page with the rules + based algorithm if distillation failed. + </summary> + <aggregation> + <history> + <statistics> + <quantiles type="std-percentiles"/> + </statistics> + </history> + </aggregation> + </metric> + <metric name="RulesDistillationTime.Success"> + <summary> + The amount of time (ms) required to distill a web page with the rules + based algorithm if distillation succeeded. + </summary> + <aggregation> + <history> + <statistics> + <quantiles type="std-percentiles"/> + </statistics> + </history> + </aggregation> + </metric> +</event> + <event name="Accessibility.Renderer"> <owner>aleventhal@chromium.org</owner> <owner>nektar@chromium.org</owner>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 124c69c..7ddccb2 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -6,7 +6,7 @@ }, "win": { "hash": "7fc90812791d74914cbeb83830922c679e81110a", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/957e728e6dc3cd807cbbb25fbd0a9fc739d72603/trace_processor_shell.exe" + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/bcbe569710dbd97b0d7d9e95d87e93be7d1f8065/trace_processor_shell.exe" }, "linux_arm": { "hash": "336a42cb9ec3c417e13a97816271fec10cdf67e5", @@ -21,8 +21,8 @@ "full_remote_path": "perfetto-luci-artifacts/v34.0/mac-arm64/trace_processor_shell" }, "linux": { - "hash": "1fb5ba5a9d703de86025743e3cb7222fe73e028e", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/bcbe569710dbd97b0d7d9e95d87e93be7d1f8065/trace_processor_shell" + "hash": "0eadb7dcd4b7a7845660666a66c756b4e00e14bb", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/55c4abdb8736d8618e0d6c1c0c6a7df5a41559a0/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index 6aa9eb6..15616ccd 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -195,7 +195,7 @@ <item id="reporting" added_in_milestone="62" content_hash_code="077eedd0" os_list="linux,windows,chromeos,android" file_path="net/reporting/reporting_uploader.cc" /> <item id="rlz_ping" added_in_milestone="63" content_hash_code="06160e82" os_list="windows,chromeos" file_path="rlz/lib/financial_ping.cc" /> <item id="safe_browsing_binary_upload_app" added_in_milestone="87" content_hash_code="03da20b9" os_list="linux,windows,chromeos" file_path="chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service.cc" /> - <item id="safe_browsing_binary_upload_connector" added_in_milestone="87" content_hash_code="031b9017" os_list="linux,windows,chromeos" file_path="chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service.cc" /> + <item id="safe_browsing_binary_upload_connector" added_in_milestone="87" content_hash_code="03c0c06a" os_list="linux,windows,chromeos" file_path="chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service.cc" /> <item id="safe_browsing_cache_collector" added_in_milestone="62" content_hash_code="03b69135" os_list="linux,windows,chromeos,android" file_path="components/safe_browsing/content/browser/threat_details_cache.cc" /> <item id="safe_browsing_certificate_error_reporting" added_in_milestone="62" content_hash_code="018e6226" os_list="linux,windows,chromeos,android" file_path="chrome/browser/ssl/certificate_error_reporter.cc" /> <item id="safe_browsing_client_side_phishing_detector" added_in_milestone="62" content_hash_code="018611e2" os_list="linux,windows,chromeos,android" file_path="components/safe_browsing/content/browser/client_side_detection_service.cc" />
diff --git a/ui/accelerated_widget_mac/ca_layer_tree_unittest_mac.mm b/ui/accelerated_widget_mac/ca_layer_tree_unittest_mac.mm index 9356415..e653b69 100644 --- a/ui/accelerated_widget_mac/ca_layer_tree_unittest_mac.mm +++ b/ui/accelerated_widget_mac/ca_layer_tree_unittest_mac.mm
@@ -5,6 +5,7 @@ #import <AVFoundation/AVFoundation.h> #include <memory> +#include "base/test/scoped_feature_list.h" #include "gpu/GLES2/gl2extchromium.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest_mac.h" @@ -193,8 +194,8 @@ gfx::Rect([content_layer bounds])); EXPECT_EQ(kCALayerLeftEdge, [content_layer edgeAntialiasingMask]); EXPECT_EQ(properties.opacity, [content_layer opacity]); - EXPECT_NSEQ(kCAFilterLinear, [content_layer minificationFilter]); - EXPECT_NSEQ(kCAFilterLinear, [content_layer magnificationFilter]); + EXPECT_NSEQ(kCAFilterNearest, [content_layer minificationFilter]); + EXPECT_NSEQ(kCAFilterNearest, [content_layer magnificationFilter]); EXPECT_EQ(properties.scale_factor, [content_layer contentsScale]); } @@ -758,6 +759,9 @@ // Test updating each layer's properties. TEST_F(CALayerTreeTest, AVLayer) { + base::test::ScopedFeatureList features; + features.InitWithFeatures({ui::kFullscreenLowPowerBackdropMac}, {}); + CALayerProperties properties; properties.io_surface = CreateScopedIOSurface(gfx::Size(256, 256), gfx::BufferFormat::BGRA_8888); @@ -862,6 +866,9 @@ // Ensure that blocklisting AVSampleBufferDisplayLayer works. TEST_F(CALayerTreeTest, AVLayerBlocklist) { + base::test::ScopedFeatureList features; + features.InitWithFeatures({ui::kFullscreenLowPowerBackdropMac}, {}); + CALayerProperties properties; properties.io_surface = CreateScopedIOSurface( gfx::Size(256, 256), gfx::BufferFormat::YUV_420_BIPLANAR); @@ -919,6 +926,9 @@ // Test fullscreen low power detection. TEST_F(CALayerTreeTest, FullscreenLowPower) { + base::test::ScopedFeatureList features; + features.InitWithFeatures({ui::kFullscreenLowPowerBackdropMac}, {}); + CALayerProperties properties; properties.io_surface = CreateScopedIOSurface( gfx::Size(256, 256), gfx::BufferFormat::YUV_420_BIPLANAR);
diff --git a/ui/accelerated_widget_mac/ca_renderer_layer_tree.h b/ui/accelerated_widget_mac/ca_renderer_layer_tree.h index 4dfdcb81..88b043a 100644 --- a/ui/accelerated_widget_mac/ca_renderer_layer_tree.h +++ b/ui/accelerated_widget_mac/ca_renderer_layer_tree.h
@@ -13,6 +13,7 @@ #include <memory> #include "base/containers/flat_map.h" +#include "base/feature_list.h" #include "base/mac/scoped_cftyperef.h" #include "base/mac/scoped_nsobject.h" #include "base/memory/raw_ptr.h" @@ -32,6 +33,10 @@ namespace ui { +ACCELERATED_WIDGET_MAC_EXPORT BASE_DECLARE_FEATURE( + kFullscreenLowPowerBackdropMac); +ACCELERATED_WIDGET_MAC_EXPORT BASE_DECLARE_FEATURE(kCALayerTreeOptimization); + struct CARendererLayerParams; enum class CALayerType {
diff --git a/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm b/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm index bef1a3c9..59876c5 100644 --- a/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm +++ b/ui/accelerated_widget_mac/ca_renderer_layer_tree.mm
@@ -12,7 +12,6 @@ #include <utility> #include "base/command_line.h" -#include "base/feature_list.h" #include "base/logging.h" #include "base/mac/foundation_util.h" #include "base/metrics/histogram_functions.h" @@ -29,6 +28,17 @@ namespace ui { +// Transitioning between AVSampleBufferDisplayLayer and CALayer with IOSurface +// contents can cause flickering. +// https://crbug.com/1441762 +BASE_FEATURE(kFullscreenLowPowerBackdropMac, + "FullscreenLowPowerBackdropMac", + base::FEATURE_DISABLED_BY_DEFAULT); + +BASE_FEATURE(kCALayerTreeOptimization, + "CALayerTreeOptimization", + base::FEATURE_ENABLED_BY_DEFAULT); + namespace { class ComparatorSkColor4f { @@ -38,10 +48,6 @@ } }; -BASE_FEATURE(kCALayerTreeOptimization, - "CALayerTreeOptimization", - base::FEATURE_ENABLED_BY_DEFAULT); - void RecordIOSurfaceHistograms( int changed_io_surfaces_during_commit, int unchanged_io_surfaces_during_commit, @@ -606,6 +612,10 @@ } bool CARendererLayerTree::RootLayer::WantsFullscreenLowPowerBackdrop() const { + if (!base::FeatureList::IsEnabled(kFullscreenLowPowerBackdropMac)) { + return false; + } + bool found_video_layer = false; for (auto& clip_layer : clip_and_sorting_layers_) { for (auto& transform_layer : clip_layer.transform_layers_) {
diff --git a/ui/events/platform/wayland/wayland_event_watcher_glib.cc b/ui/events/platform/wayland/wayland_event_watcher_glib.cc index a0275a3..278ac3d2f 100644 --- a/ui/events/platform/wayland/wayland_event_watcher_glib.cc +++ b/ui/events/platform/wayland/wayland_event_watcher_glib.cc
@@ -20,8 +20,8 @@ struct GLibWaylandSource : public GSource { // Note: The GLibWaylandSource is created and destroyed by GLib. So its // constructor/destructor may or may not get called. - raw_ptr<WaylandEventWatcherGlib> event_watcher; - raw_ptr<GPollFD> poll_fd; + raw_ptr<WaylandEventWatcherGlib, LeakedDanglingUntriaged> event_watcher; + raw_ptr<GPollFD, LeakedDanglingUntriaged> poll_fd; }; gboolean WatchSourcePrepare(GSource* source, gint* timeout_ms) {
diff --git a/ui/events/platform/x11/x11_event_watcher_glib.cc b/ui/events/platform/x11/x11_event_watcher_glib.cc index b0411f50..4b325566 100644 --- a/ui/events/platform/x11/x11_event_watcher_glib.cc +++ b/ui/events/platform/x11/x11_event_watcher_glib.cc
@@ -15,8 +15,8 @@ struct GLibX11Source : public GSource { // Note: The GLibX11Source is created and destroyed by GLib. So its // constructor/destructor may or may not get called. - raw_ptr<x11::Connection> connection; - raw_ptr<GPollFD> poll_fd; + raw_ptr<x11::Connection, LeakedDanglingUntriaged> connection; + raw_ptr<GPollFD, LeakedDanglingUntriaged> poll_fd; }; gboolean XSourcePrepare(GSource* source, gint* timeout_ms) {
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc index c7a50f5..e014534 100644 --- a/ui/views/controls/menu/menu_controller.cc +++ b/ui/views/controls/menu/menu_controller.cc
@@ -916,6 +916,7 @@ SELECTION_OPEN_SUBMENU | SELECTION_UPDATE_IMMEDIATELY); } SendMouseCaptureLostToActiveView(); + MaybeForwardToAnnotation(source, event); } void MenuController::OnMouseMoved(SubmenuView* source, @@ -957,6 +958,8 @@ // which may reset the current hot tracked button. if (new_hot_tracked_button) SetHotTrackedButton(new_hot_tracked_button); + + MaybeForwardToAnnotation(source, event); } void MenuController::OnMouseEntered(SubmenuView* source, @@ -1062,9 +1065,16 @@ if (event->type() == ui::ET_TOUCH_PRESSED) { MenuPart part = GetMenuPart(source, event->location()); if (part.type == MenuPartType::kNone) { + if (MaybeForwardToAnnotation(source, *event)) { + event->SetHandled(); + return; + } + RepostEventAndCancel(source, event); event->SetHandled(); } + } else { + MaybeForwardToAnnotation(source, *event); } } @@ -1542,6 +1552,11 @@ if (part.type == MenuPartType::kNone || (part.type == MenuPartType::kMenuItem && part.menu && part.menu->GetRootMenuItem() != state_.item->GetRootMenuItem())) { + // See if this event was located within a menu annotation. + if (MaybeForwardToAnnotation(source, *event)) { + return; + } + // Remember the time stamp of the current (press down) event. The owner can // then use this to figure out if this menu was finished with the same click // which is sent to it thereafter. @@ -3492,6 +3507,30 @@ } } +MenuController::AnnotationCallbackHandle MenuController::SetAnnotationCallback( + AnnotationCallback callback) { + // TODO(dfried): change this so multiple annotations can be supported. + // This check avoids a potential race/UAF situation. + CHECK(!annotation_callback_) + << "Only one annotation callback allowed at a time."; + return AnnotationCallbackHandle( + AsWeakPtr(), &MenuController::annotation_callback_, callback); +} + +bool MenuController::MaybeForwardToAnnotation(SubmenuView* source, + const ui::LocatedEvent& event) { + if (!annotation_callback_) { + return false; + } + + const std::unique_ptr<ui::Event> cloned = event.Clone(); + auto* located = static_cast<ui::LocatedEvent*>(cloned.get()); + const gfx::Point screen_loc = View::ConvertPointToScreen( + source->GetScrollViewContainer(), event.location()); + located->set_root_location(screen_loc); + return annotation_callback_.Run(*located); +} + bool MenuController::CanProcessInputEvents() const { #if BUILDFLAG(IS_MAC) return !menu_closure_animation_;
diff --git a/ui/views/controls/menu/menu_controller.h b/ui/views/controls/menu/menu_controller.h index fa91e570..1e6a8dc 100644 --- a/ui/views/controls/menu/menu_controller.h +++ b/ui/views/controls/menu/menu_controller.h
@@ -14,7 +14,9 @@ #include <vector> #include "base/containers/flat_set.h" +#include "base/functional/callback_forward.h" #include "base/memory/raw_ptr.h" +#include "base/memory/weak_auto_reset.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "base/timer/timer.h" @@ -99,6 +101,25 @@ kReadonly, }; + // Callback that is used to pass events to an "annotation" bubble or widget, + // such as a help bubble, that floats alongside the menu and acts as part of + // the menu for event-handling purposes. These require special handling + // because menus never actually become active, and activating any other widget + // causes the menu to close, so this handler should in most cases not activate + // the annotation widget or otherwise close the menu. + // + // Not all events will be forwarded, but mouse clicks, taps, and hover/mouse + // move events will be. `event.root_location()` will be the screen coordinates + // of the event; `event.location()` is relative to the menu and can safely be + // ignored. + // + // Returns true if `event` is handled by the annotation and should not be + // processed by the menu (except for purposes of e.g. hot-tracking). + using AnnotationCallback = + base::RepeatingCallback<bool(const ui::LocatedEvent& event)>; + using AnnotationCallbackHandle = + base::WeakAutoReset<MenuController, AnnotationCallback>; + // If a menu is currently active, this returns the controller for it. static MenuController* GetActiveInstance(); @@ -262,6 +283,11 @@ // Sets the customized rounded corners of the context menu. void SetMenuRoundedCorners(absl::optional<gfx::RoundedCornersF> corners); + // Sets the annotation event handler. The handle should be discarded when the + // calling code no longer wants to intercept events for the annotation. It is + // safe to discard the handle after the menu controller has been destroyed. + AnnotationCallbackHandle SetAnnotationCallback(AnnotationCallback callback); + private: friend class internal::MenuRunnerImpl; friend class test::MenuControllerTest; @@ -604,6 +630,11 @@ const gfx::Point& item_loc, ui::OwnedWindowAnchor* anchor); + // Possibly forwards the specified `event` to an annotation callback, if one + // is present, and returns the result (default false if no callback is set). + bool MaybeForwardToAnnotation(SubmenuView* source, + const ui::LocatedEvent& event); + // The active instance. static MenuController* active_instance_; @@ -767,6 +798,10 @@ // The rounded corners of the context menu. absl::optional<gfx::RoundedCornersF> rounded_corners_ = absl::nullopt; + + // The current annotation callback. Set if there is a menu annotation; see + // `AnnotationCallback` for more information. + AnnotationCallback annotation_callback_; }; } // namespace views
diff --git a/ui/views/controls/webview/webview.h b/ui/views/controls/webview/webview.h index 2c69bd3f..2b7d528 100644 --- a/ui/views/controls/webview/webview.h +++ b/ui/views/controls/webview/webview.h
@@ -201,7 +201,7 @@ // Set to true when |holder_| is letterboxed (scaled to be smaller than this // view, to preserve its aspect ratio). bool is_letterboxing_ = false; - raw_ptr<content::BrowserContext> browser_context_; + raw_ptr<content::BrowserContext, LeakedDanglingUntriaged> browser_context_; bool allow_accelerators_ = false; raw_ptr<View, DanglingUntriaged> crashed_overlay_view_ = nullptr; bool is_primary_web_contents_for_window_ = false;
diff --git a/url/BUILD.gn b/url/BUILD.gn index 8751cf3..63c5ebc 100644 --- a/url/BUILD.gn +++ b/url/BUILD.gn
@@ -10,6 +10,7 @@ import("//build/config/cronet/config.gni") if (is_android || is_robolectric) { + import("//build/config/android/jni.gni") import("//build/config/android/rules.gni") } @@ -393,7 +394,8 @@ if (is_robolectric) { # Use this in robolectric_binary() targets if you just need GURL and //base # functionality. Otherwise, define a custom shared_library(). - shared_library("libgurl_robolectric") { + shared_library_with_jni("libgurl_robolectric") { + testonly = true sources = [ "android/robolectric_test_main.cc" ] deps = [ "//base", @@ -402,5 +404,7 @@ # Make jni.h available. configs += [ "//third_party/jdk" ] + + java_targets = [ "//chrome/android:chrome_junit_tests" ] } }
diff --git a/weblayer/browser/autofill_client_impl.cc b/weblayer/browser/autofill_client_impl.cc index 0faeef2..d4847f1 100644 --- a/weblayer/browser/autofill_client_impl.cc +++ b/weblayer/browser/autofill_client_impl.cc
@@ -10,6 +10,7 @@ #include "components/android_autofill/browser/android_autofill_manager.h" #include "components/autofill/core/browser/autofill_download_manager.h" #include "components/autofill/core/browser/data_model/autofill_profile.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" #include "components/autofill/core/browser/ui/suggestion.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/navigation_entry.h" @@ -361,7 +362,7 @@ return false; } -void AutofillClientImpl::ExecuteCommand(autofill::Suggestion::FrontendId id) { +void AutofillClientImpl::ExecuteCommand(autofill::PopupItemId popup_item_id) { NOTREACHED(); }
diff --git a/weblayer/browser/autofill_client_impl.h b/weblayer/browser/autofill_client_impl.h index e4764f5d..1126eec8 100644 --- a/weblayer/browser/autofill_client_impl.h +++ b/weblayer/browser/autofill_client_impl.h
@@ -8,6 +8,7 @@ #include "base/compiler_specific.h" #include "build/build_config.h" #include "components/autofill/content/browser/content_autofill_client.h" +#include "components/autofill/core/browser/ui/popup_item_ids.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" @@ -153,7 +154,7 @@ void DidFillOrPreviewField(const std::u16string& autofilled_value, const std::u16string& profile_full_name) override; bool IsContextSecure() const override; - void ExecuteCommand(autofill::Suggestion::FrontendId id) override; + void ExecuteCommand(autofill::PopupItemId popup_item_id) override; void OpenPromoCodeOfferDetailsURL(const GURL& url) override; autofill::FormInteractionsFlowId GetCurrentFormInteractionsFlowId() override;