diff --git a/AUTHORS b/AUTHORS index f45b094..38bed14 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -686,6 +686,7 @@ Jihoon Chung <jihoon@gmail.com> Jihun Brent Kim <devgrapher@gmail.com> Jihwan Marc Kim <bluewhale.marc@gmail.com> +Jihye Hyun <jijinny26@gmail.com> Jihyeon Lee <wlgus7464@gmail.com> Jin Yang <jin.a.yang@intel.com> Jincheol Jo <jincheol.jo@navercorp.com> @@ -702,6 +703,7 @@ Jinwoo Song <jinwoo7.song@samsung.com> Jinyoung Hur <hur.ims@navercorp.com> Jinyoung Hur <hurims@gmail.com> +Jisu Kim <hellojs242@gmail.com> Jitendra Kumar Sahoo <jitendra.ks@samsung.com> Jitesh Pareek <j1.pareek@samsung.com> Joachim Bauch <jbauch@webrtc.org> @@ -1036,6 +1038,7 @@ Minjeong Lee <apenr1234@gmail.com> Minseok Koo <kei98301@gmail.com> Minsoo Max Koo <msu.koo@samsung.com> +Minsung Jin <m4ushold@gmail.com> Miran Karic <miran.karic@imgtec.com> Mirela Budaes <mbudaes@adobe.com> Mirela Budaes <mbudaes@gmail.com>
diff --git a/DEPS b/DEPS index 39e6884..38f105b 100644 --- a/DEPS +++ b/DEPS
@@ -295,19 +295,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': '5de18f0aacc3865198ffcb45372a83f6b0b9b27b', + 'src_internal_revision': '7a2d2c5a328e293e0a9849b8d1e17e59d56a3b14', # 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': 'ac2d5ceecb588e3be2a798896b92d27c91ad6461', + 'skia_revision': '0d16b74f74a5018c20fdaa753b41103bb08d08fd', # 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': 'a1ba74a85fdfad2d8eac3857059676bc6e0fb686', + 'v8_revision': 'a46966388bbd892ee59d5d2688287704d1844302', # 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': '00845fd649a450a00e61215f44bb4fc95d515c97', + 'angle_revision': 'b729fb74e68bb2b3db6c95067f4ffc1e0c25bc07', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -319,7 +319,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. - 'boringssl_revision': '154bb5860a47c160c3be09003908c64c1de11bff', + 'boringssl_revision': 'f371c85a8d58bf911cba6073bcca6d497af81dc9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Fuchsia sdk # and whatever else without interference from each other. @@ -371,7 +371,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '64c31ffa4d735add4a7e7520a52e0e3160216132', + 'catapult_revision': '74f545d009ceef464f840938ae079ffbc112a102', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling CrossBench # 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': '6e4e34acb617713aa7b51311d6ea87c58c609b32', + 'devtools_frontend_revision': '6d3155a3c0b50687e4f417e19d4491e66d56ef3c', # 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. @@ -745,7 +745,7 @@ 'packages': [ { 'package': 'chrome_internal/third_party/google3/data_sharing_sdk', - 'version': 'BmL2YCZyicXbUzlB_Nv7oAsX_cphB8D9DeDeEnMX8fkC', + 'version': 'OINoFC4BjUT2ky7xBnUMwlAKhv4EYTLC-XJZ59t2udUC', }, ], 'condition': 'checkout_src_internal and non_git_source', @@ -1486,7 +1486,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '1881fd29e10d5d32e8b8f6ed892c860e43dded76', + '86901d8e9a33f78ccf07acfa57b63439e7cfa5f8', 'condition': 'checkout_android and checkout_src_internal', }, @@ -1645,7 +1645,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': '0kpSWsOkTy_kz_7BrmXaMj0RWlcTCIC9WOKWl3eSM4cC', + 'version': '3f6bb_ds1Ab_INPp6lc8i778IRbWZSwVm2QBzfQFTMoC', }, ], 'condition': 'checkout_android and non_git_source', @@ -1738,7 +1738,7 @@ 'packages': [ { 'package': 'chromium/third_party/android_build_tools/lint', - 'version': '2fKjMen4v_UU1CDYJqhwJCr6uh-L5w25n9lAKx6SlP0C', + 'version': 'QltgzNfGb4l4ekv1_GjIWtuew1hrBof1WVy2B8zrkYwC', }, ], 'condition': 'checkout_android and non_git_source', @@ -1749,7 +1749,7 @@ 'packages': [ { 'package': 'chromium/third_party/android_build_tools/manifest_merger', - 'version': 'GnPGgBK8kiq32GuJB3iI20yJbFjgt2dqHsmwoPShJ-4C', + 'version': 'hVPp69VTDru05sisN9HcrOf67Tk_Mhu6P6bsR24gOrEC', }, ], 'condition': 'checkout_android and non_git_source', @@ -1978,7 +1978,7 @@ 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'fab0a4296b8830c569a4dc82285bfb58a5c2fca8', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'a7571b1596305d6a6fe26c788f24e40c579fcda8', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -2526,7 +2526,7 @@ Var('pdfium_git') + '/pdfium.git' + '@' + Var('pdfium_revision'), 'src/third_party/perfetto': - Var('chromium_git') + '/external/github.com/google/perfetto.git' + '@' + 'e2d7750acd15d57c6c88e3c8fb8c5a45f424ba96', + Var('chromium_git') + '/external/github.com/google/perfetto.git' + '@' + '993d41d0c39335e35fe577808e8f704e58d9dbfb', 'src/base/tracing/test/data': { 'bucket': 'perfetto', @@ -2950,7 +2950,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/windows-amd64', - 'version': 'zasiUhQIHGZ2e60_M6g41oz8mYgPta5JmOWV5LwFjGMC', + 'version': 'LLNTOh1PJ9ZXVrdmwgWAf0KYOgZgQhfgaldCTjmg1c0C', }, ], 'dep_type': 'cipd', @@ -2961,7 +2961,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/mac-amd64', - 'version': 'tZvHxy8AcDJhO9A-5UuZKL_-5vfE_wC-RBkElqWZpM4C', + 'version': 'xo66yxZ-zTgqRnY5597wSJpk-3BX2OpElqzYg032slAC', }, ], 'dep_type': 'cipd',
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index c9b9c0df..570a0b1 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -1284,7 +1284,8 @@ 'common_range', 'viewable_range', 'constant_range', - # Banned: Views + # Views + 'subrange', # Banned: Range factories # Banned: Range adaptors # Incidentally listed on @@ -2335,6 +2336,7 @@ 'build/android/resource_sizes.pydeps', 'build/android/test_runner.pydeps', 'build/android/test_wrapper/logdog_wrapper.pydeps', + 'build/fuchsia/test/component_storage_test.pydeps', 'build/protoc_java.pydeps', 'chrome/android/monochrome/scripts/monochrome_python_tests.pydeps', 'chrome/test/chromedriver/log_replay/client_replay_unittest.pydeps',
diff --git a/PRESUBMIT_test.py b/PRESUBMIT_test.py index a2ff946..65b2b67c 100755 --- a/PRESUBMIT_test.py +++ b/PRESUBMIT_test.py
@@ -3033,6 +3033,7 @@ 'allowed_ranges_usage.cc', [ 'std::ranges::begin(vec);', + 'std::ranges::subrange(first, last);', # std::ranges::view is a concept and allowed, but the views # library itself is not (see below) 'static_assert(std::ranges::view<SomeType>);' @@ -3040,7 +3041,7 @@ MockFile( 'banned_ranges_usage.cc', [ - 'std::ranges::subrange(first, last);', + 'std::ranges::borrowed_subrange_t(subrange);', # Edge case: make sure std::ranges::views is disallowed, # even though std::ranges::view is allowed. 'std::ranges::views::take(first, count);'
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index ab2903e..a6326088 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -860,9 +860,18 @@ renaming_sources = [] renaming_destinations = [] foreach(_locale, platform_pak_locales) { - renaming_sources += - [ "$root_out_dir/android_webview/locales/$_locale.pak" ] - renaming_destinations += [ "stored-locales/$_locale.pak" ] + if (translate_genders) { + renaming_sources += process_file_template( + all_chrome_genders, + "$root_out_dir/android_webview/locales/${_locale}_{{source_name_part}}.pak") + renaming_destinations += process_file_template( + all_chrome_genders, + "stored-locales/${_locale}_{{source_name_part}}.pak") + } else { + renaming_sources += + [ "$root_out_dir/android_webview/locales/${_locale}.pak" ] + renaming_destinations += [ "stored-locales/${_locale}.pak" ] + } } treat_as_locale_paks = true deps = [ ":repack_locales" ] @@ -1112,7 +1121,7 @@ } } -grit("generate_components_strings") { +grit_strings("generate_components_strings") { source = "../components/components_strings.grd" defines = [ @@ -1135,16 +1144,10 @@ "-w", _allowlist, ] - outputs = - [ - "grit/components_strings.h", - "java/res/values/components_strings.xml", - ] + - process_file_template( - android_bundle_locales_as_resources, - [ "java/res/values-{{source_name_part}}/components_strings.xml" ]) + - process_file_template(all_chrome_locales, - [ "components_strings_{{source_name_part}}.pak" ]) + outputs = [ "grit/components_strings.h" ] + + create_android_resources = true + output_prefix = "components_strings_" } generate_jni("common_jni") {
diff --git a/android_webview/browser/aw_browser_context.cc b/android_webview/browser/aw_browser_context.cc index 60aea01..dd45ce4 100644 --- a/android_webview/browser/aw_browser_context.cc +++ b/android_webview/browser/aw_browser_context.cc
@@ -160,7 +160,6 @@ migrate_context_storage_data("QuotaManager-journal"); migrate_context_storage_data("Service Worker"); migrate_context_storage_data("VideoDecodeStats"); - migrate_context_storage_data("databases"); migrate_context_storage_data("shared_proto_db"); migrate_context_storage_data("webrtc_event_logs"); }
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index b749005..bdb962f7 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc
@@ -176,8 +176,8 @@ // navigation, and forwards it to the proxying loader factory. class XrwNavigationThrottle : public content::NavigationThrottle { public: - explicit XrwNavigationThrottle(content::NavigationHandle* handle) - : NavigationThrottle(handle) {} + explicit XrwNavigationThrottle(content::NavigationThrottleRegistry& registry) + : NavigationThrottle(registry) {} ~XrwNavigationThrottle() override { AwProxyingURLLoaderFactory::ClearXrwResultForNavigation( navigation_handle()->GetNavigationId()); @@ -683,22 +683,16 @@ // doesn't actually call into an arbitrary client, it just posts a task to // call onPageStarted. shouldOverrideUrlLoading happens earlier (see // ContentBrowserClient::ShouldOverrideUrlLoading). - registry.MaybeAddThrottle( - navigation_interception::InterceptNavigationDelegate:: - MaybeCreateThrottleFor( - &navigation_handle, - navigation_interception::SynchronyMode::kSync)); + navigation_interception::InterceptNavigationDelegate::MaybeCreateAndAdd( + registry, navigation_interception::SynchronyMode::kSync); registry.AddThrottle(std::make_unique<PolicyBlocklistNavigationThrottle>( - &navigation_handle, + registry, AwBrowserContext::FromWebContents(navigation_handle.GetWebContents()))); - registry.MaybeAddThrottle( - AwSafeBrowsingNavigationThrottle::MaybeCreateThrottleFor( - &navigation_handle)); + AwSafeBrowsingNavigationThrottle::MaybeCreateAndAdd(registry); if (base::FeatureList::IsEnabled(kWebViewOptimizeXrwNavigationFlow)) { - registry.AddThrottle( - std::make_unique<XrwNavigationThrottle>(&navigation_handle)); + registry.AddThrottle(std::make_unique<XrwNavigationThrottle>(registry)); } if ((navigation_handle.GetNavigatingFrameType() == @@ -708,8 +702,8 @@ AwSupervisedUserUrlClassifier* urlClassifier = AwSupervisedUserUrlClassifier::GetInstance(); if (urlClassifier->ShouldCreateThrottle()) { - registry.AddThrottle(std::make_unique<AwSupervisedUserThrottle>( - &navigation_handle, urlClassifier)); + registry.AddThrottle( + std::make_unique<AwSupervisedUserThrottle>(registry, urlClassifier)); } } }
diff --git a/android_webview/browser/safe_browsing/aw_safe_browsing_navigation_throttle.cc b/android_webview/browser/safe_browsing/aw_safe_browsing_navigation_throttle.cc index a4389b3..df97e29 100644 --- a/android_webview/browser/safe_browsing/aw_safe_browsing_navigation_throttle.cc +++ b/android_webview/browser/safe_browsing/aw_safe_browsing_navigation_throttle.cc
@@ -14,27 +14,30 @@ #include "components/security_interstitials/content/security_interstitial_tab_helper.h" #include "components/security_interstitials/core/unsafe_resource.h" #include "content/public/browser/navigation_handle.h" +#include "content/public/browser/navigation_throttle_registry.h" namespace android_webview { using safe_browsing::ThreatSeverity; // static -std::unique_ptr<AwSafeBrowsingNavigationThrottle> -AwSafeBrowsingNavigationThrottle::MaybeCreateThrottleFor( - content::NavigationHandle* handle) { +void AwSafeBrowsingNavigationThrottle::MaybeCreateAndAdd( + content::NavigationThrottleRegistry& registry) { // Only outer-most main frames show the interstitial through the navigation // throttle. In other cases, the interstitial is shown via // BaseUIManager::DisplayBlockingPage. - if (!handle->IsInPrimaryMainFrame() && !handle->IsInPrerenderedMainFrame()) - return nullptr; + if (!registry.GetNavigationHandle().IsInPrimaryMainFrame() && + !registry.GetNavigationHandle().IsInPrerenderedMainFrame()) { + return; + } - return base::WrapUnique(new AwSafeBrowsingNavigationThrottle(handle)); + registry.AddThrottle( + base::WrapUnique(new AwSafeBrowsingNavigationThrottle(registry))); } AwSafeBrowsingNavigationThrottle::AwSafeBrowsingNavigationThrottle( - content::NavigationHandle* handle) - : content::NavigationThrottle(handle) {} + content::NavigationThrottleRegistry& registry) + : content::NavigationThrottle(registry) {} const char* AwSafeBrowsingNavigationThrottle::GetNameForLogging() { return "AwSafeBrowsingNavigationThrottle";
diff --git a/android_webview/browser/safe_browsing/aw_safe_browsing_navigation_throttle.h b/android_webview/browser/safe_browsing/aw_safe_browsing_navigation_throttle.h index d4a77f5..3682d5e 100644 --- a/android_webview/browser/safe_browsing/aw_safe_browsing_navigation_throttle.h +++ b/android_webview/browser/safe_browsing/aw_safe_browsing_navigation_throttle.h
@@ -7,10 +7,8 @@ #include "content/public/browser/navigation_throttle.h" -#include <memory> - namespace content { -class NavigationHandle; +class NavigationThrottleRegistry; } // namespace content namespace android_webview { @@ -29,15 +27,15 @@ // Lifetime: Temporary class AwSafeBrowsingNavigationThrottle : public content::NavigationThrottle { public: - static std::unique_ptr<AwSafeBrowsingNavigationThrottle> - MaybeCreateThrottleFor(content::NavigationHandle* handle); + static void MaybeCreateAndAdd(content::NavigationThrottleRegistry& registry); ~AwSafeBrowsingNavigationThrottle() override {} const char* GetNameForLogging() override; content::NavigationThrottle::ThrottleCheckResult WillFailRequest() override; private: - explicit AwSafeBrowsingNavigationThrottle(content::NavigationHandle* handle); + explicit AwSafeBrowsingNavigationThrottle( + content::NavigationThrottleRegistry& registry); }; } // namespace android_webview
diff --git a/android_webview/browser/supervised_user/aw_supervised_user_throttle.cc b/android_webview/browser/supervised_user/aw_supervised_user_throttle.cc index 95297ef..bce359f 100644 --- a/android_webview/browser/supervised_user/aw_supervised_user_throttle.cc +++ b/android_webview/browser/supervised_user/aw_supervised_user_throttle.cc
@@ -11,17 +11,17 @@ namespace android_webview { // static -std::unique_ptr<AwSupervisedUserThrottle> AwSupervisedUserThrottle::Create( - content::NavigationHandle* navigation_handle, +void AwSupervisedUserThrottle::CreateAndAdd( + content::NavigationThrottleRegistry& registry, AwSupervisedUserUrlClassifier* url_classifier) { - return base::WrapUnique<AwSupervisedUserThrottle>( - new AwSupervisedUserThrottle(navigation_handle, url_classifier)); + registry.AddThrottle(base::WrapUnique<AwSupervisedUserThrottle>( + new AwSupervisedUserThrottle(registry, url_classifier))); } AwSupervisedUserThrottle::AwSupervisedUserThrottle( - content::NavigationHandle* navigation_handle, + content::NavigationThrottleRegistry& registry, AwSupervisedUserUrlClassifier* url_classifier) - : NavigationThrottle(navigation_handle), url_classifier_(url_classifier) { + : NavigationThrottle(registry), url_classifier_(url_classifier) { DCHECK(url_classifier_); DETACH_FROM_SEQUENCE(sequence_checker_); }
diff --git a/android_webview/browser/supervised_user/aw_supervised_user_throttle.h b/android_webview/browser/supervised_user/aw_supervised_user_throttle.h index 0589480..551ae72 100644 --- a/android_webview/browser/supervised_user/aw_supervised_user_throttle.h +++ b/android_webview/browser/supervised_user/aw_supervised_user_throttle.h
@@ -10,6 +10,10 @@ #include "content/public/browser/navigation_throttle.h" #include "net/http/http_request_headers.h" +namespace content { +class NavigationThrottleRegistry; +} // namespace content + namespace android_webview { // This throttle is used to check if a given url (http and https only) @@ -28,13 +32,11 @@ // lives from navigation start until the navigation has been committed. class AwSupervisedUserThrottle : public content::NavigationThrottle { public: - static std::unique_ptr<AwSupervisedUserThrottle> Create( - content::NavigationHandle* navigation_handle, - AwSupervisedUserUrlClassifier* bridge); + static void CreateAndAdd(content::NavigationThrottleRegistry& registry, + AwSupervisedUserUrlClassifier* bridge); - explicit AwSupervisedUserThrottle( - content::NavigationHandle* navigation_handle, - AwSupervisedUserUrlClassifier* url_classifier); + AwSupervisedUserThrottle(content::NavigationThrottleRegistry& registry, + AwSupervisedUserUrlClassifier* url_classifier); AwSupervisedUserThrottle(const AwSupervisedUserThrottle&) = delete; AwSupervisedUserThrottle& operator=(const AwSupervisedUserThrottle&) = delete; ~AwSupervisedUserThrottle() override;
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 81dc59d..087b36c 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
@@ -217,6 +217,7 @@ Flag.baseFeature( BlinkFeatures.PRELOAD_LINK_REL_DATA_URLS, "Allow preloading data: URLs with link rel=preload"), + Flag.baseFeature(BlinkFeatures.OPTIMIZE_HTML_ELEMENT_URLS, "Optimize HTML Element URLs"), Flag.baseFeature( BlinkFeatures.DOCUMENT_POLICY_EXPECT_NO_LINKED_RESOURCES, "Enables the ability to use Document Policy header to control feature"
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 4b4af5a..d39db4a 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -6938,6 +6938,12 @@ <message name="IDS_ASH_SUNFISH_EDUCATE_TOAST_MESSAGE" desc="The message shown in a toast window to educate the user about the Sunfish feature."> Select anything on your screen to search, copy text, and more </message> + <message name="IDS_ASH_SUNFISH_RESULTS_LOADING_ACCESSIBLE_NAME" desc="The accessible name of the loading image in the Sunfish search results panel while waiting for the results web contents to load."> + Results loading + </message> + <message name="IDS_ASH_SUNFISH_RESULTS_LOADED_ACCESSIBLE_NAME" desc="Text for the accessible name that is announced when the results for the Sunfish search results panel are loaded."> + Results loaded + </message> <!-- Scanner --> <message name="IDS_ASH_SCANNER_DISCLAIMER_TITLE" desc="Text shown as the title of the suggested actions when searching your screen disclaimer view.">
diff --git a/ash/ash_strings_grd/IDS_ASH_SUNFISH_RESULTS_LOADED_ACCESSIBLE_NAME.png.sha1 b/ash/ash_strings_grd/IDS_ASH_SUNFISH_RESULTS_LOADED_ACCESSIBLE_NAME.png.sha1 new file mode 100644 index 0000000..f19df497 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_SUNFISH_RESULTS_LOADED_ACCESSIBLE_NAME.png.sha1
@@ -0,0 +1 @@ +3b7a6e4979a9f968c705a59e4d743d60fae85c45 \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_SUNFISH_RESULTS_LOADING_ACCESSIBLE_NAME.png.sha1 b/ash/ash_strings_grd/IDS_ASH_SUNFISH_RESULTS_LOADING_ACCESSIBLE_NAME.png.sha1 new file mode 100644 index 0000000..fe20041 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_SUNFISH_RESULTS_LOADING_ACCESSIBLE_NAME.png.sha1
@@ -0,0 +1 @@ +9b6a3702a6e518712aa38664c470f403cb346d98 \ No newline at end of file
diff --git a/ash/capture_mode/capture_mode_constants.h b/ash/capture_mode/capture_mode_constants.h index 0f8bf925..956f962 100644 --- a/ash/capture_mode/capture_mode_constants.h +++ b/ash/capture_mode/capture_mode_constants.h
@@ -177,6 +177,9 @@ inline constexpr int kRegionGlowMinOutsetDp = 0; inline constexpr int kRegionGlowMaxOutsetDp = 6; +// The view ID for the search results panel loading animation. +inline constexpr int kLoadingAnimationViewId = 1; + } // namespace ash::capture_mode #endif // ASH_CAPTURE_MODE_CAPTURE_MODE_CONSTANTS_H_
diff --git a/ash/capture_mode/capture_mode_controller.cc b/ash/capture_mode/capture_mode_controller.cc index 87c69641..2ae8f4c8 100644 --- a/ash/capture_mode/capture_mode_controller.cc +++ b/ash/capture_mode/capture_mode_controller.cc
@@ -14,7 +14,6 @@ #include "ash/capture_mode/capture_mode_ash_notification_view.h" #include "ash/capture_mode/capture_mode_behavior.h" #include "ash/capture_mode/capture_mode_camera_controller.h" -#include "ash/capture_mode/capture_mode_constants.h" #include "ash/capture_mode/capture_mode_education_controller.h" #include "ash/capture_mode/capture_mode_metrics.h" #include "ash/capture_mode/capture_mode_observer.h" @@ -712,8 +711,8 @@ : nullptr; } -void CaptureModeController::ShowSearchResultsPanel(const gfx::ImageSkia& image, - GURL url) { +void CaptureModeController::ShowSearchResultsPanel( + const gfx::ImageSkia& image) { // We should not use `CanShowSunfishUi` here, as that could change between // sending the region and receiving a URL (for example, if the Sunfish policy // changes). @@ -746,6 +745,9 @@ // If the panel was not visible beforehand (either the panel was not created // yet or the panel was hidden from making a new selection), emit a metric. if (!search_results_panel_widget_->IsVisible()) { + // Each time we make a new request, we should show the loading animation. + GetSearchResultsPanel()->ShowLoadingAnimation(); + search_results_panel_widget_->Show(); RecordSearchResultsPanelShown(); // Setting or updating the bounds here only accounts for newly selected @@ -763,7 +765,7 @@ if (!features::IsSunfishLensWebEnabled()) { search_results_panel->SetSearchBoxImage(image); } - search_results_panel->Navigate(url); + if (should_end_session) { Stop(); } @@ -2068,6 +2070,7 @@ return; } + gfx::ImageSkia image_skia = gfx::ImageSkia(); if (features::IsSunfishLensWebEnabled()) { const gfx::Image image = gfx::Image::CreateFrom1xBitmap(bitmap); const bool is_standalone_session = @@ -2083,19 +2086,24 @@ base::BindRepeating(&CaptureModeController::OnLensWebError, weak_ptr_factory_.GetWeakPtr(), image_search_token)); - return; + } else { + image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); + // `OnSearchUrlFetched()` will be invoked with `image` when the server + // response is fetched. + delegate_->SendRegionSearch( + bitmap, user_capture_region_, + base::BindRepeating(&CaptureModeController::OnSearchUrlFetched, + weak_ptr_factory_.GetWeakPtr(), + user_capture_region_, image_skia), + base::BindRepeating(&CaptureModeController::OnLensTextDetectionComplete, + weak_ptr_factory_.GetWeakPtr(), + image_search_token)); } - const gfx::ImageSkia image = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); - // `OnSearchUrlFetched()` will be invoked with `image` when the server - // response is fetched. - delegate_->SendRegionSearch( - bitmap, user_capture_region_, - base::BindRepeating(&CaptureModeController::OnSearchUrlFetched, - weak_ptr_factory_.GetWeakPtr(), user_capture_region_, - image), - base::BindRepeating(&CaptureModeController::OnLensTextDetectionComplete, - weak_ptr_factory_.GetWeakPtr(), image_search_token)); + // Immediately show the search results panel, with a loading animation in + // place of the web contents. We will replace it once we receive the URL from + // the server. + ShowSearchResultsPanel(image_skia); } void CaptureModeController::OnTextDetectionComplete( @@ -2208,12 +2216,14 @@ const gfx::ImageSkia& image, GURL url) { if (captured_region == user_capture_region_) { - ShowSearchResultsPanel(image, url); + NavigateSearchResultsPanel(url); } } void CaptureModeController::OnLensWebError( base::WeakPtr<BaseCaptureModeSession> image_search_token) { + CloseSearchResultsPanel(); + // TODO: crbug.com/406072681 - Show an error message if the session is no // longer active, such as in the case of clicking the Search with Lens button // in a regular session. @@ -3013,4 +3023,12 @@ base::BindOnce(std::move(callback), path)); } +void CaptureModeController::NavigateSearchResultsPanel(const GURL& url) { + if (auto* panel = GetSearchResultsPanel()) { + capture_mode_util::TriggerAccessibilityAlert( + IDS_ASH_SUNFISH_RESULTS_LOADED_ACCESSIBLE_NAME); + panel->Navigate(url); + } +} + } // namespace ash
diff --git a/ash/capture_mode/capture_mode_controller.h b/ash/capture_mode/capture_mode_controller.h index 2adb4e6f..06af9617 100644 --- a/ash/capture_mode/capture_mode_controller.h +++ b/ash/capture_mode/capture_mode_controller.h
@@ -42,6 +42,7 @@ #include "services/viz/privileged/mojom/compositing/frame_sink_video_capture.mojom-forward.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/image/image.h" +#include "ui/gfx/image/image_skia.h" class PrefRegistrySimple; @@ -150,9 +151,13 @@ // Returns the search results panel, or nullptr if none exists. SearchResultsPanel* GetSearchResultsPanel() const; - // Shows the results panel with the captured region as `image` and the search - // results `url`. - void ShowSearchResultsPanel(const gfx::ImageSkia& image, GURL url); + // Shows the results panel. `image` is only needed for the thumbnail if the + // Lens Web feature flag is disabled. + void ShowSearchResultsPanel(const gfx::ImageSkia& image); + + // Navigates the Sunfish search results panel to the given URL, if the panel + // is available. + void NavigateSearchResultsPanel(const GURL& url); // Closes the search results panel, or does nothing if it doesn't exist. void CloseSearchResultsPanel();
diff --git a/ash/capture_mode/capture_mode_session_focus_cycler.cc b/ash/capture_mode/capture_mode_session_focus_cycler.cc index 00431fc..be9228e 100644 --- a/ash/capture_mode/capture_mode_session_focus_cycler.cc +++ b/ash/capture_mode/capture_mode_session_focus_cycler.cc
@@ -633,10 +633,17 @@ SearchResultsPanel* panel = CaptureModeController::Get()->GetSearchResultsPanel(); if (panel) { - views::View* web_view = panel->GetWebViewForFocus(); - CHECK(web_view); - web_view->AboutToRequestFocusFromTabTraversal(reverse); - web_view->RequestFocus(); + // The web contents might not be available when we try to focus them, but + // we can focus the loading animation instead. + if (panel->search_results_view()) { + views::View* web_view = panel->GetWebViewForFocus(); + CHECK(web_view); + web_view->AboutToRequestFocusFromTabTraversal(reverse); + web_view->RequestFocus(); + } else { + focus_index_ = 0u; + panel->GetHighlightableLoadingAnimation()->PseudoFocus(); + } } } else if (!current_views.empty()) { DCHECK_LT(focus_index_, current_views.size()); @@ -1116,9 +1123,6 @@ case FocusGroup::kSelection: case FocusGroup::kPendingSettings: case FocusGroup::kPendingRecordingType: - // The web contents does not contain any highlightable views, as we want its - // `FocusManager` to handle tab traversal and focus. - case FocusGroup::kSearchResultsPanelWebContents: break; case FocusGroup::kTypeSource: { CaptureModeBarView* bar_view = session_->capture_mode_bar_view_; @@ -1217,16 +1221,30 @@ break; } case FocusGroup::kSearchResultsPanel: { + auto* controller = CaptureModeController::Get(); auto* search_results_panel_widget = - CaptureModeController::Get()->search_results_panel_widget(); + controller->search_results_panel_widget(); if (search_results_panel_widget && search_results_panel_widget->IsVisible()) { - items = CaptureModeController::Get() - ->GetSearchResultsPanel() - ->GetHighlightableItems(); + items = controller->GetSearchResultsPanel()->GetHighlightableItems(); } break; } + // The web contents are not highlightable, only the animation view. We'll + // let `AdvanceFocus` handle the web contents separately. + case FocusGroup::kSearchResultsPanelWebContents: { + auto* controller = CaptureModeController::Get(); + auto* search_results_panel_widget = + controller->search_results_panel_widget(); + if (search_results_panel_widget && + search_results_panel_widget->IsVisible()) { + auto* animation_view = controller->GetSearchResultsPanel() + ->GetHighlightableLoadingAnimation(); + if (animation_view) { + items.push_back(animation_view); + } + } + } } return items; }
diff --git a/ash/capture_mode/search_results_panel.cc b/ash/capture_mode/search_results_panel.cc index e6c8ca95..2d71f681 100644 --- a/ash/capture_mode/search_results_panel.cc +++ b/ash/capture_mode/search_results_panel.cc
@@ -18,6 +18,8 @@ #include "ash/strings/grit/ash_strings.h" #include "ash/style/icon_button.h" #include "ash/style/typography.h" +#include "ash/system/mahi/mahi_animation_utils.h" +#include "ash/system/mahi/resources/grit/mahi_resources.h" #include "components/vector_icons/vector_icons.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" @@ -28,6 +30,7 @@ #include "ui/display/tablet_state.h" #include "ui/views/background.h" #include "ui/views/border.h" +#include "ui/views/controls/animated_image_view.h" #include "ui/views/controls/focus_ring.h" #include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" @@ -226,20 +229,6 @@ search_box_view_->SetProperty(views::kMarginsKey, kSearchBoxViewSpacing); } - search_results_view_ = - AddChildView(CaptureModeController::Get()->CreateSearchResultsView()); - search_results_view_->SetProperty( - views::kFlexBehaviorKey, - views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred, - views::MaximumFlexSizeRule::kUnbounded)); - - // Without the native search box, there needs to be padding between the header - // and the web view. - if (features::IsSunfishLensWebEnabled()) { - search_results_view_->SetProperty(views::kMarginsKey, - kSearchResultsViewSpacing); - } - SetBackground(views::CreateRoundedRectBackground( cros_tokens::kCrosSysSystemBaseElevated, kPanelCornerRadius)); SetPaintToLayer(); @@ -249,6 +238,8 @@ layer()->SetBackgroundBlur(ColorProvider::kBackgroundBlurSigma); layer()->SetBackdropFilterQuality(ColorProvider::kBackgroundBlurQuality); + ShowLoadingAnimation(); + // Install highlightable views for when a Sunfish session is active and the // `CaptureModeSessionFocusCycler` is handling focus. Set up the focus // predicate for the focusable views now, so they will have the correct @@ -258,6 +249,12 @@ CaptureModeSessionFocusCycler::HighlightHelper::Get(close_button_) ->SetUpFocusPredicate(); + auto* animation_view = GetViewByID(capture_mode::kLoadingAnimationViewId); + CHECK(animation_view); + CaptureModeSessionFocusCycler::HighlightHelper::Install(animation_view); + CaptureModeSessionFocusCycler::HighlightHelper::Get(animation_view) + ->SetUpFocusPredicate(); + if (!features::IsSunfishLensWebEnabled()) { CaptureModeSessionFocusCycler::HighlightHelper::Install( search_box_view_->textfield_); @@ -308,11 +305,35 @@ return highlightable_items; } +CaptureModeSessionFocusCycler::HighlightableView* +SearchResultsPanel::GetHighlightableLoadingAnimation() { + auto* animation_view = GetViewByID(capture_mode::kLoadingAnimationViewId); + return animation_view ? CaptureModeSessionFocusCycler::HighlightHelper::Get( + animation_view) + : nullptr; +} + views::View* SearchResultsPanel::GetWebViewForFocus() { + CHECK(search_results_view_); return search_results_view_->GetInitiallyFocusedView(); } void SearchResultsPanel::Navigate(const GURL& url) { + if (!search_results_view_) { + // Remove the loading animation. + auto* animation_view = GetViewByID(capture_mode::kLoadingAnimationViewId); + CHECK(animation_view); + RemoveChildViewT(animation_view); + + search_results_view_ = + AddChildView(CaptureModeController::Get()->CreateSearchResultsView()); + search_results_view_->SetProperty( + views::kFlexBehaviorKey, + views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred, + views::MaximumFlexSizeRule::kUnbounded)); + search_results_view_->SetProperty(views::kMarginsKey, + kSearchResultsViewSpacing); + } search_results_view_->Navigate(url); } @@ -346,6 +367,40 @@ ->has_focus(); } +void SearchResultsPanel::ShowLoadingAnimation() { + if (GetViewByID(capture_mode::kLoadingAnimationViewId)) { + return; + } + + // Remove the search results view if present. + if (search_results_view_) { + auto* search_results_view = search_results_view_.get(); + search_results_view_ = nullptr; + RemoveChildViewT(search_results_view); + } + + CHECK(!search_results_view_); + + // Add the animation view and play it. + auto* animation_view = AddChildView( + views::Builder<views::AnimatedImageView>() + // Use an ID instead of saving a `raw_ptr` to avoid a dangling pointer + // when we remove this child later. + .SetID(capture_mode::kLoadingAnimationViewId) + .SetAccessibleName(l10n_util::GetStringUTF16( + IDS_ASH_SUNFISH_RESULTS_LOADING_ACCESSIBLE_NAME)) + .SetAnimatedImage(mahi_animation_utils::GetLottieAnimationData( + IDR_MAHI_LOADING_SUMMARY_ANIMATION)) + .Build()); + animation_view->SetProperty( + views::kFlexBehaviorKey, + views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred, + views::MaximumFlexSizeRule::kUnbounded)); + animation_view->Play(mahi_animation_utils::GetLottiePlaybackConfig( + *animation_view->animated_image()->skottie(), + IDR_MAHI_LOADING_SUMMARY_ANIMATION)); +} + void SearchResultsPanel::AddedToWidget() { GetFocusManager()->AddFocusChangeListener(this); }
diff --git a/ash/capture_mode/search_results_panel.h b/ash/capture_mode/search_results_panel.h index 3c6a31a7..30aa235 100644 --- a/ash/capture_mode/search_results_panel.h +++ b/ash/capture_mode/search_results_panel.h
@@ -8,6 +8,7 @@ #include <memory> #include "ash/ash_export.h" +#include "ash/capture_mode/capture_mode_constants.h" #include "ash/capture_mode/capture_mode_session_focus_cycler.h" #include "ash/wm/system_panel_view.h" #include "ui/base/metadata/metadata_header_macros.h" @@ -44,12 +45,24 @@ AshWebView* search_results_view() const { return search_results_view_; } views::Button* close_button() const { return close_button_; } + views::View* animation_view_for_test() { + return GetViewByID(capture_mode::kLoadingAnimationViewId); + } views::Textfield* GetSearchBoxTextfield() const; + // Gets the highlightable views for the search results panel, which may + // include the close button and the search box textfield. Does not include + // the web contents or animation as they need to be handled separately. std::vector<CaptureModeSessionFocusCycler::HighlightableView*> GetHighlightableItems() const; + // Gets the highlightable view for the loading animation view. Returns + // `nullptr` if the loading animation is not available (i.e., the web contents + // are available). + CaptureModeSessionFocusCycler::HighlightableView* + GetHighlightableLoadingAnimation(); + // Gets the inner `WebView` to receive focus events. views::View* GetWebViewForFocus(); @@ -67,6 +80,9 @@ // this view has focus, otherwise returns false. bool IsTextfieldPseudoFocused() const; + // Shows and plays a loading animation in place of the web contents. + void ShowLoadingAnimation(); + // views::View: void AddedToWidget() override; void RemovedFromWidget() override; @@ -91,7 +107,7 @@ // Owned by the views hierarchy. raw_ptr<SunfishSearchBoxView> search_box_view_ = nullptr; - raw_ptr<AshWebView> search_results_view_; + raw_ptr<AshWebView> search_results_view_ = nullptr; raw_ptr<views::Button> close_button_; // Observes display and metrics changes.
diff --git a/ash/capture_mode/sunfish_unittest.cc b/ash/capture_mode/sunfish_unittest.cc index 6683c2e..709f8d7b 100644 --- a/ash/capture_mode/sunfish_unittest.cc +++ b/ash/capture_mode/sunfish_unittest.cc
@@ -915,10 +915,11 @@ // The results panel can be dragged by points outside the search results view // and searchbox textfield. - const gfx::Point draggable_point(search_results_panel->search_results_view() - ->GetBoundsInScreen() - .origin() + - gfx::Vector2d(0, -3)); + const gfx::Point draggable_point( + search_results_panel->animation_view_for_test() + ->GetBoundsInScreen() + .origin() + + gfx::Vector2d(0, -3)); event_generator->MoveMouseTo(draggable_point); // Test that dragging the panel to arbitrary points repositions the panel. @@ -945,7 +946,7 @@ // Start dragging the panel. const gfx::Point draggable_point( - panel->search_results_view()->GetBoundsInScreen().origin() + + panel->animation_view_for_test()->GetBoundsInScreen().origin() + gfx::Vector2d(0, -3)); event_generator->MoveMouseTo(draggable_point); event_generator->PressLeftButton(); @@ -1663,7 +1664,8 @@ // Mock getting a new response from the server. Test the panel is updated. EXPECT_CALL(*search_results_panel, Navigate(testing::_)); - controller->ShowSearchResultsPanel(gfx::ImageSkia(), GURL("kTestUrl2")); + controller->ShowSearchResultsPanel(gfx::ImageSkia()); + controller->NavigateSearchResultsPanel(GURL("kTestUrl2")); } // Tests that the search results panel is closed when starting a new session.
diff --git a/ash/shelf/shelf_tooltip_manager.cc b/ash/shelf/shelf_tooltip_manager.cc index 90672ce..1bfbebe 100644 --- a/ash/shelf/shelf_tooltip_manager.cc +++ b/ash/shelf/shelf_tooltip_manager.cc
@@ -23,6 +23,7 @@ #include "ui/events/types/event_type.h" #include "ui/gfx/geometry/insets.h" #include "ui/views/controls/button/button.h" +#include "ui/views/view_tracker.h" #include "ui/wm/core/window_animations.h" namespace ash { @@ -115,8 +116,15 @@ void ShelfTooltipManager::ShowTooltipWithDelay(views::View* view) { if (ShouldShowTooltipForView(view)) { timer_.Start(FROM_HERE, base::Milliseconds(timer_delay_), - base::BindOnce(&ShelfTooltipManager::ShowTooltip, - weak_factory_.GetWeakPtr(), view)); + base::BindOnce( + [](const base::WeakPtr<ShelfTooltipManager>& self, + views::ViewTracker* view_tracker) { + if (self && view_tracker->view()) { + self->ShowTooltip(view_tracker->view()); + } + }, + weak_factory_.GetWeakPtr(), + base::Owned(std::make_unique<views::ViewTracker>(view)))); } }
diff --git a/ash/shelf/shelf_tooltip_manager_unittest.cc b/ash/shelf/shelf_tooltip_manager_unittest.cc index e9cc9f27..a3d9dde 100644 --- a/ash/shelf/shelf_tooltip_manager_unittest.cc +++ b/ash/shelf/shelf_tooltip_manager_unittest.cc
@@ -25,6 +25,7 @@ #include "ui/events/event_constants.h" #include "ui/events/test/event_generator.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" +#include "ui/views/view_tracker.h" #include "ui/views/widget/widget.h" namespace ash { @@ -52,6 +53,14 @@ bool IsTimerRunning() { return tooltip_manager_->timer_.IsRunning(); } views::Widget* GetTooltip() { return tooltip_manager_->bubble_->GetWidget(); } + void FireTimerNow() { tooltip_manager_->timer_.FireNow(); } + + void RemoveItemAt(int index) { + test_api_->SetAnimationDuration(base::Milliseconds(0)); + test_api_->RemoveItemAt(index); + test_api_->SetAnimationDuration(base::Milliseconds(1)); + } + void ShowTooltipForFirstAppIcon() { EXPECT_GE(shelf_view_->number_of_visible_apps(), 1u); tooltip_manager_->ShowTooltip( @@ -79,6 +88,25 @@ // TODO: Test that the delayed tooltip is shown, without flaky failures. } +TEST_F(ShelfTooltipManagerTest, ShowTooltipWithDelayAndAsyncViewDestruction) { + views::ViewTracker view_tracker( + shelf_view_->first_visible_button_for_testing()); + + // Show tooltip for view with delay. + tooltip_manager_->ShowTooltipWithDelay(view_tracker.view()); + EXPECT_FALSE(tooltip_manager_->IsVisible()); + EXPECT_TRUE(IsTimerRunning()); + + // Destroy view before delay completes. + RemoveItemAt(0); + EXPECT_FALSE(view_tracker.view()); + + // Verify that `tooltip_manager_` no-ops gracefully. + FireTimerNow(); + EXPECT_FALSE(IsTimerRunning()); + EXPECT_FALSE(tooltip_manager_->IsVisible()); +} + TEST_F(ShelfTooltipManagerTest, DoNotShowForInvalidView) { // The manager should not show or start the timer for a null view. tooltip_manager_->ShowTooltip(nullptr);
diff --git a/ash/shelf/shelf_view_test_api.cc b/ash/shelf/shelf_view_test_api.cc index c4000d3e..101c519c 100644 --- a/ash/shelf/shelf_view_test_api.cc +++ b/ash/shelf/shelf_view_test_api.cc
@@ -69,6 +69,10 @@ return item.id; } +void ShelfViewTestAPI::RemoveItemAt(int index) { + shelf_view_->model_->RemoveItemAt(index); +} + views::View* ShelfViewTestAPI::GetViewAt(int index) { return shelf_view_->view_model_->view_at(index); }
diff --git a/ash/shelf/shelf_view_test_api.h b/ash/shelf/shelf_view_test_api.h index 1b110c7..a066433 100644 --- a/ash/shelf/shelf_view_test_api.h +++ b/ash/shelf/shelf_view_test_api.h
@@ -55,6 +55,9 @@ // Adds a new item of the given type to the view. ShelfID AddItem(ShelfItemType type); + // Removes the item at the specified |index| from the view. + void RemoveItemAt(int index); + // Retrieve the view at |index|. views::View* GetViewAt(int index);
diff --git a/ash/strings/BUILD.gn b/ash/strings/BUILD.gn index 7e1ec08b..ef1c8ea 100644 --- a/ash/strings/BUILD.gn +++ b/ash/strings/BUILD.gn
@@ -9,12 +9,11 @@ assert(is_chromeos) -grit("strings") { +grit_strings("strings") { source = "../ash_strings.grd" defines = [ "is_chrome_branded=$is_chrome_branded" ] - outputs = [ "grit/ash_strings.h" ] + - process_file_template(all_chrome_locales, - [ "ash_strings_{{source_name_part}}.pak" ]) + outputs = [ "grit/ash_strings.h" ] + output_prefix = "ash_strings_" } # Creates locale-specific pak files with strings needed for ash_unittests, etc.
diff --git a/ash/webui/camera_app_ui/resources/strings/BUILD.gn b/ash/webui/camera_app_ui/resources/strings/BUILD.gn index d98ede1e..8e9bd48 100644 --- a/ash/webui/camera_app_ui/resources/strings/BUILD.gn +++ b/ash/webui/camera_app_ui/resources/strings/BUILD.gn
@@ -8,12 +8,10 @@ assert(is_chromeos) -grit("strings") { +grit_strings("strings") { source = "camera_strings.grd" defines = chrome_grit_defines outputs = [ "grit/ash_camera_app_strings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "ash_camera_app_strings_$locale.pak" ] - } + output_prefix = "ash_camera_app_strings_" }
diff --git a/ash/webui/common/resources/sea_pen/sea_pen_input_query_element.ts b/ash/webui/common/resources/sea_pen/sea_pen_input_query_element.ts index f47c11d..6587e803 100644 --- a/ash/webui/common/resources/sea_pen/sea_pen_input_query_element.ts +++ b/ash/webui/common/resources/sea_pen/sea_pen_input_query_element.ts
@@ -230,7 +230,7 @@ private onClickInspire_() { const index = Math.floor(Math.random() * SEA_PEN_SAMPLES.length); - this.textValue_ = SEA_PEN_SAMPLES[index].prompt; + this.textValue_ = this.i18n(SEA_PEN_SAMPLES[index].prompt); this.showCreateButton_(); this.searchInputQuery_(); }
diff --git a/base/test/android/javatests/src/org/chromium/base/test/transit/CarryOn.java b/base/test/android/javatests/src/org/chromium/base/test/transit/CarryOn.java index eb0be79..d1bbe061 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/transit/CarryOn.java +++ b/base/test/android/javatests/src/org/chromium/base/test/transit/CarryOn.java
@@ -14,7 +14,7 @@ /** CarryOn is a lightweight, stand-alone ConditionalState not tied to any Station. */ @NullMarked -public abstract class CarryOn extends ConditionalState { +public class CarryOn extends ConditionalState { private final int mId; private final String mName; @@ -60,14 +60,11 @@ /** Convenience method to create a CarryOn from one or more Conditions. */ public static CarryOn fromConditions(Condition... conditions) { - return new CarryOn() { - @Override - public void declareElements(Elements.Builder elements) { - for (Condition condition : conditions) { - elements.declareEnterCondition(condition); - } - } - }; + CarryOn carryOn = new CarryOn(); + for (Condition condition : conditions) { + carryOn.declareEnterCondition(condition); + } + return carryOn; } private static class Drop extends Transition {
diff --git a/base/test/android/javatests/src/org/chromium/base/test/transit/ConditionalState.java b/base/test/android/javatests/src/org/chromium/base/test/transit/ConditionalState.java index 1186c1d4..2a00b5b 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/transit/ConditionalState.java +++ b/base/test/android/javatests/src/org/chromium/base/test/transit/ConditionalState.java
@@ -77,12 +77,24 @@ * constructor and/or override this method. * * @param elements use the #declare___() methods to describe the Elements that define the state. + * @deprecated Declare elements in the constructor or in{@link #declareExtraElements()}. */ + @Deprecated public void declareElements(Elements.Builder elements) {} + /** + * Declare extra {@link Element}s that define this ConditionalState, such as Views. + * + * <p>Transit-layer {@link Station}s and {@link Facility}s can declare Elements in their + * constructor and/or override this method. This method is called after binding a Facility to a + * Station, so some elements are easier to declare here. + */ + public void declareExtraElements() {} + Elements getElements() { if (!mDeclareElementsCalled) { declareElements(mElements); + declareExtraElements(); mElements.consolidate(); mDeclareElementsCalled = true; }
diff --git a/base/test/android/javatests/src/org/chromium/base/test/transit/Elements.java b/base/test/android/javatests/src/org/chromium/base/test/transit/Elements.java index a5bac17e..2cec22b 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/transit/Elements.java +++ b/base/test/android/javatests/src/org/chromium/base/test/transit/Elements.java
@@ -43,8 +43,7 @@ /** * Builder for {@link Elements}. * - * <p>Passed to {@link ConditionalState#declareElements(Elements.Builder)}}, which must declare - * the ConditionalState's elements by calling the declare___() methods. + * <p>Passed to |delayedDeclarations| to add elements with declareElementFactory(). */ public static class Builder { private @Nullable Elements mOwner;
diff --git a/base/test/android/javatests/src/org/chromium/base/test/transit/ScrollableFacility.java b/base/test/android/javatests/src/org/chromium/base/test/transit/ScrollableFacility.java index 8da47fc..636dc6a 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/transit/ScrollableFacility.java +++ b/base/test/android/javatests/src/org/chromium/base/test/transit/ScrollableFacility.java
@@ -59,7 +59,7 @@ @CallSuper @Override - public void declareElements(Elements.Builder elements) { + public void declareExtraElements() { mItems = new ArrayList<>(); declareItems(new ItemsBuilder(mItems)); @@ -72,13 +72,13 @@ switch (item.mPresence) { case Presence.ABSENT: assert item.mViewSpec != null; - elements.declareNoView(item.mViewSpec.getViewMatcher()); + declareNoView(item.mViewSpec.getViewMatcher()); break; case Presence.PRESENT_AND_ENABLED: case Presence.PRESENT_AND_DISABLED: assert item.mViewSpec != null; assert item.mViewElementOptions != null; - elements.declareView(item.mViewSpec, item.mViewElementOptions); + declareView(item.mViewSpec, item.mViewElementOptions); break; case Presence.MAYBE_PRESENT: case Presence.MAYBE_PRESENT_STUB: @@ -449,8 +449,8 @@ } @Override - public void declareElements(Elements.Builder elements) { - viewElement = elements.declareView(mItem.getViewSpec(), mItem.getViewElementOptions()); + public void declareExtraElements() { + viewElement = declareView(mItem.getViewSpec(), mItem.getViewElementOptions()); } /** Select the item and trigger its |selectHandler|. */
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 708c204..25099af9 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -512,9 +512,10 @@ # Linux-specific compiler flags setup. # ------------------------------------ if (use_icf && (!is_apple || use_lld)) { - if (is_fuchsia) { + if (is_fuchsia || is_android) { # TODO(crbug.com/415810137): A temporary workaround to avoid crashing # blink on fuchsia. + # TODO(crbug.com/415842701): blink also crashing on android. ldflags += [ "-Wl,--icf=safe" ] } else { ldflags += [ "-Wl,--icf=all" ]
diff --git a/build/config/locales.gni b/build/config/locales.gni index e1f23cb53..e9396dc 100644 --- a/build/config/locales.gni +++ b/build/config/locales.gni
@@ -109,6 +109,13 @@ "zu", ] + pseudolocales +all_chrome_genders = [ + "OTHER", + "MASCULINE", + "FEMININE", + "NEUTER", +] + if (is_ios) { # Chrome on iOS uses "es-MX" and "pt" for "es-419" and "pt-BR". all_chrome_locales -= [
diff --git a/build/config/mac/rules.gni b/build/config/mac/rules.gni index b4ee8b8..c32a3e6 100644 --- a/build/config/mac/rules.gni +++ b/build/config/mac/rules.gni
@@ -314,6 +314,7 @@ visibility = [ ":$_framework_target+link" ] framework_dirs = [ root_out_dir ] frameworks = [ _framework_name ] + inputs = [ "$root_out_dir/$_framework_name" ] } create_bundle(_framework_target) {
diff --git a/build/fuchsia/test/BUILD.gn b/build/fuchsia/test/BUILD.gn index 333dc48..72e48c0 100644 --- a/build/fuchsia/test/BUILD.gn +++ b/build/fuchsia/test/BUILD.gn
@@ -18,3 +18,9 @@ "gs_util_wrapper.py", ] } + +python_library("component_storage_test") { + testonly = true + pydeps_file = "component_storage_test.pydeps" + data_deps = [ "//build/config/fuchsia:deployment_resources" ] +}
diff --git a/build/fuchsia/test/component_storage_test.py b/build/fuchsia/test/component_storage_test.py new file mode 100755 index 0000000..346333b23 --- /dev/null +++ b/build/fuchsia/test/component_storage_test.py
@@ -0,0 +1,30 @@ +#!/usr/bin/env vpython3 +# Copyright 2025 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +""" Runs component_storage tests on a fuchsia emulator. """ + +import logging +import os +import subprocess +import sys + +from test_env_setup import wait_for_env_setup + +LOG_DIR = os.environ.get('ISOLATED_OUTDIR', '/tmp') + + +def main() -> int: + """Entry of the test.""" + proc = subprocess.Popen([ + os.path.join(os.path.dirname(__file__), 'test_env_setup.py'), + '--logs-dir', LOG_DIR + ]) + assert wait_for_env_setup(proc, LOG_DIR) + logging.warning('test_env_setup.py is running on process %s', proc.pid) + proc.terminate() + return proc.wait() + + +if __name__ == '__main__': + sys.exit(main())
diff --git a/build/fuchsia/test/component_storage_test.pydeps b/build/fuchsia/test/component_storage_test.pydeps new file mode 100644 index 0000000..c639c259 --- /dev/null +++ b/build/fuchsia/test/component_storage_test.pydeps
@@ -0,0 +1,35 @@ +# Generated by running: +# build/print_python_deps.py --root build/fuchsia/test --output build/fuchsia/test/component_storage_test.pydeps build/fuchsia/test/component_storage_test.py +../../util/lib/proto/average.py +../../util/lib/proto/count.py +../../util/lib/proto/data_points.py +../../util/lib/proto/measure.py +../../util/lib/proto/measures.py +../../util/lib/proto/metric.py +../../util/lib/proto/test_script_metrics_pb2.py +../../util/lib/proto/time_consumption.py +boot_device.py +browser_runner.py +common.py +compatible_utils.py +component_storage_test.py +ffx_emulator.py +ffx_integration.py +flash_device.py +isolate_daemon.py +lockfile.py +log_manager.py +modification_waiter.py +monitors.py +publish_package.py +repeating_log.py +run_blink_test.py +run_executable_test.py +run_telemetry_test.py +run_test.py +run_webpage_test.py +serve_repo.py +start_emulator.py +test_connection.py +test_env_setup.py +test_runner.py
diff --git a/build/fuchsia/test/coveragetest.py b/build/fuchsia/test/coveragetest.py index 88f6c522..7ee986d 100755 --- a/build/fuchsia/test/coveragetest.py +++ b/build/fuchsia/test/coveragetest.py
@@ -22,7 +22,7 @@ TESTED_FILES = [ 'bundled_test_runner.py', 'common.py', 'ffx_emulator.py', 'modification_waiter.py', 'monitors.py', 'serial_boot_device.py', - 'test_env_setup.py', 'test_server.py', 'version.py' + 'test_server.py', 'version.py' ]
diff --git a/build/fuchsia/test/test_env_setup.py b/build/fuchsia/test/test_env_setup.py index bc46c79..11380b1 100755 --- a/build/fuchsia/test/test_env_setup.py +++ b/build/fuchsia/test/test_env_setup.py
@@ -21,8 +21,9 @@ import argparse import os import sys +import time -from subprocess import CompletedProcess +from subprocess import CompletedProcess, Popen from typing import List import run_test @@ -77,5 +78,18 @@ return run_test.main() +def wait_for_env_setup(proc: Popen, logs_dir: str) -> bool: + """ Waits for the test_env_setup.py process to be ready, returns false if + the process terminated unexpected. """ + pid_file = os.path.join(logs_dir, + 'test_env_setup.' + str(proc.pid) + '.pid') + while not os.path.isfile(pid_file): + proc.poll() + if proc.returncode: + return False + time.sleep(1) + return True + + if __name__ == '__main__': sys.exit(setup_env())
diff --git a/build/fuchsia/test/test_env_setup_unittests.py b/build/fuchsia/test/test_env_setup_unittests.py deleted file mode 100755 index 8dff717..0000000 --- a/build/fuchsia/test/test_env_setup_unittests.py +++ /dev/null
@@ -1,97 +0,0 @@ -#!/usr/bin/env vpython3 -# Copyright 2024 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -"""File for testing test_env_setup.py.""" - -import os -import subprocess -import time -import unittest - -from compatible_utils import running_unattended - -# TODO(crbug.com/352409265): Try to run the following tests on trybot. - - -# Test names should be self-explained, no point of adding function docstring. -# pylint: disable=missing-function-docstring - - -class TestEnvSetupTests(unittest.TestCase): - """Test class.""" - - @staticmethod - def _merge_env(env: dict, env2: dict) -> dict: - if env and env2: - return {**env, **env2} - # Always copy to avoid changing os.environ. - if env: - return {**env} - if env2: - return {**env2} - return {} - - def _start_test_env(self, env: dict = None) -> subprocess.Popen: - proc = subprocess.Popen([ - os.path.join(os.path.dirname(__file__), 'test_env_setup.py'), - '--logs-dir', '/tmp/test_env_setup' - ], - env=TestEnvSetupTests._merge_env( - os.environ, env)) - while not os.path.isfile('/tmp/test_env_setup/test_env_setup.' + - str(proc.pid) + '.pid'): - proc.poll() - self.assertIsNone(proc.returncode) - time.sleep(1) - return proc - - def _run_without_packages(self, env: dict = None): - proc = self._start_test_env(env) - proc.terminate() - proc.wait() - - def test_run_without_packages(self): - if running_unattended(): - # The test needs sdk and images to run and it's not designed to work - # on platforms other than linux. - return - self._run_without_packages() - - def test_run_without_packages_unattended(self): - if running_unattended(): - return - # Do not impact the environment of the current process. - self._run_without_packages({'CHROME_HEADLESS': '1'}) - - def _run_with_base_tests(self, env: dict = None): - env = TestEnvSetupTests._merge_env( - {'FFX_ISOLATE_DIR': '/tmp/test_env_setup/daemon'}, env) - proc = self._start_test_env(env) - try: - subprocess.run([ - os.path.join(os.path.dirname(__file__), - '../../out/fuchsia/bin/run_base_unittests'), - '--logs-dir', '/tmp/test_env_setup', '--device' - ], - env=TestEnvSetupTests._merge_env(os.environ, env), - check=True, - stdout=subprocess.DEVNULL, - stderr=subprocess.DEVNULL) - finally: - proc.terminate() - proc.wait() - - def test_run_with_base_tests(self): - if running_unattended(): - return - self._run_with_base_tests() - - def test_run_with_base_tests_unattended(self): - if running_unattended(): - return - self._run_with_base_tests({'CHROME_HEADLESS': '1'}) - - -if __name__ == '__main__': - unittest.main()
diff --git a/cc/base/features.cc b/cc/base/features.cc index fb35620..188d451 100644 --- a/cc/base/features.cc +++ b/cc/base/features.cc
@@ -121,10 +121,6 @@ const base::FeatureParam<double> kWaitForLateScrollEventsDeadlineRatio{ &kWaitForLateScrollEvents, "deadline_ratio", 0.333}; -BASE_FEATURE(kNonBatchedCopySharedImage, - "NonBatchedCopySharedImage", - base::FEATURE_ENABLED_BY_DEFAULT); - BASE_FEATURE(kDontAlwaysPushPictureLayerImpls, "DontAlwaysPushPictureLayerImpls", base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/cc/base/features.h b/cc/base/features.h index 4e96f70..6a3f3f6 100644 --- a/cc/base/features.h +++ b/cc/base/features.h
@@ -83,10 +83,6 @@ // to when tracing is enabled. CC_BASE_EXPORT BASE_DECLARE_FEATURE(kMetricsTracingCalculationReduction); -// When enabled we will submit the 'CopySharedImage' in one call and not batch -// it up into 4MiB increments. -CC_BASE_EXPORT BASE_DECLARE_FEATURE(kNonBatchedCopySharedImage); - // Currently there is a race between OnBeginFrames from the GPU process and // input arriving from the Browser process. Due to this we can start to produce // a frame while scrolling without any input events. Late arriving events are
diff --git a/cc/layers/layer.h b/cc/layers/layer.h index bd49110..e6de243 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h
@@ -663,19 +663,6 @@ void SetHasClipNode(bool val) { SetBitFlag(val, kHasClipNodeFlagMask); } bool has_clip_node() const { return GetBitFlag(kHasClipNodeFlagMask); } - // Sets that the content shown in this layer may be a video. This may be used - // by the system compositor to distinguish between animations updating the - // screen and video, which the user would be watching. This allows - // optimizations like turning off the display when video is not playing, - // without interfering with video playback. - void SetMayContainVideo(bool value) { - SetBitFlag(value, kMayContainVideoFlagMask, /*invalidate=*/false, - /*needs_push=*/true); - } - bool may_contain_video() const { - return GetBitFlag(kMayContainVideoFlagMask); - } - // Stable identifier for clients. See comment in cc/paint/element_id.h. void SetElementId(ElementId id); ElementId element_id() const { return inputs_.Read(*this).element_id; } @@ -921,6 +908,19 @@ // generated or committed. bool IsPropertyChangeAllowed() const; + // Sets that the content shown in this layer may be a video. This may be used + // by the system compositor to distinguish between animations updating the + // screen and video, which the user would be watching. This allows + // optimizations like turning off the display when video is not playing, + // without interfering with video playback. + void SetMayContainVideo(bool value) { + SetBitFlag(value, kMayContainVideoFlagMask, /*invalidate=*/false, + /*needs_push=*/true); + } + bool may_contain_video() const { + return GetBitFlag(kMayContainVideoFlagMask); + } + void IncreasePaintCount() { if (debug_info_.Read(*this)) ++debug_info_.Write(*this)->paint_count;
diff --git a/cc/layers/surface_layer.cc b/cc/layers/surface_layer.cc index cd2b306..779c014e 100644 --- a/cc/layers/surface_layer.cc +++ b/cc/layers/surface_layer.cc
@@ -25,8 +25,7 @@ } SurfaceLayer::SurfaceLayer() - : may_contain_video_(false), - deadline_in_frames_(0u), + : deadline_in_frames_(0u), stretch_content_to_fill_bounds_(false), surface_hit_testable_(false), has_pointer_events_none_(false), @@ -37,7 +36,6 @@ UpdateSubmissionStateCB update_submission_state_callback) : update_submission_state_callback_( std::move(update_submission_state_callback)), - may_contain_video_(false), deadline_in_frames_(0u), stretch_content_to_fill_bounds_(false), surface_hit_testable_(false), @@ -140,11 +138,6 @@ override_child_paint_flags_.Write(*this) = true; } -void SurfaceLayer::SetMayContainVideo(bool may_contain_video) { - may_contain_video_.Write(*this) = may_contain_video; - SetNeedsCommit(); -} - std::unique_ptr<LayerImpl> SurfaceLayer::CreateLayerImpl( LayerTreeImpl* tree_impl) const { auto layer_impl = SurfaceLayerImpl::Create(
diff --git a/cc/layers/surface_layer.h b/cc/layers/surface_layer.h index b19abae..c678142 100644 --- a/cc/layers/surface_layer.h +++ b/cc/layers/surface_layer.h
@@ -61,7 +61,7 @@ void SetOverrideChildPaintFlags(bool override_child_paint_flags); - void SetMayContainVideo(bool may_contain_video); + using Layer::SetMayContainVideo; // Layer overrides. std::unique_ptr<LayerImpl> CreateLayerImpl( @@ -98,7 +98,6 @@ ProtectedSequenceWritable<UpdateSubmissionStateCB> update_submission_state_callback_; - ProtectedSequenceReadable<bool> may_contain_video_; ProtectedSequenceReadable<viz::SurfaceRange> surface_range_; ProtectedSequenceWritable<std::optional<uint32_t>> deadline_in_frames_;
diff --git a/cc/raster/one_copy_raster_buffer_provider.cc b/cc/raster/one_copy_raster_buffer_provider.cc index 71b418c..0d747f6 100644 --- a/cc/raster/one_copy_raster_buffer_provider.cc +++ b/cc/raster/one_copy_raster_buffer_provider.cc
@@ -138,7 +138,6 @@ max_copy_texture_chromium_size) : kMaxBytesPerCopyOperation), use_partial_raster_(use_partial_raster), - bytes_scheduled_since_last_flush_(0), tile_overlay_candidate_(is_overlay_candidate), staging_pool_(std::move(task_runner), worker_context_provider, @@ -397,39 +396,9 @@ } } - if (base::FeatureList::IsEnabled(features::kNonBatchedCopySharedImage)) { - ri->CopySharedImage(staging_buffer->client_shared_image->mailbox(), - backing->shared_image()->mailbox(), 0, 0, 0, 0, - rect_to_copy.width(), rect_to_copy.height()); - } else { - int bytes_per_row = viz::ResourceSizes::UncheckedWidthInBytes<int>( - rect_to_copy.width(), staging_buffer->format); - int chunk_size_in_rows = - std::max(1, max_bytes_per_copy_operation_ / bytes_per_row); - // Align chunk size to 4. Required to support compressed texture formats. - chunk_size_in_rows = MathUtil::UncheckedRoundUp(chunk_size_in_rows, 4); - int y = 0; - int height = rect_to_copy.height(); - while (y < height) { - // Copy at most |chunk_size_in_rows|. - int rows_to_copy = std::min(chunk_size_in_rows, height - y); - DCHECK_GT(rows_to_copy, 0); - - ri->CopySharedImage(staging_buffer->client_shared_image->mailbox(), - backing->shared_image()->mailbox(), 0, y, 0, y, - rect_to_copy.width(), rows_to_copy); - y += rows_to_copy; - - // Increment |bytes_scheduled_since_last_flush_| by the amount of memory - // used for this copy operation. - bytes_scheduled_since_last_flush_ += rows_to_copy * bytes_per_row; - - if (bytes_scheduled_since_last_flush_ >= max_bytes_per_copy_operation_) { - ri->ShallowFlushCHROMIUM(); - bytes_scheduled_since_last_flush_ = 0; - } - } - } + ri->CopySharedImage(staging_buffer->client_shared_image->mailbox(), + backing->shared_image()->mailbox(), 0, 0, 0, 0, + rect_to_copy.width(), rect_to_copy.height()); if (query_target != GL_NONE) ri->EndQueryEXT(query_target);
diff --git a/cc/raster/one_copy_raster_buffer_provider.h b/cc/raster/one_copy_raster_buffer_provider.h index 057728e6..e32730d 100644 --- a/cc/raster/one_copy_raster_buffer_provider.h +++ b/cc/raster/one_copy_raster_buffer_provider.h
@@ -139,10 +139,6 @@ const raw_ptr<viz::RasterContextProvider> worker_context_provider_; const int max_bytes_per_copy_operation_; const bool use_partial_raster_; - - // Context lock must be acquired when accessing this member. - int bytes_scheduled_since_last_flush_; - const bool tile_overlay_candidate_; StagingBufferPool staging_pool_;
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index ce68883..9d076c8 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -1823,9 +1823,18 @@ renaming_destinations = [] foreach(_locale, platform_pak_locales) { - renaming_sources += - [ "$target_gen_dir/${_variant}_paks/locales/$_locale.pak" ] - renaming_destinations += [ "locales/$_locale.pak" ] + if (translate_genders) { + renaming_sources += process_file_template( + all_chrome_genders, + "$target_gen_dir/${_variant}_paks/locales/${_locale}_{{source_name_part}}.pak") + renaming_destinations += process_file_template( + all_chrome_genders, + "locales/${_locale}_{{source_name_part}}.pak") + } else { + renaming_sources += + [ "$target_gen_dir/${_variant}_paks/locales/${_locale}.pak" ] + renaming_destinations += [ "locales/${_locale}.pak" ] + } } treat_as_locale_paks = true
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/ArchivedTabsDialogCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/ArchivedTabsDialogCoordinator.java index 7c8cbc07..ab08bd9 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/ArchivedTabsDialogCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/ArchivedTabsDialogCoordinator.java
@@ -18,6 +18,7 @@ import android.text.style.ForegroundColorSpan; import android.util.Size; import android.view.LayoutInflater; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; @@ -183,8 +184,8 @@ * dialog when no archived tabs remain. */ private final Callback<Integer> mTabCountObserver = - (count) -> { - if (count == 0 && !ArchivedTabsDialogCoordinator.this.mIsOpeningLastTab) { + (tabCount) -> { + if (tabCount == 0 && !ArchivedTabsDialogCoordinator.this.mIsOpeningLastItem) { // Post task to allow the last tab to be unregistered. PostTask.postTask( TaskTraits.UI_DEFAULT, @@ -195,7 +196,7 @@ }; /** Used to override the default tab click behavior to restore/open the tab. */ - private final GridCardOnClickListenerProvider mGridCardOnCLickListenerProvider = + private final GridCardOnClickListenerProvider mGridCardOnClickListenerProvider = new GridCardOnClickListenerProvider() { @Nullable @Override @@ -208,12 +209,20 @@ public TabActionListener openTabGridDialog(@NonNull String syncId) { return new TabActionListener() { @Override - public void run(View view, int tabId) { + public void run( + View view, int tabId, @Nullable MotionEvent triggeringMotionEvent) { // Intentional no-op. } @Override - public void run(View view, String syncId) { + public void run( + View view, + String syncId, + @Nullable MotionEvent triggeringMotionEvent) { + SavedTabGroup savedTabGroup = mTabGroupSyncService.getGroup(syncId); + mIsOpeningLastItem = + getArchivedTabCount() == savedTabGroup.savedTabs.size(); + TabSwitcherPaneBase tabSwitcherPaneBase = (TabSwitcherPaneBase) mPaneManagerSupplier @@ -242,7 +251,7 @@ @Override public void onTabSelecting(int tabId, boolean fromActionButton) { - mIsOpeningLastTab = mArchivedTabModel.getCount() == 1; + mIsOpeningLastItem = getArchivedTabCount() == 1; Tab tab = mArchivedTabModel.getTabById(tabId); mArchivedTabModelOrchestrator .getTabArchiver() @@ -352,7 +361,7 @@ private OnTabSelectingListener mOnTabSelectingListener; private PropertyModel mIphMessagePropertyModel; private int mSnackbarOverrideToken; - private boolean mIsOpeningLastTab; + private boolean mIsOpeningLastItem; private boolean mIsShowing; /** @@ -506,7 +515,7 @@ } mOnTabSelectingListener = onTabSelectingListener; - mArchivedTabModel.getTabCountSupplier().addObserver(mTabCountObserver); + mArchivedTabModelOrchestrator.getTabCountSupplier().addObserver(mTabCountObserver); mUndoBarController.initialize(); TabListEditorController controller = mTabListEditorCoordinator.getController(); @@ -641,7 +650,7 @@ controller.setLifecycleObserver(null); mBackPressManager.removeHandler(mTabListEditorCoordinator.getController()); mTabArchiveSettings.removeObserver(mTabArchiveSettingsObserver); - mArchivedTabModel.getTabCountSupplier().removeObserver(mTabCountObserver); + mArchivedTabModelOrchestrator.getTabCountSupplier().removeObserver(mTabCountObserver); mSnackbarOverrideToken = TokenHolder.INVALID_TOKEN; mIsShowing = false; mTabSwitcherRecyclerView.get().setBlockTouchInput(false); @@ -668,7 +677,7 @@ @VisibleForTesting void updateTitle() { - int numInactiveTabs = mArchivedTabModel.getCount(); + int numInactiveTabs = getArchivedTabCount(); String title = mActivity .getResources() @@ -697,7 +706,7 @@ mSnackbarManager, /* bottomSheetController= */ null, TabProperties.TabActionState.CLOSABLE, - mGridCardOnCLickListenerProvider, + mGridCardOnClickListenerProvider, mModalDialogManager, mDesktopWindowStateManager, /* edgeToEdgeSupplier= */ null, @@ -758,6 +767,10 @@ }); } + private int getArchivedTabCount() { + return mArchivedTabModelOrchestrator.getTabCountSupplier().get(); + } + private void restoreArchivedTabs(List<Tab> tabs) { mArchivedTabModelOrchestrator .getTabArchiver() @@ -865,7 +878,7 @@ } GridCardOnClickListenerProvider getGridCardOnClickListenerProviderForTesting() { - return mGridCardOnCLickListenerProvider; + return mGridCardOnClickListenerProvider; } /** Returns the Edge to edge pad adjuster. */
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/ArchivedTabsMessageService.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/ArchivedTabsMessageService.java index 1e9ad786..cc066e9 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/ArchivedTabsMessageService.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/ArchivedTabsMessageService.java
@@ -12,6 +12,7 @@ import static org.chromium.chrome.browser.tasks.tab_management.ArchivedTabsCardViewProperties.WIDTH; import android.app.Activity; +import android.graphics.drawable.GradientDrawable; import android.util.Size; import android.view.LayoutInflater; import android.view.View; @@ -45,6 +46,7 @@ import org.chromium.chrome.browser.tasks.tab_management.TabListCoordinator.TabListMode; import org.chromium.chrome.browser.tasks.tab_management.TabListModel.CardProperties.ModelType; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcherMessageManager.MessageUpdateObserver; +import org.chromium.chrome.browser.theme.SurfaceColorUpdateUtils; import org.chromium.chrome.browser.ui.edge_to_edge.EdgeToEdgeController; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.components.browser_ui.desktop_windowing.DesktopWindowStateManager; @@ -107,6 +109,11 @@ }); } mEndIconView = mCustomCardView.findViewById(R.id.end_image); + GradientDrawable cardViewBg = + (GradientDrawable) + mCustomCardView.findViewById(R.id.card).getBackground(); + cardViewBg.setColor( + SurfaceColorUpdateUtils.getMessageCardBackgroundColor(mActivity)); PropertyModelChangeProcessor.create( mCustomCardModel, mCustomCardView, ArchivedTabsCardViewBinder::bind); }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardView.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardView.java index 545d19b..df18aed 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardView.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardView.java
@@ -15,8 +15,8 @@ import android.widget.LinearLayout; import org.chromium.base.Callback; +import org.chromium.chrome.browser.theme.SurfaceColorUpdateUtils; import org.chromium.chrome.tab_ui.R; -import org.chromium.components.browser_ui.styles.SemanticColorUtils; import org.chromium.ui.widget.ButtonCompat; import org.chromium.ui.widget.ChromeImageView; import org.chromium.ui.widget.TextViewWithLeading; @@ -171,7 +171,8 @@ } // Set dynamic color. GradientDrawable gradientDrawable = (GradientDrawable) getBackground(); - gradientDrawable.setColor(SemanticColorUtils.getCardBackgroundColor(getContext())); + gradientDrawable.setColor( + SurfaceColorUpdateUtils.getMessageCardBackgroundColor(getContext())); } /**
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java index c85db0f..86328b2 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java
@@ -1088,6 +1088,7 @@ TabUiUtils.closeTabGroup( mCurrentTabGroupModelFilterSupplier.get(), tabId, + /* allowUndo= */ true, hideTabGroups, /* didCloseCallback= */ null); } else if (menuId == R.id.delete_shared_group) {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallback.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallback.java index 273ef77..461251e 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallback.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallback.java
@@ -270,7 +270,9 @@ if (simpleViewHolder.model.get(CARD_TYPE) == TAB) { mTabClosedListener.run( - viewHolder.itemView, simpleViewHolder.model.get(TabProperties.TAB_ID)); + viewHolder.itemView, + simpleViewHolder.model.get(TabProperties.TAB_ID), + /* triggeringMotionEvent= */ null); RecordUserAction.record("MobileStackViewSwipeCloseTab." + mComponentName); } else if (simpleViewHolder.model.get(CARD_TYPE) == MESSAGE) {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java index 61bbfd6..fcdb81dd 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java
@@ -6,12 +6,16 @@ import static org.chromium.chrome.browser.tasks.tab_management.TabListModel.CardProperties.CARD_ALPHA; +import android.annotation.SuppressLint; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.util.Size; +import android.view.GestureDetector; +import android.view.MotionEvent; import android.view.View; +import android.view.View.OnTouchListener; import android.view.ViewGroup; import android.view.ViewStub; import android.widget.FrameLayout; @@ -21,6 +25,7 @@ import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import androidx.core.graphics.drawable.DrawableCompat; import androidx.core.view.ViewCompat; import androidx.core.widget.ImageViewCompat; @@ -41,6 +46,7 @@ import org.chromium.chrome.tab_ui.R; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.util.MotionEventUtils; import org.chromium.ui.widget.ChromeImageView; import org.chromium.ui.widget.ViewLookupCachingFrameLayout; @@ -194,6 +200,8 @@ TabActionListener tabActionListener = data == null ? null : data.tabActionListener; setNullableClickListener( tabActionListener, view.fastFindViewById(R.id.action_button), model); + setNullablePeripheralClickListener( + tabActionListener, view.fastFindViewById(R.id.action_button), model); boolean showOverflowButton = data == null ? false : data.type == TabActionButtonType.OVERFLOW; @@ -288,16 +296,44 @@ view.setOnClickListener(null); } else { view.setOnClickListener( - v -> { - if (propertyModel.containsKey(TabProperties.TAB_GROUP_SYNC_ID)) { - listener.run(v, propertyModel.get(TabProperties.TAB_GROUP_SYNC_ID)); - } else { - listener.run(v, propertyModel.get(TabProperties.TAB_ID)); - } - }); + v -> + runTabActionListener( + listener, v, propertyModel, /* triggeringMotionEvent= */ null)); } } + /** + * Sets an {@link OnPeripheralClickListener} on the given view to intercept clicks from + * peripherals. + * + * <p>Note that this method cannot replace {@link #setNullableClickListener(TabActionListener, + * View, PropertyModel)} as an {@link android.view.View.OnClickListener} is needed to handle + * clicks not from peripherals, accessibility actions, and the "confirm" key event. + * + * @param tabActionListener the {@link TabActionListener} to run when a click is detected. + * @param view the View to receive clicks. + * @param propertyModel contains data to determine how to run the {@link TabActionListener}. + */ + static void setNullablePeripheralClickListener( + @Nullable TabActionListener tabActionListener, + @NonNull View view, + @NonNull PropertyModel propertyModel) { + if (tabActionListener == null) { + view.setOnTouchListener(null); + return; + } + + view.setOnTouchListener( + new OnPeripheralClickListener( + view, + triggeringMotionEvent -> + runTabActionListener( + tabActionListener, + view, + propertyModel, + triggeringMotionEvent))); + } + static void setNullableLongClickListener( @Nullable TabActionListener listener, @NonNull View view, @@ -307,16 +343,29 @@ } else { view.setOnLongClickListener( v -> { - if (propertyModel.containsKey(TabProperties.TAB_GROUP_SYNC_ID)) { - listener.run(v, propertyModel.get(TabProperties.TAB_GROUP_SYNC_ID)); - } else { - listener.run(v, propertyModel.get(TabProperties.TAB_ID)); - } + runTabActionListener( + listener, v, propertyModel, /* triggeringMotionEvent= */ null); return true; }); } } + private static void runTabActionListener( + @NonNull TabActionListener tabActionListener, + @NonNull View view, + @NonNull PropertyModel propertyModel, + @Nullable MotionEvent triggeringMotionEvent) { + if (propertyModel.containsKey(TabProperties.TAB_GROUP_SYNC_ID)) { + tabActionListener.run( + view, + propertyModel.get(TabProperties.TAB_GROUP_SYNC_ID), + triggeringMotionEvent); + } else { + tabActionListener.run( + view, propertyModel.get(TabProperties.TAB_ID), triggeringMotionEvent); + } + } + private static void fetchPriceDrop( PropertyModel model, Callback<ShoppingPersistedTabData.PriceDrop> callback, @@ -540,4 +589,55 @@ sThumbnailFetcherForTesting = fetcher; ResettersForTesting.register(() -> sThumbnailFetcherForTesting = null); } + + /** + * An {@link OnTouchListener} to detect a click from peripherals. + * + * <p>If a {@link MotionEvent} comes from a peripheral, this listener will consume it. Then, if + * the event completes a click action, the {@link OnPeripheralClickRunnable} will be run. + * + * <p>If a {@link MotionEvent} doesn't come from a peripheral, this listener is a no-op. It + * won't consume or interpret the event. + */ + @VisibleForTesting + static final class OnPeripheralClickListener implements OnTouchListener { + + @NonNull private final GestureDetector mGestureDetector; + + OnPeripheralClickListener( + @NonNull View view, @NonNull OnPeripheralClickRunnable onPeripheralClickRunnable) { + mGestureDetector = + new GestureDetector( + view.getContext(), + new GestureDetector.SimpleOnGestureListener() { + + @Override + public boolean onSingleTapUp(@NonNull MotionEvent e) { + onPeripheralClickRunnable.run(e); + return true; + } + }); + } + + @SuppressLint("ClickableViewAccessibility") + @Override + public boolean onTouch(View v, MotionEvent event) { + if (!MotionEventUtils.isMouseEvent(event)) { + return false; + } + + mGestureDetector.onTouchEvent(event); + return true; + } + + interface OnPeripheralClickRunnable { + + /** + * Called when a peripheral click is detected. + * + * @param triggeringMotionEvent {@link MotionEvent} that triggered the click. + */ + void run(@NonNull MotionEvent triggeringMotionEvent); + } + } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListGroupMenuCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListGroupMenuCoordinator.java index 970da51..12d0c4ae 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListGroupMenuCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListGroupMenuCoordinator.java
@@ -7,6 +7,7 @@ import android.app.Activity; import android.content.Context; import android.content.res.Resources; +import android.view.MotionEvent; import android.view.View; import androidx.annotation.NonNull; @@ -66,7 +67,7 @@ TabListMediator.TabActionListener getTabActionListener() { return new TabListMediator.TabActionListener() { @Override - public void run(View view, int tabId) { + public void run(View view, int tabId, @Nullable MotionEvent triggeringMotionEvent) { @Nullable TabModel tabModel = getTabModel(); if (tabModel == null) return; @@ -86,7 +87,7 @@ } @Override - public void run(View view, String syncId) { + public void run(View view, String syncId, @Nullable MotionEvent triggeringMotionEvent) { // Intentional no-op. } };
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListGroupMenuCoordinatorUnitTest.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListGroupMenuCoordinatorUnitTest.java index 427c373..b4fcd8e 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListGroupMenuCoordinatorUnitTest.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListGroupMenuCoordinatorUnitTest.java
@@ -246,7 +246,9 @@ when(mCollaborationService.getCurrentUserRoleForGroup(COLLABORATION_ID1)) .thenReturn(MemberRole.MEMBER); - mMenuCoordinator.getTabActionListener().run(mView, TAB_ID); + mMenuCoordinator + .getTabActionListener() + .run(mView, TAB_ID, /* triggeringMotionEvent= */ null); verify(mMenuCoordinator).buildMenuActionItems(any(), eq(TAB_GROUP_TOKEN)); verify(mMenuCoordinator) @@ -269,7 +271,9 @@ when(mCollaborationService.getCurrentUserRoleForGroup(COLLABORATION_ID1)) .thenReturn(MemberRole.OWNER); - mMenuCoordinator.getTabActionListener().run(mView, TAB_ID); + mMenuCoordinator + .getTabActionListener() + .run(mView, TAB_ID, /* triggeringMotionEvent= */ null); verify(mMenuCoordinator).buildMenuActionItems(any(), eq(TAB_GROUP_TOKEN)); verify(mMenuCoordinator)
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java index 695e571..6ec95983 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -28,6 +28,7 @@ import android.text.TextUtils; import android.util.Pair; import android.util.Size; +import android.view.MotionEvent; import android.view.View; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; @@ -114,6 +115,7 @@ import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey; import org.chromium.ui.modelutil.SimpleRecyclerViewAdapter; +import org.chromium.ui.util.MotionEventUtils; import org.chromium.ui.util.XrUtils; import org.chromium.url.GURL; @@ -185,13 +187,27 @@ boolean isReorderAction(int action); } - /** Interface for implementing a {@link Runnable} that takes a tabId for a generic action. */ + /** Interface for implementing a generic tab action. */ public interface TabActionListener { - /** Run the action for the given view and tabId. */ - void run(View view, int tabId); + /** + * Runs the action for the given {@code view} and {@code tabId}. + * + * @param view {@link View} for the tab. + * @param tabId ID of the tab. + * @param triggeringMotionEvent {@link MotionEvent} that triggered the action; it will be + * {@code null} if the action is not a result of direct interpretation of {@link + * MotionEvent}s. For example, this parameter will be {@code null} if the action is run + * by a {@link android.view.View.OnClickListener} where {@link MotionEvent} is not + * available. + */ + void run(View view, int tabId, @Nullable MotionEvent triggeringMotionEvent); - /** Run the action for the given view and tab group sync id. */ - void run(View view, String syncId); + /** + * Runs the action for the given {@code view} and tab group {@code syncId}. + * + * @see #run(View, int, MotionEvent) + */ + void run(View view, String syncId, @Nullable MotionEvent triggeringMotionEvent); } /** @@ -392,7 +408,7 @@ private final TabActionListener mTabSelectedListener = new TabActionListener() { @Override - public void run(View view, int tabId) { + public void run(View view, int tabId, @Nullable MotionEvent triggeringMotionEvent) { if (mModelList.indexFromTabId(tabId) == TabModel.INVALID_TAB_INDEX) return; mNextTabId = tabId; @@ -429,7 +445,8 @@ } @Override - public void run(View view, String syncId) { + public void run( + View view, String syncId, @Nullable MotionEvent triggeringMotionEvent) { // Intentional no-op. } @@ -462,7 +479,7 @@ private final TabActionListener mSelectableTabOnClickListener = new TabActionListener() { @Override - public void run(View view, int tabId) { + public void run(View view, int tabId, @Nullable MotionEvent triggeringMotionEvent) { SelectionDelegate<TabListEditorItemSelectionId> selectionDelegate = getTabSelectionDelegate(); assert selectionDelegate != null; @@ -490,7 +507,8 @@ } @Override - public void run(View view, String syncId) { + public void run( + View view, String syncId, @Nullable MotionEvent triggeringMotionEvent) { SelectionDelegate<TabListEditorItemSelectionId> selectionDelegate = getTabSelectionDelegate(); assert selectionDelegate != null; @@ -1153,7 +1171,8 @@ mTabClosedListener = new TabActionListener() { @Override - public void run(View view, int tabId) { + public void run( + View view, int tabId, @Nullable MotionEvent triggeringMotionEvent) { // TODO(crbug.com/40638921): Consider disabling all touch events during // animation. if (mModelList.indexFromTabId(tabId) == TabModel.INVALID_TAB_INDEX) return; @@ -1166,9 +1185,13 @@ setUseShrinkCloseAnimation(tabId, /* useShrinkCloseAnimation= */ true); if (mActionsOnAllRelatedTabs && filter.isTabInTabGroup(closingTab)) { onGroupClosedFrom(tabId); + + // TODO(crbug.com/375468032): use "triggeringMotionEvent" to determine + // if the "undo" snackbar should be shown when closing a tab group. TabUiUtils.closeTabGroup( mCurrentTabGroupModelFilterSupplier.get(), tabId, + /* allowUndo= */ true, /* hideTabGroups= */ true, getOnMaybeTabClosedCallback(tabId)); return; @@ -1177,10 +1200,13 @@ onTabClosedFrom(tabId, mComponentName); Tab currentTab = TabModelUtils.getCurrentTab(tabModel); Tab nextTab = currentTab == closingTab ? getNextTab(tabId) : null; + boolean allowUndo = + triggeringMotionEvent == null + || !MotionEventUtils.isMouseEvent(triggeringMotionEvent); TabClosureParams closureParams = TabClosureParams.closeTab(closingTab) .recommendedNextTab(nextTab) - .allowUndo(true) + .allowUndo(allowUndo) .build(); @Nullable @@ -1192,7 +1218,8 @@ } @Override - public void run(View view, String syncId) { + public void run( + View view, String syncId, @Nullable MotionEvent triggeringMotionEvent) { int index = mModelList.indexFromSyncId(syncId); if (index == TabModel.INVALID_TAB_INDEX) return; @@ -1244,7 +1271,8 @@ TabActionListener swipeSafeTabActionListener = new TabActionListener() { @Override - public void run(View view, int tabId) { + public void run( + View view, int tabId, @Nullable MotionEvent triggeringMotionEvent) { // The DefaultItemAnimator is prone to crashing in combination with the // swipe animation when closing the last tab. Avoid this issue by disabling // the default item animation for the duration of the removal of the last @@ -1260,7 +1288,7 @@ mRecyclerViewItemAnimationToggle.setDisableItemAnimations(true); } - mTabClosedListener.run(view, tabId); + mTabClosedListener.run(view, tabId, /* triggeringMotionEvent= */ null); // It is necessary to post the restoration as otherwise any animation // triggered by removing the tab will still use the animator as they are @@ -1276,7 +1304,8 @@ } @Override - public void run(View view, String syncId) { + public void run( + View view, String syncId, @Nullable MotionEvent triggeringMotionEvent) { // Swipe is disabled in the {@link ArchivedTabsDialogCoordinator} // implementation of the TabListMediator. Intentional no-op. } @@ -1454,8 +1483,14 @@ } } } + + // The current implementation of TAB_GROUP card types places all groups at the beginning of + // the model list. As a result, if any tab group cards exist, adjust the index for tab + // insertion to start after the allotted count of tab groups in the model list. + tabIndex += mModelList.getTabGroupCardCount(); + // Get the position of the nth tab card ignoring any other CARD_TYPE entries present in the - // model list. + // model list outside of TAB and TAB_GROUP. return mModelList.indexOfNthTabCard(tabIndex); } @@ -2796,7 +2831,11 @@ setUseShrinkCloseAnimation(tabId, /* useShrinkCloseAnimation= */ true); onGroupClosedFrom(tabId); TabUiUtils.closeTabGroup( - filter, tabId, hideTabGroups, getOnMaybeTabClosedCallback(tabId)); + filter, + tabId, + /* allowUndo= */ true, + hideTabGroups, + getOnMaybeTabClosedCallback(tabId)); } else if (menuId == R.id.edit_group_name) { RecordUserAction.record("TabGroupItemMenu.Rename"); renameTabGroup(tabId);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListModel.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListModel.java index 17d21d2..a5421ca 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListModel.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListModel.java
@@ -158,7 +158,7 @@ int lastTabIndex = TabModel.INVALID_TAB_INDEX; for (int i = 0; i < size(); i++) { PropertyModel model = get(i).model; - if (model.get(CARD_TYPE) == TAB) { + if (model.get(CARD_TYPE) == TAB || model.get(CARD_TYPE) == TAB_GROUP) { if (tabCount++ == n) return i; lastTabIndex = i; } @@ -177,6 +177,18 @@ return getTabCardCountsBefore(index); } + /** Get the number of TAB_GROUP cards in the TabListModel. */ + public int getTabGroupCardCount() { + int tabGroupCardCount = 0; + for (int i = 0; i < size(); i++) { + PropertyModel model = get(i).model; + if (model.get(CARD_TYPE) == TAB_GROUP) { + tabGroupCardCount++; + } + } + return tabGroupCardCount; + } + /** * Get the number of TAB cards before the given index in TabListModel. *
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewBinder.java index 98ed678..2173dfa 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewBinder.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabStripViewBinder.java
@@ -63,13 +63,19 @@ TabActionButtonData data = model.get(TabProperties.TAB_ACTION_BUTTON_DATA); assert data.type != TabActionButtonData.TabActionButtonType.OVERFLOW; - data.tabActionListener.run(v, model.get(TabProperties.TAB_ID)); + data.tabActionListener.run( + v, + model.get(TabProperties.TAB_ID), + /* triggeringMotionEvent= */ null); }); } else { button.setOnClickListener( v -> { model.get(TabProperties.TAB_CLICK_LISTENER) - .run(v, model.get(TabProperties.TAB_ID)); + .run( + v, + model.get(TabProperties.TAB_ID), + /* triggeringMotionEvent= */ null); }); } setContentDescription(view, model);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneMediator.java index 38c1b60..91e0eac 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneMediator.java
@@ -8,6 +8,7 @@ import static org.chromium.chrome.browser.tasks.tab_management.TabListContainerProperties.FOCUS_TAB_INDEX_FOR_ACCESSIBILITY; import static org.chromium.chrome.browser.tasks.tab_management.TabListContainerProperties.INITIAL_SCROLL_INDEX; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -50,13 +51,14 @@ private final TabActionListener mTabGridDialogOpener = new TabActionListener() { @Override - public void run(View view, int tabId) { + public void run(View view, int tabId, @Nullable MotionEvent triggeringMotionEvent) { openTabGroupDialog(tabId); RecordUserAction.record("TabGridDialog.ExpandedFromSwitcher"); } @Override - public void run(View view, String syncId) { + public void run( + View view, String syncId, @Nullable MotionEvent triggeringMotionEvent) { // Intentional no-op. } };
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneMediatorUnitTest.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneMediatorUnitTest.java index ed924d49..07414e9 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneMediatorUnitTest.java
@@ -352,7 +352,7 @@ public void testOpenTabGridDialog() { TabActionListener listener = mMediator.openTabGridDialog(mGroupedTab1); assertNotNull(listener); - listener.run(mCustomView, mGroupedTab1.getId()); + listener.run(mCustomView, mGroupedTab1.getId(), /* triggeringMotionEvent= */ null); verify(mTabGridDialogController).resetWithListOfTabs(List.of(mGroupedTab1, mGroupedTab2)); } @@ -368,7 +368,7 @@ TabActionListener listener = mMediator.openTabGridDialog(mUngroupedTab); assertNotNull(listener); - listener.run(mCustomView, mUngroupedTab.getId()); + listener.run(mCustomView, mUngroupedTab.getId(), /* triggeringMotionEvent= */ null); verify(mTabGridDialogController).resetWithListOfTabs(List.of(mUngroupedTab)); }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiUtils.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiUtils.java index c5a5ee16..09e060d 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiUtils.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiUtils.java
@@ -62,12 +62,14 @@ * * @param filter The {@link TabGroupModelFilter} to act on. * @param tabId The ID of one of the tabs in the tab group. + * @param allowUndo Whether to allow undo of the tab group closure. * @param hideTabGroups Whether to hide or delete the tab group. * @param didCloseCallback Run after the close confirmation to indicate if a close happened. */ public static void closeTabGroup( TabGroupModelFilter filter, int tabId, + boolean allowUndo, boolean hideTabGroups, @Nullable Callback<Boolean> didCloseCallback) { TabModel tabModel = filter.getTabModel(); @@ -79,7 +81,7 @@ TabClosureParams closureParams = TabClosureParams.forCloseTabGroup(filter, tab.getTabGroupId()) .hideTabGroups(hideTabGroups) - .allowUndo(true) + .allowUndo(allowUndo) .build(); @Nullable TabModelActionListener listener = buildMaybeDidCloseTabListener(didCloseCallback);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiUtilsUnitTest.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiUtilsUnitTest.java index 80185f44..ebbbf66 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiUtilsUnitTest.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiUtilsUnitTest.java
@@ -4,9 +4,12 @@ package org.chromium.chrome.browser.tasks.tab_management; +import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -134,15 +137,50 @@ @Test public void testCloseTabGroup_NoTab() { TabUiUtils.closeTabGroup( - mFilter, Tab.INVALID_TAB_ID, /* hideTabGroups= */ false, mDidCloseTabsCallback); + mFilter, + Tab.INVALID_TAB_ID, + /* allowUndo= */ true, + /* hideTabGroups= */ false, + mDidCloseTabsCallback); verify(mDidCloseTabsCallback).onResult(false); } @Test + public void testCloseTabGroup_AllowUndo() { + testCloseTabGroupForAllowUndoParam(/* shouldAllowUndo= */ true); + } + + @Test + public void testCloseTabGroup_DisallowUndo() { + testCloseTabGroupForAllowUndoParam(/* shouldAllowUndo= */ false); + } + + private void testCloseTabGroupForAllowUndoParam(boolean shouldAllowUndo) { + // Act + TabUiUtils.closeTabGroup( + mFilter, + TAB_ID, + shouldAllowUndo, + /* hideTabGroups= */ false, + /* didCloseCallback= */ null); + + // Assert + ArgumentCaptor<TabClosureParams> tabClosureParamsCaptor = + ArgumentCaptor.forClass(TabClosureParams.class); + verify(mTabRemover) + .closeTabs( + tabClosureParamsCaptor.capture(), + /* allowDialog= */ anyBoolean(), + /* listener= */ nullable(TabModelActionListener.class)); + assertEquals(shouldAllowUndo, tabClosureParamsCaptor.getValue().allowUndo); + } + + @Test public void testCloseTabGroup_NoHide() { boolean hideTabGroups = false; - TabUiUtils.closeTabGroup(mFilter, TAB_ID, hideTabGroups, mDidCloseTabsCallback); + TabUiUtils.closeTabGroup( + mFilter, TAB_ID, /* allowUndo= */ true, hideTabGroups, mDidCloseTabsCallback); verify(mTabRemover) .closeTabs( @@ -186,7 +224,8 @@ public void testCloseTabGroup_Hide() { boolean hideTabGroups = true; - TabUiUtils.closeTabGroup(mFilter, TAB_ID, hideTabGroups, mDidCloseTabsCallback); + TabUiUtils.closeTabGroup( + mFilter, TAB_ID, /* allowUndo= */ true, hideTabGroups, mDidCloseTabsCallback); verify(mTabRemover) .closeTabs(
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java index 5c1da73..9c78c146 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java
@@ -30,10 +30,13 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.VectorDrawable; +import android.os.SystemClock; import android.util.Size; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewStub; +import android.view.accessibility.AccessibilityNodeInfo; import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.ImageView; @@ -41,6 +44,7 @@ import android.widget.TextView; import androidx.annotation.IdRes; +import androidx.annotation.Nullable; import androidx.core.widget.ImageViewCompat; import androidx.test.annotation.UiThreadTest; import androidx.test.filters.MediumTest; @@ -210,13 +214,14 @@ private TabListMediator.TabActionListener mMockCloseListener = new TabListMediator.TabActionListener() { @Override - public void run(View view, int tabId) { + public void run(View view, int tabId, @Nullable MotionEvent triggeringMotionEvent) { mCloseClicked.set(true); mCloseTabId.set(tabId); } @Override - public void run(View view, String syncId) {} + public void run( + View view, String syncId, @Nullable MotionEvent triggeringMotionEvent) {} }; private AtomicBoolean mCloseClicked = new AtomicBoolean(); private AtomicInteger mCloseTabId = new AtomicInteger(); @@ -224,13 +229,14 @@ private TabListMediator.TabActionListener mMockSelectedListener = new TabListMediator.TabActionListener() { @Override - public void run(View view, int tabId) { + public void run(View view, int tabId, @Nullable MotionEvent triggeringMotionEvent) { mSelectClicked.set(true); mSelectTabId.set(tabId); } @Override - public void run(View view, String syncId) {} + public void run( + View view, String syncId, @Nullable MotionEvent triggeringMotionEvent) {} }; private AtomicBoolean mSelectClicked = new AtomicBoolean(); private AtomicInteger mSelectTabId = new AtomicInteger(); @@ -238,13 +244,14 @@ private TabListMediator.TabActionListener mMockCreateGroupButtonListener = new TabListMediator.TabActionListener() { @Override - public void run(View view, int tabId) { + public void run(View view, int tabId, @Nullable MotionEvent triggeringMotionEvent) { mCreateGroupButtonClicked.set(true); mCreateGroupTabId.set(tabId); } @Override - public void run(View view, String syncId) {} + public void run( + View view, String syncId, @Nullable MotionEvent triggeringMotionEvent) {} }; private AtomicBoolean mCreateGroupButtonClicked = new AtomicBoolean(); private AtomicInteger mCreateGroupTabId = new AtomicInteger(); @@ -644,6 +651,64 @@ @Test @MediumTest @UiThreadTest + public void testCloseButtonClick() { + ImageView gridActionButton = mTabGridView.findViewById(R.id.action_button); + Assert.assertFalse(mCloseClicked.get()); + + gridActionButton.performClick(); + + Assert.assertTrue(mCloseClicked.get()); + Assert.assertEquals(TAB1_ID, mCloseTabId.get()); + } + + @Test + @MediumTest + @UiThreadTest + public void testCloseButtonPeripheralClick() { + // Setup + ImageView gridActionButton = mTabGridView.findViewById(R.id.action_button); + Assert.assertFalse(mCloseClicked.get()); + + // Act: peripheral click is intercepted by an OnTouchListener, so we should dispatch + // MotionEvents to simulate a click. + long motionDownTime = SystemClock.uptimeMillis(); + gridActionButton.dispatchTouchEvent( + TabUiTestHelper.createMouseMotionEvent( + motionDownTime, + /* eventTime= */ motionDownTime, + MotionEvent.ACTION_DOWN, + /* x= */ 0.0f, + /* y= */ 0.0f)); + gridActionButton.dispatchTouchEvent( + TabUiTestHelper.createMouseMotionEvent( + motionDownTime, + /* eventTime= */ motionDownTime + 200, + MotionEvent.ACTION_UP, + /* x= */ 0.0f, + /* y= */ 0.0f)); + + // Assert + Assert.assertTrue(mCloseClicked.get()); + Assert.assertEquals(TAB1_ID, mCloseTabId.get()); + } + + @Test + @MediumTest + @UiThreadTest + public void testCloseButtonA11yClick() { + ImageView gridActionButton = mTabGridView.findViewById(R.id.action_button); + Assert.assertFalse(mCloseClicked.get()); + + gridActionButton.performAccessibilityAction( + AccessibilityNodeInfo.ACTION_CLICK, /* arguments= */ null); + + Assert.assertTrue(mCloseClicked.get()); + Assert.assertEquals(TAB1_ID, mCloseTabId.get()); + } + + @Test + @MediumTest + @UiThreadTest public void testCloseButtonDescription() { ImageView listActionButton = mTabListView.findViewById(R.id.end_button); ImageView gridActionButton = mTabGridView.findViewById(R.id.action_button);
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayoutTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayoutTest.java index 085e73e..bfebffe 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayoutTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayoutTest.java
@@ -27,6 +27,7 @@ import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.closeFirstTabGroupInTabSwitcher; import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.closeFirstTabInTabSwitcher; +import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.closeNthTabInTabSwitcher; import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.createTabGroup; import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.createTabs; import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.enterTabSwitcher; @@ -271,6 +272,25 @@ @Test @MediumTest + public void testCloseTabViaCloseButton_peripheralClick_noUndoSnackbar() { + // Setup + ChromeTabbedActivity activity = mActivityTestRule.getActivity(); + SnackbarManager snackbarManager = activity.getSnackbarManager(); + createTabs(activity, /* isIncognito= */ false, /* tabsCount= */ 3); + enterTabSwitcher(activity); + verifyTabSwitcherCardCount(activity, /* count= */ 3); + assertNull(snackbarManager.getCurrentSnackbarForTesting()); + + // Act + closeNthTabInTabSwitcher(activity, /* index= */ 0, /* performMouseClick= */ true); + + // Assert: no undo snackbar & tab closed + assertNull(snackbarManager.getCurrentSnackbarForTesting()); + verifyTabSwitcherCardCount(activity, /* count= */ 2); + } + + @Test + @MediumTest @DisabledTest(message = "Flaky - https://crbug.com/1124041, crbug.com/1061178") public void testSwipeToDismiss_Gts() { ChromeTabbedActivity cta = mActivityTestRule.getActivity();
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java index 68097e1b..60c85f5b 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java
@@ -32,7 +32,12 @@ import android.app.Activity; import android.content.Context; import android.graphics.drawable.BitmapDrawable; +import android.os.SystemClock; import android.provider.Settings; +import android.view.InputDevice; +import android.view.MotionEvent; +import android.view.MotionEvent.PointerCoords; +import android.view.MotionEvent.PointerProperties; import android.view.View; import android.view.ViewGroup; @@ -284,12 +289,23 @@ } /** - * Close the Nth tab in grid tab switcher. + * Closes the Nth tab in grid tab switcher. * - * @param context The activity context. - * @param index The index of the target tab to close. + * @see #closeNthTabInTabSwitcher(Context, int, boolean) */ static void closeNthTabInTabSwitcher(Context context, int index) { + closeNthTabInTabSwitcher(context, index, /* performMouseClick= */ false); + } + + /** + * Closes the Nth tab in grid tab switcher. + * + * @param context the Activity context. + * @param index the index of the tab to close. + * @param performMouseClick whether to click the close button by simulating {@link MotionEvent}s + * from a mouse. + */ + static void closeNthTabInTabSwitcher(Context context, int index, boolean performMouseClick) { onView( allOf( isDescendantOfA(withId(getTabSwitcherAncestorId(context))), @@ -312,12 +328,66 @@ RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(index); assert viewHolder != null; - viewHolder.itemView.findViewById(R.id.action_button).performClick(); + + View actionButton = + viewHolder.itemView.findViewById(R.id.action_button); + if (!performMouseClick) { + actionButton.performClick(); + return; + } + + long motionDownTime = SystemClock.uptimeMillis(); + actionButton.dispatchTouchEvent( + createMouseMotionEvent( + motionDownTime, + /* eventTime= */ motionDownTime, + MotionEvent.ACTION_DOWN, + /* x= */ 0.0f, + /* y= */ 0.0f)); + actionButton.dispatchTouchEvent( + createMouseMotionEvent( + motionDownTime, + /* eventTime= */ motionDownTime + 200, + MotionEvent.ACTION_UP, + /* x= */ 0.0f, + /* y= */ 0.0f)); } }); } /** + * Creates a {@link MotionEvent} that matches one from a mouse. + * + * <p>All parameters are for {@link MotionEvent#obtain}. + */ + static MotionEvent createMouseMotionEvent( + long downTime, long eventTime, int action, float x, float y) { + PointerProperties pointerProperties = new MotionEvent.PointerProperties(); + pointerProperties.id = 0; + pointerProperties.toolType = MotionEvent.TOOL_TYPE_MOUSE; + + PointerCoords pointerCoords = new PointerCoords(); + pointerCoords.x = x; + pointerCoords.y = y; + + return MotionEvent.obtain( + downTime, + eventTime, + action, + /* pointerCount= */ 1, + new PointerProperties[] {pointerProperties}, + new PointerCoords[] {pointerCoords}, + /* metaState= */ 0, + /* buttonState= */ 0, + /* xPrecision= */ 1.0f, + /* yPrecision= */ 1.0f, + /* deviceId= */ 0, + /* edgeFlags= */ 0, + InputDevice.SOURCE_MOUSE, + /* flags= */ 0); + } + + /** * Check whether the tab list in {@link android.widget.PopupWindow} is completely showing. This * can be used for tab grid dialog and tab group popup UI. *
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/ArchivedTabsDialogCoordinatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/ArchivedTabsDialogCoordinatorUnitTest.java index c61dd6f3..504678d 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/ArchivedTabsDialogCoordinatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/ArchivedTabsDialogCoordinatorUnitTest.java
@@ -12,7 +12,6 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -129,7 +128,7 @@ private Activity mActivity; private ArchivedTabsDialogCoordinator mCoordinator; - private ObservableSupplierImpl<Integer> mTabCountSupplier = new ObservableSupplierImpl<>(); + private ObservableSupplierImpl<Integer> mTabCountSupplier = new ObservableSupplierImpl<>(1); private ObservableSupplierImpl<EdgeToEdgeController> mEdgeToEdgeSupplier = new ObservableSupplierImpl<>(); private OneshotSupplierImpl<PaneManager> mPaneManagerSupplier = new OneshotSupplierImpl<>(); @@ -201,13 +200,12 @@ } }); - doReturn(mArchivedTabModelSelector) - .when(mArchivedTabModelOrchestrator) - .getTabModelSelector(); - doReturn(mArchivedTabModel).when(mArchivedTabModelSelector).getModel(false); - doReturn(mTabCountSupplier).when(mArchivedTabModel).getTabCountSupplier(); + when(mArchivedTabModelOrchestrator.getTabModelSelector()) + .thenReturn(mArchivedTabModelSelector); + when(mArchivedTabModelSelector.getModel(false)).thenReturn(mArchivedTabModel); + when(mArchivedTabModelOrchestrator.getTabCountSupplier()).thenReturn(mTabCountSupplier); - doReturn(mTabListEditorController).when(mTabListEditorCoordinator).getController(); + when(mTabListEditorCoordinator.getController()).thenReturn(mTabListEditorController); doAnswer( invocationOnMock -> { mCoordinator.getTabListEditorLifecycleObserver().willHide(); @@ -224,15 +222,10 @@ verify(mRootView).addView(any()); verify(mTabListEditorController).show(any(), eq(Collections.emptyList()), eq(null)); verify(mTabListEditorController).setNavigationProvider(any()); - verify(mTabListEditorController).setToolbarTitle("0 inactive tabs"); + verify(mTabListEditorController, times(2)).setToolbarTitle("1 inactive tab"); verify(mBackPressManager).addHandler(any(), eq(BackPressHandler.Type.ARCHIVED_TABS_DIALOG)); - doReturn(1).when(mArchivedTabModel).getCount(); - mCoordinator.updateTitle(); - verify(mTabListEditorController).setToolbarTitle("1 inactive tab"); - - doReturn(2).when(mArchivedTabModel).getCount(); - mCoordinator.updateTitle(); + mTabCountSupplier.set(2); verify(mTabListEditorController).setToolbarTitle("2 inactive tabs"); } @@ -255,22 +248,17 @@ public void testAddRemoveTab() { mCoordinator.show(mOnTabSelectingListener); - // First add a tab - doReturn(1).when(mArchivedTabModel).getCount(); - mTabCountSupplier.set(1); - verify(mTabListEditorController).setToolbarTitle("1 inactive tab"); + // First verify a tab exists as the base condition for showing. + verify(mTabListEditorController, times(2)).setToolbarTitle("1 inactive tab"); - // Then a second - doReturn(2).when(mArchivedTabModel).getCount(); + // Then add a second tab. mTabCountSupplier.set(2); verify(mTabListEditorController).setToolbarTitle("2 inactive tabs"); - // Then close bloth - doReturn(1).when(mArchivedTabModel).getCount(); + // Then close both tabs. mTabCountSupplier.set(1); - verify(mTabListEditorController, times(2)).setToolbarTitle("1 inactive tab"); + verify(mTabListEditorController, times(3)).setToolbarTitle("1 inactive tab"); - doReturn(0).when(mArchivedTabModel).getCount(); mTabCountSupplier.set(0); // Allow animations to finish. @@ -294,7 +282,7 @@ @Test public void testDestroyHidesDialog() { - doReturn(true).when(mTabListEditorController).isVisible(); + when(mTabListEditorController.isVisible()).thenReturn(true); mCoordinator.show(mOnTabSelectingListener); mCoordinator.destroy(); @@ -353,9 +341,10 @@ when(mPaneManager.getPaneForId(PaneId.TAB_SWITCHER)).thenReturn(mTabSwitcherPaneBase); when(mTabGroupSyncService.getGroup(TAB_GROUP_ID_STRING)) .thenReturn(savedTabGroupBefore) + .thenReturn(savedTabGroupBefore) .thenReturn(savedTabGroupAfter); when(mCurrentTabGroupModelFilter.getRootIdFromTabGroupId(TAB_GROUP_ID)).thenReturn(TAB1_ID); - doReturn(true).when(mTabListEditorController).isVisible(); + when(mTabListEditorController.isVisible()).thenReturn(true); // Show the dialog. mCoordinator.show(mOnTabSelectingListener); @@ -364,7 +353,7 @@ GridCardOnClickListenerProvider provider = mCoordinator.getGridCardOnClickListenerProviderForTesting(); TabActionListener listener = provider.openTabGridDialog(TAB_GROUP_ID_STRING); - listener.run(mItemView1, TAB_GROUP_ID_STRING); + listener.run(mItemView1, TAB_GROUP_ID_STRING, /* triggeringMotionEvent= */ null); verify(mTabGroupUiActionHandler).openTabGroup(TAB_GROUP_ID_STRING);
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallbackUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallbackUnitTest.java index 73cc895..a9e68401e 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallbackUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridItemTouchHelperCallbackUnitTest.java
@@ -243,7 +243,7 @@ public void onSwipeTab_Delete() { mItemTouchHelperCallback.onSwiped(mMockViewHolder1, POSITION1); - verify(mTabClosedListener).run(mItemView1, TAB1_ID); + verify(mTabClosedListener).run(mItemView1, TAB1_ID, /* triggeringMotionEvent= */ null); } @Test
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinderUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinderUnitTest.java index 9055510d0..85eb598 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinderUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinderUnitTest.java
@@ -12,6 +12,7 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isA; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; @@ -31,6 +32,7 @@ import android.graphics.drawable.Drawable; import android.util.Size; import android.view.ContextThemeWrapper; +import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.view.ViewStub; @@ -38,6 +40,8 @@ import android.widget.ImageView; import android.widget.ImageView.ScaleType; +import androidx.annotation.Nullable; + import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -59,7 +63,11 @@ import org.chromium.chrome.browser.tab_ui.TabListFaviconProvider.TabFavicon; import org.chromium.chrome.browser.tab_ui.TabListFaviconProvider.TabFaviconFetcher; import org.chromium.chrome.browser.tab_ui.TabThumbnailView; +import org.chromium.chrome.browser.tasks.tab_management.TabGridViewBinder.OnPeripheralClickListener; import org.chromium.chrome.browser.tasks.tab_management.TabListMediator.ShoppingPersistedTabDataFetcher; +import org.chromium.chrome.browser.tasks.tab_management.TabListMediator.TabActionButtonData; +import org.chromium.chrome.browser.tasks.tab_management.TabListMediator.TabActionButtonData.TabActionButtonType; +import org.chromium.chrome.browser.tasks.tab_management.TabListMediator.TabActionListener; import org.chromium.chrome.browser.tasks.tab_management.TabProperties.TabActionState; import org.chromium.ui.modelutil.PropertyModel; @@ -468,6 +476,32 @@ verify(mViewGroup).setTabActionButtonTint(any()); } + @Test + public void bindTabWithActionButtonData_setOnClickListenerAndOnPeripheralClickListener() { + TabActionButtonData tabActionButtonData = + new TabActionButtonData( + TabActionButtonType.CLOSE, + new TabActionListener() { + @Override + public void run( + View view, + int tabId, + @Nullable MotionEvent triggeringMotionEvent) {} + + @Override + public void run( + View view, + String syncId, + @Nullable MotionEvent triggeringMotionEvent) {} + }); + mModel.set(TabProperties.TAB_ACTION_BUTTON_DATA, tabActionButtonData); + + TabGridViewBinder.bindTab(mModel, mViewGroup, TabProperties.TAB_ACTION_BUTTON_DATA); + + verify(mActionButton).setOnClickListener(any()); + verify(mActionButton).setOnTouchListener(isA(OnPeripheralClickListener.class)); + } + private void assertImageMatrix( ArgumentCaptor<Matrix> matrixCaptor, float expectedScale, float expectedTrans) { float[] matValues = new float[9];
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java index f087f5f..6d97ae2 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
@@ -53,8 +53,10 @@ import android.graphics.Bitmap; import android.graphics.Rect; import android.os.Bundle; +import android.os.SystemClock; import android.util.Pair; import android.util.Size; +import android.view.MotionEvent; import android.view.View; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; @@ -984,7 +986,10 @@ .get(1) .model .get(TabProperties.TAB_CLICK_LISTENER) - .run(mItemView2, mModelList.get(1).model.get(TabProperties.TAB_ID)); + .run( + mItemView2, + mModelList.get(1).model.get(TabProperties.TAB_ID), + /* triggeringMotionEvent= */ null); verify(mGridCardOnClickListenerProvider) .onTabSelecting(mModelList.get(1).model.get(TabProperties.TAB_ID), true); @@ -999,9 +1004,13 @@ .get(0) .model .get(TabProperties.TAB_CLICK_LISTENER) - .run(mItemView1, mModelList.get(0).model.get(TabProperties.TAB_ID)); + .run( + mItemView1, + mModelList.get(0).model.get(TabProperties.TAB_ID), + /* triggeringMotionEvent= */ null); - verify(mOpenGroupActionListener).run(mItemView1, TAB1_ID); + verify(mOpenGroupActionListener) + .run(mItemView1, TAB1_ID, /* triggeringMotionEvent= */ null); } @Test @@ -1013,9 +1022,13 @@ .get(0) .model .get(TabProperties.TAB_CLICK_LISTENER) - .run(mItemView1, mModelList.get(0).model.get(TabProperties.TAB_ID)); + .run( + mItemView1, + mModelList.get(0).model.get(TabProperties.TAB_ID), + /* triggeringMotionEvent= */ null); - verify(mOpenGroupActionListener).run(mItemView1, TAB1_ID); + verify(mOpenGroupActionListener) + .run(mItemView1, TAB1_ID, /* triggeringMotionEvent= */ null); } @Test @@ -1026,7 +1039,10 @@ .model .get(TabProperties.TAB_ACTION_BUTTON_DATA) .tabActionListener - .run(mItemView2, mModelList.get(1).model.get(TabProperties.TAB_ID)); + .run( + mItemView2, + mModelList.get(1).model.get(TabProperties.TAB_ID), + /* triggeringMotionEvent= */ null); TabClosureParams params = TabClosureParams.closeTab(mTab2).allowUndo(true).build(); verify(mTabRemover) @@ -1048,6 +1064,31 @@ } @Test + public void sendsCloseSignalCorrectly_TriggeringMotionEventFromMouse_DisallowUndo() { + mMediator.setActionOnAllRelatedTabsForTesting(false); + mModelList + .get(1) + .model + .get(TabProperties.TAB_ACTION_BUTTON_DATA) + .tabActionListener + .run( + mItemView2, + mModelList.get(1).model.get(TabProperties.TAB_ID), + TabUiTestHelper.createMouseMotionEvent( + /* downTime= */ SystemClock.uptimeMillis(), + /* eventTime= */ SystemClock.uptimeMillis() + 200, + MotionEvent.ACTION_UP, + /* x= */ 0, + /* y= */ 0)); + + verify(mTabRemover) + .closeTabs( + eq(TabClosureParams.closeTab(mTab2).allowUndo(false).build()), + /* allowDialog= */ eq(true), + /* listener= */ any()); + } + + @Test public void sendsCloseSignalCorrectly_ActionOnAllRelatedTabs() { mMediator.setActionOnAllRelatedTabsForTesting(true); mModelList @@ -1055,7 +1096,10 @@ .model .get(TabProperties.TAB_ACTION_BUTTON_DATA) .tabActionListener - .run(mItemView2, mModelList.get(1).model.get(TabProperties.TAB_ID)); + .run( + mItemView2, + mModelList.get(1).model.get(TabProperties.TAB_ID), + /* triggeringMotionEvent= */ null); verify(mTabRemover) .closeTabs( @@ -1073,7 +1117,10 @@ .model .get(TabProperties.TAB_ACTION_BUTTON_DATA) .tabActionListener - .run(mItemView2, mModelList.get(1).model.get(TabProperties.TAB_ID)); + .run( + mItemView2, + mModelList.get(1).model.get(TabProperties.TAB_ID), + /* triggeringMotionEvent= */ null); verify(mTabRemover) .closeTabs( @@ -3986,7 +4033,11 @@ when(mTabGroupModelFilter.isTabInTabGroup(mTab2)).thenReturn(false); ThumbnailFetcher fetcher2 = mModelList.get(1).model.get(TabProperties.THUMBNAIL_FETCHER); - mModelList.get(1).model.get(TabProperties.TAB_CLICK_LISTENER).run(mItemView2, TAB2_ID); + mModelList + .get(1) + .model + .get(TabProperties.TAB_CLICK_LISTENER) + .run(mItemView2, TAB2_ID, /* triggeringMotionEvent= */ null); assertThat(mModelList.get(1).model.get(TabProperties.IS_SELECTED), equalTo(true)); assertEquals(fetcher2, mModelList.get(1).model.get(TabProperties.THUMBNAIL_FETCHER)); } @@ -4029,7 +4080,11 @@ when(mTabGroupModelFilter.isTabInTabGroup(mTab2)).thenReturn(true); ThumbnailFetcher fetcher2 = mModelList.get(1).model.get(TabProperties.THUMBNAIL_FETCHER); - mModelList.get(1).model.get(TabProperties.TAB_CLICK_LISTENER).run(mItemView2, TAB2_ID); + mModelList + .get(1) + .model + .get(TabProperties.TAB_CLICK_LISTENER) + .run(mItemView2, TAB2_ID, /* triggeringMotionEvent= */ null); assertThat(mModelList.get(1).model.get(TabProperties.IS_SELECTED), equalTo(true)); assertNotEquals(fetcher2, mModelList.get(1).model.get(TabProperties.THUMBNAIL_FETCHER)); } @@ -4800,7 +4855,10 @@ .model .get(TabProperties.TAB_ACTION_BUTTON_DATA) .tabActionListener - .run(mItemView1, mModelList.get(0).model.get(TabProperties.TAB_GROUP_SYNC_ID)); + .run( + mItemView1, + mModelList.get(0).model.get(TabProperties.TAB_GROUP_SYNC_ID), + /* triggeringMotionEvent= */ null); // Assert that the tab group has been removed from the model list and archive status reset. assertEquals(TAB, mModelList.get(0).model.get(CARD_TYPE)); @@ -4818,9 +4876,13 @@ .get(0) .model .get(TabProperties.TAB_CLICK_LISTENER) - .run(mItemView1, mModelList.get(0).model.get(TabProperties.TAB_GROUP_SYNC_ID)); + .run( + mItemView1, + mModelList.get(0).model.get(TabProperties.TAB_GROUP_SYNC_ID), + /* triggeringMotionEvent= */ null); - verify(mOpenGroupActionListener).run(mItemView1, SYNC_GROUP_ID1); + verify(mOpenGroupActionListener) + .run(mItemView1, SYNC_GROUP_ID1, /* triggeringMotionEvent= */ null); } @Test @@ -4869,7 +4931,10 @@ .get(0) .model .get(TabProperties.TAB_CLICK_LISTENER) - .run(mItemView1, mModelList.get(0).model.get(TabProperties.TAB_GROUP_SYNC_ID)); + .run( + mItemView1, + mModelList.get(0).model.get(TabProperties.TAB_GROUP_SYNC_ID), + /* triggeringMotionEvent= */ null); assertThat(mModelList.get(0).model.get(TabProperties.IS_SELECTED), equalTo(true)); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ai/PageSummaryButtonController.java b/chrome/android/java/src/org/chromium/chrome/browser/ai/PageSummaryButtonController.java index c8d71cf..cdcce42 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ai/PageSummaryButtonController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ai/PageSummaryButtonController.java
@@ -56,8 +56,7 @@ /* supportsTinting= */ true, /* iphCommandBuilder= */ null, AdaptiveToolbarButtonVariant.PAGE_SUMMARY, - /* tooltipTextResId= */ R.string.menu_summarize_with_ai, - /* showBackgroundHighlight= */ true); + /* tooltipTextResId= */ R.string.menu_summarize_with_ai); mContext = context; mAiAssistantService = aiAssistantService; mTrackerSupplier = tracker; @@ -75,7 +74,6 @@ AdaptiveToolbarButtonVariant.PAGE_SUMMARY, /* actionChipLabelResId= */ Resources.ID_NULL, /* tooltipTextResId= */ R.string.menu_review_pdf_with_ai, - /* showBackgroundHighlight= */ true, /* hasErrorBadge= */ false); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabGroupContextMenuCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabGroupContextMenuCoordinator.java index 8aaabb1..e261c2d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabGroupContextMenuCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabGroupContextMenuCoordinator.java
@@ -189,6 +189,7 @@ TabUiUtils.closeTabGroup( tabGroupModelFilter, tabId, + /* allowUndo= */ true, /* hideTabGroups= */ true, /* didCloseCallback= */ null); recordUserAction("CloseGroup"); @@ -196,6 +197,7 @@ TabUiUtils.closeTabGroup( tabGroupModelFilter, tabId, + /* allowUndo= */ true, /* hideTabGroups= */ false, /* didCloseCallback= */ null); recordUserAction("DeleteGroup");
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeToolbarButtonController.java b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeToolbarButtonController.java index 1815cb6e4..5b62084b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeToolbarButtonController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/dom_distiller/ReaderModeToolbarButtonController.java
@@ -43,8 +43,7 @@ /* supportsTinting= */ true, /* iphCommandBuilder= */ null, AdaptiveToolbarButtonVariant.READER_MODE, - /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ false); + /* tooltipTextResId= */ Resources.ID_NULL); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/identity_disc/IdentityDiscController.java b/chrome/android/java/src/org/chromium/chrome/browser/identity_disc/IdentityDiscController.java index 09014ff..8239c8d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/identity_disc/IdentityDiscController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/identity_disc/IdentityDiscController.java
@@ -121,8 +121,7 @@ R.string.iph_identity_disc_accessibility_text), /* isEnabled= */ true, AdaptiveToolbarButtonVariant.UNKNOWN, - /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ true); + /* tooltipTextResId= */ Resources.ID_NULL); } /** Registers itself to observe sign-in and sync status events. */ @@ -192,7 +191,6 @@ AdaptiveToolbarButtonVariant.UNKNOWN, buttonSpec.getActionChipLabelResId(), buttonSpec.getHoverTooltipTextId(), - buttonSpec.shouldShowBackgroundHighlight(), /* hasErrorBadge= */ mIdentityError != SyncError.NO_ERROR); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ChromePaymentRequestService.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ChromePaymentRequestService.java index 9193520..8df86f7b4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ChromePaymentRequestService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ChromePaymentRequestService.java
@@ -13,6 +13,7 @@ import androidx.appcompat.app.AlertDialog; import org.chromium.base.Callback; +import org.chromium.base.Log; import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.autofill.PersonalDataManagerFactory; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; @@ -42,6 +43,7 @@ import org.chromium.components.payments.PaymentResponseHelper; import org.chromium.components.payments.PaymentResponseHelperInterface; import org.chromium.components.payments.secure_payment_confirmation.SecurePaymentConfirmationAuthnController; +import org.chromium.components.payments.secure_payment_confirmation.SecurePaymentConfirmationAuthnController.SpcResponseStatus; import org.chromium.components.payments.secure_payment_confirmation.SecurePaymentConfirmationNoMatchingCredController; import org.chromium.content_public.browser.RenderFrameHost; import org.chromium.content_public.browser.WebContents; @@ -68,6 +70,8 @@ */ public class ChromePaymentRequestService implements BrowserPaymentRequest, PaymentUiService.Delegate { + private static final String TAG = "ChromePaymentReqServ"; + // Null-check is necessary because retainers of ChromePaymentRequestService could still // reference ChromePaymentRequestService after mPaymentRequestService is set null, e.g., // crbug.com/1122148. @@ -356,20 +360,28 @@ assert mSpcAuthnUiController == null; mSpcAuthnUiController = SecurePaymentConfirmationAuthnController.create(mWebContents); - Callback<Boolean> responseCallback = - (response) -> { - mJourneyLogger.setAborted(AbortReason.ABORTED_BY_USER); - - // User wishes to proceed with payment but not through SPC. - if (response) { - disconnectFromClientWithDebugMessage( - ErrorStrings.WEB_AUTHN_OPERATION_TIMED_OUT_OR_NOT_ALLOWED, - PaymentErrorReason.NOT_ALLOWED_ERROR); - } else { - disconnectFromClientWithDebugMessage( - ErrorStrings.USER_CANCELLED, PaymentErrorReason.USER_CANCEL); + Callback<Integer> responseCallback = + (responseStatus) -> { + switch (responseStatus) { + case SpcResponseStatus.ANOTHER_WAY: + mJourneyLogger.setAborted(AbortReason.ABORTED_BY_USER); + disconnectFromClientWithDebugMessage( + ErrorStrings.WEB_AUTHN_OPERATION_TIMED_OUT_OR_NOT_ALLOWED, + PaymentErrorReason.NOT_ALLOWED_ERROR); + break; + case SpcResponseStatus.CANCEL: + mJourneyLogger.setAborted(AbortReason.ABORTED_BY_USER); + disconnectFromClientWithDebugMessage( + ErrorStrings.USER_CANCELLED, + PaymentErrorReason.USER_CANCEL); + break; + default: + Log.e(TAG, "Unexpected SPC response status: %d", responseStatus); + mJourneyLogger.setAborted(AbortReason.ABORTED_BY_USER); + disconnectFromClientWithDebugMessage( + ErrorStrings.WEB_AUTHN_OPERATION_TIMED_OUT_OR_NOT_ALLOWED, + PaymentErrorReason.NOT_ALLOWED_ERROR); } - mSpcAuthnUiController = null; }; @@ -422,18 +434,34 @@ PaymentMethodData spcMethodData = mSpec.getMethodData().get(MethodStrings.SECURE_PAYMENT_CONFIRMATION); assert spcMethodData != null; - Callback<Boolean> responseCallback = - (response) -> { - if (response) { - onSecurePaymentConfirmationUiAccepted(getSelectedPaymentApp()); - } else { - mJourneyLogger.setAborted(AbortReason.ABORTED_BY_USER); - disconnectFromClientWithDebugMessage( - ErrorStrings.WEB_AUTHN_OPERATION_TIMED_OUT_OR_NOT_ALLOWED, - PaymentErrorReason.NOT_ALLOWED_ERROR); + Callback<Integer> responseCallback = + (responseStatus) -> { + switch (responseStatus) { + case SpcResponseStatus.ACCEPT: + onSecurePaymentConfirmationUiAccepted(getSelectedPaymentApp()); + break; + case SpcResponseStatus.ANOTHER_WAY: + mJourneyLogger.setAborted(AbortReason.ABORTED_BY_USER); + disconnectFromClientWithDebugMessage( + ErrorStrings.WEB_AUTHN_OPERATION_TIMED_OUT_OR_NOT_ALLOWED, + PaymentErrorReason.NOT_ALLOWED_ERROR); + break; + case SpcResponseStatus.CANCEL: + mJourneyLogger.setAborted(AbortReason.ABORTED_BY_USER); + disconnectFromClientWithDebugMessage( + ErrorStrings.USER_CANCELLED, + PaymentErrorReason.USER_CANCEL); + break; + default: + Log.e(TAG, "Unexpected SPC response status: %d", responseStatus); + mJourneyLogger.setAborted(AbortReason.ABORTED_BY_USER); + disconnectFromClientWithDebugMessage( + ErrorStrings.WEB_AUTHN_OPERATION_TIMED_OUT_OR_NOT_ALLOWED, + PaymentErrorReason.NOT_ALLOWED_ERROR); } mSpcAuthnUiController = null; }; + Runnable optOutCallback = () -> { mJourneyLogger.setAborted(AbortReason.USER_OPTED_OUT);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareButtonController.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareButtonController.java index 1c0a647..c5db914 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareButtonController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareButtonController.java
@@ -66,8 +66,7 @@ /* supportsTinting= */ true, /* iphCommandBuilder= */ null, AdaptiveToolbarButtonVariant.SHARE, - /* tooltipTextResId= */ R.string.adaptive_toolbar_button_preference_share, - /* showBackgroundHighlight= */ true); + /* tooltipTextResId= */ R.string.adaptive_toolbar_button_preference_share); mShareDelegateSupplier = shareDelegateSupplier; mTrackerSupplier = trackerSupplier;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsConstraintsHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsConstraintsHelper.java index f7b532c..0798fbd2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsConstraintsHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabBrowserControlsConstraintsHelper.java
@@ -178,7 +178,6 @@ public void destroy() { if (mVisibilityDelegate != null) { mVisibilityDelegate.removeObserver(mConstraintsChangedCallback); - mVisibilityDelegate.destroy(); mVisibilityDelegate = null; } @@ -193,7 +192,6 @@ private void updateVisibilityDelegate() { if (mVisibilityDelegate != null) { mVisibilityDelegate.removeObserver(mConstraintsChangedCallback); - mVisibilityDelegate.destroy(); } mVisibilityDelegate = mTab.getDelegateFactory().createBrowserControlsVisibilityDelegate(mTab);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabStateBrowserControlsVisibilityDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabStateBrowserControlsVisibilityDelegate.java index 1a0d276..68a99aa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabStateBrowserControlsVisibilityDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabStateBrowserControlsVisibilityDelegate.java
@@ -49,7 +49,6 @@ private boolean mIsFocusedNodeEditable; private final Set<Long> mOutstandingNavigations = new HashSet<>(); - private final TabObserver mTabObserver; /** * Basic constructor. @@ -60,7 +59,8 @@ super(BrowserControlsState.BOTH); mTab = (TabImpl) tab; - mTabObserver = + + mTab.addObserver( new EmptyTabObserver() { @SuppressLint("HandlerLeak") private Handler mHandler = @@ -218,18 +218,11 @@ // Remove pending handler actions to prevent memory leaks. mHandler.removeCallbacksAndMessages(null); } - }; - mTab.addObserver(mTabObserver); - + }); onWebContentsUpdated(mTab.getWebContents()); updateVisibilityConstraints(); } - @Override - public void destroy() { - mTab.removeObserver(mTabObserver); - } - private void onWebContentsUpdated(WebContents contents) { if (mWebContents == contents) return; mWebContents = contents;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/FakeServerHelper.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/FakeServerHelper.java index 5a2b018..0a1efca 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/FakeServerHelper.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/FakeServerHelper.java
@@ -357,7 +357,7 @@ .addCollaboration(mNativeFakeServer, collaborationId)); } - /** Adds collaboration from fake sync server. */ + /** Removes collaboration from fake sync server. */ public void removeCollaboration(String collaborationId) { ThreadUtils.runOnUiThreadBlocking( () -> @@ -365,6 +365,15 @@ .removeCollaboration(mNativeFakeServer, collaborationId)); } + /** Adds collaboration group to fake sync server. */ + public void addCollaborationGroupToFakeServer(String collaborationId) { + ThreadUtils.runOnUiThreadBlocking( + () -> + FakeServerHelperJni.get() + .addCollaborationGroupToFakeServer( + mNativeFakeServer, collaborationId)); + } + @NativeMethods interface Natives { long createFakeServer(); @@ -445,5 +454,8 @@ void addCollaboration(long fakeServer, @JniType("std::string") String collaborationId); void removeCollaboration(long fakeServer, @JniType("std::string") String collaborationId); + + void addCollaborationGroupToFakeServer( + long fakeServer, @JniType("std::string") String collaborationId); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhoneTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhoneTest.java index 5b31cb72..76c14cf 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhoneTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhoneTest.java
@@ -239,8 +239,7 @@ null, false, AdaptiveToolbarButtonVariant.UNKNOWN, - 0, - false)); + 0)); // Make sure the button is visible in the beginning of the test. assertEquals(true, realMenuButtonCoordinator.isVisible()); @@ -349,8 +348,7 @@ null, true, AdaptiveToolbarButtonVariant.UNKNOWN, - 0, - false); + 0); // Show a button, this will inflate the optional button view and create its coordinator. ThreadUtils.runOnUiThreadBlocking(() -> mToolbar.updateOptionalButton(buttonData)); @@ -394,8 +392,7 @@ null, true, AdaptiveToolbarButtonVariant.UNKNOWN, - 0, - false); + 0); // Show a button, this will inflate the optional button view and create its coordinator. ThreadUtils.runOnUiThreadBlocking(() -> mToolbar.updateOptionalButton(buttonData)); @@ -439,8 +436,7 @@ null, true, AdaptiveToolbarButtonVariant.UNKNOWN, - 0, - false); + 0); // Show a button, this will inflate the optional button view and create its coordinator. ThreadUtils.runOnUiThreadBlocking(() -> mToolbar.updateOptionalButton(buttonData)); @@ -589,8 +585,7 @@ null, true, AdaptiveToolbarButtonVariant.UNKNOWN, - 0, - false); + 0); ThreadUtils.runOnUiThreadBlocking(() -> mToolbar.updateOptionalButton(buttonData)); verify(mOptionalButtonCoordinator).updateButton(buttonData, false);
diff --git a/chrome/android/junit/BUILD.gn b/chrome/android/junit/BUILD.gn index 123582c..236338d 100644 --- a/chrome/android/junit/BUILD.gn +++ b/chrome/android/junit/BUILD.gn
@@ -67,6 +67,7 @@ "//chrome/android:usage_stats_proto_java", "//chrome/android/features/keyboard_accessory:internal_java", "//chrome/android/features/tab_ui:java_resources", + "//chrome/android/features/tab_ui:test_support_javalib", "//chrome/android/features/tab_ui/public:java", "//chrome/android/features/tab_ui/public:ui_java_resources", "//chrome/android/webapk/libs/client:client_java",
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabStateBrowserControlsVisibilityDelegateTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabStateBrowserControlsVisibilityDelegateTest.java index 0ca8809..83aa649e 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabStateBrowserControlsVisibilityDelegateTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabStateBrowserControlsVisibilityDelegateTest.java
@@ -5,7 +5,6 @@ package org.chromium.chrome.browser.tab; import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -198,13 +197,4 @@ BrowserControlsState.BOTH, controlsVisibilityDelegate.calculateVisibilityConstraints()); } - - @Test - public void testDestroy() { - TabStateBrowserControlsVisibilityDelegate controlsVisibilityDelegate = - new TabStateBrowserControlsVisibilityDelegate(mTabImpl); - verify(mTabImpl).addObserver(any()); - controlsVisibilityDelegate.destroy(); - verify(mTabImpl).removeObserver(any()); - } }
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn index 476d661..9b4b553d 100644 --- a/chrome/app/BUILD.gn +++ b/chrome/app/BUILD.gn
@@ -82,14 +82,12 @@ } } -grit("generated_resources") { +grit_strings("generated_resources") { source = "generated_resources.grd" defines = chrome_grit_defines + [ "is_cfm=${is_cfm}" ] output_dir = "$root_gen_dir/chrome" - outputs = - [ "grit/generated_resources.h" ] + - process_file_template(all_chrome_locales, - [ "generated_resources_{{source_name_part}}.pak" ]) + outputs = [ "grit/generated_resources.h" ] + if (is_android) { create_android_resources = true } @@ -110,14 +108,11 @@ } } -grit("branded_strings") { +grit_strings("branded_strings") { source = "${branding_path_product}_strings.grd" defines = chrome_grit_defines output_dir = "$root_gen_dir/chrome" - outputs = - [ "grit/branded_strings.h" ] + - process_file_template(all_chrome_locales, - [ "branded_strings_{{source_name_part}}.pak" ]) + outputs = [ "grit/branded_strings.h" ] if (is_android) { create_android_resources = true
diff --git a/chrome/app/chrome_command_ids.h b/chrome/app/chrome_command_ids.h index 7dbc937b..44f3323 100644 --- a/chrome/app/chrome_command_ids.h +++ b/chrome/app/chrome_command_ids.h
@@ -351,6 +351,7 @@ #define IDC_CONTENT_CONTEXT_OPENLINKINPROFILE 50108 #define IDC_CONTENT_CONTEXT_OPENLINKBOOKMARKAPP 50109 #define IDC_CONTENT_CONTEXT_OPENLINKPREVIEW 50110 +#define IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW 50111 // Image items. #define IDC_CONTENT_CONTEXT_SAVEIMAGEAS 50120 #define IDC_CONTENT_CONTEXT_COPYIMAGELOCATION 50121
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index b6aaaba..8c721e6 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -630,6 +630,9 @@ <message name="IDS_CONTENT_CONTEXT_OPENLINKOFFTHERECORD" desc="The name of the open a link in Incognito window command"> Open link in inco&gnito window </message> + <message name="IDS_CONTENT_CONTEXT_OPENLINKSPLITVIEW" translateable="false" desc="The name of the open a link in split view command"> + Open link in split view + </message> <message name="IDS_CONTENT_CONTEXT_OPENLINKINPROFILES" desc="The name of the open a link as a different user context menu"> Open link as </message> @@ -939,6 +942,9 @@ <message name="IDS_CONTENT_CONTEXT_OPENLINKOFFTHERECORD" desc="In Title Case: The name of the open a link in Incognito window command"> Open Link in Inco&gnito Window </message> + <message name="IDS_CONTENT_CONTEXT_OPENLINKSPLITVIEW" translateable="false" desc="The name of the open a link in split view command"> + Open Link in Split View + </message> <message name="IDS_CONTENT_CONTEXT_OPENLINKINPROFILES" desc="In Title Case: The name of the open a link as a different user context menu"> Open Link as </message>
diff --git a/chrome/app/resources/BUILD.gn b/chrome/app/resources/BUILD.gn index d896c75f..3b967e8f 100644 --- a/chrome/app/resources/BUILD.gn +++ b/chrome/app/resources/BUILD.gn
@@ -11,17 +11,14 @@ assert(!is_ios, "Chromium/iOS shouldn't use anything in //chrome") assert(!is_fuchsia, "Fuchsia shouldn't use anything in //chrome") -grit("locale_settings") { +grit_strings("locale_settings") { source = "locale_settings.grd" defines = chrome_grit_defines output_dir = "$root_gen_dir/chrome" - outputs = - [ "grit/locale_settings.h" ] + - process_file_template(all_chrome_locales, - [ "locale_settings_{{source_name_part}}.pak" ]) + outputs = [ "grit/locale_settings.h" ] } -grit("platform_locale_settings") { +grit_strings("platform_locale_settings") { if (is_win) { source = "locale_settings_win.grd" } else if (is_mac) { @@ -38,9 +35,7 @@ } defines = chrome_grit_defines - outputs = [ "grit/platform_locale_settings.h" ] + - process_file_template( - locales_with_pseudolocales, - [ "platform_locale_settings_{{source_name_part}}.pak" ]) + outputs = [ "grit/platform_locale_settings.h" ] + locales = locales_with_pseudolocales output_dir = "$root_gen_dir/chrome" }
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 56cab97..be7189c 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -295,6 +295,8 @@ "chrome_content_browser_client.h", "chrome_content_browser_client_binder_policies.cc", "chrome_content_browser_client_binder_policies.h", + "chrome_content_browser_client_navigation_throttles.cc", + "chrome_content_browser_client_navigation_throttles.h", "chrome_content_browser_client_parts.h", "chrome_content_browser_client_receiver_bindings.cc", "chrome_resource_bundle_helper.cc",
diff --git a/chrome/browser/OWNERS b/chrome/browser/OWNERS index dcd151a..d0d86445 100644 --- a/chrome/browser/OWNERS +++ b/chrome/browser/OWNERS
@@ -34,6 +34,8 @@ per-file chrome_content_browser_client.cc=* per-file chrome_content_browser_client.h=* per-file chrome_content_browser_client_browsertest.cc=* +per-file chrome_content_browser_client_navigation_throttles.cc=* +per-file chrome_content_browser_client_navigation_throttles.h=* per-file chrome_content_browser_client_unittest.cc=* per-file chrome_browser_field_trials*=file://components/variations/OWNERS
diff --git a/chrome/browser/accessibility/accessibility_labels_service.cc b/chrome/browser/accessibility/accessibility_labels_service.cc index 9a6b3a383..5e7a26c 100644 --- a/chrome/browser/accessibility/accessibility_labels_service.cc +++ b/chrome/browser/accessibility/accessibility_labels_service.cc
@@ -63,7 +63,7 @@ const PrefService* pref_service = profile_->GetPrefs(); std::string accept_languages_pref = pref_service->GetString(language::prefs::kAcceptLanguages); - for (std::string lang : + for (const std::string& lang : base::SplitString(accept_languages_pref, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) { accept_languages.push_back(lang);
diff --git a/chrome/browser/accessibility/pdf_ocr_controller.cc b/chrome/browser/accessibility/pdf_ocr_controller.cc index 76be195..f7f0b0c 100644 --- a/chrome/browser/accessibility/pdf_ocr_controller.cc +++ b/chrome/browser/accessibility/pdf_ocr_controller.cc
@@ -134,7 +134,7 @@ } void RecordAcceptLanguages(const std::string& accept_languages) { - for (std::string language : + for (const std::string& language : base::SplitString(accept_languages, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) { // Convert to a Chrome language code synonym. This language synonym is then
diff --git a/chrome/browser/apps/icon_standardizer.cc b/chrome/browser/apps/icon_standardizer.cc index b2dd1f2..14f6f03 100644 --- a/chrome/browser/apps/icon_standardizer.cc +++ b/chrome/browser/apps/icon_standardizer.cc
@@ -221,7 +221,7 @@ TRACE_EVENT0("ui", "apps::StandardizeSize"); gfx::ImageSkia final_image; - for (gfx::ImageSkiaRep rep : image.image_reps()) { + for (const gfx::ImageSkiaRep& rep : image.image_reps()) { std::optional<gfx::ImageSkiaRep> new_rep = StandardizeSizeOfImageRep(rep, rep.scale()); if (!new_rep) { @@ -344,7 +344,7 @@ gfx::ImageSkia final_image; gfx::ImageSkia standard_size_image = StandardizeSize(image); - for (gfx::ImageSkiaRep rep : standard_size_image.image_reps()) { + for (const gfx::ImageSkiaRep& rep : standard_size_image.image_reps()) { std::optional<gfx::ImageSkiaRep> standard_rep = CreateStandardIconImageRep(rep, rep.scale()); final_image.AddRepresentation(standard_rep.value_or(rep));
diff --git a/chrome/browser/apps/platform_apps/platform_app_navigation_redirector.cc b/chrome/browser/apps/platform_apps/platform_app_navigation_redirector.cc index cda6618..3599e48e 100644 --- a/chrome/browser/apps/platform_apps/platform_app_navigation_redirector.cc +++ b/chrome/browser/apps/platform_apps/platform_app_navigation_redirector.cc
@@ -84,30 +84,30 @@ } // namespace // static -std::unique_ptr<content::NavigationThrottle> -PlatformAppNavigationRedirector::MaybeCreateThrottleFor( - content::NavigationHandle* handle) { +void PlatformAppNavigationRedirector::MaybeCreateAndAdd( + content::NavigationThrottleRegistry& registry) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - DVLOG(1) << "Considering URL for redirection: " << handle->GetURL().spec(); + content::NavigationHandle& handle = registry.GetNavigationHandle(); + DVLOG(1) << "Considering URL for redirection: " << handle.GetURL().spec(); content::BrowserContext* browser_context = - handle->GetWebContents()->GetBrowserContext(); + handle.GetWebContents()->GetBrowserContext(); DCHECK(browser_context); - if (!handle->IsInOutermostMainFrame()) { + if (!handle.IsInOutermostMainFrame()) { DVLOG(1) << "Skip redirection: navigation is from an iframe or inner page"; - return nullptr; + return; } // Support only GET for now. - if (handle->IsPost()) { + if (handle.IsPost()) { DVLOG(1) << "Skip redirection: method is not GET"; - return nullptr; + return; } - if (!handle->GetURL().SchemeIsHTTPOrHTTPS()) { + if (!handle.GetURL().SchemeIsHTTPOrHTTPS()) { DVLOG(1) << "Skip redirection: scheme is not HTTP or HTTPS"; - return nullptr; + return; } // Redirect URLs to apps only in regular mode. Technically, apps are not @@ -116,7 +116,7 @@ Profile* profile = Profile::FromBrowserContext(browser_context); if (profile->IsOffTheRecord()) { DVLOG(1) << "Skip redirection: unsupported in incognito and guest modes"; - return nullptr; + return; } for (const auto& extension_ref : @@ -129,19 +129,20 @@ const UrlHandlerInfo* handler = UrlHandlers::GetMatchingPlatformAppUrlHandler(extension_ref.get(), - handle->GetURL()); + handle.GetURL()); if (handler) { DVLOG(1) << "Found matching app handler for redirection: " << extension_ref->name() << "(" << extension_ref->id() << "):" << handler->id; - return std::make_unique< - navigation_interception::InterceptNavigationThrottle>( - handle, - base::BindRepeating(&LaunchAppWithUrl, extension_ref, handler->id), - navigation_interception::SynchronyMode::kSync, std::nullopt); + registry.AddThrottle( + std::make_unique< + navigation_interception::InterceptNavigationThrottle>( + registry, + base::BindRepeating(&LaunchAppWithUrl, extension_ref, + handler->id), + navigation_interception::SynchronyMode::kSync, std::nullopt)); } } DVLOG(1) << "Skipping redirection: no matching app handler found"; - return nullptr; }
diff --git a/chrome/browser/apps/platform_apps/platform_app_navigation_redirector.h b/chrome/browser/apps/platform_apps/platform_app_navigation_redirector.h index 6ae67f8..e845bb7cb 100644 --- a/chrome/browser/apps/platform_apps/platform_app_navigation_redirector.h +++ b/chrome/browser/apps/platform_apps/platform_app_navigation_redirector.h
@@ -5,13 +5,8 @@ #ifndef CHROME_BROWSER_APPS_PLATFORM_APPS_PLATFORM_APP_NAVIGATION_REDIRECTOR_H_ #define CHROME_BROWSER_APPS_PLATFORM_APPS_PLATFORM_APP_NAVIGATION_REDIRECTOR_H_ -#include <memory> - -#include "content/public/browser/navigation_throttle.h" - namespace content { -class NavigationHandle; -class NavigationThrottle; +class NavigationThrottleRegistry; } // namespace content // This class creates navigation throttles that redirect navigations to URLs for @@ -19,8 +14,7 @@ // manifest key. Note that this is a UI thread class. class PlatformAppNavigationRedirector { public: - static std::unique_ptr<content::NavigationThrottle> MaybeCreateThrottleFor( - content::NavigationHandle* handle); + static void MaybeCreateAndAdd(content::NavigationThrottleRegistry& registry); PlatformAppNavigationRedirector(const PlatformAppNavigationRedirector&) = delete; PlatformAppNavigationRedirector& operator=(
diff --git a/chrome/browser/autocomplete/keyword_extensions_delegate_impl.h b/chrome/browser/autocomplete/keyword_extensions_delegate_impl.h index 0369dfa..762a0ed 100644 --- a/chrome/browser/autocomplete/keyword_extensions_delegate_impl.h +++ b/chrome/browser/autocomplete/keyword_extensions_delegate_impl.h
@@ -65,9 +65,7 @@ void OnOmniboxDefaultSuggestionChanged() override; ACMatches* matches() { return &provider_->matches_; } - void set_done(bool done) { - provider_->done_ = done; - } + void set_done(bool done) { provider_->done_ = done; } // Notifies the KeywordProvider about asynchronous updates from the extension. void OnProviderUpdate(bool updated_matches);
diff --git a/chrome/browser/autocomplete/search_provider_unittest.cc b/chrome/browser/autocomplete/search_provider_unittest.cc index 22e2af55..79c8b7d3 100644 --- a/chrome/browser/autocomplete/search_provider_unittest.cc +++ b/chrome/browser/autocomplete/search_provider_unittest.cc
@@ -187,24 +187,24 @@ // BaseSearchProviderTest ----------------------------------------------------- // Base class that configures following environment: -// . The TemplateURL default_t_url_ is set as the default provider. -// . The TemplateURL keyword_t_url_ is added to the TemplateURLService. -// TemplateURL values are set by subclasses. Most tests use SearchProviderTest -// with valid ones. -// . The URL created by using the search term term1_ with default_t_url_ is +// - The `TemplateURL` `default_t_url_` is set as the default provider. +// - The `TemplateURL` `keyword_t_url_` is added to the `TemplateURLService`. +// `TemplateURL` values are set by subclasses. Most tests use +// `SearchProviderTest` with valid ones. +// - The URL created by using the search term `term1_` with `default_t_url_` is // added to history. -// . The URL created by using the search term keyword_term_ with keyword_t_url_ -// is added to history. -// . test_url_loader_factory_ is set as the URLLoaderFactory. +// - The URL created by using the search term `keyword_term_` with +// `keyword_t_url_` is added to history. +// - `test_url_loader_factory_` is set as the `URLLoaderFactory`. // -// Most tests use SearchProviderTest subclass, see below. +// Most tests use `SearchProviderTest` subclass, see below. class BaseSearchProviderTest : public testing::Test, public AutocompleteProviderListener { public: struct ResultInfo { - ResultInfo() : result_type(AutocompleteMatchType::NUM_TYPES), - allowed_to_be_default_match(false) { - } + ResultInfo() + : result_type(AutocompleteMatchType::NUM_TYPES), + allowed_to_be_default_match(false) {} ResultInfo(GURL gurl, AutocompleteMatch::Type result_type, bool allowed_to_be_default_match, @@ -442,8 +442,7 @@ for (size_t j = 0; j < cases[i].num_results; ++j) { EXPECT_EQ(cases[i].output[j].gurl, matches[j].destination_url); EXPECT_EQ(cases[i].output[j].result_type, matches[j].type); - EXPECT_EQ(cases[i].output[j].fill_into_edit, - matches[j].fill_into_edit); + EXPECT_EQ(cases[i].output[j].fill_into_edit, matches[j].fill_into_edit); EXPECT_EQ(cases[i].output[j].allowed_to_be_default_match, matches[j].allowed_to_be_default_match); } @@ -1333,213 +1332,345 @@ const ExpectedMatch matches[6]; const std::string inline_autocompletion; } cases[] = { - // Ensure that suggestrelevance scores reorder matches. - { "[\"a\",[\"b\", \"c\"],[],[],{\"google:suggestrelevance\":[1, 2]}]", - { { "a", true }, { "c", false }, { "b", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch }, - std::string() }, - { "[\"a\",[\"http://b.com\", \"http://c.com\"],[],[]," + // Ensure that suggestrelevance scores reorder matches. + {"[\"a\",[\"b\", \"c\"],[],[],{\"google:suggestrelevance\":[1, 2]}]", + {{"a", true}, + {"c", false}, + {"b", false}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + std::string()}, + {"[\"a\",[\"http://b.com\", \"http://c.com\"],[],[]," "{\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"]," - "\"google:suggestrelevance\":[1, 2]}]", - { { "a", true }, { "c.com", false }, { "b.com", false }, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - std::string() }, + "\"google:suggestrelevance\":[1, 2]}]", + {{"a", true}, + {"c.com", false}, + {"b.com", false}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + std::string()}, - // Without suggested relevance scores, we should only allow one - // navsuggest result to be be displayed. - { "[\"a\",[\"http://b.com\", \"http://c.com\"],[],[]," + // Without suggested relevance scores, we should only allow one + // navsuggest result to be be displayed. + {"[\"a\",[\"http://b.com\", \"http://c.com\"],[],[]," "{\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"]}]", - { { "a", true }, { "b.com", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - std::string() }, + {{"a", true}, + {"b.com", false}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + std::string()}, - // Ensure that verbatimrelevance scores reorder or suppress verbatim. - // Negative values will have no effect; the calculated value will be used. - { "[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":9999," - "\"google:suggestrelevance\":[9998]}]", - { { "a", true}, { "a1", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - std::string() }, - { "[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":9998," - "\"google:suggestrelevance\":[9999]}]", - { { "a1", true }, { "a", true }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - "1" }, - { "[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":0," - "\"google:suggestrelevance\":[9999]}]", - { { "a1", true }, kEmptyExpectedMatch, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - "1" }, - { "[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":-1," - "\"google:suggestrelevance\":[9999]}]", - { { "a1", true }, { "a", true }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - "1" }, - { "[\"a\",[\"http://a.com\"],[],[]," + // Ensure that verbatimrelevance scores reorder or suppress verbatim. + // Negative values will have no effect; the calculated value will be used. + {"[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":9999," + "\"google:suggestrelevance\":[9998]}]", + {{"a", true}, + {"a1", false}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + std::string()}, + {"[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":9998," + "\"google:suggestrelevance\":[9999]}]", + {{"a1", true}, + {"a", true}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + "1"}, + {"[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":0," + "\"google:suggestrelevance\":[9999]}]", + {{"a1", true}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + "1"}, + {"[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":-1," + "\"google:suggestrelevance\":[9999]}]", + {{"a1", true}, + {"a", true}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + "1"}, + {"[\"a\",[\"http://a.com\"],[],[]," "{\"google:suggesttype\":[\"NAVIGATION\"]," - "\"google:verbatimrelevance\":9999," - "\"google:suggestrelevance\":[9998]}]", - { { "a", true }, { "a.com", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - std::string() }, - { "[\"a\",[\"http://a.com\"],[],[]," + "\"google:verbatimrelevance\":9999," + "\"google:suggestrelevance\":[9998]}]", + {{"a", true}, + {"a.com", false}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + std::string()}, + {"[\"a\",[\"http://a.com\"],[],[]," "{\"google:suggesttype\":[\"NAVIGATION\"]," - "\"google:verbatimrelevance\":9998," - "\"google:suggestrelevance\":[9999]}]", - { { "a.com", true }, { "a", true }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - ".com" }, - { "[\"a\",[\"http://a.com\"],[],[]," + "\"google:verbatimrelevance\":9998," + "\"google:suggestrelevance\":[9999]}]", + {{"a.com", true}, + {"a", true}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + ".com"}, + {"[\"a\",[\"http://a.com\"],[],[]," "{\"google:suggesttype\":[\"NAVIGATION\"]," - "\"google:verbatimrelevance\":0," - "\"google:suggestrelevance\":[9999]}]", - { { "a.com", true }, kEmptyExpectedMatch, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - ".com" }, - { "[\"a\",[\"http://a.com\"],[],[]," + "\"google:verbatimrelevance\":0," + "\"google:suggestrelevance\":[9999]}]", + {{"a.com", true}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + ".com"}, + {"[\"a\",[\"http://a.com\"],[],[]," "{\"google:suggesttype\":[\"NAVIGATION\"]," - "\"google:verbatimrelevance\":-1," - "\"google:suggestrelevance\":[9999]}]", - { { "a.com", true }, { "a", true }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - ".com" }, + "\"google:verbatimrelevance\":-1," + "\"google:suggestrelevance\":[9999]}]", + {{"a.com", true}, + {"a", true}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + ".com"}, - // Ensure that both types of relevance scores reorder matches together. - { "[\"a\",[\"a1\", \"a2\"],[],[],{\"google:suggestrelevance\":[9999, 9997]," - "\"google:verbatimrelevance\":9998}]", - { { "a1", true }, { "a", true }, { "a2", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch }, - "1" }, + // Ensure that both types of relevance scores reorder matches together. + {"[\"a\",[\"a1\", \"a2\"],[],[],{\"google:suggestrelevance\":[9999, " + "9997],\"google:verbatimrelevance\":9998}]", + {{"a1", true}, + {"a", true}, + {"a2", false}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + "1"}, - // Check that an inlineable result appears first regardless of its score. - // Also, if the result set lacks a single inlineable result, abandon the - // request to suppress verbatim (verbatim_relevance=0), which will then - // cause verbatim to appear (first). - { "[\"a\",[\"b\"],[],[],{\"google:suggestrelevance\":[9999]}]", - { { "a", true }, { "b", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - std::string() }, - { "[\"a\",[\"b\"],[],[],{\"google:suggestrelevance\":[9999]," - "\"google:verbatimrelevance\":0}]", - { { "a", true }, { "b", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - std::string() }, - { "[\"a\",[\"http://b.com\"],[],[]," + // Check that an inlineable result appears first regardless of its score. + // Also, if the result set lacks a single inlineable result, abandon the + // request to suppress verbatim (verbatim_relevance=0), which will then + // cause verbatim to appear (first). + {"[\"a\",[\"b\"],[],[],{\"google:suggestrelevance\":[9999]}]", + {{"a", true}, + {"b", false}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + std::string()}, + {"[\"a\",[\"b\"],[],[],{\"google:suggestrelevance\":[9999]," + "\"google:verbatimrelevance\":0}]", + {{"a", true}, + {"b", false}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + std::string()}, + {"[\"a\",[\"http://b.com\"],[],[]," "{\"google:suggesttype\":[\"NAVIGATION\"]," - "\"google:suggestrelevance\":[9999]}]", - { { "a", true }, { "b.com", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - std::string() }, - { "[\"a\",[\"http://b.com\"],[],[]," + "\"google:suggestrelevance\":[9999]}]", + {{"a", true}, + {"b.com", false}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + std::string()}, + {"[\"a\",[\"http://b.com\"],[],[]," "{\"google:suggesttype\":[\"NAVIGATION\"]," - "\"google:suggestrelevance\":[9999]," - "\"google:verbatimrelevance\":0}]", - { { "a", true }, { "b.com", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - std::string() }, + "\"google:suggestrelevance\":[9999]," + "\"google:verbatimrelevance\":0}]", + {{"a", true}, + {"b.com", false}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + std::string()}, - // Allow low-scoring matches. - { "[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":0}]", - { { "a1", true }, kEmptyExpectedMatch, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - "1" }, - { "[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":10}]", - { { "a1", true }, { "a", true }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - "1" }, - { "[\"a\",[\"a1\"],[],[],{\"google:suggestrelevance\":[10]," - "\"google:verbatimrelevance\":0}]", - { { "a1", true }, kEmptyExpectedMatch, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - "1" }, - { "[\"a\",[\"a1\", \"a2\"],[],[],{\"google:suggestrelevance\":[10, 20]," - "\"google:verbatimrelevance\":0}]", - { { "a2", true }, { "a1", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - "2" }, - { "[\"a\",[\"a1\", \"a2\"],[],[],{\"google:suggestrelevance\":[10, 30]," - "\"google:verbatimrelevance\":20}]", - { { "a2", true }, { "a", true }, { "a1", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch }, - "2" }, - { "[\"a\",[\"http://a.com\"],[],[]," + // Allow low-scoring matches. + {"[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":0}]", + {{"a1", true}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + "1"}, + {"[\"a\",[\"a1\"],[],[],{\"google:verbatimrelevance\":10}]", + {{"a1", true}, + {"a", true}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + "1"}, + {"[\"a\",[\"a1\"],[],[],{\"google:suggestrelevance\":[10]," + "\"google:verbatimrelevance\":0}]", + {{"a1", true}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + "1"}, + {"[\"a\",[\"a1\", \"a2\"],[],[],{\"google:suggestrelevance\":[10, 20]," + "\"google:verbatimrelevance\":0}]", + {{"a2", true}, + {"a1", false}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + "2"}, + {"[\"a\",[\"a1\", \"a2\"],[],[],{\"google:suggestrelevance\":[10, 30]," + "\"google:verbatimrelevance\":20}]", + {{"a2", true}, + {"a", true}, + {"a1", false}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + "2"}, + {"[\"a\",[\"http://a.com\"],[],[]," "{\"google:suggesttype\":[\"NAVIGATION\"]," - "\"google:suggestrelevance\":[10]," - "\"google:verbatimrelevance\":0}]", - { { "a.com", true }, kEmptyExpectedMatch, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - ".com" }, - { "[\"a\",[\"http://a1.com\", \"http://a2.com\"],[],[]," + "\"google:suggestrelevance\":[10]," + "\"google:verbatimrelevance\":0}]", + {{"a.com", true}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + ".com"}, + {"[\"a\",[\"http://a1.com\", \"http://a2.com\"],[],[]," "{\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"]," - "\"google:suggestrelevance\":[10, 20]," - "\"google:verbatimrelevance\":0}]", - { { "a2.com", true }, { "a1.com", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - "2.com" }, + "\"google:suggestrelevance\":[10, 20]," + "\"google:verbatimrelevance\":0}]", + {{"a2.com", true}, + {"a1.com", false}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + "2.com"}, - // Ensure that all suggestions are considered, regardless of order. - { "[\"a\",[\"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\"],[],[]," + // Ensure that all suggestions are considered, regardless of order. + {"[\"a\",[\"b\", \"c\", \"d\", \"e\", \"f\", \"g\", \"h\"],[],[]," "{\"google:suggestrelevance\":[10, 20, 30, 40, 50, 60, 70]}]", - { { "a", true }, { "h", false }, { "g", false }, { "f", false }, - { "e", false }, { "d", false } }, - std::string() }, - { "[\"a\",[\"http://b.com\", \"http://c.com\", \"http://d.com\"," - "\"http://e.com\", \"http://f.com\", \"http://g.com\"," - "\"http://h.com\"],[],[]," + {{"a", true}, + {"h", false}, + {"g", false}, + {"f", false}, + {"e", false}, + {"d", false}}, + std::string()}, + {"[\"a\",[\"http://b.com\", \"http://c.com\", \"http://d.com\"," + "\"http://e.com\", \"http://f.com\", \"http://g.com\"," + "\"http://h.com\"],[],[]," "{\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"," - "\"NAVIGATION\", \"NAVIGATION\"," - "\"NAVIGATION\", \"NAVIGATION\"," - "\"NAVIGATION\"]," - "\"google:suggestrelevance\":[10, 20, 30, 40, 50, 60, 70]}]", - { { "a", true }, { "h.com", false }, { "g.com", false }, - { "f.com", false }, { "e.com", false }, { "d.com", false } }, - std::string() }, + "\"NAVIGATION\", \"NAVIGATION\"," + "\"NAVIGATION\", \"NAVIGATION\"," + "\"NAVIGATION\"]," + "\"google:suggestrelevance\":[10, 20, 30, 40, 50, 60, 70]}]", + {{"a", true}, + {"h.com", false}, + {"g.com", false}, + {"f.com", false}, + {"e.com", false}, + {"d.com", false}}, + std::string()}, - // Ensure that incorrectly sized suggestion relevance lists are ignored. - { "[\"a\",[\"a1\", \"a2\"],[],[],{\"google:suggestrelevance\":[10]}]", - { { "a", true }, { "a1", false }, { "a2", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch }, - std::string() }, - { "[\"a\",[\"a1\"],[],[],{\"google:suggestrelevance\":[9999, 10]}]", - { { "a", true }, { "a1", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - std::string() }, - { "[\"a\",[\"http://a1.com\", \"http://a2.com\"],[],[]," + // Ensure that incorrectly sized suggestion relevance lists are ignored. + {"[\"a\",[\"a1\", \"a2\"],[],[],{\"google:suggestrelevance\":[10]}]", + {{"a", true}, + {"a1", false}, + {"a2", false}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + std::string()}, + {"[\"a\",[\"a1\"],[],[],{\"google:suggestrelevance\":[9999, 10]}]", + {{"a", true}, + {"a1", false}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + std::string()}, + {"[\"a\",[\"http://a1.com\", \"http://a2.com\"],[],[]," "{\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"]," - "\"google:suggestrelevance\":[10]}]", - { { "a", true }, { "a1.com", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - std::string() }, - { "[\"a\",[\"http://a1.com\"],[],[]," + "\"google:suggestrelevance\":[10]}]", + {{"a", true}, + {"a1.com", false}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + std::string()}, + {"[\"a\",[\"http://a1.com\"],[],[]," "{\"google:suggesttype\":[\"NAVIGATION\"]," "\"google:suggestrelevance\":[9999, 10]}]", - { { "a", true }, { "a1.com", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - std::string() }, + {{"a", true}, + {"a1.com", false}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + std::string()}, - // Ensure that all 'verbatim' results are merged with their maximum score. - { "[\"a\",[\"a\", \"a1\", \"a2\"],[],[]," + // Ensure that all 'verbatim' results are merged with their maximum score. + {"[\"a\",[\"a\", \"a1\", \"a2\"],[],[]," "{\"google:suggestrelevance\":[9998, 9997, 9999]}]", - { { "a2", true }, { "a", true }, { "a1", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch }, - "2" }, - { "[\"a\",[\"a\", \"a1\", \"a2\"],[],[]," + {{"a2", true}, + {"a", true}, + {"a1", false}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + "2"}, + {"[\"a\",[\"a\", \"a1\", \"a2\"],[],[]," "{\"google:suggestrelevance\":[9998, 9997, 9999]," - "\"google:verbatimrelevance\":0}]", - { { "a2", true }, { "a", true }, { "a1", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch }, - "2" }, + "\"google:verbatimrelevance\":0}]", + {{"a2", true}, + {"a", true}, + {"a1", false}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + "2"}, - // Ensure that verbatim is always generated without other suggestions. - // TODO(msw): Ensure verbatimrelevance is respected (except suppression). - { "[\"a\",[],[],[],{\"google:verbatimrelevance\":1}]", - { { "a", true }, kEmptyExpectedMatch, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - std::string() }, - { "[\"a\",[],[],[],{\"google:verbatimrelevance\":0}]", - { { "a", true }, kEmptyExpectedMatch, kEmptyExpectedMatch, - kEmptyExpectedMatch, kEmptyExpectedMatch, kEmptyExpectedMatch }, - std::string() }, + // Ensure that verbatim is always generated without other suggestions. + // TODO(msw): Ensure verbatimrelevance is respected (except suppression). + {"[\"a\",[],[],[],{\"google:verbatimrelevance\":1}]", + {{"a", true}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + std::string()}, + {"[\"a\",[],[],[],{\"google:verbatimrelevance\":0}]", + {{"a", true}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + std::string()}, }; for (auto& test_case : cases) { @@ -1580,7 +1711,7 @@ bool from_keyword; bool allowed_to_be_default_match; }; - const KeywordFetcherMatch kEmptyMatch = { kNotApplicable, false, false }; + const KeywordFetcherMatch kEmptyMatch = {kNotApplicable, false, false}; struct Cases { const std::string json; const KeywordFetcherMatch matches[6]; @@ -2009,186 +2140,183 @@ const std::string second_json; const ExpectedMatch second_async_matches[4]; } cases[] = { - // A simple test that verifies we don't inline autocomplete after the - // first asynchronous response, but we do at the next keystroke if the - // response's results were good enough. Furthermore, we should continue - // inline autocompleting after the second asynchronous response if the new - // top suggestion is the same as the old inline autocompleted suggestion. - { "[\"a\",[\"ab1\", \"ab2\"],[],[]," + // A simple test that verifies we don't inline autocomplete after the + // first asynchronous response, but we do at the next keystroke if the + // response's results were good enough. Furthermore, we should continue + // inline autocompleting after the second asynchronous response if the new + // top suggestion is the same as the old inline autocompleted suggestion. + {"[\"a\",[\"ab1\", \"ab2\"],[],[]," "{\"google:verbatimrelevance\":9000," - "\"google:suggestrelevance\":[9002, 9001]}]", - { { "a", true }, { "ab1", false }, { "ab2", false }, - kEmptyExpectedMatch }, - { { "ab1", true }, { "ab2", true }, { "ab", true }, - kEmptyExpectedMatch }, - "[\"ab\",[\"ab1\", \"ab2\"],[],[]," + "\"google:suggestrelevance\":[9002, 9001]}]", + {{"a", true}, {"ab1", false}, {"ab2", false}, kEmptyExpectedMatch}, + {{"ab1", true}, {"ab2", true}, {"ab", true}, kEmptyExpectedMatch}, + "[\"ab\",[\"ab1\", \"ab2\"],[],[]," "{\"google:verbatimrelevance\":9000," - "\"google:suggestrelevance\":[9002, 9001]}]", - { { "ab1", true }, { "ab2", false }, { "ab", true }, - kEmptyExpectedMatch } }, - // Ditto, just for a navigation suggestion. - { "[\"a\",[\"ab1.com\", \"ab2.com\"],[],[]," + "\"google:suggestrelevance\":[9002, 9001]}]", + {{"ab1", true}, {"ab2", false}, {"ab", true}, kEmptyExpectedMatch}}, + // Ditto, just for a navigation suggestion. + {"[\"a\",[\"ab1.com\", \"ab2.com\"],[],[]," "{\"google:verbatimrelevance\":9000," - "\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"]," - "\"google:suggestrelevance\":[9002, 9001]}]", - { { "a", true }, { "ab1.com", false }, { "ab2.com", false }, - kEmptyExpectedMatch }, - { { "ab1.com", true }, { "ab2.com", true }, { "ab", true }, - kEmptyExpectedMatch }, - "[\"ab\",[\"ab1.com\", \"ab2.com\"],[],[]," + "\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"]," + "\"google:suggestrelevance\":[9002, 9001]}]", + {{"a", true}, + {"ab1.com", false}, + {"ab2.com", false}, + kEmptyExpectedMatch}, + {{"ab1.com", true}, + {"ab2.com", true}, + {"ab", true}, + kEmptyExpectedMatch}, + "[\"ab\",[\"ab1.com\", \"ab2.com\"],[],[]," "{\"google:verbatimrelevance\":9000," - "\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"]," - "\"google:suggestrelevance\":[9002, 9001]}]", - { { "ab1.com", true }, { "ab2.com", false }, { "ab", true }, - kEmptyExpectedMatch } }, - // A more realistic test of the same situation. - { "[\"a\",[\"abcdef\", \"abcdef.com\", \"abc\"],[],[]," + "\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"]," + "\"google:suggestrelevance\":[9002, 9001]}]", + {{"ab1.com", true}, + {"ab2.com", false}, + {"ab", true}, + kEmptyExpectedMatch}}, + // A more realistic test of the same situation. + {"[\"a\",[\"abcdef\", \"abcdef.com\", \"abc\"],[],[]," "{\"google:verbatimrelevance\":900," - "\"google:suggesttype\":[\"QUERY\", \"NAVIGATION\", \"QUERY\"]," - "\"google:suggestrelevance\":[1250, 1200, 1000]}]", - { { "a", true }, { "abcdef", false }, { "abcdef.com", false }, - { "abc", false } }, - { { "abcdef", true }, { "abcdef.com", true }, { "abc", true }, - { "ab", true } }, - "[\"ab\",[\"abcdef\", \"abcdef.com\", \"abc\"],[],[]," + "\"google:suggesttype\":[\"QUERY\", \"NAVIGATION\", \"QUERY\"]," + "\"google:suggestrelevance\":[1250, 1200, 1000]}]", + {{"a", true}, {"abcdef", false}, {"abcdef.com", false}, {"abc", false}}, + {{"abcdef", true}, {"abcdef.com", true}, {"abc", true}, {"ab", true}}, + "[\"ab\",[\"abcdef\", \"abcdef.com\", \"abc\"],[],[]," "{\"google:verbatimrelevance\":900," - "\"google:suggesttype\":[\"QUERY\", \"NAVIGATION\", \"QUERY\"]," - "\"google:suggestrelevance\":[1250, 1200, 1000]}]", - { { "abcdef", true }, { "abcdef.com", false }, { "abc", false }, - { "ab", true } } }, + "\"google:suggesttype\":[\"QUERY\", \"NAVIGATION\", \"QUERY\"]," + "\"google:suggestrelevance\":[1250, 1200, 1000]}]", + {{"abcdef", true}, {"abcdef.com", false}, {"abc", false}, {"ab", true}}}, - // Without an original inline autcompletion, a new inline autcompletion - // should be rejected. - { "[\"a\",[\"ab1\", \"ab2\"],[],[]," + // Without an original inline autcompletion, a new inline autcompletion + // should be rejected. + {"[\"a\",[\"ab1\", \"ab2\"],[],[]," "{\"google:verbatimrelevance\":9000," - "\"google:suggestrelevance\":[8000, 7000]}]", - { { "a", true }, { "ab1", false }, { "ab2", false }, - kEmptyExpectedMatch }, - { { "ab", true }, { "ab1", true }, { "ab2", true }, - kEmptyExpectedMatch }, - "[\"ab\",[\"ab1\", \"ab2\"],[],[]," + "\"google:suggestrelevance\":[8000, 7000]}]", + {{"a", true}, {"ab1", false}, {"ab2", false}, kEmptyExpectedMatch}, + {{"ab", true}, {"ab1", true}, {"ab2", true}, kEmptyExpectedMatch}, + "[\"ab\",[\"ab1\", \"ab2\"],[],[]," "{\"google:verbatimrelevance\":9000," - "\"google:suggestrelevance\":[9002, 9001]}]", - { { "ab", true }, { "ab1", false }, { "ab2", false }, - kEmptyExpectedMatch } }, - // For the same test except with the queries scored in the opposite order - // on the second JSON response, the queries should be ordered by the second - // response's scores, not the first. - { "[\"a\",[\"ab1\", \"ab2\"],[],[]," + "\"google:suggestrelevance\":[9002, 9001]}]", + {{"ab", true}, {"ab1", false}, {"ab2", false}, kEmptyExpectedMatch}}, + // For the same test except with the queries scored in the opposite order + // on the second JSON response, the queries should be ordered by the + // second response's scores, not the first. + {"[\"a\",[\"ab1\", \"ab2\"],[],[]," "{\"google:verbatimrelevance\":9000," - "\"google:suggestrelevance\":[8000, 7000]}]", - { { "a", true }, { "ab1", false }, { "ab2", false }, - kEmptyExpectedMatch }, - { { "ab", true }, { "ab1", true }, { "ab2", true }, - kEmptyExpectedMatch }, - "[\"ab\",[\"ab1\", \"ab2\"],[],[]," + "\"google:suggestrelevance\":[8000, 7000]}]", + {{"a", true}, {"ab1", false}, {"ab2", false}, kEmptyExpectedMatch}, + {{"ab", true}, {"ab1", true}, {"ab2", true}, kEmptyExpectedMatch}, + "[\"ab\",[\"ab1\", \"ab2\"],[],[]," "{\"google:verbatimrelevance\":9000," - "\"google:suggestrelevance\":[9001, 9002]}]", - { { "ab", true }, { "ab2", false }, { "ab1", false }, - kEmptyExpectedMatch } }, - // Now, the same verifications but with the new inline autocompletion as a - // navsuggestion. The new autocompletion should still be rejected. - { "[\"a\",[\"ab1.com\", \"ab2.com\"],[],[]," + "\"google:suggestrelevance\":[9001, 9002]}]", + {{"ab", true}, {"ab2", false}, {"ab1", false}, kEmptyExpectedMatch}}, + // Now, the same verifications but with the new inline autocompletion as a + // navsuggestion. The new autocompletion should still be rejected. + {"[\"a\",[\"ab1.com\", \"ab2.com\"],[],[]," "{\"google:verbatimrelevance\":9000," - "\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"]," - "\"google:suggestrelevance\":[8000, 7000]}]", - { { "a", true }, { "ab1.com", false }, { "ab2.com", false }, - kEmptyExpectedMatch }, - { { "ab", true }, { "ab1.com", true }, { "ab2.com", true }, - kEmptyExpectedMatch }, - "[\"ab\",[\"ab1.com\", \"ab2.com\"],[],[]," + "\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"]," + "\"google:suggestrelevance\":[8000, 7000]}]", + {{"a", true}, + {"ab1.com", false}, + {"ab2.com", false}, + kEmptyExpectedMatch}, + {{"ab", true}, + {"ab1.com", true}, + {"ab2.com", true}, + kEmptyExpectedMatch}, + "[\"ab\",[\"ab1.com\", \"ab2.com\"],[],[]," "{\"google:verbatimrelevance\":9000," - "\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"]," - "\"google:suggestrelevance\":[9002, 9001]}]", - { { "ab", true }, { "ab1.com", false }, { "ab2.com", false }, - kEmptyExpectedMatch } }, - { "[\"a\",[\"ab1.com\", \"ab2.com\"],[],[]," + "\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"]," + "\"google:suggestrelevance\":[9002, 9001]}]", + {{"ab", true}, + {"ab1.com", false}, + {"ab2.com", false}, + kEmptyExpectedMatch}}, + {"[\"a\",[\"ab1.com\", \"ab2.com\"],[],[]," "{\"google:verbatimrelevance\":9000," - "\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"]," - "\"google:suggestrelevance\":[8000, 7000]}]", - { { "a", true }, { "ab1.com", false }, { "ab2.com", false }, - kEmptyExpectedMatch }, - { { "ab", true }, { "ab1.com", true }, { "ab2.com", true }, - kEmptyExpectedMatch }, - "[\"ab\",[\"ab1.com\", \"ab2.com\"],[],[]," + "\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"]," + "\"google:suggestrelevance\":[8000, 7000]}]", + {{"a", true}, + {"ab1.com", false}, + {"ab2.com", false}, + kEmptyExpectedMatch}, + {{"ab", true}, + {"ab1.com", true}, + {"ab2.com", true}, + kEmptyExpectedMatch}, + "[\"ab\",[\"ab1.com\", \"ab2.com\"],[],[]," "{\"google:verbatimrelevance\":9000," - "\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"]," - "\"google:suggestrelevance\":[9001, 9002]}]", - { { "ab", true }, { "ab2.com", false }, { "ab1.com", false }, - kEmptyExpectedMatch } }, + "\"google:suggesttype\":[\"NAVIGATION\", \"NAVIGATION\"]," + "\"google:suggestrelevance\":[9001, 9002]}]", + {{"ab", true}, + {"ab2.com", false}, + {"ab1.com", false}, + kEmptyExpectedMatch}}, - // It's okay to abandon an inline autocompletion asynchronously. - { "[\"a\",[\"ab1\", \"ab2\"],[],[]," + // It's okay to abandon an inline autocompletion asynchronously. + {"[\"a\",[\"ab1\", \"ab2\"],[],[]," "{\"google:verbatimrelevance\":9000," - "\"google:suggestrelevance\":[9002, 9001]}]", - { { "a", true }, { "ab1", false }, { "ab2", false }, - kEmptyExpectedMatch }, - { { "ab1", true }, { "ab2", true }, { "ab", true }, - kEmptyExpectedMatch }, - "[\"ab\",[\"ab1\", \"ab2\"],[],[]," + "\"google:suggestrelevance\":[9002, 9001]}]", + {{"a", true}, {"ab1", false}, {"ab2", false}, kEmptyExpectedMatch}, + {{"ab1", true}, {"ab2", true}, {"ab", true}, kEmptyExpectedMatch}, + "[\"ab\",[\"ab1\", \"ab2\"],[],[]," "{\"google:verbatimrelevance\":9000," - "\"google:suggestrelevance\":[8000, 7000]}]", - { { "ab", true }, { "ab1", true }, { "ab2", false }, - kEmptyExpectedMatch } }, + "\"google:suggestrelevance\":[8000, 7000]}]", + {{"ab", true}, {"ab1", true}, {"ab2", false}, kEmptyExpectedMatch}}, - // If a suggestion is equivalent to the verbatim suggestion, it should be - // collapsed into one. Furthermore, it should be allowed to be the default - // match even if it was not previously displayed inlined. This test is - // mainly for checking the first_async_matches. - { "[\"a\",[\"A\"],[],[]," + // If a suggestion is equivalent to the verbatim suggestion, it should be + // collapsed into one. Furthermore, it should be allowed to be the + // default match even if it was not previously displayed inlined. This + // test is mainly for checking the first_async_matches. + {"[\"a\",[\"A\"],[],[]," "{\"google:verbatimrelevance\":9000, " - "\"google:suggestrelevance\":[9001]}]", - { { "A", true }, kEmptyExpectedMatch, kEmptyExpectedMatch, - kEmptyExpectedMatch }, - { { "ab", true }, { "A", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch }, - std::string(), - { { "ab", true }, { "A", false }, kEmptyExpectedMatch, - kEmptyExpectedMatch } }, + "\"google:suggestrelevance\":[9001]}]", + {{"A", true}, + kEmptyExpectedMatch, + kEmptyExpectedMatch, + kEmptyExpectedMatch}, + {{"ab", true}, {"A", false}, kEmptyExpectedMatch, kEmptyExpectedMatch}, + std::string(), + {{"ab", true}, {"A", false}, kEmptyExpectedMatch, kEmptyExpectedMatch}}, - // Note: it's possible that the suggest server returns a suggestion with - // an inline autocompletion (that as usual we delay in allowing it to - // be displayed as an inline autocompletion until the next keystroke), - // then, in response to the next keystroke, the server returns a different - // suggestion as an inline autocompletion. This is not likely to happen. - // Regardless, if it does, one could imagine three different behaviors: - // - keep the original inline autocompletion until the next keystroke - // (i.e., don't abandon an inline autocompletion asynchronously), then - // use the new suggestion - // - abandon all inline autocompletions upon the server response, then use - // the new suggestion on the next keystroke - // - ignore the new inline autocompletion provided by the server, yet - // possibly keep the original if it scores well in the most recent - // response, then use the new suggestion on the next keystroke - // All of these behaviors are reasonable. The main thing we want to - // ensure is that the second asynchronous response shouldn't cause *a new* - // inline autocompletion to be displayed. We test that here. - // The current implementation does the third bullet, but all of these - // behaviors seem reasonable. - { "[\"a\",[\"ab1\", \"ab2\"],[],[]," + // Note: it's possible that the suggest server returns a suggestion with + // an inline autocompletion (that as usual we delay in allowing it to + // be displayed as an inline autocompletion until the next keystroke), + // then, in response to the next keystroke, the server returns a different + // suggestion as an inline autocompletion. This is not likely to happen. + // Regardless, if it does, one could imagine three different behaviors: + // - keep the original inline autocompletion until the next keystroke + // (i.e., don't abandon an inline autocompletion asynchronously), then + // use the new suggestion + // - abandon all inline autocompletions upon the server response, then use + // the new suggestion on the next keystroke + // - ignore the new inline autocompletion provided by the server, yet + // possibly keep the original if it scores well in the most recent + // response, then use the new suggestion on the next keystroke + // All of these behaviors are reasonable. The main thing we want to + // ensure is that the second asynchronous response shouldn't cause *a new* + // inline autocompletion to be displayed. We test that here. + // The current implementation does the third bullet, but all of these + // behaviors seem reasonable. + {"[\"a\",[\"ab1\", \"ab2\"],[],[]," "{\"google:verbatimrelevance\":9000," - "\"google:suggestrelevance\":[9002, 9001]}]", - { { "a", true }, { "ab1", false }, { "ab2", false }, - kEmptyExpectedMatch }, - { { "ab1", true }, { "ab2", true }, { "ab", true }, - kEmptyExpectedMatch }, - "[\"ab\",[\"ab1\", \"ab3\"],[],[]," + "\"google:suggestrelevance\":[9002, 9001]}]", + {{"a", true}, {"ab1", false}, {"ab2", false}, kEmptyExpectedMatch}, + {{"ab1", true}, {"ab2", true}, {"ab", true}, kEmptyExpectedMatch}, + "[\"ab\",[\"ab1\", \"ab3\"],[],[]," "{\"google:verbatimrelevance\":9000," - "\"google:suggestrelevance\":[9002, 9900]}]", - { { "ab1", true }, { "ab3", false }, { "ab", true }, - kEmptyExpectedMatch } }, - { "[\"a\",[\"ab1\", \"ab2\"],[],[]," + "\"google:suggestrelevance\":[9002, 9900]}]", + {{"ab1", true}, {"ab3", false}, {"ab", true}, kEmptyExpectedMatch}}, + {"[\"a\",[\"ab1\", \"ab2\"],[],[]," "{\"google:verbatimrelevance\":9000," - "\"google:suggestrelevance\":[9002, 9001]}]", - { { "a", true }, { "ab1", false }, { "ab2", false }, - kEmptyExpectedMatch }, - { { "ab1", true }, { "ab2", true }, { "ab", true }, - kEmptyExpectedMatch }, - "[\"ab\",[\"ab1\", \"ab3\"],[],[]," + "\"google:suggestrelevance\":[9002, 9001]}]", + {{"a", true}, {"ab1", false}, {"ab2", false}, kEmptyExpectedMatch}, + {{"ab1", true}, {"ab2", true}, {"ab", true}, kEmptyExpectedMatch}, + "[\"ab\",[\"ab1\", \"ab3\"],[],[]," "{\"google:verbatimrelevance\":9000," - "\"google:suggestrelevance\":[8000, 9500]}]", - { { "ab", true }, { "ab3", false }, { "ab1", true }, - kEmptyExpectedMatch } }, + "\"google:suggestrelevance\":[8000, 9500]}]", + {{"ab", true}, {"ab3", false}, {"ab1", true}, kEmptyExpectedMatch}}, }; for (auto& test_case : cases) { @@ -2364,8 +2492,8 @@ }); for (size_t i = 0; i < std::size(cases); ++i) { - QueryForInputAndWaitForFetcherResponses( - cases[i].input, false, cases[i].json, std::string()); + QueryForInputAndWaitForFetcherResponses(cases[i].input, false, + cases[i].json, std::string()); const std::string description = "for input with json=" + cases[i].json; const ACMatches& matches = provider_->matches(); @@ -2376,12 +2504,12 @@ size_t j = 0; // Ensure that the returned matches equal the expectations. for (; j < matches.size(); ++j) - EXPECT_EQ(ASCIIToUTF16(cases[i].matches[j]), - matches[j].contents) << description; + EXPECT_EQ(ASCIIToUTF16(cases[i].matches[j]), matches[j].contents) + << description; // Ensure that no expected matches are missing. for (; j < std::size(cases[i].matches); ++j) - EXPECT_EQ(kNotApplicable, cases[i].matches[j]) << - "Case # " << i << " " << description; + EXPECT_EQ(kNotApplicable, cases[i].matches[j]) + << "Case # " << i << " " << description; } } @@ -2392,14 +2520,14 @@ AutocompleteMatch::Type match_type; bool allowed_to_be_default_match; }; - const DefaultFetcherUrlInputMatch kEmptyMatch = - { kNotApplicable, AutocompleteMatchType::NUM_TYPES, false }; + const DefaultFetcherUrlInputMatch kEmptyMatch = { + kNotApplicable, AutocompleteMatchType::NUM_TYPES, false}; struct { const std::string input; const std::string json; const DefaultFetcherUrlInputMatch output[4]; } cases[] = { - // clang-format off + // clang-format off // Ensure NAVIGATION matches are allowed to be listed first for URL input. // Non-inlineable matches should not be allowed to be the default match. // Note that the top-scoring inlineable match is moved to the top @@ -2480,7 +2608,7 @@ { "http://a.com", AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, true }, kEmptyMatch } }, - // clang-format on + // clang-format on }; for (auto& test_case : cases) { @@ -2695,132 +2823,111 @@ const bool allowed_to_be_default_match_in_regular_mode; const bool allowed_to_be_default_match_in_prevent_inline_mode; } cases[] = { - // Do not inline matches that do not contain the input; trim http as needed. - { "x", "http://www.abc.com", - "www.abc.com", std::string(), false, false }, - { "https:", "http://www.abc.com", - "www.abc.com", std::string(), false, false }, - { "http://www.abc.com/a", "http://www.abc.com", - "http://www.abc.com", std::string(), false, - false }, + // Do not inline matches that do not contain the input; trim http as + // needed. + {"x", "http://www.abc.com", "www.abc.com", std::string(), false, false}, + {"https:", "http://www.abc.com", "www.abc.com", std::string(), false, + false}, + {"http://www.abc.com/a", "http://www.abc.com", "http://www.abc.com", + std::string(), false, false}, - // Do not inline matches with invalid input prefixes; trim http as needed. - { "ttp", "http://www.abc.com", - "www.abc.com", std::string(), false, false }, - { "://w", "http://www.abc.com", - "www.abc.com", std::string(), false, false }, - { "ww.", "http://www.abc.com", - "www.abc.com", std::string(), false, false }, - { ".ab", "http://www.abc.com", - "www.abc.com", std::string(), false, false }, - { "bc", "http://www.abc.com", - "www.abc.com", std::string(), false, false }, - { ".com", "http://www.abc.com", - "www.abc.com", std::string(), false, false }, + // Do not inline matches with invalid input prefixes; trim http as needed. + {"ttp", "http://www.abc.com", "www.abc.com", std::string(), false, false}, + {"://w", "http://www.abc.com", "www.abc.com", std::string(), false, + false}, + {"ww.", "http://www.abc.com", "www.abc.com", std::string(), false, false}, + {".ab", "http://www.abc.com", "www.abc.com", std::string(), false, false}, + {"bc", "http://www.abc.com", "www.abc.com", std::string(), false, false}, + {".com", "http://www.abc.com", "www.abc.com", std::string(), false, + false}, - // Do not inline matches that omit input domain labels; trim http as needed. - { "www.a", "http://a.com", - "a.com", std::string(), false, false }, - { "http://www.a", "http://a.com", - "http://a.com", std::string(), false, false }, - { "www.a", "ftp://a.com", - "ftp://a.com", std::string(), false, false }, - { "ftp://www.a", "ftp://a.com", - "ftp://a.com", std::string(), false, false }, + // Do not inline matches that omit input domain labels; trim http as + // needed. + {"www.a", "http://a.com", "a.com", std::string(), false, false}, + {"http://www.a", "http://a.com", "http://a.com", std::string(), false, + false}, + {"www.a", "ftp://a.com", "ftp://a.com", std::string(), false, false}, + {"ftp://www.a", "ftp://a.com", "ftp://a.com", std::string(), false, + false}, - // Input matching but with nothing to inline will not yield an offset, but - // will be allowed to be default. - { "abc.com", "http://www.abc.com", - "www.abc.com", std::string(), true, true }, - { "http://www.abc.com", "http://www.abc.com", - "http://www.abc.com", std::string(), true, true }, + // Input matching but with nothing to inline will not yield an offset, but + // will be allowed to be default. + {"abc.com", "http://www.abc.com", "www.abc.com", std::string(), true, + true}, + {"http://www.abc.com", "http://www.abc.com", "http://www.abc.com", + std::string(), true, true}, - // Inputs with trailing whitespace should inline when possible. - { "abc.com ", "http://www.abc.com", - "www.abc.com", std::string(), true, true }, - { "abc.com ", "http://www.abc.com/bar", - "www.abc.com/bar", "/bar", false, false }, + // Inputs with trailing whitespace should inline when possible. + {"abc.com ", "http://www.abc.com", "www.abc.com", std::string(), true, + true}, + {"abc.com ", "http://www.abc.com/bar", "www.abc.com/bar", "/bar", false, + false}, - // Inline matches when the input is a leading substring of the scheme. - { "h", "http://www.abc.com", - "http://www.abc.com", "ttp://www.abc.com", true, false }, - { "http", "http://www.abc.com", - "http://www.abc.com", "://www.abc.com", true, false }, + // Inline matches when the input is a leading substring of the scheme. + {"h", "http://www.abc.com", "http://www.abc.com", "ttp://www.abc.com", + true, false}, + {"http", "http://www.abc.com", "http://www.abc.com", "://www.abc.com", + true, false}, - // Inline matches when the input is a leading substring of the full URL. - { "http:", "http://www.abc.com", - "http://www.abc.com", "//www.abc.com", true, false }, - { "http://w", "http://www.abc.com", - "http://www.abc.com", "ww.abc.com", true, false }, - { "http://www.", "http://www.abc.com", - "http://www.abc.com", "abc.com", true, false }, - { "http://www.ab", "http://www.abc.com", - "http://www.abc.com", "c.com", true, false }, - { "http://www.abc.com/p", "http://www.abc.com/path/file.htm?q=x#foo", - "http://www.abc.com/path/file.htm?q=x#foo", - "ath/file.htm?q=x#foo", - true, false }, - { "http://abc.com/p", "http://abc.com/path/file.htm?q=x#foo", - "http://abc.com/path/file.htm?q=x#foo", - "ath/file.htm?q=x#foo", - true, false}, + // Inline matches when the input is a leading substring of the full URL. + {"http:", "http://www.abc.com", "http://www.abc.com", "//www.abc.com", + true, false}, + {"http://w", "http://www.abc.com", "http://www.abc.com", "ww.abc.com", + true, false}, + {"http://www.", "http://www.abc.com", "http://www.abc.com", "abc.com", + true, false}, + {"http://www.ab", "http://www.abc.com", "http://www.abc.com", "c.com", + true, false}, + {"http://www.abc.com/p", "http://www.abc.com/path/file.htm?q=x#foo", + "http://www.abc.com/path/file.htm?q=x#foo", "ath/file.htm?q=x#foo", true, + false}, + {"http://abc.com/p", "http://abc.com/path/file.htm?q=x#foo", + "http://abc.com/path/file.htm?q=x#foo", "ath/file.htm?q=x#foo", true, + false}, - // Inline matches with valid URLPrefixes; only trim "http://". - { "w", "http://www.abc.com", - "www.abc.com", "ww.abc.com", true, false }, - { "www.a", "http://www.abc.com", - "www.abc.com", "bc.com", true, false }, - { "abc", "http://www.abc.com", - "www.abc.com", ".com", true, false }, - { "abc.c", "http://www.abc.com", - "www.abc.com", "om", true, false }, - { "abc.com/p", "http://www.abc.com/path/file.htm?q=x#foo", - "www.abc.com/path/file.htm?q=x#foo", - "ath/file.htm?q=x#foo", - true, false }, - { "abc.com/p", "http://abc.com/path/file.htm?q=x#foo", - "abc.com/path/file.htm?q=x#foo", - "ath/file.htm?q=x#foo", - true, false }, + // Inline matches with valid URLPrefixes; only trim "http://". + {"w", "http://www.abc.com", "www.abc.com", "ww.abc.com", true, false}, + {"www.a", "http://www.abc.com", "www.abc.com", "bc.com", true, false}, + {"abc", "http://www.abc.com", "www.abc.com", ".com", true, false}, + {"abc.c", "http://www.abc.com", "www.abc.com", "om", true, false}, + {"abc.com/p", "http://www.abc.com/path/file.htm?q=x#foo", + "www.abc.com/path/file.htm?q=x#foo", "ath/file.htm?q=x#foo", true, + false}, + {"abc.com/p", "http://abc.com/path/file.htm?q=x#foo", + "abc.com/path/file.htm?q=x#foo", "ath/file.htm?q=x#foo", true, false}, - // Inline matches using the maximal URLPrefix components. - { "h", "http://help.com", - "help.com", "elp.com", true, false }, - { "http", "http://http.com", - "http.com", ".com", true, false }, - { "h", "http://www.help.com", - "www.help.com", "elp.com", true, false }, - { "http", "http://www.http.com", - "www.http.com", ".com", true, false }, - { "w", "http://www.www.com", - "www.www.com", "ww.com", true, false }, + // Inline matches using the maximal URLPrefix components. + {"h", "http://help.com", "help.com", "elp.com", true, false}, + {"http", "http://http.com", "http.com", ".com", true, false}, + {"h", "http://www.help.com", "www.help.com", "elp.com", true, false}, + {"http", "http://www.http.com", "www.http.com", ".com", true, false}, + {"w", "http://www.www.com", "www.www.com", "ww.com", true, false}, - // Test similar behavior for the ftp and https schemes. - { "ftp://www.ab", "ftp://www.abc.com/path/file.htm?q=x#foo", - "ftp://www.abc.com/path/file.htm?q=x#foo", - "c.com/path/file.htm?q=x#foo", true, false }, - { "www.ab", "ftp://www.abc.com/path/file.htm?q=x#foo", - "ftp://www.abc.com/path/file.htm?q=x#foo", - "c.com/path/file.htm?q=x#foo", true, false }, - { "ab", "ftp://www.abc.com/path/file.htm?q=x#foo", - "ftp://www.abc.com/path/file.htm?q=x#foo", - "c.com/path/file.htm?q=x#foo", true, false }, - { "ab", "ftp://abc.com/path/file.htm?q=x#foo", - "ftp://abc.com/path/file.htm?q=x#foo", - "c.com/path/file.htm?q=x#foo", true, false }, - { "https://www.ab", "https://www.abc.com/path/file.htm?q=x#foo", - "https://www.abc.com/path/file.htm?q=x#foo", - "c.com/path/file.htm?q=x#foo", - true, false }, - { "www.ab", "https://www.abc.com/path/file.htm?q=x#foo", - "https://www.abc.com/path/file.htm?q=x#foo", - "c.com/path/file.htm?q=x#foo", true, false }, - { "ab", "https://www.abc.com/path/file.htm?q=x#foo", - "https://www.abc.com/path/file.htm?q=x#foo", - "c.com/path/file.htm?q=x#foo", true, false }, - { "ab", "https://abc.com/path/file.htm?q=x#foo", - "https://abc.com/path/file.htm?q=x#foo", - "c.com/path/file.htm?q=x#foo", true, false }, + // Test similar behavior for the ftp and https schemes. + {"ftp://www.ab", "ftp://www.abc.com/path/file.htm?q=x#foo", + "ftp://www.abc.com/path/file.htm?q=x#foo", "c.com/path/file.htm?q=x#foo", + true, false}, + {"www.ab", "ftp://www.abc.com/path/file.htm?q=x#foo", + "ftp://www.abc.com/path/file.htm?q=x#foo", "c.com/path/file.htm?q=x#foo", + true, false}, + {"ab", "ftp://www.abc.com/path/file.htm?q=x#foo", + "ftp://www.abc.com/path/file.htm?q=x#foo", "c.com/path/file.htm?q=x#foo", + true, false}, + {"ab", "ftp://abc.com/path/file.htm?q=x#foo", + "ftp://abc.com/path/file.htm?q=x#foo", "c.com/path/file.htm?q=x#foo", + true, false}, + {"https://www.ab", "https://www.abc.com/path/file.htm?q=x#foo", + "https://www.abc.com/path/file.htm?q=x#foo", + "c.com/path/file.htm?q=x#foo", true, false}, + {"www.ab", "https://www.abc.com/path/file.htm?q=x#foo", + "https://www.abc.com/path/file.htm?q=x#foo", + "c.com/path/file.htm?q=x#foo", true, false}, + {"ab", "https://www.abc.com/path/file.htm?q=x#foo", + "https://www.abc.com/path/file.htm?q=x#foo", + "c.com/path/file.htm?q=x#foo", true, false}, + {"ab", "https://abc.com/path/file.htm?q=x#foo", + "https://abc.com/path/file.htm?q=x#foo", "c.com/path/file.htm?q=x#foo", + true, false}, }; for (auto& test_case : cases) { @@ -3058,9 +3165,8 @@ std::string fill_into_edit; AutocompleteMatchType::Type type; }; - const Match kEmptyMatch = { - kNotApplicable, kNotApplicable, kNotApplicable, kNotApplicable, - AutocompleteMatchType::NUM_TYPES}; + const Match kEmptyMatch = {kNotApplicable, kNotApplicable, kNotApplicable, + kNotApplicable, AutocompleteMatchType::NUM_TYPES}; omnibox::EntityInfo entity_info; entity_info.set_name("xy"); @@ -3153,10 +3259,8 @@ for (; j < matches.size(); ++j) { const Match& match = test_case.matches[j]; SCOPED_TRACE(" and match index: " + base::NumberToString(j)); - EXPECT_EQ(match.contents, - base::UTF16ToUTF8(matches[j].contents)); - EXPECT_EQ(match.description, - base::UTF16ToUTF8(matches[j].description)); + EXPECT_EQ(match.contents, base::UTF16ToUTF8(matches[j].contents)); + EXPECT_EQ(match.description, base::UTF16ToUTF8(matches[j].description)); EXPECT_EQ(match.query_params, matches[j].search_terms_args->additional_query_params); EXPECT_EQ(match.fill_into_edit, @@ -3183,10 +3287,9 @@ AutocompleteMatchType::Type type; bool from_keyword; }; - const Match kEmptyMatch = { kNotApplicable, - false, - AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, - false }; + const Match kEmptyMatch = {kNotApplicable, false, + AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, + false}; struct { const std::string input_text; @@ -3294,17 +3397,16 @@ ClearAllResults(); std::string input_str("abc"); - QueryForInputAndWaitForFetcherResponses( - ASCIIToUTF16(input_str), false, "this is a bad non-json response", - std::string()); + QueryForInputAndWaitForFetcherResponses(ASCIIToUTF16(input_str), false, + "this is a bad non-json response", + std::string()); const ACMatches& matches = provider_->matches(); // Should have exactly one "search what you typed" match ASSERT_EQ(1U, matches.size()); EXPECT_EQ(input_str, base::UTF16ToUTF8(matches[0].contents)); - EXPECT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, - matches[0].type); + EXPECT_EQ(AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED, matches[0].type); } // A basic test that verifies that the XSSI guarded JSON response is parsed @@ -3314,9 +3416,7 @@ std::string contents; AutocompleteMatchType::Type type; }; - const Match kEmptyMatch = { - kNotApplicable, AutocompleteMatchType::NUM_TYPES - }; + const Match kEmptyMatch = {kNotApplicable, AutocompleteMatchType::NUM_TYPES}; struct Cases { const std::string input_text; @@ -3648,8 +3748,8 @@ TEST_F(SearchProviderTest, TestDeleteMatch) { const char kDeleteUrl[] = "https://www.google.com/complete/deleteitem?q=foo"; - AutocompleteMatch match( - provider_.get(), 0, true, AutocompleteMatchType::SEARCH_SUGGEST); + AutocompleteMatch match(provider_.get(), 0, true, + AutocompleteMatchType::SEARCH_SUGGEST); match.RecordAdditionalInfo(SearchProvider::kDeletionUrlKey, kDeleteUrl); // Test a successful deletion request.
diff --git a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/AddToBookmarksToolbarButtonController.java b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/AddToBookmarksToolbarButtonController.java index 345483d..d9c3fad 100644 --- a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/AddToBookmarksToolbarButtonController.java +++ b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/AddToBookmarksToolbarButtonController.java
@@ -95,8 +95,7 @@ /* supportsTinting= */ true, /* iphCommandBuilder= */ null, AdaptiveToolbarButtonVariant.ADD_TO_BOOKMARKS, - /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ true); + /* tooltipTextResId= */ Resources.ID_NULL); mActivityLifecycleDispatcher = activityLifecycleDispatcher; mTabBookmarkerSupplier = tabBookmarkerSupplier; mTrackerSupplier = trackerSupplier; @@ -129,7 +128,6 @@ AdaptiveToolbarButtonVariant.ADD_TO_BOOKMARKS, /* actionChipLabelResId= */ Resources.ID_NULL, /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ true, /* hasErrorBadge= */ false); mIsTablet = DeviceFormFactor.isNonMultiDisplayContextOnTablet(mContext);
diff --git a/chrome/browser/browser_controls/android/java/src/org/chromium/chrome/browser/browser_controls/BrowserStateBrowserControlsVisibilityDelegate.java b/chrome/browser/browser_controls/android/java/src/org/chromium/chrome/browser/browser_controls/BrowserStateBrowserControlsVisibilityDelegate.java index e27dc477..84ce777 100644 --- a/chrome/browser/browser_controls/android/java/src/org/chromium/chrome/browser/browser_controls/BrowserStateBrowserControlsVisibilityDelegate.java +++ b/chrome/browser/browser_controls/android/java/src/org/chromium/chrome/browser/browser_controls/BrowserStateBrowserControlsVisibilityDelegate.java
@@ -10,6 +10,7 @@ import androidx.annotation.VisibleForTesting; import org.chromium.base.CommandLine; +import org.chromium.base.lifetime.Destroyable; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.Supplier; import org.chromium.build.annotations.NullMarked; @@ -24,8 +25,8 @@ * running activity. */ @NullMarked -public class BrowserStateBrowserControlsVisibilityDelegate - extends BrowserControlsVisibilityDelegate { +public class BrowserStateBrowserControlsVisibilityDelegate extends BrowserControlsVisibilityDelegate + implements Destroyable { /** Minimum duration (in milliseconds) that the controls are shown when requested. */ @VisibleForTesting public static final long MINIMUM_SHOW_DURATION_MS = 3000; @@ -129,6 +130,7 @@ sDisableOverridesForTesting = true; } + /** Performs clean-up. */ @Override public void destroy() { mHandler.removeCallbacksAndMessages(null);
diff --git a/chrome/browser/browser_switcher/browser_switcher_navigation_throttle.cc b/chrome/browser/browser_switcher/browser_switcher_navigation_throttle.cc index 2663ec0..a4b8eb6 100644 --- a/chrome/browser/browser_switcher/browser_switcher_navigation_throttle.cc +++ b/chrome/browser/browser_switcher/browser_switcher_navigation_throttle.cc
@@ -20,6 +20,7 @@ #include "components/no_state_prefetch/browser/no_state_prefetch_contents.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_handle.h" +#include "content/public/browser/navigation_throttle_registry.h" #include "content/public/browser/web_contents.h" #include "net/base/url_util.h" @@ -31,8 +32,9 @@ void OpenBrowserSwitchPage(base::WeakPtr<content::WebContents> web_contents, const GURL& url, ui::PageTransition transition_type) { - if (!web_contents) + if (!web_contents) { return; + } GURL about_url(chrome::kChromeUIBrowserSwitchURL); about_url = net::AppendQueryParameter(about_url, "url", url.spec()); @@ -95,24 +97,27 @@ } // namespace // static -std::unique_ptr<content::NavigationThrottle> -BrowserSwitcherNavigationThrottle::MaybeCreateThrottleFor( - content::NavigationHandle* navigation) { +void BrowserSwitcherNavigationThrottle::MaybeCreateAndAdd( + content::NavigationThrottleRegistry& registry) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + content::NavigationHandle& handle = registry.GetNavigationHandle(); content::BrowserContext* browser_context = - navigation->GetWebContents()->GetBrowserContext(); + handle.GetWebContents()->GetBrowserContext(); Profile* profile = Profile::FromBrowserContext(browser_context); - if (!profile->IsRegularProfile()) - return nullptr; + if (!profile->IsRegularProfile()) { + return; + } - if (!navigation->IsInPrimaryMainFrame()) - return nullptr; + if (!handle.IsInPrimaryMainFrame()) { + return; + } - return std::make_unique<navigation_interception::InterceptNavigationThrottle>( - navigation, base::BindRepeating(&MaybeLaunchAlternativeBrowser), - navigation_interception::SynchronyMode::kSync, std::nullopt); + registry.AddThrottle( + std::make_unique<navigation_interception::InterceptNavigationThrottle>( + registry, base::BindRepeating(&MaybeLaunchAlternativeBrowser), + navigation_interception::SynchronyMode::kSync, std::nullopt)); } } // namespace browser_switcher
diff --git a/chrome/browser/browser_switcher/browser_switcher_navigation_throttle.h b/chrome/browser/browser_switcher/browser_switcher_navigation_throttle.h index 245387dd..dee6b82c 100644 --- a/chrome/browser/browser_switcher/browser_switcher_navigation_throttle.h +++ b/chrome/browser/browser_switcher/browser_switcher_navigation_throttle.h
@@ -5,7 +5,9 @@ #ifndef CHROME_BROWSER_BROWSER_SWITCHER_BROWSER_SWITCHER_NAVIGATION_THROTTLE_H_ #define CHROME_BROWSER_BROWSER_SWITCHER_BROWSER_SWITCHER_NAVIGATION_THROTTLE_H_ -#include "content/public/browser/navigation_throttle.h" +namespace content { +class NavigationThrottleRegistry; +} // namespace content namespace browser_switcher { @@ -19,9 +21,8 @@ BrowserSwitcherNavigationThrottle& operator=( const BrowserSwitcherNavigationThrottle&) = delete; - // Creates a |NavigationThrottle| if needed for the navigation. - static std::unique_ptr<content::NavigationThrottle> MaybeCreateThrottleFor( - content::NavigationHandle* navigation); + // Creates a `NavigationThrottle` if needed for the navigation. + static void MaybeCreateAndAdd(content::NavigationThrottleRegistry& registry); }; } // namespace browser_switcher
diff --git a/chrome/browser/browser_switcher/browser_switcher_navigation_throttle_unittest.cc b/chrome/browser/browser_switcher/browser_switcher_navigation_throttle_unittest.cc index eec9050f..aaa68dc 100644 --- a/chrome/browser/browser_switcher/browser_switcher_navigation_throttle_unittest.cc +++ b/chrome/browser/browser_switcher/browser_switcher_navigation_throttle_unittest.cc
@@ -20,6 +20,7 @@ #include "content/public/browser/navigation_throttle.h" #include "content/public/browser/web_contents.h" #include "content/public/test/mock_navigation_handle.h" +#include "content/public/test/mock_navigation_throttle_registry.h" #include "content/public/test/test_utils.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -80,9 +81,8 @@ return std::make_unique<NiceMock<MockNavigationHandle>>(url, main_rfh()); } - std::unique_ptr<NavigationThrottle> CreateNavigationThrottle( - content::NavigationHandle* handle) { - return BrowserSwitcherNavigationThrottle::MaybeCreateThrottleFor(handle); + void CreateNavigationThrottle(content::NavigationThrottleRegistry& registry) { + BrowserSwitcherNavigationThrottle::MaybeCreateAndAdd(registry); } MockBrowserSwitcherSitelist* sitelist() { return sitelist_; } @@ -102,19 +102,26 @@ EXPECT_CALL(*sitelist(), GetDecision(_)).WillOnce(Return(stay())); std::unique_ptr<MockNavigationHandle> handle = CreateMockNavigationHandle(GURL("https://example.com/")); - std::unique_ptr<NavigationThrottle> throttle = - CreateNavigationThrottle(handle.get()); - EXPECT_EQ(NavigationThrottle::PROCEED, throttle->WillStartRequest()); + content::MockNavigationThrottleRegistry registry( + handle.get(), + content::MockNavigationThrottleRegistry::RegistrationMode::kHold); + CreateNavigationThrottle(registry); + ASSERT_EQ(1u, registry.throttles().size()); + EXPECT_EQ(NavigationThrottle::PROCEED, + registry.throttles()[0]->WillStartRequest()); } TEST_F(BrowserSwitcherNavigationThrottleTest, LaunchesOnStartRequest) { EXPECT_CALL(*sitelist(), GetDecision(_)).WillOnce(Return(go())); std::unique_ptr<MockNavigationHandle> handle = CreateMockNavigationHandle(GURL("https://example.com/")); - std::unique_ptr<NavigationThrottle> throttle = - CreateNavigationThrottle(handle.get()); + content::MockNavigationThrottleRegistry registry( + handle.get(), + content::MockNavigationThrottleRegistry::RegistrationMode::kHold); + CreateNavigationThrottle(registry); + ASSERT_EQ(1u, registry.throttles().size()); EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, - throttle->WillStartRequest()); + registry.throttles()[0]->WillStartRequest()); base::RunLoop().RunUntilIdle(); } @@ -126,15 +133,19 @@ CreateMockNavigationHandle(GURL("https://yahoo.com/")); ON_CALL(*handle, WasServerRedirect()).WillByDefault(Return(false)); - std::unique_ptr<NavigationThrottle> throttle = - CreateNavigationThrottle(handle.get()); - EXPECT_EQ(NavigationThrottle::PROCEED, throttle->WillStartRequest()); + content::MockNavigationThrottleRegistry registry( + handle.get(), + content::MockNavigationThrottleRegistry::RegistrationMode::kHold); + CreateNavigationThrottle(registry); + EXPECT_EQ(1u, registry.throttles().size()); + EXPECT_EQ(NavigationThrottle::PROCEED, + registry.throttles()[0]->WillStartRequest()); ON_CALL(*handle, WasServerRedirect()).WillByDefault(Return(true)); handle->set_url(GURL("https://bing.com/")); EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, - throttle->WillRedirectRequest()); + registry.throttles()[0]->WillRedirectRequest()); base::RunLoop().RunUntilIdle(); } @@ -145,14 +156,15 @@ handle->set_has_committed(true); handle->set_is_in_primary_main_frame(false); - std::unique_ptr<NavigationThrottle> throttle_non_primary_main_frame = - CreateNavigationThrottle(handle.get()); - EXPECT_EQ(nullptr, throttle_non_primary_main_frame.get()); + content::MockNavigationThrottleRegistry registry( + handle.get(), + content::MockNavigationThrottleRegistry::RegistrationMode::kHold); + CreateNavigationThrottle(registry); + EXPECT_EQ(0u, registry.throttles().size()); handle->set_is_in_primary_main_frame(true); - std::unique_ptr<NavigationThrottle> throttle_in_primary_main_frame = - CreateNavigationThrottle(handle.get()); - EXPECT_NE(nullptr, throttle_in_primary_main_frame.get()); + CreateNavigationThrottle(registry); + EXPECT_EQ(1u, registry.throttles().size()); } } // namespace browser_switcher
diff --git a/chrome/browser/browsing_data/counters/site_settings_counter.cc b/chrome/browser/browsing_data/counters/site_settings_counter.cc index b5d91f2..8b004195 100644 --- a/chrome/browser/browsing_data/counters/site_settings_counter.cc +++ b/chrome/browser/browsing_data/counters/site_settings_counter.cc
@@ -111,7 +111,7 @@ const std::vector<std::string> tab_discard_exceptions = performance_manager::user_tuning::prefs::GetTabDiscardExceptionsBetween( pref_service_, period_start, period_end); - for (auto exception : tab_discard_exceptions) { + for (const auto& exception : tab_discard_exceptions) { url_matcher::util::FilterComponents components; bool is_valid = url_matcher::util::FilterToComponents( exception, &components.scheme, &components.host,
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 2ee8a27d..57a1acd3 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -65,6 +65,7 @@ #include "chrome/browser/child_process_host_flags.h" #include "chrome/browser/chrome_browser_main_extra_parts_nacl_deprecation.h" #include "chrome/browser/chrome_content_browser_client_binder_policies.h" +#include "chrome/browser/chrome_content_browser_client_navigation_throttles.h" #include "chrome/browser/chrome_content_browser_client_parts.h" #include "chrome/browser/content_settings/cookie_settings_factory.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" @@ -277,7 +278,6 @@ #include "components/no_state_prefetch/common/no_state_prefetch_final_status.h" #include "components/no_state_prefetch/common/no_state_prefetch_url_loader_throttle.h" #include "components/omnibox/common/omnibox_features.h" -#include "components/page_load_metrics/browser/metrics_navigation_throttle.h" #include "components/page_load_metrics/browser/metrics_web_contents_observer.h" #include "components/payments/content/payment_handler_navigation_throttle.h" #include "components/payments/content/payment_request_display_manager.h" @@ -5399,18 +5399,11 @@ void ChromeContentBrowserClient::CreateThrottlesForNavigation( content::NavigationThrottleRegistry& registry) { + CreateAndAddChromeThrottlesForNavigation(registry); + content::NavigationHandle& handle = registry.GetNavigationHandle(); - if (handle.IsInMainFrame()) { - // MetricsNavigationThrottle requires that it runs before - // NavigationThrottles that may delay or cancel navigations, so only - // NavigationThrottles that don't delay or cancel navigations (e.g. - // throttles that are only observing callbacks without affecting navigation - // behavior) should be added before MetricsNavigationThrottle. - // TODO(https://crbug.com/412524375): This assumption is fragile. This - // should be cared by adding an attribute flag to - // NavigationThrottleRegistry::AddThrottle(). - page_load_metrics::MetricsNavigationThrottle::CreateAndAdd(registry); - } + // TODO(https://crbug.com/412524375): Move the following code to + // CreateAndAddChromeThrottlesForNavigation(). #if BUILDFLAG(IS_ANDROID) // TODO(davidben): This is insufficient to integrate with prerender properly. @@ -5419,10 +5412,8 @@ prerender::ChromeNoStatePrefetchContentsDelegate::FromWebContents( handle.GetWebContents()); if (!no_state_prefetch_contents) { - registry.MaybeAddThrottle( - navigation_interception::InterceptNavigationDelegate:: - MaybeCreateThrottleFor( - &handle, navigation_interception::SynchronyMode::kAsync)); + navigation_interception::InterceptNavigationDelegate::MaybeCreateAndAdd( + registry, navigation_interception::SynchronyMode::kAsync); } registry.AddThrottle(InterceptOMADownloadNavigationThrottle::Create(&handle)); @@ -5436,8 +5427,7 @@ #elif BUILDFLAG(ENABLE_PLATFORM_APPS) // Redirect some navigations to apps that have registered matching URL // handlers ('url_handlers' in the manifest). - registry.MaybeAddThrottle( - PlatformAppNavigationRedirector::MaybeCreateThrottleFor(&handle)); + PlatformAppNavigationRedirector::MaybeCreateAndAdd(registry); #endif #if BUILDFLAG(IS_CHROMEOS) @@ -5556,7 +5546,7 @@ PasswordManagerNavigationThrottle::MaybeCreateThrottleFor(&handle)); registry.AddThrottle(std::make_unique<PolicyBlocklistNavigationThrottle>( - &handle, handle.GetWebContents()->GetBrowserContext())); + registry, handle.GetWebContents()->GetBrowserContext())); // Before setting up SSL error detection, configure SSLErrorHandler to invoke // the relevant extension API whenever an SSL interstitial is shown. @@ -5636,9 +5626,8 @@ #endif #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) - registry.MaybeAddThrottle( - browser_switcher::BrowserSwitcherNavigationThrottle:: - MaybeCreateThrottleFor(&handle)); + browser_switcher::BrowserSwitcherNavigationThrottle::MaybeCreateAndAdd( + registry); #endif #if BUILDFLAG(IS_CHROMEOS) @@ -5712,7 +5701,7 @@ registry.MaybeAddThrottle(MaybeCreateNavigationAblationThrottle(&handle)); #if !BUILDFLAG(IS_ANDROID) - registry.MaybeAddThrottle(MaybeCreateWebViewSidePanelThrottleFor(&handle)); + MaybeCreateAndAddWebViewSidePanelThrottle(registry); #endif auto* privacy_sandbox_settings = @@ -5770,6 +5759,9 @@ registry.MaybeAddThrottle( web_app::IsolatedWebAppThrottle::MaybeCreateThrottleFor(&handle)); #endif // !BUILDFLAG(IS_ANDROID) + + // Add new throttles in CreateAndAddChromeThrottlesForNavigation() rather than + // here. } std::vector<std::unique_ptr<content::CommitDeferringCondition>>
diff --git a/chrome/browser/chrome_content_browser_client_navigation_throttles.cc b/chrome/browser/chrome_content_browser_client_navigation_throttles.cc new file mode 100644 index 0000000..475a92c --- /dev/null +++ b/chrome/browser/chrome_content_browser_client_navigation_throttles.cc
@@ -0,0 +1,27 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chrome_content_browser_client_navigation_throttles.h" + +#include "components/page_load_metrics/browser/metrics_navigation_throttle.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/navigation_throttle_registry.h" + +void CreateAndAddChromeThrottlesForNavigation( + content::NavigationThrottleRegistry& registry) { + content::NavigationHandle& handle = registry.GetNavigationHandle(); + if (handle.IsInMainFrame()) { + // MetricsNavigationThrottle requires that it runs before + // NavigationThrottles that may delay or cancel navigations, so only + // NavigationThrottles that don't delay or cancel navigations (e.g. + // throttles that are only observing callbacks without affecting navigation + // behavior) should be added before MetricsNavigationThrottle. + // TODO(https://crbug.com/412524375): This assumption is fragile. This + // should be cared by adding an attribute flag to + // NavigationThrottleRegistry::AddThrottle(). + page_load_metrics::MetricsNavigationThrottle::CreateAndAdd(registry); + } + + // Add new throttles here. +} \ No newline at end of file
diff --git a/chrome/browser/chrome_content_browser_client_navigation_throttles.h b/chrome/browser/chrome_content_browser_client_navigation_throttles.h new file mode 100644 index 0000000..1d9fcb70 --- /dev/null +++ b/chrome/browser/chrome_content_browser_client_navigation_throttles.h
@@ -0,0 +1,15 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROME_CONTENT_BROWSER_CLIENT_NAVIGATION_THROTTLE_H_ +#define CHROME_BROWSER_CHROME_CONTENT_BROWSER_CLIENT_NAVIGATION_THROTTLE_H_ + +namespace content { +class NavigationThrottleRegistry; +} // namespace content + +void CreateAndAddChromeThrottlesForNavigation( + content::NavigationThrottleRegistry& registry); + +#endif // CHROME_BROWSER_CHROME_CONTENT_BROWSER_CLIENT_NAVIGATION_THROTTLE_H_ \ No newline at end of file
diff --git a/chrome/browser/collaboration/android/java/src/org/chromium/chrome/browser/collaboration/CollaborationControllerDelegateImpl.java b/chrome/browser/collaboration/android/java/src/org/chromium/chrome/browser/collaboration/CollaborationControllerDelegateImpl.java index 6c536e8..9878e56 100644 --- a/chrome/browser/collaboration/android/java/src/org/chromium/chrome/browser/collaboration/CollaborationControllerDelegateImpl.java +++ b/chrome/browser/collaboration/android/java/src/org/chromium/chrome/browser/collaboration/CollaborationControllerDelegateImpl.java
@@ -222,8 +222,7 @@ ServiceStatus serviceStatus = CollaborationServiceFactory.getForProfile(profile).getServiceStatus(); - if (serviceStatus.signinStatus == SigninStatus.NOT_SIGNED_IN - && !signinManager.isSigninAllowed()) { + if (serviceStatus.signinStatus == SigninStatus.SIGNIN_DISABLED) { // The signin option is disabled manually by the user in settings. openSigninSettingsModel(resultCallback); return;
diff --git a/chrome/browser/collaboration/android/java/src/org/chromium/chrome/browser/collaboration/CollaborationControllerDelegateImplUnitTest.java b/chrome/browser/collaboration/android/java/src/org/chromium/chrome/browser/collaboration/CollaborationControllerDelegateImplUnitTest.java index e4e3059..7926e7b 100644 --- a/chrome/browser/collaboration/android/java/src/org/chromium/chrome/browser/collaboration/CollaborationControllerDelegateImplUnitTest.java +++ b/chrome/browser/collaboration/android/java/src/org/chromium/chrome/browser/collaboration/CollaborationControllerDelegateImplUnitTest.java
@@ -217,7 +217,13 @@ createDelegate(FlowType.JOIN); long resultCallback = 1; - doReturn(false).when(mSigninManager).isSigninAllowed(); + doReturn( + new ServiceStatus( + SigninStatus.SIGNIN_DISABLED, + /* syncStatus= */ 0, + /* collaborationStatus= */ 0)) + .when(mCollaborationService) + .getServiceStatus(); mCollaborationControllerDelegateImpl.showAuthenticationUi(resultCallback); verify(mLoadingFullscreenCoordinator).closeLoadingScreen();
diff --git a/chrome/browser/collaboration/android/java/src/org/chromium/chrome/browser/collaboration/CollaborationIntegrationTest.java b/chrome/browser/collaboration/android/java/src/org/chromium/chrome/browser/collaboration/CollaborationIntegrationTest.java index 986f7f8..cb95023 100644 --- a/chrome/browser/collaboration/android/java/src/org/chromium/chrome/browser/collaboration/CollaborationIntegrationTest.java +++ b/chrome/browser/collaboration/android/java/src/org/chromium/chrome/browser/collaboration/CollaborationIntegrationTest.java
@@ -9,10 +9,12 @@ import static androidx.test.espresso.action.ViewActions.scrollTo; import static androidx.test.espresso.assertion.ViewAssertions.matches; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; +import static androidx.test.espresso.matcher.ViewMatchers.isDisplayingAtLeast; import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; import static org.hamcrest.Matchers.allOf; +import static org.mockito.Mockito.doReturn; import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.addBlankTabs; import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.clickFirstCardFromTabSwitcher; @@ -21,15 +23,25 @@ import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.verifyTabSwitcherCardCount; import static org.chromium.ui.test.util.ViewUtils.onViewWaiting; +import android.view.View; + +import androidx.test.espresso.UiController; +import androidx.test.espresso.ViewAction; import androidx.test.filters.MediumTest; +import org.hamcrest.Matcher; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.chromium.base.Callback; import org.chromium.base.ThreadUtils; +import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CriteriaHelper; import org.chromium.base.test.util.DoNotBatch; @@ -37,14 +49,17 @@ import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.data_sharing.DataSharingServiceFactory; +import org.chromium.chrome.browser.data_sharing.DataSharingTabManager; import org.chromium.chrome.browser.data_sharing.DataSharingUiDelegateAndroid; import org.chromium.chrome.browser.data_sharing.FakeDataSharingUIDelegateImpl; import org.chromium.chrome.browser.firstrun.FirstRunStatus; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.share.ShareDelegate; import org.chromium.chrome.browser.sync.SyncTestRule; import org.chromium.chrome.browser.tab.TabLaunchType; +import org.chromium.chrome.browser.tab_group_sync.TabGroupSyncServiceFactory; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.R; import org.chromium.components.data_sharing.DataSharingSDKDelegateBridge; @@ -53,15 +68,21 @@ import org.chromium.components.data_sharing.GroupToken; import org.chromium.components.signin.identitymanager.ConsentLevel; import org.chromium.components.signin.test.util.TestAccounts; +import org.chromium.components.sync.UserSelectableType; +import org.chromium.components.tab_group_sync.LocalTabGroupId; +import org.chromium.components.tab_group_sync.SavedTabGroup; +import org.chromium.components.tab_group_sync.TabGroupSyncService; import org.chromium.ui.test.util.DeviceRestriction; import org.chromium.ui.test.util.GmsCoreVersionRestriction; +import java.util.Arrays; +import java.util.HashSet; import java.util.concurrent.atomic.AtomicBoolean; /** Instrumentation tests for {@link CollaborationService}. */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) -@EnableFeatures({ChromeFeatureList.DATA_SHARING}) +@EnableFeatures({ChromeFeatureList.DATA_SHARING, ChromeFeatureList.TAB_GROUP_SYNC_ANDROID}) @DoNotBatch(reason = "Tabs can't be closed reliably between tests.") // TODO(crbug.com/399444939) Re-enable on automotive devices if needed. // Only run on device non-auto and with valid Google services. @@ -73,15 +94,21 @@ private static final long WAIT_TIMEOUT_MS = 1000L; private static final String TEST_COLLABORATION_ID = "collaboration_id"; + private static final String TEST_ACCESS_TOKEN = "access_token"; @Rule(order = 0) public SyncTestRule mActivityTestRule = new SyncTestRule(); + @Rule(order = 1) + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + private FakeDataSharingUIDelegateImpl mDataSharingUIDelegate; private DataSharingSDKDelegateTestImpl mDataSharingSDKDelegate; private Profile mProfile; private String mUrl; + @Mock private ObservableSupplier<ShareDelegate> mShareDelegateSupplier; + @Mock private ShareDelegate mShareDelegate; public CollaborationIntegrationTest() { DataSharingUiDelegateAndroid.setForTesting(mDataSharingUIDelegate); @@ -212,7 +239,11 @@ public void testCollaborationCreateFlow() { final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); final AtomicBoolean createCalled = new AtomicBoolean(); - mDataSharingUIDelegate.setShowCreateFlowRunnable(() -> createCalled.set(true)); + Callback<Boolean> callback = + (success) -> { + createCalled.set(true); + }; + mDataSharingUIDelegate.setShowCreateFlowCallback(callback); // Create a tab group and enter TabGridDialog. addBlankTabs(cta, false, 3); @@ -262,4 +293,104 @@ onViewWaiting(withText(R.string.collaboration_sync_description)) .check(matches(isDisplayed())); } + + @Test + @MediumTest + public void testDataSharingShowShare() { + // Sign in and sets selected types for tab groups. + mActivityTestRule.setUpAccountAndSignInForTesting(); + mActivityTestRule.setSelectedTypes( + true, + new HashSet<>( + Arrays.asList( + UserSelectableType.TABS, UserSelectableType.SAVED_TAB_GROUPS))); + + // Create a tab group and open tab grid dialog. + final ChromeTabbedActivity cta = (ChromeTabbedActivity) mActivityTestRule.getActivity(); + addBlankTabs(cta, false, 2); + enterTabSwitcher(cta); + mergeAllNormalTabsToAGroup(cta); + LocalTabGroupId localTabGroupId = + new LocalTabGroupId( + cta.getTabModelSelector().getModel(false).getTabAt(0).getTabGroupId()); + clickFirstCardFromTabSwitcher(cta); + CriteriaHelper.pollUiThread(() -> isDialogFullyVisible(cta)); + + // Setting create flow callback to show share sheet with share link. + Callback<Boolean> callback = + (success) -> { + mDataSharingUIDelegate.forceGroupCreation( + TEST_COLLABORATION_ID, TEST_ACCESS_TOKEN); + }; + mDataSharingUIDelegate.setShowCreateFlowCallback(callback); + setupShareDelegateSupplier(); + + onView(withId(R.id.share_button)).perform(relaxedClick()); + prepareToShareTabGroup(/* owner= */ true, localTabGroupId, TEST_COLLABORATION_ID); + + // Check share button changes to manage. + onViewWaiting(withText(R.string.tab_grid_manage_button_text)).check(matches(isDisplayed())); + } + + private static ViewAction relaxedClick() { + final ViewAction clickAction = click(); + return new ViewAction() { + @Override + public Matcher<View> getConstraints() { + return isDisplayingAtLeast(51); + } + + @Override + public String getDescription() { + return clickAction.getDescription(); + } + + @Override + public void perform(UiController uiController, View view) { + clickAction.perform(uiController, view); + } + }; + } + + private boolean isDialogFullyVisible(ChromeTabbedActivity cta) { + View dialogView = cta.findViewById(R.id.dialog_parent_view); + View dialogContainerView = cta.findViewById(R.id.dialog_container_view); + return dialogView.getVisibility() == View.VISIBLE && dialogContainerView.getAlpha() == 1f; + } + + // Prepares the tab group to be shared. + private void prepareToShareTabGroup( + boolean owner, LocalTabGroupId tabGroupId, String collaborationId) { + TabGroupSyncService tabGroupSyncService = getTabGroupSyncService(); + assert (tabGroupSyncService != null && collaborationId != null); + mActivityTestRule.getFakeServerHelper().addCollaboration(collaborationId); + tabGroupSyncService.setCollaborationAvailableInFinderForTesting(collaborationId); + SavedTabGroup savedGroup = tabGroupSyncService.getGroup(tabGroupId); + assert (savedGroup != null && savedGroup.collaborationId == null); + mActivityTestRule.getFakeServerHelper().addCollaborationGroupToFakeServer(collaborationId); + ThreadUtils.runOnUiThreadBlocking( + () -> { + mActivityTestRule.getSyncService().triggerRefresh(); + }); + } + + /** Return the {@link} to TabGroupSyncService for the current profile. */ + private TabGroupSyncService getTabGroupSyncService() { + return ThreadUtils.runOnUiThreadBlocking( + () -> { + return TabGroupSyncServiceFactory.getForProfile(mProfile); + }); + } + + // Mock share delegate and return success for opening the share sheet. + private void setupShareDelegateSupplier(){ + ThreadUtils.runOnUiThreadBlocking( + () -> { + doReturn(mShareDelegate).when(mShareDelegateSupplier).get(); + var rootUiCoordinator = + mActivityTestRule.getActivity().getRootUiCoordinatorForTesting(); + DataSharingTabManager dstm = rootUiCoordinator.getDataSharingTabManager(); + dstm.setShareDelegateSupplierForTesting(mShareDelegateSupplier); + }); + } }
diff --git a/chrome/browser/commerce/android/java/src/org/chromium/chrome/browser/commerce/PriceNotificationSettingsFragment.java b/chrome/browser/commerce/android/java/src/org/chromium/chrome/browser/commerce/PriceNotificationSettingsFragment.java index fde524b..d1b6d100 100644 --- a/chrome/browser/commerce/android/java/src/org/chromium/chrome/browser/commerce/PriceNotificationSettingsFragment.java +++ b/chrome/browser/commerce/android/java/src/org/chromium/chrome/browser/commerce/PriceNotificationSettingsFragment.java
@@ -6,7 +6,6 @@ import static org.chromium.build.NullUtil.assumeNonNull; -import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Intent; import android.content.pm.PackageManager; @@ -16,6 +15,7 @@ import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; +import org.chromium.base.Callback; import org.chromium.base.ContextUtils; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; @@ -27,7 +27,7 @@ import org.chromium.chrome.browser.preferences.PrefServiceUtil; import org.chromium.chrome.browser.settings.ChromeBaseSettingsFragment; import org.chromium.chrome.browser.signin.services.IdentityServicesProvider; -import org.chromium.components.browser_ui.notifications.NotificationManagerProxyImpl; +import org.chromium.components.browser_ui.notifications.BaseNotificationManagerProxyFactory; import org.chromium.components.browser_ui.notifications.NotificationProxyUtils; import org.chromium.components.browser_ui.settings.ChromeSwitchPreference; import org.chromium.components.browser_ui.settings.SettingsUtils; @@ -127,45 +127,60 @@ * state of notifications and the price tracking channel */ private void updateMobileNotificationsText() { - if (mMobileNotificationsText == null) return; + arePriceTrackingNotificationsEnabled( + (enabled) -> { + if (mMobileNotificationsText == null) return; + String linkText = + getString(R.string.chrome_notification_settings_for_price_tracking); - String linkText = getString(R.string.chrome_notification_settings_for_price_tracking); + String settingsFullText; + if (enabled) { + settingsFullText = + getString( + R.string.price_notifications_settings_mobile_description_on, + linkText); + } else { + settingsFullText = + getString( + R.string + .price_notifications_settings_mobile_description_off, + linkText); + } - String settingsFullText; - if (arePriceTrackingNotificationsEnabled()) { - settingsFullText = - getString( - R.string.price_notifications_settings_mobile_description_on, linkText); - } else { - settingsFullText = - getString( - R.string.price_notifications_settings_mobile_description_off, linkText); - } + SpanApplier.SpanInfo info = + new SpanApplier.SpanInfo( + "<link>", + "</link>", + new ChromeClickableSpan( + getContext(), (view) -> launchAppSettings())); - SpanApplier.SpanInfo info = - new SpanApplier.SpanInfo( - "<link>", - "</link>", - new ChromeClickableSpan(getContext(), (view) -> launchAppSettings())); - SpanApplier.applySpans(settingsFullText, info); - - mMobileNotificationsText.setSummary(SpanApplier.applySpans(settingsFullText, info)); + mMobileNotificationsText.setSummary( + SpanApplier.applySpans(settingsFullText, info)); + }); } /** - * @return True if both app-level and price tracking notifications are enabled. + * Check if both app-level and price tracking notifications are enabled. + * + * @param callback Callback to return the result. */ - private boolean arePriceTrackingNotificationsEnabled() { - NotificationChannel channel = - NotificationManagerProxyImpl.getInstance() - .getNotificationChannel( - ChromeChannelDefinitions.ChannelId.PRICE_DROP_DEFAULT); - if (NotificationProxyUtils.areNotificationsEnabled() - && channel != null - && channel.getImportance() != NotificationManager.IMPORTANCE_NONE) { - return true; + private void arePriceTrackingNotificationsEnabled(Callback<Boolean> callback) { + if (!NotificationProxyUtils.areNotificationsEnabled()) { + callback.onResult(false); + return; } - return false; + BaseNotificationManagerProxyFactory.create() + .getNotificationChannel( + ChromeChannelDefinitions.ChannelId.PRICE_DROP_DEFAULT, + (channel) -> { + if (channel != null + && channel.getImportance() + != NotificationManager.IMPORTANCE_NONE) { + callback.onResult(true); + } else { + callback.onResult(false); + } + }); } /** Launch app settings so the user can view or change notification settings. */
diff --git a/chrome/browser/commerce/coupons/android/java/src/org/chromium/chrome/browser/commerce/coupons/DiscountsButtonController.java b/chrome/browser/commerce/coupons/android/java/src/org/chromium/chrome/browser/commerce/coupons/DiscountsButtonController.java index 15d6329..45d3ace 100644 --- a/chrome/browser/commerce/coupons/android/java/src/org/chromium/chrome/browser/commerce/coupons/DiscountsButtonController.java +++ b/chrome/browser/commerce/coupons/android/java/src/org/chromium/chrome/browser/commerce/coupons/DiscountsButtonController.java
@@ -45,8 +45,7 @@ /* supportsTinting= */ true, /* iphCommandBuilder= */ null, AdaptiveToolbarButtonVariant.DISCOUNTS, - /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ true); + /* tooltipTextResId= */ Resources.ID_NULL); mBottomSheetController = bottomSheetController; mBottomSheetObserver =
diff --git a/chrome/browser/commerce/price_insights/android/java/src/org/chromium/chrome/browser/price_insights/PriceInsightsButtonController.java b/chrome/browser/commerce/price_insights/android/java/src/org/chromium/chrome/browser/price_insights/PriceInsightsButtonController.java index 775957a..e585d2c1 100644 --- a/chrome/browser/commerce/price_insights/android/java/src/org/chromium/chrome/browser/price_insights/PriceInsightsButtonController.java +++ b/chrome/browser/commerce/price_insights/android/java/src/org/chromium/chrome/browser/price_insights/PriceInsightsButtonController.java
@@ -73,8 +73,7 @@ /* supportsTinting= */ true, /* iphCommandBuilder= */ null, AdaptiveToolbarButtonVariant.PRICE_INSIGHTS, - /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ true); + /* tooltipTextResId= */ Resources.ID_NULL); mContext = context; mBottomSheetController = bottomSheetController;
diff --git a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingButtonController.java b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingButtonController.java index b75fb3e..16fb221 100644 --- a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingButtonController.java +++ b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingButtonController.java
@@ -71,8 +71,7 @@ /* supportsTinting= */ true, /* iphCommandBuilder= */ null, AdaptiveToolbarButtonVariant.PRICE_TRACKING, - /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ false); + /* tooltipTextResId= */ Resources.ID_NULL); mSnackbarManager = snackbarManager; mTabBookmarkerSupplier = tabBookmarkerSupplier; mBottomSheetController = bottomSheetController; @@ -96,7 +95,6 @@ /* buttonVariant= */ AdaptiveToolbarButtonVariant.PRICE_TRACKING, /* actionChipLabelResId= */ Resources.ID_NULL, /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ true, /* hasErrorBadge= */ false); mBottomSheetObserver =
diff --git a/chrome/browser/data_sharing/android/java/res/values/dimens.xml b/chrome/browser/data_sharing/android/java/res/values/dimens.xml index 78adafc..a8d48c0 100644 --- a/chrome/browser/data_sharing/android/java/res/values/dimens.xml +++ b/chrome/browser/data_sharing/android/java/res/values/dimens.xml
@@ -29,5 +29,6 @@ <dimen name="recent_activity_content_area_min_height">200dp</dimen> <dimen name="recent_activity_favicon_size">22dp</dimen> <dimen name="recent_activity_favicon_bg_size">40dp</dimen> + <dimen name="recent_activity_menu_width">258dp</dimen> </resources>
diff --git a/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/DataSharingTabManager.java b/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/DataSharingTabManager.java index 1c6375c..e23095e29 100644 --- a/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/DataSharingTabManager.java +++ b/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/DataSharingTabManager.java
@@ -98,7 +98,7 @@ private final ObservableSupplier<TabModelSelector> mTabModelSelectorSupplier; private final DataSharingTabGroupsDelegate mDataSharingTabGroupsDelegate; private final Supplier<BottomSheetController> mBottomSheetControllerSupplier; - private final ObservableSupplier<ShareDelegate> mShareDelegateSupplier; + private ObservableSupplier<ShareDelegate> mShareDelegateSupplier; private final WindowAndroid mWindowAndroid; private final Resources mResources; private final OneshotSupplier<TabGroupUiActionHandler> mTabGroupUiActionHandlerSupplier; @@ -603,7 +603,6 @@ DataSharingStringConfig.StringKey.LEARN_ABOUT_SHARED_TAB_GROUPS, R.string.collaboration_learn_about_shared_groups) .build(); - String sessionId = uiDelegate.showCreateFlow( new DataSharingCreateUiConfig.Builder() @@ -756,7 +755,7 @@ R.string.collaboration_group_is_full_description) .setResourceId( DataSharingStringConfig.StringKey.ACTIVITY_LOGS_TITLE, - R.string.data_sharing_shared_tab_group_activity) + R.string.data_sharing_shared_tab_groups_activity) .build(); DataSharingManageUiConfig.ManageCallback manageCallback = @@ -956,4 +955,10 @@ BulkFaviconUtil getBulkFaviconUtilForTesting() { return mBulkFaviconUtil; } + + /** Override ShareDelegateSupplier for testing. */ + public void setShareDelegateSupplierForTesting( + ObservableSupplier<ShareDelegate> shareDelegateSupplier) { + mShareDelegateSupplier = shareDelegateSupplier; + } }
diff --git a/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/FakeDataSharingUIDelegateImpl.java b/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/FakeDataSharingUIDelegateImpl.java index e1cd88110..b5a82c7 100644 --- a/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/FakeDataSharingUIDelegateImpl.java +++ b/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/FakeDataSharingUIDelegateImpl.java
@@ -6,6 +6,7 @@ import androidx.annotation.Nullable; +import org.chromium.base.Callback; import org.chromium.build.annotations.NullMarked; import org.chromium.components.data_sharing.DataSharingUIDelegate; import org.chromium.components.data_sharing.configs.DataSharingAvatarBitmapConfig; @@ -20,8 +21,9 @@ public class FakeDataSharingUIDelegateImpl implements DataSharingUIDelegate { private @Nullable Runnable mShowJoinFlowRunnable; - private @Nullable Runnable mShowCreateFlowRunnable; + private @Nullable Callback<Boolean> mShowCreateFlowCallback; private @Nullable Runnable mShowManageFlowRunnable; + private @Nullable DataSharingCreateUiConfig mCreateUiConfig; public FakeDataSharingUIDelegateImpl() {} @@ -33,7 +35,11 @@ @Override public String showCreateFlow(DataSharingCreateUiConfig createUiConfig) { - if (mShowCreateFlowRunnable != null) mShowCreateFlowRunnable.run(); + assert this.mCreateUiConfig == null; + this.mCreateUiConfig = createUiConfig; + if (mShowCreateFlowCallback != null) { + mShowCreateFlowCallback.onResult(true); + } return ""; } @@ -61,13 +67,30 @@ mShowJoinFlowRunnable = runnable; } - /* Set a runnable to be called when showCreateFlow() is called. */ - public void setShowCreateFlowRunnable(Runnable runnable) { - mShowCreateFlowRunnable = runnable; + /* Set a callback to be called when showCreateFlow() is called. */ + public void setShowCreateFlowCallback(Callback<Boolean> callback) { + mShowCreateFlowCallback = callback; } /* Set a runnable to be called when showManageFlow() is called. */ public void setShowManageFlowRunnable(Runnable runnable) { mShowManageFlowRunnable = runnable; } + + /* Creates group data and calls onGroupCreatedWithWait when showCreateFlow() is called. */ + public void forceGroupCreation(String collaborationId, String accessToken) { + org.chromium.components.sync.protocol.GroupData groupData = + org.chromium.components.sync.protocol.GroupData.newBuilder() + .setGroupId(collaborationId) + .setAccessToken(accessToken) + .build(); + if (mCreateUiConfig == null || mCreateUiConfig.getCreateCallback() == null) return; + mCreateUiConfig + .getCreateCallback() + .onGroupCreatedWithWait( + groupData, + (success) -> { + assert success; + }); + } }
diff --git a/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/ui/recent_activity/RecentActivityListCoordinator.java b/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/ui/recent_activity/RecentActivityListCoordinator.java index edff4551..77210e0 100644 --- a/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/ui/recent_activity/RecentActivityListCoordinator.java +++ b/chrome/browser/data_sharing/android/java/src/org/chromium/chrome/browser/data_sharing/ui/recent_activity/RecentActivityListCoordinator.java
@@ -159,14 +159,14 @@ ModelList modelList = new ModelList(); modelList.add( BrowserUiListMenuUtils.buildMenuListItem( - R.string.data_sharing_shared_tab_group_activity, + R.string.data_sharing_shared_tab_groups_activity, R.id.see_full_activity, 0, /* enabled= */ true)); ListMenu.Delegate delegate = (model) -> { int textId = model.get(ListMenuItemProperties.TITLE_ID); - if (textId == R.string.data_sharing_shared_tab_group_activity) { + if (textId == R.string.data_sharing_shared_tab_groups_activity) { mShowFullActivityRunnable.run(); } }; @@ -194,6 +194,8 @@ } }; + menuView.setMenuMaxWidth( + view.getResources().getDimensionPixelSize(R.dimen.recent_activity_menu_width)); menuView.setDelegate(listMenuDelegate); menuView.tryToFitLargestItem(true); menuView.showMenu();
diff --git a/chrome/browser/data_sharing/desktop/data_sharing_sdk_delegate_desktop.cc b/chrome/browser/data_sharing/desktop/data_sharing_sdk_delegate_desktop.cc index f6b4b531..807f87f 100644 --- a/chrome/browser/data_sharing/desktop/data_sharing_sdk_delegate_desktop.cc +++ b/chrome/browser/data_sharing/desktop/data_sharing_sdk_delegate_desktop.cc
@@ -46,7 +46,7 @@ ->page_handler(); CHECK(handler); auto mojom_params = data_sharing::mojom::ReadGroupsParams::New(); - for (auto group_param : params.group_params()) { + for (const auto& group_param : params.group_params()) { auto param = data_sharing::mojom::ReadGroupParams::New(); param->group_id = group_param.group_id(); param->consistency_token = group_param.consistency_token();
diff --git a/chrome/browser/devtools/devtools_file_helper.cc b/chrome/browser/devtools/devtools_file_helper.cc index d5e02056..a7e5c57d 100644 --- a/chrome/browser/devtools/devtools_file_helper.cc +++ b/chrome/browser/devtools/devtools_file_helper.cc
@@ -238,7 +238,7 @@ const HandlePermissionsCallback& handle_permissions_callback) { auto file_system_paths = storage_->GetDraggedFileSystemPaths(GURL(file_system_url)); - for (auto file_system_path : file_system_paths) { + for (const auto& file_system_path : file_system_paths) { InnerAddFileSystem(handle_permissions_callback, kDefaultFileSystemType, file_system_path); } @@ -432,7 +432,7 @@ prefs::kDevToolsFileSystemPaths, base::BindRepeating(RunOnUIThread, change_handler_on_ui)); } - for (auto file_system_path : file_system_paths_) { + for (const auto& file_system_path : file_system_paths_) { auto path = base::FilePath::FromUTF8Unsafe(file_system_path.first); auto file_system = storage_->RegisterFileSystem(path, file_system_path.second); @@ -490,7 +490,7 @@ remaining.swap(file_system_paths_); DCHECK(file_watcher_.get()); - for (auto file_system_path : GetActiveFileSystemPaths()) { + for (const auto& file_system_path : GetActiveFileSystemPaths()) { if (remaining.find(file_system_path.first) == remaining.end()) { auto path = base::FilePath::FromUTF8Unsafe(file_system_path.first); auto file_system = @@ -503,7 +503,7 @@ file_system_paths_[file_system_path.first] = file_system_path.second; } - for (auto file_system : remaining) { + for (const auto& file_system : remaining) { delegate_->FileSystemRemoved(file_system.first); base::FilePath path = base::FilePath::FromUTF8Unsafe(file_system.first); storage_->UnregisterFileSystem(path);
diff --git a/chrome/browser/download/chrome_download_manager_delegate.cc b/chrome/browser/download/chrome_download_manager_delegate.cc index f6edfd2..00a2081 100644 --- a/chrome/browser/download/chrome_download_manager_delegate.cc +++ b/chrome/browser/download/chrome_download_manager_delegate.cc
@@ -1043,6 +1043,11 @@ .is_attachment() && offline_pages::OfflinePageUtils::CanDownloadAsOfflinePage(url, mime_type)) { +#if BUILDFLAG(IS_ANDROID) + if (profile_->IsOffTheRecord()) { + return false; + } +#endif // BUILDFLAG(IS_ANDROID) offline_pages::OfflinePageUtils::ScheduleDownload( web_contents, offline_pages::kDownloadNamespace, url, offline_pages::OfflinePageUtils::DownloadUIActionFlags::ALL,
diff --git a/chrome/browser/download/download_prefs.cc b/chrome/browser/download/download_prefs.cc index 86e7eb9e..e61ac542 100644 --- a/chrome/browser/download/download_prefs.cc +++ b/chrome/browser/download/download_prefs.cc
@@ -525,7 +525,7 @@ void DownloadPrefs::SaveAutoOpenState() { std::string extensions; - for (auto it : auto_open_by_user_) { + for (const auto& it : auto_open_by_user_) { #if BUILDFLAG(IS_WIN) // TODO(phajdan.jr): Why we're using Sys conversion here, but not in ctor? std::string this_extension = base::SysWideToUTF8(it);
diff --git a/chrome/browser/enterprise/data_controls/chrome_dlp_rules_manager.cc b/chrome/browser/enterprise/data_controls/chrome_dlp_rules_manager.cc index 65bb803..28d9010a 100644 --- a/chrome/browser/enterprise/data_controls/chrome_dlp_rules_manager.cc +++ b/chrome/browser/enterprise/data_controls/chrome_dlp_rules_manager.cc
@@ -188,7 +188,7 @@ } std::map<Level, std::set<std::string>> result; - for (auto it : destination_level_map) { + for (const auto& it : destination_level_map) { if (it.first == kWildCardMatching) { result[it.second] = {it.first}; } else if (it.second >= wildcard_level &&
diff --git a/chrome/browser/enterprise/profile_management/oidc_auth_response_capture_navigation_throttle.cc b/chrome/browser/enterprise/profile_management/oidc_auth_response_capture_navigation_throttle.cc index e865d83..06c5b23c 100644 --- a/chrome/browser/enterprise/profile_management/oidc_auth_response_capture_navigation_throttle.cc +++ b/chrome/browser/enterprise/profile_management/oidc_auth_response_capture_navigation_throttle.cc
@@ -113,7 +113,7 @@ profile_management::features::kOidcAuthAdditionalUrls.Get(), ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - for (std::string url : urls) { + for (const std::string& url : urls) { allowed_urls.push_back(url); } } @@ -147,7 +147,7 @@ profile_management::features::kOidcAuthAdditionalHosts.Get(), ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - for (std::string host : hosts) { + for (const std::string& host : hosts) { allowed_hosts.push_back(host); } }
diff --git a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_apitest.cc b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_apitest.cc index 930bb111..3de9dca 100644 --- a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_apitest.cc +++ b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_apitest.cc
@@ -666,8 +666,8 @@ #endif IN_PROC_BROWSER_TEST_F(EnterpriseReportingPrivateApiTest, MAYBE_GetFileSystemInfo_Success) { - // Use the test runner process and binary as test parameters, as it will always - // be running. + // Use the test runner process and binary as test parameters, as it will + // always be running. auto test_runner_file_path = device_signals::GetProcessExePath(base::Process::Current().Pid()); @@ -1113,14 +1113,8 @@ RunTest(kTestJS); } -// TODO(crbug.com/414870123): Flaky on win. -#if BUILDFLAG(IS_WIN) -#define MAYBE_ReportingPolicyEnabled DISABLED_ReportingPolicyEnabled -#else -#define MAYBE_ReportingPolicyEnabled ReportingPolicyEnabled -#endif IN_PROC_BROWSER_TEST_F(EnterpriseReportDataMaskingEventTest, - MAYBE_ReportingPolicyEnabled) { + ReportingPolicyEnabled) { auto event_validator = event_report_validator_helper_->CreateValidator(); api::enterprise_reporting_private::TriggeredRuleInfo rule_info; @@ -1137,6 +1131,8 @@ api::enterprise_reporting_private::EventResult::kEventResultDataMasked; event.url = "https://foo.com"; event.triggered_rule_info.push_back(std::move(rule_info)); + base::RunLoop run_loop; + event_validator.SetDoneClosure(run_loop.QuitClosure()); event_validator.ExpectDataMaskingEvent("test-user@chromium.org", profile()->GetPath().AsUTF8Unsafe(), std::move(event)); @@ -1147,6 +1143,7 @@ profile()->GetPrefs(), true, {"sensitiveDataEvent"}, {}); RunTest(kTestJS); + run_loop.Run(); } class EnterpriseOnDataMaskingRulesTriggeredTest
diff --git a/chrome/browser/extensions/api/image_writer_private/operation.cc b/chrome/browser/extensions/api/image_writer_private/operation.cc index 2dc7ca87..b50823c 100644 --- a/chrome/browser/extensions/api/image_writer_private/operation.cc +++ b/chrome/browser/extensions/api/image_writer_private/operation.cc
@@ -27,6 +27,10 @@ namespace extensions { namespace image_writer { +crypto::obsolete::Md5 MakeMd5HasherForImageWriter() { + return crypto::obsolete::Md5(); +} + namespace { // Returns true if the file at |image_path| is an archived image. @@ -260,8 +264,6 @@ return; } - base::MD5Init(&md5_context_); - base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ); if (!file.IsValid()) { Error(error::kImageOpenError); @@ -274,7 +276,8 @@ return; } - PostTask(base::BindOnce(&Operation::MD5Chunk, this, std::move(file), 0, + PostTask(base::BindOnce(&Operation::MD5Chunk, this, std::move(file), + MakeMd5HasherForImageWriter(), 0, base::checked_cast<size_t>(file_size), std::move(callback))); } @@ -285,6 +288,7 @@ void Operation::MD5Chunk( base::File file, + crypto::obsolete::Md5 md5, size_t bytes_processed, size_t bytes_total, base::OnceCallback<void(const std::string&)> callback) { @@ -299,22 +303,20 @@ if (read_size == 0) { // Nothing to read, we are done. - base::MD5Digest digest; - base::MD5Final(&digest, &md5_context_); - std::move(callback).Run(base::MD5DigestToBase16(digest)); + std::move(callback).Run(base::ToLowerASCII(base::HexEncode(md5.Finish()))); } else { int64_t offset = base::checked_cast<int64_t>(bytes_processed); auto target = base::span(buffer).first(read_size); if (file.ReadAndCheck(offset, target)) { // Process data. - base::MD5Update(&md5_context_, target); + md5.Update(target); bytes_processed += read_size; int percent_curr = (bytes_processed * kProgressComplete) / bytes_total; SetProgress(percent_curr); PostTask(base::BindOnce(&Operation::MD5Chunk, this, std::move(file), - bytes_processed, bytes_total, + std::move(md5), bytes_processed, bytes_total, std::move(callback))); // Skip closing the file. return;
diff --git a/chrome/browser/extensions/api/image_writer_private/operation.h b/chrome/browser/extensions/api/image_writer_private/operation.h index 37103c1c..b56140c 100644 --- a/chrome/browser/extensions/api/image_writer_private/operation.h +++ b/chrome/browser/extensions/api/image_writer_private/operation.h
@@ -12,7 +12,6 @@ #include "base/files/file.h" #include "base/files/scoped_temp_dir.h" #include "base/functional/callback.h" -#include "base/hash/md5.h" #include "base/memory/ref_counted_memory.h" #include "base/memory/weak_ptr.h" #include "base/task/sequenced_task_runner.h" @@ -20,6 +19,7 @@ #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "chrome/common/extensions/api/image_writer_private.h" +#include "crypto/obsolete/md5.h" #include "extensions/common/extension_id.h" #if BUILDFLAG(IS_CHROMEOS) @@ -204,6 +204,7 @@ // Incrementally calculates the MD5 sum of a file. void MD5Chunk(base::File file, + crypto::obsolete::Md5 md5, size_t bytes_processed, size_t bytes_total, const base::OnceCallback<void(const std::string&)> callback); @@ -221,10 +222,6 @@ image_writer_api::Stage stage_; int progress_; - // MD5 contexts don't play well with smart pointers. Just going to allocate - // memory here. This requires that we only do one MD5 sum at a time. - base::MD5Context md5_context_; - // Cleanup operations that must be run. All these functions are run on // `task_runner_`. std::vector<base::OnceClosure> cleanup_functions_;
diff --git a/chrome/browser/extensions/api/image_writer_private/write_from_url_operation_unittest.cc b/chrome/browser/extensions/api/image_writer_private/write_from_url_operation_unittest.cc index ab317fe..11901dd 100644 --- a/chrome/browser/extensions/api/image_writer_private/write_from_url_operation_unittest.cc +++ b/chrome/browser/extensions/api/image_writer_private/write_from_url_operation_unittest.cc
@@ -17,6 +17,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" #include "content/public/test/url_loader_interceptor.h" +#include "crypto/obsolete/md5.h" namespace extensions { namespace image_writer { @@ -202,12 +203,10 @@ } TEST_F(ImageWriterWriteFromUrlOperationTest, VerifyFile) { - base::HeapArray<char> char_buffer = - base::HeapArray<char>::Uninit(kTestFileSize); - base::ReadFile(test_utils_.GetImagePath(), char_buffer); - base::MD5Digest expected_digest; - base::MD5Sum(base::as_bytes(char_buffer.as_span()), &expected_digest); - std::string expected_hash = base::MD5DigestToBase16(expected_digest); + auto buffer = base::HeapArray<uint8_t>::Uninit(kTestFileSize); + base::ReadFile(test_utils_.GetImagePath(), buffer); + std::string expected_hash = base::ToLowerASCII( + base::HexEncode(crypto::obsolete::Md5::HashForTesting(buffer.as_span()))); scoped_refptr<WriteFromUrlOperationForTest> operation = CreateOperation(GURL(""), expected_hash);
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index 06e7b27f0..c2b4aff 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc
@@ -669,7 +669,7 @@ remove_list.push_back(extension->id()); } } - for (auto extension_id : remove_list) { + for (const auto& extension_id : remove_list) { std::u16string error; if (!extension_registrar_->UninstallExtension( extension_id, UNINSTALL_REASON_INTERNAL_MANAGEMENT, &error)) {
diff --git a/chrome/browser/first_party_sets/first_party_sets_overrides_policy_handler.cc b/chrome/browser/first_party_sets/first_party_sets_overrides_policy_handler.cc index 92d3eb2..2f42e20 100644 --- a/chrome/browser/first_party_sets/first_party_sets_overrides_policy_handler.cc +++ b/chrome/browser/first_party_sets/first_party_sets_overrides_policy_handler.cc
@@ -87,7 +87,7 @@ policy_value->GetDict()); // Output warnings that occur when parsing the policy. - for (ParseWarning parse_warning : warnings) { + for (const ParseWarning& parse_warning : warnings) { errors->AddError(policy_name(), IDS_POLICY_SCHEMA_VALIDATION_ERROR, ParseWarningTypeToString(parse_warning.type()), parse_warning.path(),
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 4786e1f4..a7987fc5 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -2541,7 +2541,7 @@ }, { "name": "enable-accessibility-manage-broadcast-recevier-on-background", - "owners": [ "avvall@google.com", "elabadysayed@google.com", "//ui/accessibility/OWNERS" ], + "owners": ["elabadysayed@google.com", "//ui/accessibility/OWNERS" ], "expiry_milestone": 145 }, {
diff --git a/chrome/browser/glic/host/context/glic_focused_tab_manager.cc b/chrome/browser/glic/host/context/glic_focused_tab_manager.cc index 19dfce9..094a5ac0 100644 --- a/chrome/browser/glic/host/context/glic_focused_tab_manager.cc +++ b/chrome/browser/glic/host/context/glic_focused_tab_manager.cc
@@ -16,6 +16,9 @@ #include "chrome/browser/ui/browser_window.h" #include "content/public/common/url_constants.h" #include "ui/views/widget/widget.h" +#if BUILDFLAG(IS_MAC) +#include "ui/base/cocoa/appkit_utils.h" +#endif namespace glic { @@ -278,6 +281,12 @@ } BrowserWindowInterface* GlicFocusedTabManager::ComputeBrowserCandidate() { +#if BUILDFLAG(IS_MAC) + if (!ui::IsActiveApplication()) { + return nullptr; + } +#endif + if (window_controller_->IsAttached()) { // When attached, we only allow focus if attached window is active. Browser* const attached_browser = window_controller_->attached_browser();
diff --git a/chrome/browser/glic/widget/glic_window_animator.cc b/chrome/browser/glic/widget/glic_window_animator.cc index 50b7baf..52b02c6e 100644 --- a/chrome/browser/glic/widget/glic_window_animator.cc +++ b/chrome/browser/glic/widget/glic_window_animator.cc
@@ -16,25 +16,11 @@ namespace glic { -namespace { - -constexpr static int kResizeAnimationDurationMs = 300; - -} // namespace - GlicWindowAnimator::GlicWindowAnimator(GlicWindowController* window_controller) : window_controller_(window_controller) {} GlicWindowAnimator::~GlicWindowAnimator() = default; -void GlicWindowAnimator::RunCloseAnimation(GlicButton* glic_button, - base::OnceClosure callback) { - // The widget is going away so it's fine to replace any existing animation. - AnimateBounds(glic_button->GetBoundsWithInset(), - base::Milliseconds(kResizeAnimationDurationMs), - std::move(callback)); -} - void GlicWindowAnimator::AnimateBounds(const gfx::Rect& target_bounds, base::TimeDelta duration, base::OnceClosure callback) {
diff --git a/chrome/browser/glic/widget/glic_window_animator.h b/chrome/browser/glic/widget/glic_window_animator.h index 446f284..db6b1e7c 100644 --- a/chrome/browser/glic/widget/glic_window_animator.h +++ b/chrome/browser/glic/widget/glic_window_animator.h
@@ -27,9 +27,6 @@ GlicWindowAnimator& operator=(const GlicWindowAnimator&) = delete; ~GlicWindowAnimator() override; - // Runs the attached close animation for the Glic widget. - void RunCloseAnimation(GlicButton* glic_button, base::OnceClosure callback); - // Animate the window size, maintaining the position of the top right corner. // If there is already a running bounds change animation, update that // animation's target size.
diff --git a/chrome/browser/glic/widget/glic_window_controller.h b/chrome/browser/glic/widget/glic_window_controller.h index acc5306..8983e7b 100644 --- a/chrome/browser/glic/widget/glic_window_controller.h +++ b/chrome/browser/glic/widget/glic_window_controller.h
@@ -207,12 +207,9 @@ // Possible states for the glic window. Public for testing. // * Closed (aka hidden, invisible) - // * OpenAnimation (showing an animation built into chrome, independent of - // the content of the glic window) // * Waiting for glic to load (the open animation has finished, but the // glic window contents is not yet ready) // * Open (aka showing, visible) - // * CloseAnimation // * Detaching // * ClosingToReopenDetached enum class State { @@ -221,7 +218,6 @@ kOpen, kDetaching, kClosingToReopenDetached, - kCloseAnimation, }; virtual State state() const = 0;
diff --git a/chrome/browser/glic/widget/glic_window_controller_impl.cc b/chrome/browser/glic/widget/glic_window_controller_impl.cc index 5b835ec..7ecb640 100644 --- a/chrome/browser/glic/widget/glic_window_controller_impl.cc +++ b/chrome/browser/glic/widget/glic_window_controller_impl.cc
@@ -1009,7 +1009,7 @@ void GlicWindowControllerImpl::CloseInternal( std::optional<mojom::InvocationSource> reopen_detached_source) { - if (state_ == State::kCloseAnimation || state_ == State::kClosed) { + if (state_ == State::kClosed) { return; } @@ -1024,16 +1024,7 @@ glic_window_animator_->SetGlicWebViewVisibility(false); } - if (attached_browser_) { - SetWindowState(State::kCloseAnimation); - GlicButton* glic_button = GetGlicButton(*attached_browser_); - glic_window_animator_->RunCloseAnimation( - glic_button, base::BindOnce(&GlicWindowControllerImpl::CloseFinish, - weak_ptr_factory_.GetWeakPtr(), - reopen_detached, reopen_detached_source)); - } else { CloseFinish(reopen_detached, reopen_detached_source); - } } void GlicWindowControllerImpl::CloseFinish( @@ -1322,7 +1313,7 @@ } bool GlicWindowControllerImpl::IsShowing() const { - return !(state_ == State::kClosed || state_ == State::kCloseAnimation); + return !(state_ == State::kClosed); } bool GlicWindowControllerImpl::IsPanelOrFreShowing() const {
diff --git a/chrome/browser/keyboard_accessory/android/BUILD.gn b/chrome/browser/keyboard_accessory/android/BUILD.gn index df30f7b..d745bbf 100644 --- a/chrome/browser/keyboard_accessory/android/BUILD.gn +++ b/chrome/browser/keyboard_accessory/android/BUILD.gn
@@ -55,7 +55,6 @@ "//chrome/browser/password_manager/android/access_loss:test_support", "//chrome/browser/password_manager/android/grouped_affiliations:test_utils", "//chrome/browser/plus_addresses", - "//chrome/browser/plus_addresses:impl", "//chrome/test:test_support", "//components/autofill/content/browser:test_support", "//components/autofill/core/browser",
diff --git a/chrome/browser/media/router/discovery/access_code/access_code_cast_pref_updater_impl.cc b/chrome/browser/media/router/discovery/access_code/access_code_cast_pref_updater_impl.cc index cc39284..05fd2b0 100644 --- a/chrome/browser/media/router/discovery/access_code/access_code_cast_pref_updater_impl.cc +++ b/chrome/browser/media/router/discovery/access_code/access_code_cast_pref_updater_impl.cc
@@ -26,7 +26,7 @@ // multiple times, we use ip-based deduping of stored media sinks to // ensure that the same sink (possibly with a different older stored named) // isn't stored twice in the cast list. - for (auto existing_sink_ids : + for (const auto& existing_sink_ids : AccessCodeCastPrefUpdaterImpl::GetMatchingIPEndPoints( pref_service_->GetDict(prefs::kAccessCodeCastDevices), sink.cast_data().ip_endpoint)) {
diff --git a/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service.cc b/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service.cc index 35a4355..fc66b7fe2 100644 --- a/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service.cc +++ b/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service.cc
@@ -732,7 +732,7 @@ void AccessCodeCastSinkService::InitExpirationTimers( const std::vector<MediaSinkInternal>& cast_sinks) { - for (auto cast_sink : cast_sinks) { + for (const auto& cast_sink : cast_sinks) { SetExpirationTimer(cast_sink.id()); } } @@ -912,7 +912,7 @@ void AccessCodeCastSinkService::AddStoredDevicesToMediaRouter( const std::vector<MediaSinkInternal>& cast_sinks) { std::vector<MediaSinkInternal> cast_sinks_to_add; - for (auto cast_sink : cast_sinks) { + for (const auto& cast_sink : cast_sinks) { AddSinkResultCallback callback = base::BindOnce(AddRememberedSinkMetricsCallback); AddSinkToMediaRouter(cast_sink, std::move(callback));
diff --git a/chrome/browser/media/router/mojo/media_router_desktop.cc b/chrome/browser/media/router/mojo/media_router_desktop.cc index 9d998c9b..9be7ae6 100644 --- a/chrome/browser/media/router/mojo/media_router_desktop.cc +++ b/chrome/browser/media/router/mojo/media_router_desktop.cc
@@ -98,9 +98,9 @@ std::vector<MediaRoute> routes_a, std::vector<MediaRoute> routes_b) { std::vector<MediaRoute> routes; - for (auto route_a : routes_a) { + for (const auto& route_a : routes_a) { bool route_seen = false; - for (auto route_b : routes_b) { + for (const auto& route_b : routes_b) { if (route_a.media_route_id() == route_b.media_route_id()) { route_seen = true; }
diff --git a/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationWrapperBuilderFactory.java b/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationWrapperBuilderFactory.java index 868aeca..0e6b3b7 100644 --- a/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationWrapperBuilderFactory.java +++ b/chrome/browser/notifications/android/java/src/org/chromium/chrome/browser/notifications/NotificationWrapperBuilderFactory.java
@@ -10,7 +10,7 @@ import org.chromium.build.annotations.NullMarked; import org.chromium.build.annotations.Nullable; import org.chromium.chrome.browser.notifications.channels.ChromeChannelDefinitions; -import org.chromium.components.browser_ui.notifications.NotificationManagerProxyImpl; +import org.chromium.components.browser_ui.notifications.BaseNotificationManagerProxyFactory; import org.chromium.components.browser_ui.notifications.NotificationMetadata; import org.chromium.components.browser_ui.notifications.NotificationWrapperBuilder; import org.chromium.components.browser_ui.notifications.channels.ChannelsInitializer; @@ -44,7 +44,7 @@ ChannelsInitializer channelsInitializer = new ChannelsInitializer( - NotificationManagerProxyImpl.getInstance(), + BaseNotificationManagerProxyFactory.create(), ChromeChannelDefinitions.getInstance(), context.getResources());
diff --git a/chrome/browser/on_device_translation/language_pack_util.h b/chrome/browser/on_device_translation/language_pack_util.h index 246f6da9..e5157293 100644 --- a/chrome/browser/on_device_translation/language_pack_util.h +++ b/chrome/browser/on_device_translation/language_pack_util.h
@@ -5,9 +5,11 @@ #ifndef CHROME_BROWSER_ON_DEVICE_TRANSLATION_LANGUAGE_PACK_UTIL_H_ #define CHROME_BROWSER_ON_DEVICE_TRANSLATION_LANGUAGE_PACK_UTIL_H_ -#include <array> +#include <optional> #include <set> +#include <string> #include <string_view> +#include <vector> #include "base/containers/fixed_flat_map.h" @@ -146,7 +148,7 @@ const LanguagePackComponentConfig& config); // The config for the TranslateKit en-es language pack. -const LanguagePackComponentConfig kTranslateKitEnEsConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnEsConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kEs, .public_key_sha = {0x63, 0xbd, 0x10, 0x98, 0x4e, 0xaa, 0xc3, 0xbe, @@ -156,7 +158,7 @@ }; // The config for the TranslateKit en-ja language pack. -const LanguagePackComponentConfig kTranslateKitEnJaConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnJaConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kJa, .public_key_sha = {0x7d, 0x22, 0x33, 0x74, 0x1c, 0xa8, 0x62, 0x58, @@ -166,7 +168,7 @@ }; // The config for the TranslateKit ar-en language pack. -const LanguagePackComponentConfig kTranslateKitArEnConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitArEnConfig = { .language1 = SupportedLanguage::kAr, .language2 = SupportedLanguage::kEn, .public_key_sha = {0xa1, 0xb3, 0x67, 0xf5, 0x5a, 0x8a, 0xfc, 0x1b, @@ -175,7 +177,7 @@ 0x6c, 0x5b, 0x90, 0x57, 0x79, 0x03, 0x74, 0x93}}; // The config for the TranslateKit bn-en language pack. -const LanguagePackComponentConfig kTranslateKitBnEnConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitBnEnConfig = { .language1 = SupportedLanguage::kBn, .language2 = SupportedLanguage::kEn, .public_key_sha = {0x62, 0x6f, 0x69, 0x31, 0x9c, 0x78, 0xf3, 0x92, @@ -184,7 +186,7 @@ 0x77, 0xa8, 0x59, 0xab, 0x34, 0xe9, 0xad, 0xaf}}; // The config for the TranslateKit de-en language pack. -const LanguagePackComponentConfig kTranslateKitDeEnConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitDeEnConfig = { .language1 = SupportedLanguage::kDe, .language2 = SupportedLanguage::kEn, .public_key_sha = {0xd7, 0x55, 0x73, 0xae, 0x4f, 0x45, 0x74, 0xab, @@ -193,7 +195,7 @@ 0x21, 0xbd, 0x81, 0x71, 0x91, 0x80, 0xdb, 0x13}}; // The config for the TranslateKit en-fr language pack. -const LanguagePackComponentConfig kTranslateKitEnFrConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnFrConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kFr, .public_key_sha = {0xe5, 0xa2, 0x55, 0xf1, 0x20, 0x0a, 0xb3, 0x0f, @@ -202,7 +204,7 @@ 0x73, 0x1d, 0x96, 0xe4, 0x99, 0x14, 0x14, 0x45}}; // The config for the TranslateKit en-hi language pack. -const LanguagePackComponentConfig kTranslateKitEnHiConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnHiConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kHi, .public_key_sha = {0xa9, 0x81, 0xd8, 0xbc, 0x0d, 0x1d, 0xdf, 0x28, @@ -211,7 +213,7 @@ 0x90, 0xb5, 0x4a, 0xc7, 0x2f, 0xc9, 0xc2, 0xab}}; // The config for the TranslateKit en-it language pack. -const LanguagePackComponentConfig kTranslateKitEnItConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnItConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kIt, .public_key_sha = {0xd7, 0xc3, 0x40, 0x59, 0x34, 0x55, 0x61, 0x1e, @@ -220,7 +222,7 @@ 0x9e, 0x37, 0x55, 0xe8, 0x0e, 0xce, 0x42, 0x3e}}; // The config for the TranslateKit en-ko language pack. -const LanguagePackComponentConfig kTranslateKitEnKoConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnKoConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kKo, .public_key_sha = {0xe2, 0x0c, 0x8f, 0x9e, 0x6d, 0x33, 0x06, 0x3c, @@ -229,7 +231,7 @@ 0xbd, 0xf4, 0x9b, 0x94, 0x02, 0x35, 0xcc, 0x7a}}; // The config for the TranslateKit en-nl language pack. -const LanguagePackComponentConfig kTranslateKitEnNlConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnNlConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kNl, .public_key_sha = {0x7d, 0xb7, 0x14, 0x60, 0x47, 0xda, 0xd9, 0xaa, @@ -238,7 +240,7 @@ 0xf0, 0x70, 0x41, 0xb0, 0x90, 0xc3, 0x89, 0x6b}}; // The config for the TranslateKit en-pl language pack. -const LanguagePackComponentConfig kTranslateKitEnPlConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnPlConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kPl, .public_key_sha = {0x10, 0x03, 0x30, 0xeb, 0xe4, 0x8f, 0x45, 0xf3, @@ -247,7 +249,7 @@ 0xb8, 0xf8, 0xa1, 0x6b, 0x61, 0xb9, 0x71, 0x91}}; // The config for the TranslateKit en-pt language pack. -const LanguagePackComponentConfig kTranslateKitEnPtConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnPtConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kPt, .public_key_sha = {0xcd, 0x31, 0x4d, 0x32, 0x6e, 0x09, 0xe9, 0x16, @@ -256,7 +258,7 @@ 0xbd, 0xd1, 0xe3, 0xa9, 0x38, 0x73, 0xd9, 0xee}}; // The config for the TranslateKit en-ru language pack. -const LanguagePackComponentConfig kTranslateKitEnRuConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnRuConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kRu, .public_key_sha = {0x31, 0xe6, 0xdd, 0x3f, 0x9d, 0x86, 0xd1, 0x3d, @@ -265,7 +267,7 @@ 0xba, 0x2c, 0x44, 0x62, 0x58, 0xa2, 0x33, 0xc3}}; // The config for the TranslateKit en-th language pack. -const LanguagePackComponentConfig kTranslateKitEnThConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnThConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kTh, .public_key_sha = {0x73, 0xab, 0x92, 0x29, 0x91, 0xea, 0x31, 0x87, @@ -274,7 +276,7 @@ 0xa1, 0x63, 0xa5, 0x8b, 0x3c, 0x97, 0x4e, 0xe2}}; // The config for the TranslateKit en-tr language pack. -const LanguagePackComponentConfig kTranslateKitEnTrConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnTrConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kTr, .public_key_sha = {0xc5, 0x75, 0x1d, 0x50, 0x3e, 0x87, 0xaf, 0xad, @@ -283,7 +285,7 @@ 0x60, 0x36, 0x57, 0xff, 0xb7, 0x2b, 0xd8, 0x6e}}; // The config for the TranslateKit en-vi language pack. -const LanguagePackComponentConfig kTranslateKitEnViConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnViConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kVi, .public_key_sha = {0xb3, 0xff, 0x8e, 0xa7, 0x44, 0x40, 0xce, 0xc4, @@ -292,7 +294,7 @@ 0x66, 0x09, 0x36, 0x18, 0xe4, 0xd4, 0x39, 0x33}}; // The config for the TranslateKit en-zh language pack. -const LanguagePackComponentConfig kTranslateKitEnZhConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnZhConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kZh, .public_key_sha = {0x1e, 0x44, 0x3e, 0x1c, 0x99, 0x33, 0x56, 0xd2, @@ -301,7 +303,7 @@ 0x1f, 0x9c, 0x1e, 0xe3, 0x9d, 0x7e, 0x55, 0xc5}}; // The config for the TranslateKit en-zh-Hant language pack. -const LanguagePackComponentConfig kTranslateKitEnZhHantConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnZhHantConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kZhHant, .public_key_sha = {0xe8, 0x50, 0xdf, 0x7d, 0x99, 0xef, 0x90, 0x2e, @@ -310,7 +312,7 @@ 0xcb, 0x70, 0x7e, 0x63, 0xcf, 0xaa, 0x5f, 0x3b}}; // The config for the TranslateKit bg-en language pack. -const LanguagePackComponentConfig kTranslateKitBgEnConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitBgEnConfig = { .language1 = SupportedLanguage::kBg, .language2 = SupportedLanguage::kEn, .public_key_sha = {0x6c, 0xdf, 0x57, 0x5f, 0x99, 0x8e, 0x24, 0xb1, @@ -319,7 +321,7 @@ 0x69, 0xea, 0x47, 0xd1, 0xf5, 0xc7, 0xc3, 0xe5}}; // The config for the TranslateKit cs-en language pack. -const LanguagePackComponentConfig kTranslateKitCsEnConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitCsEnConfig = { .language1 = SupportedLanguage::kCs, .language2 = SupportedLanguage::kEn, .public_key_sha = {0xb1, 0xc4, 0xea, 0x3f, 0xb5, 0xcf, 0xba, 0x79, @@ -328,7 +330,7 @@ 0x6e, 0x83, 0x9a, 0xfd, 0xea, 0xbb, 0x82, 0x65}}; // The config for the TranslateKit da-en language pack. -const LanguagePackComponentConfig kTranslateKitDaEnConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitDaEnConfig = { .language1 = SupportedLanguage::kDa, .language2 = SupportedLanguage::kEn, .public_key_sha = {0x03, 0xed, 0xf8, 0x44, 0x84, 0xaa, 0x9e, 0x13, @@ -337,7 +339,7 @@ 0xcd, 0x7d, 0x6b, 0x7d, 0x38, 0x89, 0xe7, 0x7d}}; // The config for the TranslateKit el-en language pack. -const LanguagePackComponentConfig kTranslateKitElEnConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitElEnConfig = { .language1 = SupportedLanguage::kEl, .language2 = SupportedLanguage::kEn, .public_key_sha = {0x29, 0xa0, 0x99, 0xad, 0x64, 0x3f, 0x23, 0x88, @@ -346,7 +348,7 @@ 0x28, 0xf6, 0x46, 0x39, 0x5f, 0x88, 0x61, 0xed}}; // The config for the TranslateKit en-fi language pack. -const LanguagePackComponentConfig kTranslateKitEnFiConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnFiConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kFi, .public_key_sha = {0x92, 0xb7, 0xbb, 0xb7, 0xc7, 0xad, 0x82, 0x5b, @@ -355,7 +357,7 @@ 0x48, 0x35, 0xc7, 0x93, 0x77, 0x0a, 0x81, 0x85}}; // The config for the TranslateKit en-hr language pack. -const LanguagePackComponentConfig kTranslateKitEnHrConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnHrConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kHr, .public_key_sha = {0x6a, 0x1a, 0x78, 0x89, 0x45, 0x2b, 0x32, 0xf1, @@ -364,7 +366,7 @@ 0x3c, 0x55, 0x03, 0xed, 0x63, 0x21, 0x17, 0xdb}}; // The config for the TranslateKit en-hu language pack. -const LanguagePackComponentConfig kTranslateKitEnHuConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnHuConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kHu, .public_key_sha = {0xf4, 0xee, 0xf9, 0x6f, 0x3c, 0x96, 0x24, 0xc3, @@ -373,7 +375,7 @@ 0x75, 0x7d, 0xb4, 0x55, 0x9e, 0x3e, 0xc9, 0x24}}; // The config for the TranslateKit en-id language pack. -const LanguagePackComponentConfig kTranslateKitEnIdConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnIdConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kId, .public_key_sha = {0xa1, 0x07, 0xf5, 0x27, 0xbd, 0x5a, 0x87, 0x1f, @@ -382,7 +384,7 @@ 0x47, 0x85, 0x8c, 0x1d, 0x88, 0x40, 0x1d, 0x1d}}; // The config for the TranslateKit en-iw language pack. -const LanguagePackComponentConfig kTranslateKitEnIwConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnIwConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kIw, .public_key_sha = {0x31, 0x28, 0xaf, 0x49, 0xe0, 0x6e, 0x38, 0xc8, @@ -391,7 +393,7 @@ 0x40, 0x33, 0x8e, 0x09, 0x5d, 0x78, 0x6f, 0x3c}}; // The config for the TranslateKit en-lt language pack. -const LanguagePackComponentConfig kTranslateKitEnLtConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnLtConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kLt, .public_key_sha = {0xe3, 0x60, 0xdd, 0x89, 0xe4, 0x3e, 0x7a, 0x2a, @@ -400,7 +402,7 @@ 0xef, 0x82, 0x05, 0x97, 0x12, 0xcc, 0xa5, 0xfa}}; // The config for the TranslateKit en-no language pack. -const LanguagePackComponentConfig kTranslateKitEnNoConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnNoConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kNo, .public_key_sha = {0xc7, 0xce, 0xeb, 0x48, 0x16, 0x9e, 0x4e, 0x88, @@ -409,7 +411,7 @@ 0xa6, 0x99, 0x90, 0xf1, 0xfa, 0x5a, 0x99, 0xa0}}; // The config for the TranslateKit en-ro language pack. -const LanguagePackComponentConfig kTranslateKitEnRoConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnRoConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kRo, .public_key_sha = {0x0a, 0x2f, 0xeb, 0x3c, 0xac, 0xf3, 0x64, 0xbf, @@ -418,7 +420,7 @@ 0x47, 0x24, 0x37, 0x15, 0xcc, 0x7f, 0x03, 0xa7}}; // The config for the TranslateKit en-sk language pack. -const LanguagePackComponentConfig kTranslateKitEnSkConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnSkConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kSk, .public_key_sha = {0xf4, 0xe9, 0x21, 0x11, 0x45, 0xae, 0x0a, 0x0c, @@ -427,7 +429,7 @@ 0x25, 0xa5, 0x65, 0xfa, 0xdf, 0xd6, 0xf5, 0x9d}}; // The config for the TranslateKit en-sl language pack. -const LanguagePackComponentConfig kTranslateKitEnSlConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnSlConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kSl, .public_key_sha = {0xe1, 0x5f, 0xa1, 0xfb, 0x33, 0xbb, 0x42, 0xe5, @@ -436,7 +438,7 @@ 0x50, 0x6a, 0x71, 0x6b, 0xe0, 0xbe, 0x65, 0xed}}; // The config for the TranslateKit en-sv language pack. -const LanguagePackComponentConfig kTranslateKitEnSvConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnSvConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kSv, .public_key_sha = {0xf7, 0xff, 0xca, 0x43, 0xfb, 0x2e, 0xcd, 0x44, @@ -445,7 +447,7 @@ 0xdd, 0xc4, 0x87, 0xed, 0xf9, 0x22, 0x0a, 0x6b}}; // The config for the TranslateKit en-uk language pack. -const LanguagePackComponentConfig kTranslateKitEnUkConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnUkConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kUk, .public_key_sha = {0xe0, 0x84, 0x14, 0x12, 0x2b, 0xce, 0xb0, 0xbc, @@ -453,7 +455,7 @@ 0xa3, 0x39, 0x69, 0x87, 0x82, 0x86, 0x10, 0xd3, 0x55, 0x54, 0x50, 0x94, 0x01, 0xec, 0xc5, 0xe3}}; -const LanguagePackComponentConfig kTranslateKitEnKnConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnKnConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kKn, .public_key_sha = {0x5c, 0x9d, 0x42, 0x31, 0xca, 0xf4, 0x97, 0x21, @@ -461,7 +463,7 @@ 0xa3, 0x8e, 0x84, 0x72, 0x60, 0xc6, 0x12, 0x54, 0x9b, 0x49, 0xc8, 0xef, 0xa4, 0xae, 0x16, 0x79}}; -const LanguagePackComponentConfig kTranslateKitEnTaConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnTaConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kTa, .public_key_sha = {0xab, 0xf0, 0x56, 0xfa, 0x09, 0xfe, 0x6f, 0x40, @@ -469,7 +471,7 @@ 0xc1, 0xdd, 0x3c, 0xc0, 0x41, 0x49, 0x14, 0xe4, 0xc2, 0xd5, 0xf6, 0xbd, 0xcd, 0x9c, 0xc4, 0x5d}}; -const LanguagePackComponentConfig kTranslateKitEnTeConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnTeConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kTe, .public_key_sha = {0xc7, 0x1c, 0x20, 0x31, 0x2a, 0x3f, 0xe8, 0x66, @@ -477,7 +479,7 @@ 0x0f, 0x4f, 0x47, 0x69, 0x1a, 0x83, 0xf7, 0xca, 0x73, 0x0d, 0x8b, 0x86, 0xd8, 0x12, 0xf0, 0x39}}; -const LanguagePackComponentConfig kTranslateKitEnMrConfig = { +inline constexpr LanguagePackComponentConfig kTranslateKitEnMrConfig = { .language1 = SupportedLanguage::kEn, .language2 = SupportedLanguage::kMr, .public_key_sha = {0x5e, 0x81, 0xf0, 0xcf, 0x35, 0xbc, 0x9b, 0x58, @@ -486,7 +488,7 @@ 0x9d, 0x2e, 0xe3, 0xde, 0x5e, 0x42, 0x00, 0x02}}; // The config for each language pack. -constexpr auto kLanguagePackComponentConfigMap = +inline constexpr auto kLanguagePackComponentConfigMap = base::MakeFixedFlatMap<LanguagePackKey, const LanguagePackComponentConfig*>( {{LanguagePackKey::kEn_Es, &kTranslateKitEnEsConfig}, {LanguagePackKey::kEn_Ja, &kTranslateKitEnJaConfig},
diff --git a/chrome/browser/page_info/web_view_side_panel_throttle.cc b/chrome/browser/page_info/web_view_side_panel_throttle.cc index 893aa895..ffda410 100644 --- a/chrome/browser/page_info/web_view_side_panel_throttle.cc +++ b/chrome/browser/page_info/web_view_side_panel_throttle.cc
@@ -8,6 +8,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/navigation_throttle.h" +#include "content/public/browser/navigation_throttle_registry.h" #include "content/public/browser/page_navigator.h" #include "content/public/browser/web_contents.h" #include "net/base/url_util.h" @@ -45,47 +46,50 @@ WebViewSidePanelWebContentsUserData::~WebViewSidePanelWebContentsUserData() = default; -std::unique_ptr<content::NavigationThrottle> -MaybeCreateWebViewSidePanelThrottleFor(content::NavigationHandle* handle) { +void MaybeCreateAndAddWebViewSidePanelThrottle( + content::NavigationThrottleRegistry& registry) { // Only install throttle for WebContents that are in the WebViewSidePanel. - if (!handle || !handle->IsInPrimaryMainFrame() || !handle->GetWebContents() || - !handle->GetWebContents()->GetUserData( + auto& handle = registry.GetNavigationHandle(); + if (!handle.IsInPrimaryMainFrame() || !handle.GetWebContents() || + !handle.GetWebContents()->GetUserData( kWebViewSidePanelWebContentsUserDataKey)) { - return nullptr; + return; } - const GURL& observed_url = handle->GetURL(); - return std::make_unique<navigation_interception::InterceptNavigationThrottle>( - handle, - base::BindRepeating( - [](const GURL& observed_url, content::NavigationHandle* handle, - bool should_run_async, - navigation_interception::InterceptNavigationThrottle:: - ResultCallback result_callback) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - CHECK(!should_run_async); - auto* data = static_cast<WebViewSidePanelWebContentsUserData*>( - handle->GetWebContents()->GetUserData( - kWebViewSidePanelWebContentsUserDataKey)); - // The delegate is stored in a WeakPtr. Check if it is still there. - if (!data->delegate()) { - std::move(result_callback).Run(true); - return; - } - const GURL& next_url = handle->GetURL(); - if (CanNavigateInPanel(handle, observed_url, next_url)) { - std::move(result_callback).Run(false); - return; - } + const GURL& observed_url = handle.GetURL(); + registry.AddThrottle( + std::make_unique<navigation_interception::InterceptNavigationThrottle>( + registry, + base::BindRepeating( + [](const GURL& observed_url, content::NavigationHandle* handle, + bool should_run_async, + navigation_interception::InterceptNavigationThrottle:: + ResultCallback result_callback) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + CHECK(!should_run_async); + auto* data = static_cast<WebViewSidePanelWebContentsUserData*>( + handle->GetWebContents()->GetUserData( + kWebViewSidePanelWebContentsUserDataKey)); + // The delegate is stored in a WeakPtr. Check if it is still + // there. + if (!data->delegate()) { + std::move(result_callback).Run(true); + return; + } + const GURL& next_url = handle->GetURL(); + if (CanNavigateInPanel(handle, observed_url, next_url)) { + std::move(result_callback).Run(false); + return; + } - content::OpenURLParams params( - next_url, content::Referrer(handle->GetReferrer()), - WindowOpenDisposition::NEW_FOREGROUND_TAB, - handle->GetPageTransition(), handle->IsRendererInitiated()); - params.initiator_origin = handle->GetInitiatorOrigin(); - params.initiator_base_url = handle->GetInitiatorBaseUrl(); - data->delegate()->OpenUrlInBrowser(params); - std::move(result_callback).Run(true); - }, - observed_url), - navigation_interception::SynchronyMode::kSync, std::nullopt); + content::OpenURLParams params( + next_url, content::Referrer(handle->GetReferrer()), + WindowOpenDisposition::NEW_FOREGROUND_TAB, + handle->GetPageTransition(), handle->IsRendererInitiated()); + params.initiator_origin = handle->GetInitiatorOrigin(); + params.initiator_base_url = handle->GetInitiatorBaseUrl(); + data->delegate()->OpenUrlInBrowser(params); + std::move(result_callback).Run(true); + }, + observed_url), + navigation_interception::SynchronyMode::kSync, std::nullopt)); }
diff --git a/chrome/browser/page_info/web_view_side_panel_throttle.h b/chrome/browser/page_info/web_view_side_panel_throttle.h index b7f3137..cbabbf6 100644 --- a/chrome/browser/page_info/web_view_side_panel_throttle.h +++ b/chrome/browser/page_info/web_view_side_panel_throttle.h
@@ -12,25 +12,27 @@ namespace content { struct OpenURLParams; -class NavigationHandle; class NavigationThrottle; +class NavigationThrottleRegistry; } // namespace content extern const char kWebViewSidePanelWebContentsUserDataKey[]; // Holds a handler to open a URL in a new tab in the browser that the sidepanel // of this webcontents is associated with. The NavigationThrottle from -// |MaybeCreateWebViewSidePanelThrottleFor| will check if this UserData is present -// and if it is present, intercepts navigations if |IsNavigationAllowed| -// and opens them using |OpenUrlInBrowser| instead. -class WebViewSidePanelWebContentsUserData : public base::SupportsUserData::Data { +// `MaybeCreateAndAddWebViewSidePanelThrottle` will check if this UserData is +// present and if it is present, intercepts navigations if `IsNavigationAllowed` +// and opens them using `OpenUrlInBrowser` instead. +class WebViewSidePanelWebContentsUserData + : public base::SupportsUserData::Data { public: class Delegate { public: virtual void OpenUrlInBrowser(const content::OpenURLParams& params) = 0; }; - explicit WebViewSidePanelWebContentsUserData(base::WeakPtr<Delegate> delegate); + explicit WebViewSidePanelWebContentsUserData( + base::WeakPtr<Delegate> delegate); ~WebViewSidePanelWebContentsUserData() override; Delegate* delegate() { return delegate_.get(); } @@ -41,7 +43,7 @@ // Installs a NavigationThrottle if an WebViewSidePanelWebContentsUserData is // associated with the WebContents of this navigation. -std::unique_ptr<content::NavigationThrottle> -MaybeCreateWebViewSidePanelThrottleFor(content::NavigationHandle* handle); +void MaybeCreateAndAddWebViewSidePanelThrottle( + content::NavigationThrottleRegistry& registry); #endif // CHROME_BROWSER_PAGE_INFO_WEB_VIEW_SIDE_PANEL_THROTTLE_H_
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 index 937c759..690560b 100644 --- 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
@@ -75,10 +75,8 @@ 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 (const auto& tab_strip_web_contents : GetAllWebContents()) { for (content::WebContents* web_contents : tab_strip_web_contents) { if (web_contents) { base::TimeTicks last_active = web_contents->GetLastActiveTimeTicks(); @@ -113,10 +111,7 @@ 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) { + for (const auto& tab_strip_web_contents : GetAllWebContents()) { 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()) {
diff --git a/chrome/browser/password_manager/android/BUILD.gn b/chrome/browser/password_manager/android/BUILD.gn index 0af05157..ca888f9a 100644 --- a/chrome/browser/password_manager/android/BUILD.gn +++ b/chrome/browser/password_manager/android/BUILD.gn
@@ -665,7 +665,6 @@ "//chrome/browser/password_manager/android/access_loss:test_support", "//chrome/browser/password_manager/android/add_username_dialog:android", "//chrome/browser/plus_addresses", - "//chrome/browser/plus_addresses:impl", "//chrome/browser/prefs", "//chrome/browser/sync", "//chrome/browser/touch_to_fill/password_manager/password_generation/android:public",
diff --git a/chrome/browser/pdf/pdf_extension_js_test.cc b/chrome/browser/pdf/pdf_extension_js_test.cc index 1c168c0..b17e27cc 100644 --- a/chrome/browser/pdf/pdf_extension_js_test.cc +++ b/chrome/browser/pdf/pdf_extension_js_test.cc
@@ -624,14 +624,7 @@ RunTestsInJsModule("ink2_size_selector_test.js", "test.pdf"); } -// TODO(crbug.com/416359681): Ink2ViewerToolbar is flaky on Mac12 and Mac13 -// tests. -#if !BUILDFLAG(IS_MAC) -#define MAYBE_Ink2ViewerToolbar Ink2ViewerToolbar -#else -#define MAYBE_Ink2ViewerToolbar DISABLED_Ink2ViewerToolbar -#endif -IN_PROC_BROWSER_TEST_P(PDFExtensionJSInk2Test, MAYBE_Ink2ViewerToolbar) { +IN_PROC_BROWSER_TEST_P(PDFExtensionJSInk2Test, Ink2ViewerToolbar) { RunTestsInJsModule("ink2_viewer_toolbar_test.js", "test.pdf"); }
diff --git a/chrome/browser/performance_manager/user_tuning/cpu_health_tracker.cc b/chrome/browser/performance_manager/user_tuning/cpu_health_tracker.cc index 7b9f6cd..bfb2947 100644 --- a/chrome/browser/performance_manager/user_tuning/cpu_health_tracker.cc +++ b/chrome/browser/performance_manager/user_tuning/cpu_health_tracker.cc
@@ -69,7 +69,7 @@ int CpuHealthTracker::GetTotalCpuPercentUsage(ActionableTabsResult tabs) { int total_cpu = 0; - for (resource_attribution::PageContext context : tabs) { + for (const resource_attribution::PageContext& context : tabs) { auto iter = tab_page_measurements_.find(context); if (iter != tab_page_measurements_.end()) { total_cpu += iter->second.value();
diff --git a/chrome/browser/performance_manager/user_tuning/performance_detection_manager.cc b/chrome/browser/performance_manager/user_tuning/performance_detection_manager.cc index c5ab1a3..5c8a8daa5 100644 --- a/chrome/browser/performance_manager/user_tuning/performance_detection_manager.cc +++ b/chrome/browser/performance_manager/user_tuning/performance_detection_manager.cc
@@ -70,7 +70,7 @@ std::vector<const PageNode*> eligible_nodes; std::vector<resource_attribution::PageContext> eligible_page_contexts; - for (resource_attribution::PageContext context : tabs) { + for (const resource_attribution::PageContext& context : tabs) { const PageNode* page_node = context.GetPageNode(); if (page_node) { eligible_nodes.emplace_back(page_node);
diff --git a/chrome/browser/plus_addresses/BUILD.gn b/chrome/browser/plus_addresses/BUILD.gn index 6d0184c..fd7367c 100644 --- a/chrome/browser/plus_addresses/BUILD.gn +++ b/chrome/browser/plus_addresses/BUILD.gn
@@ -12,15 +12,12 @@ public_deps = [ "//base", - "//chrome/browser/profiles:profile", - "//components/plus_addresses", - ] - - deps = [ "//chrome/browser/affiliations", + "//chrome/browser/profiles:profile", "//chrome/browser/sync:factories", "//components/affiliations/core/browser:affiliations", "//components/autofill/core/common:features", + "//components/plus_addresses", "//components/plus_addresses:features", "//components/plus_addresses:hats_utils", "//components/plus_addresses/settings", @@ -36,28 +33,7 @@ "plus_address_service_factory.cc", "plus_address_setting_service_factory.cc", ] - - public_deps = [ - "//base", - "//chrome/browser:browser_public_dependencies", - "//chrome/browser/profiles:profile", - "//components/plus_addresses", - ] - - deps = [ - ":plus_addresses", - "//chrome/browser/affiliations", - "//chrome/browser/sync", - "//components/affiliations/core/browser:affiliations", - "//components/autofill/core/common:features", - "//components/plus_addresses:features", - "//components/plus_addresses:hats_utils", - "//components/plus_addresses/settings", - "//components/signin/public/identity_manager", - "//components/sync/model", - "//components/variations/service", - "//services/network/public/cpp", - ] + deps = [ ":plus_addresses" ] } if (!is_android) {
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index dba44001..91c3a30 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -2468,7 +2468,7 @@ base::BindRepeating(&PopulatePolicyHandlerParameters), base::BindRepeating(&GetChromePolicyDetails), AreFuturePoliciesEnabledByDefault())); - for (PolicyToPreferenceMapEntry entry : kSimplePolicyMap) { + for (const PolicyToPreferenceMapEntry& entry : kSimplePolicyMap) { handlers->AddHandler(std::make_unique<SimplePolicyHandler>( entry.policy_name, entry.preference_path, entry.value_type)); }
diff --git a/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util.cc b/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util.cc index fe1cb448..4e31514 100644 --- a/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util.cc +++ b/chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_util.cc
@@ -1455,7 +1455,7 @@ needs_update[key_value.first] = lcpp_origin; } } - for (auto it : needs_update) { + for (const auto& it : needs_update) { origin_map_->UpdateData(it.first, it.second); } }
diff --git a/chrome/browser/prefs/session_startup_pref.cc b/chrome/browser/prefs/session_startup_pref.cc index 266dc5f..b6b0ed4 100644 --- a/chrome/browser/prefs/session_startup_pref.cc +++ b/chrome/browser/prefs/session_startup_pref.cc
@@ -92,8 +92,9 @@ // Always save the URLs, that way the UI can remain consistent even if the // user changes the startup type pref. base::Value::List url_pref_list; - for (GURL url : pref.urls) + for (const GURL& url : pref.urls) { url_pref_list.Append(url.spec()); + } prefs->SetList(prefs::kURLsToRestoreOnStartup, std::move(url_pref_list)); } }
diff --git a/chrome/browser/preloading/navigation_ablation_throttle.cc b/chrome/browser/preloading/navigation_ablation_throttle.cc index 25def7f..edeada8 100644 --- a/chrome/browser/preloading/navigation_ablation_throttle.cc +++ b/chrome/browser/preloading/navigation_ablation_throttle.cc
@@ -75,7 +75,7 @@ return AblationType::kDefaultSearchQuery; } - for (auto url_ref : default_search->url_refs()) { + for (const auto& url_ref : default_search->url_refs()) { if (url::Origin::Create(navigation_url) == url::Origin::Create(GURL(url_ref.GetURL()))) { return AblationType::kDefaultSearchHost;
diff --git a/chrome/browser/profiles/gaia_info_update_service.cc b/chrome/browser/profiles/gaia_info_update_service.cc index cecf493..1b27c0f 100644 --- a/chrome/browser/profiles/gaia_info_update_service.cc +++ b/chrome/browser/profiles/gaia_info_update_service.cc
@@ -233,7 +233,7 @@ // Regenerate based on the info from signed-in accounts (if not available // now, it will be regenerated soon via OnExtendedAccountInfoUpdated() once // downloaded). - for (gaia::ListedAccount account : + for (const gaia::ListedAccount& account : accounts_in_cookie_jar_info.GetPotentiallyInvalidSignedInAccounts()) { UpdateAnyAccount( identity_manager_->FindExtendedAccountInfoByAccountId(account.id));
diff --git a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudToolbarButtonController.java b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudToolbarButtonController.java index 415b19b9..05c8c25a 100644 --- a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudToolbarButtonController.java +++ b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudToolbarButtonController.java
@@ -51,8 +51,7 @@ /* supportsTinting= */ true, /* iphCommandBuilder= */ null, AdaptiveToolbarButtonVariant.READ_ALOUD, - /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ true); + /* tooltipTextResId= */ Resources.ID_NULL); mControllerSupplier = controllerSupplier; mTrackerSupplier = trackerSupplier; }
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index 14bacc2..1b785aa 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -9,8 +9,10 @@ #include <algorithm> #include <memory> #include <set> +#include <string> #include <utility> +#include "base/check.h" #include "base/command_line.h" #include "base/containers/contains.h" #include "base/feature_list.h" @@ -45,10 +47,6 @@ #include "chrome/browser/download/download_prefs.h" #include "chrome/browser/download/download_stats.h" #include "chrome/browser/glic/glic_enabling.h" -#if BUILDFLAG(ENABLE_GLIC) -#include "chrome/browser/glic/glic_keyed_service.h" -#include "chrome/browser/glic/glic_keyed_service_factory.h" -#endif // BUILDFLAG(ENABLE_GLIC) #include "chrome/browser/language/language_model_manager_factory.h" #include "chrome/browser/media/router/media_router_feature.h" #include "chrome/browser/navigation_predictor/navigation_predictor_features.h" @@ -261,6 +259,11 @@ #include "extensions/common/extension.h" #endif +#if BUILDFLAG(ENABLE_GLIC) +#include "chrome/browser/glic/glic_keyed_service.h" +#include "chrome/browser/glic/glic_keyed_service_factory.h" +#endif // BUILDFLAG(ENABLE_GLIC) + #if BUILDFLAG(ENABLE_PDF) #include "chrome/browser/pdf/pdf_extension_util.h" #include "components/pdf/browser/pdf_frame_util.h" @@ -319,6 +322,10 @@ #include "chrome/browser/ui/toasts/toast_controller.h" #include "chrome/browser/ui/toasts/toast_features.h" #include "chrome/browser/ui/webui/webui_embedding_context.h" +#include "components/tabs/public/split_tab_data.h" +#include "components/tabs/public/split_tab_id.h" +#include "components/tabs/public/tab_interface.h" +#include "ui/base/page_transition_types.h" #endif using base::UserMetricsAction; @@ -526,13 +533,14 @@ {IDC_CONTENT_CONTEXT_USE_PASSKEY_FROM_ANOTHER_DEVICE, 153}, {IDC_CONTENT_CONTEXT_RELOAD_GLIC, 154}, {IDC_CONTENT_CONTEXT_CLOSE_GLIC, 155}, + {IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW, 156}, // To add new items: // - Add one more line above this comment block, using the UMA value // from the line below this comment block. // - Increment the UMA value in that latter line. // - Add the new item to the RenderViewContextMenuItem enum in // tools/metrics/histograms/metadata/ui/enums.xml. - {0, 156}}); + {0, 157}}); // These UMA values are for the ContextMenuOptionDesktop enum, used for // the ContextMenu.SelectedOptionDesktop histograms. @@ -568,12 +576,13 @@ // Removed: {IDC_CONTENT_CONTEXT_TRANSLATEIMAGEWITHLENS, 28}, {IDC_CONTENT_CONTEXT_SEARCHWEBFORNEWTAB, 29}, {IDC_CONTENT_CONTEXT_OPENLINKPREVIEW, 30}, + {IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW, 31}, // To add new items: // - Add one more line above this comment block, using the UMA value // from the line below this comment block. // - Increment the UMA value in that latter line. // - Add the new item to the ContextMenuOptionDesktop enum in - // tools/metrics/histograms/enums.xml. + // tools/metrics/histograms/metadata/enums.xml. {0, 31}}); return *(type == UmaEnumIdLookupType::GeneralEnumId ? kGeneralMap @@ -638,6 +647,7 @@ return id == IDC_CONTENT_CONTEXT_OPENLINKNEWTAB || id == IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW || id == IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD || + id == IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW || (id >= IDC_OPEN_LINK_IN_PROFILE_FIRST && id <= IDC_OPEN_LINK_IN_PROFILE_LAST); } @@ -856,6 +866,8 @@ kGlicCloseMenuItem); DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(RenderViewContextMenu, kGlicReloadMenuItem); +DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(RenderViewContextMenu, + kOpenLinkInSplitMenuItem); DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(RenderViewContextMenu, kRegionSearchItem); DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(RenderViewContextMenu, kSearchForImageItem); @@ -1783,6 +1795,25 @@ } #if !BUILDFLAG(IS_ANDROID) + // Opening a link in split view should also go through the same constraints + // as opening a link in a new tab since a split view tab is a new tab that + // is then joined with the current active tab. + Browser* const browser = GetBrowser(); + if (base::FeatureList::IsEnabled(features::kSideBySide) && browser && + browser->is_type_normal() && show_open_in_new_tab) { + menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW, + IDS_CONTENT_CONTEXT_OPENLINKSPLITVIEW); + const int command_index = + menu_model_.GetIndexOfCommandId(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW) + .value(); + menu_model_.SetIsNewFeatureAt( + command_index, + UserEducationService::MaybeShowNewBadge( + GetBrowserContext(), features::kSideBySideLinkMenuNewBadge)); + menu_model_.SetElementIdentifierAt(command_index, + kOpenLinkInSplitMenuItem); + } + if (base::FeatureList::IsEnabled(blink::features::kLinkPreview) && !is_link_to_iwa) { menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_OPENLINKPREVIEW, @@ -2908,6 +2939,7 @@ case IDC_CONTENT_CONTEXT_OPENLINKNEWTAB: case IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW: case IDC_CONTENT_CONTEXT_OPENLINKPREVIEW: + case IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW: return navigation_allowed && params_.link_url.is_valid() && IsOpenLinkAllowedByDlp(params_.link_url); @@ -3266,6 +3298,11 @@ ExecOpenLinkPreview(); break; + case IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW: +#if !BUILDFLAG(IS_ANDROID) + OpenLinkInSplitView(); +#endif // !BUILDFLAG(IS_ANDROID) + break; case IDC_CONTENT_CONTEXT_SAVELINKAS: CheckSupervisedUserURLFilterAndSaveLinkAs(); break; @@ -4869,6 +4906,40 @@ } #endif // BUILDFLAG(IS_CHROMEOS) +#if !BUILDFLAG(IS_ANDROID) +void RenderViewContextMenu::OpenLinkInSplitView() { + Browser* const browser = GetBrowser(); + CHECK(browser); + CHECK(browser->is_type_normal()); + + TabStripModel* const tab_strip_model = browser->tab_strip_model(); + tabs::TabInterface* const source_tab = + tabs::TabInterface::GetFromContents(source_web_contents_); + if (source_tab->IsSplit()) { + // Navigate the inactive tab to the URL + const split_tabs::SplitTabId split_id = source_tab->GetSplit().value(); + for (tabs::TabInterface* tab : + tab_strip_model->GetSplitData(split_id)->ListTabs()) { + if (tab != source_tab) { + // Navigate the tab that wasn't the source of the context menu to the + // URL + tab->GetContents()->GetController().LoadURL( + params_.link_url, content::Referrer(), + ui::PageTransition::PAGE_TRANSITION_LINK, std::string()); + break; + } + } + } else { // Create new split tab + const int active_index = tab_strip_model->active_index(); + tab_strip_model->delegate()->AddTabAt( + params_.link_url, active_index + 1, true, + tab_strip_model->GetTabGroupForTab(active_index)); + tab_strip_model->AddToNewSplit({active_index}, + split_tabs::SplitTabLayout::kVertical); + } +} +#endif // !BUILDFLAG(IS_ANDROID) + bool RenderViewContextMenu::IsLinkToIsolatedWebApp() const { // Using `unfiltered_link_url`, because `link_url` is being replaced with // about:blank#blocked if the source is a normal site.
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.h b/chrome/browser/renderer_context_menu/render_view_context_menu.h index ef71da5..912be875 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.h +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.h
@@ -110,6 +110,7 @@ DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kComposeMenuItem); DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kGlicCloseMenuItem); DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kGlicReloadMenuItem); + DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kOpenLinkInSplitMenuItem); DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kRegionSearchItem); DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kSearchForImageItem); DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kSearchForVideoFrameItem); @@ -457,6 +458,14 @@ void ShowClipboardHistoryMenu(int event_flags); #endif // BUILDFLAG(IS_CHROMEOS) +#if !BUILDFLAG(IS_ANDROID) + // Opens the link in a new split view so that the linked page will be visible + // next to the active tab. If the active tab is already in the split view, + // then the tab that wasn't the source of the link will be navigated to the + // link instead. + void OpenLinkInSplitView(); +#endif // !BUILDFLAG(IS_ANDROID) + // The destination URL to use if the user tries to search for or navigate to // a text selection. GURL selection_navigation_url_; @@ -577,6 +586,7 @@ IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW, IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD, IDC_OPEN_LINK_IN_PROFILE_FIRST, IDC_OPEN_LINK_IN_PROFILE_LAST, + IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW, // Open link commands that appear in certain scenarios. IDC_CONTENT_CONTEXT_OPENLINKBOOKMARKAPP,
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc index d19b088e..a49b6a0 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu_browsertest.cc
@@ -214,7 +214,8 @@ {media::kContextMenuSaveVideoFrameAs, media::kContextMenuSearchForVideoFrame, toast_features::kLinkCopiedToast, toast_features::kImageCopiedToast, - toast_features::kVideoFrameCopiedToast}, + toast_features::kVideoFrameCopiedToast, features::kSideBySide, + features::kSideBySideLinkMenuNewBadge}, {}); } @@ -994,6 +995,7 @@ // Content contextual commands. IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, IDC_CONTENT_CONTEXT_COPYIMAGE, IDC_CONTENT_CONTEXT_COPYIMAGELOCATION, IDC_CONTENT_CONTEXT_INSPECTELEMENT, + IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW, // Other commands (we only test a subset). IDC_VIEW_SOURCE}; for (int command_id : kCommandsToTest) { @@ -1026,6 +1028,7 @@ // Content contextual commands. IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, IDC_CONTENT_CONTEXT_COPYIMAGE, IDC_CONTENT_CONTEXT_COPYIMAGELOCATION, IDC_CONTENT_CONTEXT_INSPECTELEMENT, + IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW, // Other commands (we only test a subset). IDC_VIEW_SOURCE}; for (int command_id : kCommandsToTest) { @@ -1054,6 +1057,7 @@ // Verify other commands are disabled. static constexpr int kCommandsDisabledInLockedFullscreen[] = { IDC_VIEW_SOURCE, IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, + IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW, IDC_CONTENT_CONTEXT_INSPECTELEMENT}; for (int command_id : kCommandsDisabledInLockedFullscreen) { EXPECT_FALSE(menu->IsCommandIdEnabled(command_id)) @@ -1075,6 +1079,7 @@ // Content contextual commands. IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, IDC_CONTENT_CONTEXT_COPYIMAGE, IDC_CONTENT_CONTEXT_COPYIMAGELOCATION, IDC_CONTENT_CONTEXT_INSPECTELEMENT, + IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW, // Other commands (we only test a subset). IDC_VIEW_SOURCE}; for (int command_id : kCommandsToTest) { @@ -1100,6 +1105,7 @@ // Verify other commands are disabled. static constexpr int kCommandsDisabledForOnTask[] = { IDC_VIEW_SOURCE, IDC_CONTENT_CONTEXT_OPENLINKNEWTAB, + IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW, IDC_CONTENT_CONTEXT_INSPECTELEMENT}; for (int command_id : kCommandsDisabledForOnTask) { EXPECT_FALSE(menu->IsCommandIdEnabled(command_id)) @@ -1121,6 +1127,7 @@ ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION)); + ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKBOOKMARKAPP)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKINPROFILE)); ASSERT_FALSE(menu->IsItemInRangePresent(IDC_OPEN_LINK_IN_PROFILE_FIRST, @@ -1140,6 +1147,7 @@ ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKBOOKMARKAPP)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION)); + ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKINPROFILE)); ASSERT_FALSE(menu->IsItemInRangePresent(IDC_OPEN_LINK_IN_PROFILE_FIRST, IDC_OPEN_LINK_IN_PROFILE_LAST)); @@ -1156,6 +1164,7 @@ ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); + ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKBOOKMARKAPP)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKINPROFILE)); @@ -1175,6 +1184,7 @@ ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); + ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKBOOKMARKAPP)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKINPROFILE)); @@ -1210,6 +1220,7 @@ ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION)); + ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKBOOKMARKAPP)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKINPROFILE)); ASSERT_FALSE(menu->IsItemInRangePresent(IDC_OPEN_LINK_IN_PROFILE_FIRST, @@ -1230,6 +1241,7 @@ ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); + ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKBOOKMARKAPP)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKINPROFILE)); @@ -1250,6 +1262,7 @@ ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); + ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKBOOKMARKAPP)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKINPROFILE)); @@ -1271,6 +1284,7 @@ ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); + ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKBOOKMARKAPP)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKINPROFILE)); @@ -1294,6 +1308,7 @@ ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); + ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKBOOKMARKAPP)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKINPROFILE)); @@ -1309,6 +1324,7 @@ ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); + ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKINPROFILE)); ASSERT_FALSE(menu->IsItemInRangePresent(IDC_OPEN_LINK_IN_PROFILE_FIRST, @@ -2082,6 +2098,7 @@ ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); + ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION)); // With only one profile exists, we don't add any items to the context menu // for opening links in other profiles. @@ -2108,6 +2125,7 @@ ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); + ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION)); // With the second profile not yet open and thus not active, an inline entry // to open the link with the secondary profile is not displayed. @@ -2149,6 +2167,7 @@ ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); + ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION)); // With the second profile open, an inline entry to open the link with the // secondary profile is displayed. @@ -2168,6 +2187,7 @@ ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); + ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION)); // With the second profile closed but active, an inline entry to open the // link with the secondary profile is displayed. @@ -2186,6 +2206,7 @@ ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); + ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION)); // With at least two secondary profiles, they are displayed in a submenu. raw_ptr<ui::MenuModel> model = nullptr; @@ -3468,6 +3489,7 @@ EXPECT_FALSE(menu1->IsItemEnabled(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB)); EXPECT_FALSE(menu1->IsItemEnabled(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); + ASSERT_FALSE(menu1->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW)); EXPECT_FALSE(menu1->IsItemEnabled(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD)); } @@ -3483,4 +3505,52 @@ EXPECT_FALSE(menu1->IsItemEnabled(IDC_CONTENT_CONTEXT_OPENLINKPREVIEW)); } +IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, DoNotShowSplitTabInWebApp) { + const GURL test_url("http://www.example.com/"); + const AppId app_id = InstallTestWebApp(GURL(kAppUrl1)); + Browser* const app_window = OpenTestWebApp(app_id); + ASSERT_FALSE(app_window->is_type_normal()); + + std::unique_ptr<TestRenderViewContextMenu> menu = + CreateContextMenuMediaTypeNoneInWebContents( + app_window->tab_strip_model()->GetActiveWebContents(), test_url, + test_url); + + EXPECT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW)); +} + +IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, OpenLinkInNewSplitTab) { + const GURL test_url("http://www.example.com/"); + std::unique_ptr<TestRenderViewContextMenu> menu = + CreateContextMenuMediaTypeNone(test_url, test_url); + + EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW)); + + TabStripModel* const tab_strip_model = browser()->tab_strip_model(); + ASSERT_EQ(tab_strip_model->count(), 1); + menu->ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW, 0); + ASSERT_EQ(tab_strip_model->count(), 2); + EXPECT_EQ(tab_strip_model->active_index(), 1); + EXPECT_TRUE(tab_strip_model->GetActiveTab()->IsSplit()); + EXPECT_TRUE(tab_strip_model->GetTabAtIndex(0)->IsSplit()); +} + +IN_PROC_BROWSER_TEST_P(ContextMenuBrowserTest, OpenLinkInExistingSplitTab) { + const GURL test_url("http://www.example.com/"); + TabStripModel* const tab_strip_model = browser()->tab_strip_model(); + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url)); + chrome::NewSplitTab(browser()); + tab_strip_model->ActivateTabAt(0); + ASSERT_NE(tab_strip_model->GetWebContentsAt(1)->GetURL(), test_url); + + std::unique_ptr<TestRenderViewContextMenu> menu = + CreateContextMenuMediaTypeNone(test_url, test_url); + + EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW)); + menu->ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW, 0); + ASSERT_EQ(tab_strip_model->count(), 2); + EXPECT_TRUE(tab_strip_model->GetTabAtIndex(0)->IsSplit()); + EXPECT_EQ(tab_strip_model->GetWebContentsAt(1)->GetURL(), test_url); +} + } // namespace
diff --git a/chrome/browser/resources/ash/settings/os_languages_page/os_japanese_dictionary_expand.html b/chrome/browser/resources/ash/settings/os_languages_page/os_japanese_dictionary_expand.html index 2c204f00..ee53bf0 100644 --- a/chrome/browser/resources/ash/settings/os_languages_page/os_japanese_dictionary_expand.html +++ b/chrome/browser/resources/ash/settings/os_languages_page/os_japanese_dictionary_expand.html
@@ -46,7 +46,7 @@ </cr-expand-button> <div class="separator"></div> <cr-icon-button class="icon-clear" - on-click="deleteDictionary_" + on-click="showDeleteDialog_" title="DeleteDictionary" > </cr-icon-button> @@ -86,3 +86,14 @@ </cr-button> </template> </iron-collapse> + +<template is="dom-if" if="[[showingDeleteDialog_]]" restamp> + <cr-dialog close-text="delete" show-on-attach> + <div slot="title">Delete this dictionary</div> + <div slot="body">[[dict.name]] will be permanently deleted. This action can't be undone</div> + <div slot="button-container"> + <cr-button class="cancel-button" on-click="hideDeleteDialog_">Cancel</cr-button> + <cr-button class="action-button" on-click="deleteDictionary_">Delete</cr-button> + </div> + </cr-dialog> +</template> \ No newline at end of file
diff --git a/chrome/browser/resources/ash/settings/os_languages_page/os_japanese_dictionary_expand.ts b/chrome/browser/resources/ash/settings/os_languages_page/os_japanese_dictionary_expand.ts index 37d9898..e666415b 100644 --- a/chrome/browser/resources/ash/settings/os_languages_page/os_japanese_dictionary_expand.ts +++ b/chrome/browser/resources/ash/settings/os_languages_page/os_japanese_dictionary_expand.ts
@@ -43,6 +43,9 @@ syncedEntriesCount: { type: Number, }, + showingDeleteDialog_: { + type: Boolean, + }, }; } @@ -56,6 +59,8 @@ // Whether or not this container UI is expanded or folded. private expanded_ = false; + private showingDeleteDialog_ = false; + // Adds a new entry locally to create an entry-row component. private addEntry_(): void { // This changes the entries array from the parent component which it will @@ -87,6 +92,15 @@ if (dictionarySaved) { this.dispatchSavedEvent_(); } + this.showingDeleteDialog_ = false; + } + + private hideDeleteDialog_() { + this.showingDeleteDialog_ = false; + } + + private showDeleteDialog_() { + this.showingDeleteDialog_ = true; } // Export dictionary.
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/BUILD.gn index aef67f6..dc5b2ab7 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/BUILD.gn +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/BUILD.gn
@@ -159,6 +159,7 @@ "log_page/log.ts", "log_page/log_loader.ts", "offscreen/offscreen.ts", + "offscreen/liblouis_worker.ts", "panel/i_search_ui.ts", "panel/menu_manager.ts", "panel/panel.ts",
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/background/braille/liblouis.ts b/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/background/braille/liblouis.ts index 5b73f87..17949a9 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/background/braille/liblouis.ts +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/background/braille/liblouis.ts
@@ -7,8 +7,19 @@ */ import {TestImportManager} from '/common/testing/test_import_manager.js'; +import {OffscreenCommandType} from '../../common/offscreen_command_type.js'; + type LoadCallback = (instance: LibLouis) => void; type MessageCallback = (message: Object) => void; +type SerializedMessageEvent = { + command: OffscreenCommandType, + data: string, +}; +type SerializedErrorEvent = { + command: OffscreenCommandType, + message: string, +}; + interface Dictionary { [key: string]: any; @@ -25,8 +36,6 @@ /** Next message ID to be used. Incremented with each sent message. */ private nextMessageId_ = 1; - worker?: Worker; - /** * @param wasmPath Path to .wasm file for the module. * @param tablesDir Path to tables directory. @@ -35,16 +44,27 @@ wasmPath: string, _tablesDir?: string, loadCallback?: LoadCallback) { this.wasmPath_ = wasmPath; - this.loadOrReload_(loadCallback); + chrome.runtime.onMessage + .addListener( + (message: any|undefined, _sender: chrome.runtime.MessageSender, + _sendResponse: (value: any) => void) => + this.handleMessageFromOffscreen_(message)) + + this.loadOrReload_(loadCallback); } - /** - * Convenience method to wait for the constructor to resolve its callback. - * @param wasmPath Path to .wasm file for the module. - * @param tablesDir Path to tables directory. - */ - static async create(wasmPath: string, tablesDir?: string): Promise<LibLouis> { - return new Promise(resolve => new LibLouis(wasmPath, tablesDir, resolve)); + private handleMessageFromOffscreen_(message: any|undefined): boolean { + switch (message['command']) { + case OffscreenCommandType.LIBLOUIS_MESSAGE: + this.onInstanceMessage_(message); + break; + case OffscreenCommandType.LIBLOUIS_ERROR: + this.onInstanceError_(message); + break; + } + // Returns false as the response is not asynchronous and the callback does + // not need to be kept alive. + return false; } isLoaded(): boolean { @@ -87,9 +107,6 @@ * @param callback Callback to receive the reply. */ rpc(command: string, message: Dictionary, callback: MessageCallback): void { - if (!this.worker) { - throw Error('Cannot send RPC: liblouis instance not loaded'); - } const messageId = '' + this.nextMessageId_++; message['message_id'] = messageId; message['command'] = command; @@ -97,25 +114,33 @@ if (LibLouis.DEBUG) { globalThis.console.debug('RPC -> ' + json); } - this.worker.postMessage(json); this.pendingRpcCallbacks_[messageId] = callback; + + chrome.runtime.sendMessage( + undefined, + {command: OffscreenCommandType.LIBLOUIS_RPC, messageJson: json}, + undefined, (error: any) => { + if (error && error.message) { + throw Error(error.message); + } + }); } /** Invoked when the Web Assembly instance successfully loads. */ private onInstanceLoad_(): void {} /** Invoked when the Web Assembly instance fails to load. */ - private onInstanceError_(e: ErrorEvent): void { - globalThis.console.error('Error in liblouis ' + e.message); + private onInstanceError_(serializedEvent: SerializedErrorEvent): void { + globalThis.console.error('Error in liblouis ' + serializedEvent.message); this.loadOrReload_(); } /** Invoked when the Web Assembly instance posts a message. */ - private onInstanceMessage_(e: MessageEvent): void { + private onInstanceMessage_(serializedEvent: SerializedMessageEvent): void { if (LibLouis.DEBUG) { - globalThis.console.debug('RPC <- ' + e.data); + globalThis.console.debug('RPC <- ' + serializedEvent.data); } - const message = /** @type {!Object} */ (JSON.parse(e.data)); + const message = /** @type {!Object} */ (JSON.parse(serializedEvent.data)); const messageId = message['in_reply_to']; if (messageId === undefined) { globalThis.console.warn( @@ -133,11 +158,11 @@ } private loadOrReload_(loadCallback?: LoadCallback): void { - this.worker = new Worker(this.wasmPath_); - this.worker.addEventListener( - 'message', e => this.onInstanceMessage_(e), false /* useCapture */); - this.worker.addEventListener( - 'error', e => this.onInstanceError_(e), false /* useCapture */); + chrome.runtime.sendMessage(undefined, { + command: OffscreenCommandType.LIBLOUIS_START_WORKER, + wasmPath: this.wasmPath_ + }); + this.rpc('load', {}, () => { this.isLoaded_ = true; loadCallback && loadCallback(this); @@ -193,7 +218,7 @@ translate( text: string, formTypeMap: number[]|number, callback: TranslateCallback): void { - if (!this.instance_.worker) { + if (!this.instance_.isLoaded()) { callback( null /*cells*/, null /*textToBraille*/, null /*brailleToText*/); return; @@ -236,7 +261,7 @@ * @param callback Callback for result. */ backTranslate(cells: ArrayBuffer, callback: BackTranslateCallback): void { - if (!this.instance_.worker) { + if (!this.instance_.isLoaded()) { callback(null /*text*/); return; }
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/background/braille/liblouis_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/background/braille/liblouis_test.js index c7a7b3a8..8720b89 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/background/braille/liblouis_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/background/braille/liblouis_test.js
@@ -15,9 +15,8 @@ async setUpDeferred() { await super.setUpDeferred(); - const path = chrome.runtime.getURL( - 'chromevox/third_party/liblouis/liblouis_wrapper.js'); - this.liblouis = await LibLouis.create(path, ''); + this.liblouis = BrailleTranslatorManager.instance.getLibLouisForTest(); + await new Promise((resolve) => this.waitForLibLouisLoad(resolve)); } async backTranslate(tableNames, buffer) { @@ -30,6 +29,14 @@ return new Promise( resolve => translator.translate(text, [], (...args) => resolve(args))); } + + async waitForLibLouisLoad(resolve) { + if (this.liblouis.isLoaded()) { + resolve() + } else { + setTimeout(() => this.waitForLibLouisLoad(resolve), 500); + } + } }; function assertEqualsUint8Array(expected, actual) {
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/common/offscreen_command_type.ts b/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/common/offscreen_command_type.ts index 6b80882..8ea174c 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/common/offscreen_command_type.ts +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/common/offscreen_command_type.ts
@@ -12,6 +12,10 @@ EARCON_CANCEL_PROGRESS = 'EarconCancelProgress', EARCON_RESET_PAN = 'EarconSesetPan', EARCON_SET_POSITION_FOR_RECT = 'EarconSetPositionForRect', + LIBLOUIS_START_WORKER = 'LibLouisStartWorker', + LIBLOUIS_RPC = 'LibLouisRPC', + LIBLOUIS_MESSAGE = 'LibLouisMessage', + LIBLOUIS_ERROR = 'LibLouisError', ON_CLIPBOARD_DATA_CHANGED = 'onClipboardDataChanged', ON_KEY_DOWN = 'onKeyDown', ON_KEY_UP = 'onKeyUp',
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/offscreen/liblouis_worker.ts b/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/offscreen/liblouis_worker.ts new file mode 100644 index 0000000..54107e19 --- /dev/null +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/offscreen/liblouis_worker.ts
@@ -0,0 +1,69 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {OffscreenCommandType} from '../common/offscreen_command_type.js'; + +type MessageSender = chrome.runtime.MessageSender; +type SendResponse = (value: any) => void; + +export class LibLouisWorker { + private worker_: Worker|null = null; + + static instance?: LibLouisWorker; + + constructor() { + chrome.runtime.onMessage.addListener( + (message: any|undefined, _sender: MessageSender, + sendResponse: SendResponse) => + this.handleMessageFromServiceWorker_(message, sendResponse)); + } + + private handleMessageFromServiceWorker_( + message: any|undefined, sendResponse: SendResponse): boolean { + switch (message['command']) { + case OffscreenCommandType.LIBLOUIS_START_WORKER: + this.startWorker_(message['wasmPath']); + break; + case OffscreenCommandType.LIBLOUIS_RPC: + if (!this.worker_) { + sendResponse( + {message: 'Cannot send RPC: liblouis worker not started.'}); + } else { + this.worker_.postMessage(message['messageJson']); + // No error. + sendResponse({}); + } + break; + } + return false; + } + + static init(): void { + if (LibLouisWorker.instance) { + throw 'Error: trying to create two instances of singleton ' + + 'LibLouisWorker.'; + } + LibLouisWorker.instance = new LibLouisWorker(); + } + + private startWorker_(wasmPath: string): void { + this.worker_ = new Worker(wasmPath); + this.worker_.addEventListener( + 'message', e => this.onInstanceMessage_(e), false /* useCapture */); + this.worker_.addEventListener( + 'error', e => this.onInstanceError_(e), false /* useCapture */); + } + + private onInstanceMessage_(e: MessageEvent): void { + chrome.runtime.sendMessage( + undefined, + {command: OffscreenCommandType.LIBLOUIS_MESSAGE, data: e.data}); + } + + private onInstanceError_(e: ErrorEvent): void { + chrome.runtime.sendMessage( + undefined, + {command: OffscreenCommandType.LIBLOUIS_ERROR, message: e.message}); + } +}
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/offscreen/offscreen.ts b/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/offscreen/offscreen.ts index 272bfe1..b54b367 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/offscreen/offscreen.ts +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/mv3/offscreen/offscreen.ts
@@ -6,6 +6,8 @@ import {InternalKeyEvent} from '../common/internal_key_event.js'; import {OffscreenCommandType} from '../common/offscreen_command_type.js'; +import {LibLouisWorker} from './liblouis_worker.js'; + type MessageSender = chrome.runtime.MessageSender; type SendResponse = (value: any) => void; @@ -195,3 +197,4 @@ OffscreenClipboardHandler.init(); OffscreenSpeechSynthesis.init(); EarconEngine.init(); +LibLouisWorker.init();
diff --git a/chrome/browser/resources/settings/glic_page/glic_page.ts b/chrome/browser/resources/settings/glic_page/glic_page.ts index 355029dd..dfe76caae 100644 --- a/chrome/browser/resources/settings/glic_page/glic_page.ts +++ b/chrome/browser/resources/settings/glic_page/glic_page.ts
@@ -94,6 +94,13 @@ }; } + static get observers() { + return [ + 'onTabContextEnabledChanged_(' + + `prefs.${SettingsGlicPageFeaturePrefName.TAB_CONTEXT_ENABLED}.value)`, + ]; + } + private shortcutInput_: string; private focusToggleShortcutInput_: string; private removedShortcut_: string|null = null; @@ -117,10 +124,6 @@ this.registeredFocusToggleShortcut_ = await this.browserProxy_.getGlicFocusToggleShortcut(); await CrSettingsPrefs.initialized; - this.tabAccessToggleExpanded_ = - this.getPref<boolean>( - SettingsGlicPageFeaturePrefName.TAB_CONTEXT_ENABLED) - .value; } private onGlicPageClick_() { @@ -222,10 +225,14 @@ } } + // Update the tab access collapsible any time the tab access pref changes. + private onTabContextEnabledChanged_(enabled: boolean) { + this.tabAccessToggleExpanded_ = enabled; + } + private onTabAccessToggleChange_(event: CustomEvent) { const target = event.target as SettingsToggleButtonElement; const enabled = target.checked; - this.tabAccessToggleExpanded_ = enabled; this.metricsBrowserProxy_.recordAction( 'Glic.Settings.TabContext' + (enabled ? '.Enabled' : '.Disabled')); }
diff --git a/chrome/browser/resources/side_panel/read_anything/app.ts b/chrome/browser/resources/side_panel/read_anything/app.ts index 2112914..ef181b2 100644 --- a/chrome/browser/resources/side_panel/read_anything/app.ts +++ b/chrome/browser/resources/side_panel/read_anything/app.ts
@@ -41,10 +41,6 @@ const linkDataAttribute = 'link'; -// The maximum speech length that should be used with remote voices -// due to a TTS engine bug with voices timing out on too-long text. -export const MAX_SPEECH_LENGTH: number = 175; - export interface AppElement { $: { toolbar: ReadAnythingToolbarElement, @@ -131,9 +127,6 @@ protected accessor localeToDisplayName_: {[locale: string]: string} = {}; - // Metrics captured for logging. - private playSessionStartTime: number = -1; - private notificationManager_ = VoiceNotificationManager.getInstance(); private logger_: ReadAnythingLogger = ReadAnythingLogger.getInstance(); private styleUpdater_: AppStyleUpdater; @@ -210,7 +203,6 @@ this.hasContent_ = false; this.firstTextNodeSetForReadAloud = null; this.nodeStore_.clearDomNodes(); - this.clearReadAloudState(); } this.settingsPrefs_ = { @@ -490,7 +482,7 @@ this.hasContent_ = false; if (this.isReadAloudEnabled_) { this.speech_.cancel(); - this.clearReadAloudState(); + this.speechController_.clearReadAloudState(); } } @@ -514,7 +506,7 @@ const previousWordBoundaryState = {...this.wordBoundaries_.state}; this.speech_.cancel(); - this.clearReadAloudState(); + this.speechController_.clearReadAloudState(); const container = this.$.container; // Remove all children from container. Use `replaceChildren` rather than @@ -894,11 +886,10 @@ protected onPlayPauseClick_() { if (this.speechController_.isSpeechActive()) { - this.logSpeechPlaySession_(); this.speechController_.stopSpeech(PauseActionSource.BUTTON_CLICK); } else { - this.playSessionStartTime = Date.now(); this.playSpeech(); + this.speechController_.onPlay(); } } @@ -919,12 +910,16 @@ this.previewVoicePlaying_ = this.speechController_.getPreviewVoicePlaying(); } - onPause() { - // Restore links if they're enabled when speech pauses. Don't restore links - // if it's paused from a non-pause button (e.g. voice previews) so the links - // don't flash off and on. - if (chrome.readingMode.linksEnabled && - this.speechController_.isPausedFromButton()) { + onStop() { + if (!chrome.readingMode.linksEnabled) { + return; + } + + // Restore links if they're enabled when speech pauses via button click or + // when it finishes the page. + const pauseSource = this.speechController_.getPauseSource(); + if ((pauseSource === PauseActionSource.BUTTON_CLICK) || + pauseSource === PauseActionSource.SPEECH_FINISHED) { this.updateLinks_(); } } @@ -944,16 +939,6 @@ this.resetSpeechPostSettingChange_(); } - private logSpeechPlaySession_() { - // Don't log a playback session just in case something has gotten out of - // sync and we call stopSpeech before playSpeech. - if (this.playSessionStartTime > 0) { - this.logger_.logSpeechPlaySession( - this.playSessionStartTime, this.selectedVoice_); - this.playSessionStartTime = -1; - } - } - protected playNextGranularity_() { this.speechController_.setIsSpeechBeingRepositioned(true); @@ -964,7 +949,7 @@ chrome.readingMode.movePositionToNextGranularity(); if (!this.highlightAndPlayMessage()) { - this.onSpeechFinished(); + this.speechController_.onSpeechFinished(); } } @@ -982,7 +967,7 @@ if (!this.highlightAndPlayMessage(/*isInterrupted=*/ false, /*isMovingBackward=*/ true)) { - this.onSpeechFinished(); + this.speechController_.onSpeechFinished(); } } @@ -1014,7 +999,7 @@ if (!this.highlightAndPlayInterruptedMessage()) { // Ensure we're updating Read Aloud state if there's no text to // speak. - this.onSpeechFinished(); + this.speechController_.onSpeechFinished(); } } } @@ -1061,7 +1046,7 @@ this.firstTextNodeSetForReadAloud); if (!this.highlightAndPlayMessage()) { // Ensure we're updating Read Aloud state if there's no text to speak. - this.onSpeechFinished(); + this.speechController_.onSpeechFinished(); } } } @@ -1143,7 +1128,7 @@ // includes the selection. this.highlighter_.resetPreviousHighlight(); if (!this.highlightAndPlayMessage()) { - this.onSpeechFinished(); + this.speechController_.onSpeechFinished(); } }, playFromSelectionTimeout); @@ -1220,31 +1205,6 @@ return this.highlightAndPlayMessage(isInterrupted, isMovingBackward); } - // Gets the accessible text boundary for the given string. - getAccessibleTextLength(utteranceText: string): number { - // Splicing on commas won't work for all locales, but since this is a - // simple strategy for splicing text in languages that do use commas - // that reduces the need for calling getAccessibleBoundary. - // TODO(crbug.com/40927698): Investigate if we can utilize comma splices - // directly in the utils methods called by #getAccessibleBoundary. - const lastCommaIndex = - utteranceText.substring(0, MAX_SPEECH_LENGTH).lastIndexOf(', '); - - // To prevent infinite looping, only use the lastCommaIndex if it's not the - // first character. Otherwise, use getAccessibleBoundary to prevent - // repeatedly splicing on the first comma of the same substring. - if (lastCommaIndex > 0) { - return lastCommaIndex; - } - - // TODO: crbug.com/40927698 - getAccessibleBoundary breaks on the nearest - // word boundary, but if there's some type of punctuation (such as a comma), - // it would be preferable to break on the punctuation so the pause in - // speech sounds more natural. - return chrome.readingMode.getAccessibleBoundary( - utteranceText, MAX_SPEECH_LENGTH); - } - private playText(utteranceText: string) { // This check is needed due limits of TTS audio for remote voices. See // crbug.com/1176078 for more details. @@ -1252,12 +1212,9 @@ // maximum text length if we're using a local voice. If we do somehow // attempt to speak text that's too long, this will be able to be handled // by listening for a text-too-long error in message.onerror. - const isTextTooLong = this.selectedVoice_?.localService ? - false : - utteranceText.length > MAX_SPEECH_LENGTH; - const endBoundary = isTextTooLong ? - this.getAccessibleTextLength(utteranceText) : - utteranceText.length; + const isTextTooLong = this.speechController_.isTextTooLong(utteranceText); + const endBoundary = this.speechController_.getUtteranceEndBoundary( + utteranceText, isTextTooLong); this.playTextWithBoundaries(utteranceText, isTextTooLong, endBoundary); } @@ -1290,7 +1247,7 @@ chrome.readingMode.movePositionToNextGranularity(); // Continue speaking with the next block of text. if (!this.highlightAndPlayMessage()) { - this.onSpeechFinished(); + this.speechController_.onSpeechFinished(); } }; @@ -1323,7 +1280,8 @@ // this is still preferable to no speech. this.speech_.cancel(); this.playTextWithBoundaries( - utteranceText, true, this.getAccessibleTextLength(utteranceText)); + utteranceText, true, + this.speechController_.getUtteranceEndBoundary(utteranceText, true)); return; } if (error.error === 'invalid-argument') { @@ -1374,24 +1332,6 @@ return utteranceText; } - private onSpeechFinished() { - this.logger_.logSpeechStopSource( - chrome.readingMode.contentFinishedStopSource); - this.clearReadAloudState(); - - // Show links when speech finishes playing. - if (chrome.readingMode.linksEnabled) { - this.updateLinks_(); - } - this.logSpeechPlaySession_(); - } - - private clearReadAloudState() { - this.speechController_.reset(); - this.highlighter_.clearHighlightFormatting(); - this.wordBoundaries_.resetToDefaultState(); - } - protected onSelectVoice_( event: CustomEvent<{selectedVoice: SpeechSynthesisVoice}>) { event.preventDefault();
diff --git a/chrome/browser/resources/side_panel/read_anything/read_aloud/speech_controller.ts b/chrome/browser/resources/side_panel/read_anything/read_aloud/speech_controller.ts index 9f02745..c081528 100644 --- a/chrome/browser/resources/side_panel/read_anything/read_aloud/speech_controller.ts +++ b/chrome/browser/resources/side_panel/read_anything/read_aloud/speech_controller.ts
@@ -17,8 +17,12 @@ import {WordBoundaries} from './word_boundaries.js'; import type {WordBoundaryState} from './word_boundaries.js'; +// The maximum speech length that should be used with remote voices +// due to a TTS engine bug with voices timing out on too-long text. +export const MAX_SPEECH_LENGTH: number = 175; + export interface SpeechListener { - onPause(): void; + onStop(): void; onIsSpeechActiveChange(): void; onIsAudioCurrentlyPlayingChange(): void; onEngineStateChange(): void; @@ -39,6 +43,7 @@ constructor() { // Send over the initial state. + this.clearReadAloudState(); this.isSpeechActiveChanged(this.isSpeechActive()); } @@ -151,6 +156,10 @@ chrome.readingMode.preprocessTextForSpeech(); } + onPlay() { + this.model_.setPlaySessionStartTime(Date.now()); + } + stopSpeech(pauseSource: PauseActionSource) { this.setIsSpeechActive(false); this.setIsAudioCurrentlyPlaying(false); @@ -166,13 +175,14 @@ // synth.pause() and synth.resume() for speech to resume from where it left // off. if (this.isPausedFromButton()) { + this.logSpeechPlaySession_(); this.speech_.pause(); } else { // Canceling clears all the Utterances that are queued up via synth.play() this.speech_.cancel(); } - this.listeners_.forEach(l => l.onPause()); + this.listeners_.forEach(l => l.onStop()); } setOnSpeechSynthesisUtteranceStart(message: SpeechSynthesisUtterance) { @@ -286,6 +296,21 @@ } } + onSpeechFinished() { + this.clearReadAloudState(); + this.model_.setPauseSource(PauseActionSource.SPEECH_FINISHED); + this.listeners_.forEach(l => l.onStop()); + this.logger_.logSpeechStopSource( + chrome.readingMode.contentFinishedStopSource); + this.logSpeechPlaySession_(); + } + + clearReadAloudState() { + this.reset(); + this.highlighter_.clearHighlightFormatting(); + this.wordBoundaries_.resetToDefaultState(); + } + setPreviousReadingPositionIfExists( previousWordBoundaryState: WordBoundaryState, previousSpeechPlayingState: SpeechPlayingState) { @@ -343,6 +368,39 @@ axNodeIds, scrollIntoView, shouldUpdateSentenceHighlight); } + isTextTooLong(text: string): boolean { + return !this.voicePackController_.getCurrentVoice()?.localService && + text.length > MAX_SPEECH_LENGTH; + } + + getUtteranceEndBoundary(text: string, isTextTooLong: boolean): number { + return isTextTooLong ? this.getAccessibleTextLength_(text) : text.length; + } + + // Gets the accessible text boundary for the given string. + private getAccessibleTextLength_(text: string): number { + // Splicing on commas won't work for all locales, but since this is a + // simple strategy for splicing text in languages that do use commas + // that reduces the need for calling getAccessibleBoundary. + // TODO(crbug.com/40927698): Investigate if we can utilize comma splices + // directly in the utils methods called by #getAccessibleBoundary. + const lastCommaIndex = + text.substring(0, MAX_SPEECH_LENGTH).lastIndexOf(', '); + + // To prevent infinite looping, only use the lastCommaIndex if it's not the + // first character. Otherwise, use getAccessibleBoundary to prevent + // repeatedly splicing on the first comma of the same substring. + if (lastCommaIndex > 0) { + return lastCommaIndex; + } + + // TODO: crbug.com/40927698 - getAccessibleBoundary breaks on the nearest + // word boundary, but if there's some type of punctuation (such as a comma), + // it would be preferable to break on the punctuation so the pause in + // speech sounds more natural. + return chrome.readingMode.getAccessibleBoundary(text, MAX_SPEECH_LENGTH); + } + private isSpeechActiveChanged(isSpeechActive: boolean) { this.listeners_.forEach(l => l.onIsSpeechActiveChange()); chrome.readingMode.onSpeechPlayingStateChanged(isSpeechActive); @@ -354,6 +412,15 @@ this.speech_.speak(message); } + private logSpeechPlaySession_() { + const startTime = this.model_.getPlaySessionStartTime(); + if (startTime) { + this.logger_.logSpeechPlaySession( + startTime, this.voicePackController_.getCurrentVoice()); + this.model_.setPlaySessionStartTime(null); + } + } + static getInstance(): SpeechController { return instance || (instance = new SpeechController()); }
diff --git a/chrome/browser/resources/side_panel/read_anything/read_aloud/speech_model.ts b/chrome/browser/resources/side_panel/read_anything/read_aloud/speech_model.ts index 709bb37..59f0769 100644 --- a/chrome/browser/resources/side_panel/read_anything/read_aloud/speech_model.ts +++ b/chrome/browser/resources/side_panel/read_anything/read_aloud/speech_model.ts
@@ -8,6 +8,7 @@ VOICE_PREVIEW, VOICE_SETTINGS_CHANGE, ENGINE_INTERRUPT, + SPEECH_FINISHED, } export interface SpeechPlayingState { @@ -67,6 +68,9 @@ // last position so we can check if it's still in the new page. private lastReadingPosition_: ReadingPosition|null = null; + // Used for logging play time. + private playSessionStartTime_: number|null = null; + reset(): void { this.speechPlayingState_ = { isSpeechTreeInitialized: false, @@ -80,6 +84,14 @@ this.previewVoicePlaying_ = null; } + getPlaySessionStartTime(): number|null { + return this.playSessionStartTime_; + } + + setPlaySessionStartTime(time: number|null): void { + this.playSessionStartTime_ = time; + } + getLastPosition(): ReadingPosition|null { return this.lastReadingPosition_; }
diff --git a/chrome/browser/resources/side_panel/read_anything/read_anything.ts b/chrome/browser/resources/side_panel/read_anything/read_anything.ts index 152287ef..f941149 100644 --- a/chrome/browser/resources/side_panel/read_anything/read_anything.ts +++ b/chrome/browser/resources/side_panel/read_anything/read_anything.ts
@@ -9,7 +9,6 @@ export {PageCallbackRouter} from '//resources/cr_components/color_change_listener/color_change_listener.mojom-webui.js'; export type {CrActionMenuElement} from '//resources/cr_elements/cr_action_menu/cr_action_menu.js'; export type {AppElement} from './app.js'; -export {MAX_SPEECH_LENGTH} from './app.js'; export {AppStyleUpdater} from './app_style_updater.js'; export {getCurrentSpeechRate, playFromSelectionTimeout, spinnerDebounceTimeout, ToolbarEvent} from './common.js'; export {getNewIndex, isArrow, isForwardArrow, isHorizontalArrow} from './keyboard_util.js'; @@ -24,7 +23,7 @@ export {MetricsBrowserProxy, MetricsBrowserProxyImpl, ReadAloudHighlightState, ReadAloudSettingsChange, ReadAnythingNewPage, ReadAnythingSettingsChange, ReadAnythingSpeechError, ReadAnythingVoiceType} from './metrics_browser_proxy.js'; export {NodeStore} from './node_store.js'; export {currentReadHighlightClass, previousReadHighlightClass, ReadAloudHighlighter} from './read_aloud/highlighter.js'; -export {SpeechController, SpeechListener} from './read_aloud/speech_controller.js'; +export {MAX_SPEECH_LENGTH, SpeechController, SpeechListener} from './read_aloud/speech_controller.js'; export {PauseActionSource, SpeechEngineState, SpeechModel} from './read_aloud/speech_model.js'; export {VoiceLanguageListener, VoicePackController} from './read_aloud/voice_pack_controller.js'; export {VoicePackModel} from './read_aloud/voice_pack_model.js';
diff --git a/chrome/browser/safe_browsing/android/BUILD.gn b/chrome/browser/safe_browsing/android/BUILD.gn index 58fd64ba..066d23e 100644 --- a/chrome/browser/safe_browsing/android/BUILD.gn +++ b/chrome/browser/safe_browsing/android/BUILD.gn
@@ -131,6 +131,7 @@ testonly = true resources_package = "org.chromium.chrome.browser.safe_browsing.settings" sources = [ + "java/src/org/chromium/chrome/browser/safe_browsing/AdvancedProtectionMediatorIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/safe_browsing/settings/EnhancedProtectionSettingsFragmentTest.java", "javatests/src/org/chromium/chrome/browser/safe_browsing/settings/SafeBrowsingSettingsFragmentTest.java", "javatests/src/org/chromium/chrome/browser/safe_browsing/settings/StandardProtectionSettingsFragmentTest.java", @@ -151,6 +152,7 @@ "//chrome/test/android:chrome_java_integration_test_support", "//components/browser_ui/settings/android:java", "//components/browser_ui/widget/android:java", + "//components/permissions/android:core_java", "//components/policy/android:policy_java_test_support", "//components/prefs/android:java", "//components/signin/public/android:java",
diff --git a/chrome/browser/safe_browsing/android/java/src/org/chromium/chrome/browser/safe_browsing/AdvancedProtectionMediator.java b/chrome/browser/safe_browsing/android/java/src/org/chromium/chrome/browser/safe_browsing/AdvancedProtectionMediator.java index f06b569..b1f39c50 100644 --- a/chrome/browser/safe_browsing/android/java/src/org/chromium/chrome/browser/safe_browsing/AdvancedProtectionMediator.java +++ b/chrome/browser/safe_browsing/android/java/src/org/chromium/chrome/browser/safe_browsing/AdvancedProtectionMediator.java
@@ -10,8 +10,10 @@ import androidx.fragment.app.Fragment; +import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.shared_preferences.SharedPreferencesManager; import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.ChromeSharedPreferences; import org.chromium.chrome.browser.privacy.settings.PrivacySettingsNavigation; @@ -49,6 +51,8 @@ mShouldShowMessageOnStartup = advancedProtectionSetting; } } + + recordStartupHistograms(provider); } public void destroy() { @@ -111,4 +115,11 @@ ChromePreferenceKeys.OS_ADVANCED_PROTECTION_SETTING_UPDATED_TIME, System.currentTimeMillis()); } + + private void recordStartupHistograms( + @Nullable OsAdditionalSecurityPermissionProvider provider) { + RecordHistogram.recordBooleanHistogram( + "SafeBrowsing.Android.AdvancedProtection.Enabled", + provider != null && provider.isAdvancedProtectionRequestedByOs()); + } }
diff --git a/chrome/browser/safe_browsing/android/java/src/org/chromium/chrome/browser/safe_browsing/AdvancedProtectionMediatorIntegrationTest.java b/chrome/browser/safe_browsing/android/java/src/org/chromium/chrome/browser/safe_browsing/AdvancedProtectionMediatorIntegrationTest.java new file mode 100644 index 0000000..83c70f36 --- /dev/null +++ b/chrome/browser/safe_browsing/android/java/src/org/chromium/chrome/browser/safe_browsing/AdvancedProtectionMediatorIntegrationTest.java
@@ -0,0 +1,66 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.safe_browsing; + +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; + +import org.chromium.base.test.util.Batch; +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.Features.DisableFeatures; +import org.chromium.base.test.util.HistogramWatcher; +import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.ChromeTabbedActivityTestRule; +import org.chromium.chrome.test.util.AdvancedProtectionTestRule; +import org.chromium.components.permissions.PermissionsAndroidFeatureList; + +/** Integration test for {@link AdvancedProtectionMediator}. */ +@RunWith(ChromeJUnit4ClassRunner.class) +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +@DisableFeatures(PermissionsAndroidFeatureList.OS_ADDITIONAL_SECURITY_PERMISSION_KILL_SWITCH) +@Batch(Batch.PER_CLASS) +public class AdvancedProtectionMediatorIntegrationTest { + @ClassRule + public static final AdvancedProtectionTestRule sAdvancedProtectionTestRule = + new AdvancedProtectionTestRule(); + + @Rule + public final ChromeTabbedActivityTestRule mActivityTestRule = + new ChromeTabbedActivityTestRule(); + + private static final String ADVANCED_PROTECTION_UMA = + "SafeBrowsing.Android.AdvancedProtection.Enabled"; + + @Before + public void setUp() { + sAdvancedProtectionTestRule.setIsAdvancedProtectionRequestedByOs(false); + } + + @Test + @MediumTest + public void testUmaOnStartup_AdvancedProtectionEnabled() { + sAdvancedProtectionTestRule.setIsAdvancedProtectionRequestedByOs(true); + HistogramWatcher watcher = + HistogramWatcher.newSingleRecordWatcher(ADVANCED_PROTECTION_UMA, true); + mActivityTestRule.startMainActivityOnBlankPage(); + watcher.pollInstrumentationThreadUntilSatisfied(); + } + + @Test + @MediumTest + public void testUmaOnStartup_AdvancedProtectionDisabled() { + sAdvancedProtectionTestRule.setIsAdvancedProtectionRequestedByOs(false); + HistogramWatcher watcher = + HistogramWatcher.newSingleRecordWatcher(ADVANCED_PROTECTION_UMA, false); + mActivityTestRule.startMainActivityOnBlankPage(); + watcher.pollInstrumentationThreadUntilSatisfied(); + } +}
diff --git a/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc b/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc index 430d58b..15a81484 100644 --- a/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc +++ b/chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc
@@ -174,7 +174,7 @@ if (service_->IsHashManuallyBlocklisted(request.digests().sha256())) return true; - for (auto bin_itr : request.archived_binary()) { + for (const auto& bin_itr : request.archived_binary()) { if (service_->IsHashManuallyBlocklisted(bin_itr.digests().sha256())) return true; }
diff --git a/chrome/browser/sessions/session_restore_delegate.cc b/chrome/browser/sessions/session_restore_delegate.cc index 92b7823..fd27913 100644 --- a/chrome/browser/sessions/session_restore_delegate.cc +++ b/chrome/browser/sessions/session_restore_delegate.cc
@@ -118,7 +118,7 @@ } else { std::vector<content::WebContents*> web_contents_vector; web_contents_vector.reserve(tabs.size()); - for (auto tab : tabs) { + for (const auto& tab : tabs) { CHECK(tab.contents()); web_contents_vector.push_back(tab.contents()); }
diff --git a/chrome/browser/speech/on_device_speech_recognition_impl.cc b/chrome/browser/speech/on_device_speech_recognition_impl.cc index e7a6511..16077071 100644 --- a/chrome/browser/speech/on_device_speech_recognition_impl.cc +++ b/chrome/browser/speech/on_device_speech_recognition_impl.cc
@@ -176,7 +176,7 @@ std::vector<std::string> accept_languages; language_prefs_->GetAcceptLanguagesList(&accept_languages); - for (auto accept_language : accept_languages) { + for (const auto& accept_language : accept_languages) { if (l10n_util::GetLanguage(base::ToLowerASCII(accept_language)) == l10n_util::GetLanguage(base::ToLowerASCII(language))) { return true;
diff --git a/chrome/browser/sync/android/fake_server_helper_android.cc b/chrome/browser/sync/android/fake_server_helper_android.cc index 3897d39..3962c2c 100644 --- a/chrome/browser/sync/android/fake_server_helper_android.cc +++ b/chrome/browser/sync/android/fake_server_helper_android.cc
@@ -18,13 +18,20 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/sync/sync_service_factory.h" +#include "components/data_sharing/public/group_data.h" #include "components/sync/base/data_type.h" #include "components/sync/base/time.h" +#include "components/sync/model/data_type_sync_bridge.h" +#include "components/sync/model/in_memory_metadata_change_list.h" +#include "components/sync/model/mutable_data_batch.h" +#include "components/sync/protocol/collaboration_group_specifics.pb.h" +#include "components/sync/protocol/entity_data.h" #include "components/sync/protocol/entity_specifics.pb.h" #include "components/sync/protocol/sync_entity.pb.h" #include "components/sync/protocol/sync_enums.pb.h" #include "components/sync/service/sync_service_impl.h" #include "components/sync/test/bookmark_entity_builder.h" +#include "components/sync/test/collaboration_group_util.h" #include "components/sync/test/entity_builder_factory.h" #include "components/sync/test/fake_server.h" #include "components/sync/test/fake_server_network_resources.h" @@ -402,3 +409,32 @@ reinterpret_cast<fake_server::FakeServer*>(fake_server); fake_server_ptr->RemoveCollaboration(collaboration_id); } + +static void JNI_FakeServerHelper_AddCollaborationGroupToFakeServer( + JNIEnv* env, + jlong fake_server, + std::string& collaboration_id) { + const data_sharing::GroupId group_id = + data_sharing::GroupId(collaboration_id); + const sync_pb::CollaborationGroupSpecifics collab_specifics = + collaboration_group_utils::MakeCollaborationGroupSpecifics( + group_id.value()); + + sync_pb::EntitySpecifics entity_specifics; + *entity_specifics.mutable_collaboration_group() = collab_specifics; + + sync_pb::SyncEntity::CollaborationMetadata metadata; + metadata.set_collaboration_id(collaboration_id); + + std::string client_tag = collab_specifics.collaboration_id(); + int64_t creation_time = + collab_specifics.changed_at_timestamp_millis_since_unix_epoch(); + int64_t update_time = creation_time; + + fake_server::FakeServer* fake_server_ptr = + reinterpret_cast<fake_server::FakeServer*>(fake_server); + fake_server_ptr->InjectEntity( + syncer::PersistentUniqueClientEntity::CreateFromSharedSpecificsForTesting( + "non_unique_name", client_tag, entity_specifics, creation_time, + update_time, metadata)); +}
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 0e9fa60..60d0906 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -420,7 +420,6 @@ "//chrome/browser/ui/page_info", "//chrome/browser/ui/page_info:impl", "//chrome/browser/ui/plus_addresses", - "//chrome/browser/ui/plus_addresses:impl", "//chrome/browser/ui/prefs", "//chrome/browser/ui/prefs:impl", "//chrome/browser/ui/safety_hub", @@ -4102,8 +4101,8 @@ "views/frame/multi_contents_resize_area.h", "views/frame/multi_contents_view.cc", "views/frame/multi_contents_view.h", - "views/frame/multi_contents_view_drag_entrypoint_controller.cc", - "views/frame/multi_contents_view_drag_entrypoint_controller.h", + "views/frame/multi_contents_view_drop_target_controller.cc", + "views/frame/multi_contents_view_drop_target_controller.h", "views/frame/native_browser_frame.h", "views/frame/native_browser_frame_factory.cc", "views/frame/native_browser_frame_factory.h",
diff --git a/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/SurfaceColorUpdateUtils.java b/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/SurfaceColorUpdateUtils.java index 6fa36ead..8665245a 100644 --- a/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/SurfaceColorUpdateUtils.java +++ b/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/SurfaceColorUpdateUtils.java
@@ -174,4 +174,18 @@ context, R.color.gm3_baseline_surface_container_highest_dark) : defaultBackground; } + + /** + * Returns the background color for the grid tab switcher message card based on the enabled flag + * and incognito. + * + * @param context {@link Context} used to retrieve colors. + * @return The background color. + */ + public static @ColorInt int getMessageCardBackgroundColor(Context context) { + // TODO(crbug.com/414404094): Add semantic color for incognito. + return useNewGtsSurfaceColor() + ? SemanticColorUtils.getColorSurfaceContainerLow(context) + : SemanticColorUtils.getCardBackgroundColor(context); + } }
diff --git a/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/SurfaceColorUpdateUtilsUnitTest.java b/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/SurfaceColorUpdateUtilsUnitTest.java index 49d6ec54..1c405959 100644 --- a/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/SurfaceColorUpdateUtilsUnitTest.java +++ b/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/SurfaceColorUpdateUtilsUnitTest.java
@@ -102,6 +102,12 @@ assertEquals( ContextCompat.getColor(mContext, R.color.gm3_baseline_surface_dim_dark), tabCardViewBackgroundColorIncognito); + + int messageCardBackgroundColor = + SurfaceColorUpdateUtils.getMessageCardBackgroundColor(mContext); + assertEquals( + SemanticColorUtils.getColorSurfaceContainerLow(mContext), + messageCardBackgroundColor); } @Test @@ -133,6 +139,11 @@ ContextCompat.getColor( mContext, R.color.gm3_baseline_surface_container_highest_dark), tabCardViewBackgroundColorIncognito); + + int messageCardBackgroundColor = + SurfaceColorUpdateUtils.getMessageCardBackgroundColor(mContext); + assertEquals( + SemanticColorUtils.getCardBackgroundColor(mContext), messageCardBackgroundColor); } @Test
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/VoiceToolbarButtonController.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/VoiceToolbarButtonController.java index 3e1ade8..90b2105d 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/VoiceToolbarButtonController.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/VoiceToolbarButtonController.java
@@ -77,8 +77,7 @@ /* supportsTinting= */ true, /* iphCommandBuilder= */ null, AdaptiveToolbarButtonVariant.VOICE, - /* tooltipTextResId= */ R.string.adaptive_toolbar_button_preference_voice_search, - /* showBackgroundHighlight= */ true); + /* tooltipTextResId= */ R.string.adaptive_toolbar_button_preference_voice_search); mTrackerSupplier = trackerSupplier; mVoiceSearchDelegate = voiceSearchDelegate; }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonController.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonController.java index a00f865..a9241d9 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonController.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonController.java
@@ -277,7 +277,6 @@ receivedButtonSpec.getButtonVariant(), receivedButtonSpec.getActionChipLabelResId(), receivedButtonSpec.getHoverTooltipTextId(), - receivedButtonSpec.shouldShowBackgroundHighlight(), receivedButtonSpec.hasErrorBadge())); } return mButtonData;
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonControllerTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonControllerTest.java index 104217bb..7fbcbb8 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonControllerTest.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/AdaptiveToolbarButtonControllerTest.java
@@ -97,8 +97,7 @@ /* iphCommandBuilder= */ null, /* isEnabled= */ true, AdaptiveToolbarButtonVariant.UNKNOWN, - /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ false); + /* tooltipTextResId= */ Resources.ID_NULL); mConfiguration.screenWidthDp = 420; doReturn(mProfile).when(mProfile).getOriginalProfile(); mProfileSupplier = new ObservableSupplierImpl<>(); @@ -473,7 +472,6 @@ variant, /* actionChipLabelResId= */ 0, /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ false, /* hasErrorBadge= */ false); } }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/OpenInBrowserButtonController.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/OpenInBrowserButtonController.java index 340d9e0..ec24c1b7 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/OpenInBrowserButtonController.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/OpenInBrowserButtonController.java
@@ -55,8 +55,7 @@ /* supportsTinting= */ true, /* iphCommandBuilder= */ null, AdaptiveToolbarButtonVariant.OPEN_IN_BROWSER, - /* tooltipTextResId= */ R.string.menu_open_in_product, - /* showBackgroundHighlight= */ true); + /* tooltipTextResId= */ R.string.menu_open_in_product); setShouldShowOnIncognitoTabs(true); mOpenInBrowserRunnable = openInBrowserRunnable; mTrackerSupplier = trackerSupplier;
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/OptionalNewTabButtonController.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/OptionalNewTabButtonController.java index 4348774..e89bf46 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/OptionalNewTabButtonController.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/OptionalNewTabButtonController.java
@@ -110,8 +110,7 @@ /* supportsTinting= */ true, /* iphCommandBuilder= */ null, AdaptiveToolbarButtonVariant.NEW_TAB, - /* tooltipTextResId= */ R.string.new_tab_title, - /* showBackgroundHighlight= */ true); + /* tooltipTextResId= */ R.string.new_tab_title); setShouldShowOnIncognitoTabs(true); mContext = context;
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/TranslateToolbarButtonController.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/TranslateToolbarButtonController.java index 2b0f736..dc373bb85 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/TranslateToolbarButtonController.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/adaptive/TranslateToolbarButtonController.java
@@ -49,8 +49,7 @@ /* supportsTinting= */ true, null, AdaptiveToolbarButtonVariant.TRANSLATE, - /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ true); + /* tooltipTextResId= */ Resources.ID_NULL); mTrackerSupplier = trackerSupplier; }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/BaseButtonDataProvider.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/BaseButtonDataProvider.java index 44ec4d5..570de2cb 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/BaseButtonDataProvider.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/BaseButtonDataProvider.java
@@ -53,8 +53,6 @@ * @param adaptiveButtonVariant Enum value of {@link AdaptiveToolbarButtonVariant}, used for * metrics. * @param tooltipTextResId String to show as a tooltip when the button is hovered over. - * @param showBackgroundHighlight Whether to use a custom background drawable to handle - * highlight and focus UI states. */ public BaseButtonDataProvider( Supplier<Tab> activeTabSupplier, @@ -65,8 +63,7 @@ boolean supportsTinting, @Nullable IphCommandBuilder iphCommandBuilder, @AdaptiveToolbarButtonVariant int adaptiveButtonVariant, - @StringRes int tooltipTextResId, - boolean showBackgroundHighlight) { + @StringRes int tooltipTextResId) { mActiveTabSupplier = activeTabSupplier; mModalDialogManager = modalDialogManager; if (mModalDialogManager != null) { @@ -103,8 +100,7 @@ /* iphCommandBuilder= */ iphCommandBuilder, /* isEnabled= */ true, adaptiveButtonVariant, - tooltipTextResId, - showBackgroundHighlight); + tooltipTextResId); } /**
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/BaseButtonDataProviderTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/BaseButtonDataProviderTest.java index 9a2921c..88d5cf0 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/BaseButtonDataProviderTest.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/BaseButtonDataProviderTest.java
@@ -60,10 +60,9 @@ contentDescription, actionChipLabelResId, supportsTinting, - null, + /* iphCommandBuilder= */ null, adaptiveButtonVariant, - Resources.ID_NULL, - false); + /* tooltipTextResId= */ Resources.ID_NULL); } @Override
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/ButtonData.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/ButtonData.java index 01211e40..ff2634e0 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/ButtonData.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/ButtonData.java
@@ -7,7 +7,6 @@ import android.graphics.drawable.Drawable; import android.view.View; -import androidx.annotation.DrawableRes; import androidx.annotation.StringRes; import org.chromium.build.annotations.NullMarked; @@ -31,13 +30,6 @@ /** Returns {@code true} if the button is supposed to be enabled and clickable. */ boolean isEnabled(); - /** Sets the background resource that will be used to highlight the button. */ - /* package */ void setBackgroundResource(@DrawableRes int resId); - - /** Gets the background resource that will be used to highlight the button. */ - @DrawableRes - /* package */ int getBackgroundResource(); - /** * Returns a {@link ButtonSpec} describing button properties which don't change often. When * feasible, a {@link ButtonDataProvider} should prefer to reuse a single {@code ButtonSpec} @@ -58,7 +50,6 @@ @AdaptiveToolbarButtonVariant private final int mButtonVariant; private final boolean mIsDynamicAction; @StringRes private final int mActionChipLabelResId; - private final boolean mShowBackgroundHighlight; @StringRes private final int mTooltipTextResId; private final boolean mHasErrorBadge; @@ -72,7 +63,6 @@ @AdaptiveToolbarButtonVariant int buttonVariant, int actionChipLabelResId, int tooltipTextResId, - boolean showBackgroundHighlight, boolean hasErrorBadge) { mDrawable = drawable; mOnClickListener = onClickListener; @@ -84,7 +74,6 @@ mIsDynamicAction = AdaptiveToolbarFeatures.isDynamicAction(mButtonVariant); mActionChipLabelResId = actionChipLabelResId; mTooltipTextResId = tooltipTextResId; - mShowBackgroundHighlight = showBackgroundHighlight; mHasErrorBadge = hasErrorBadge; } @@ -146,14 +135,6 @@ } /** - * Returns {@code true} if a background highlight on hover, keyboard focus, press etc. - * should be shown for the button. - */ - public boolean shouldShowBackgroundHighlight() { - return mShowBackgroundHighlight; - } - - /** * Returns {@code true} if the button has an error badge. False otherwise. The button's * height is increased to accommodate the larger icon when an error badge is present. */
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/ButtonDataImpl.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/ButtonDataImpl.java index 56f85650..184ced4 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/ButtonDataImpl.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/ButtonDataImpl.java
@@ -8,12 +8,10 @@ import android.graphics.drawable.Drawable; import android.view.View.OnClickListener; -import androidx.annotation.DrawableRes; import androidx.annotation.StringRes; import org.chromium.build.annotations.NullMarked; import org.chromium.build.annotations.Nullable; -import org.chromium.chrome.browser.toolbar.R; import org.chromium.chrome.browser.toolbar.adaptive.AdaptiveToolbarButtonVariant; import org.chromium.chrome.browser.user_education.IphCommandBuilder; @@ -24,7 +22,6 @@ public class ButtonDataImpl implements ButtonData { private boolean mCanShow; private boolean mIsEnabled; - private @DrawableRes int mBackgroundResId; private @SuppressWarnings("NullAway.Init") ButtonSpec mButtonSpec; @@ -39,8 +36,7 @@ @Nullable IphCommandBuilder iphCommandBuilder, boolean isEnabled, @AdaptiveToolbarButtonVariant int buttonVariant, - int tooltipTextResId, - boolean showBackgroundHighlight) { + int tooltipTextResId) { this( canShow, drawable, @@ -51,8 +47,7 @@ iphCommandBuilder, isEnabled, buttonVariant, - tooltipTextResId, - showBackgroundHighlight); + tooltipTextResId); } public ButtonDataImpl( @@ -65,13 +60,9 @@ @Nullable IphCommandBuilder iphCommandBuilder, boolean isEnabled, @AdaptiveToolbarButtonVariant int buttonVariant, - @StringRes int tooltipTextResId, - boolean showBackgroundHighlight) { + @StringRes int tooltipTextResId) { mCanShow = canShow; mIsEnabled = isEnabled; - if (showBackgroundHighlight) { - mBackgroundResId = R.drawable.default_icon_background; - } mButtonSpec = new ButtonSpec( drawable, @@ -83,7 +74,6 @@ buttonVariant, actionChipLabelResId, tooltipTextResId, - showBackgroundHighlight, /* hasErrorBadge= */ false); } @@ -98,16 +88,6 @@ } @Override - public void setBackgroundResource(@DrawableRes int resId) { - mBackgroundResId = resId; - } - - @Override - public int getBackgroundResource() { - return mBackgroundResId; - } - - @Override public ButtonSpec getButtonSpec() { return mButtonSpec; } @@ -138,7 +118,6 @@ currentSpec.getButtonVariant(), currentSpec.getActionChipLabelResId(), currentSpec.getHoverTooltipTextId(), - currentSpec.shouldShowBackgroundHighlight(), currentSpec.hasErrorBadge()); setButtonSpec(newSpec); } @@ -157,7 +136,6 @@ currentSpec.getButtonVariant(), newActionChipResourceId, currentSpec.getHoverTooltipTextId(), - currentSpec.shouldShowBackgroundHighlight(), currentSpec.hasErrorBadge()); setButtonSpec(newSpec); } @@ -176,7 +154,6 @@ currentSpec.getButtonVariant(), currentSpec.getActionChipLabelResId(), currentSpec.getHoverTooltipTextId(), - currentSpec.shouldShowBackgroundHighlight(), currentSpec.hasErrorBadge()); setButtonSpec(newSpec); }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonCoordinator.java index dafdac0f..d1d1304 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonCoordinator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonCoordinator.java
@@ -20,7 +20,6 @@ import org.chromium.base.supplier.Supplier; import org.chromium.build.annotations.NullMarked; import org.chromium.build.annotations.Nullable; -import org.chromium.chrome.browser.toolbar.R; import org.chromium.chrome.browser.toolbar.adaptive.AdaptiveToolbarFeatures; import org.chromium.chrome.browser.user_education.IphCommandBuilder; import org.chromium.chrome.browser.user_education.UserEducationHelper; @@ -175,12 +174,7 @@ // Reset background alpha, in case the IPH onDismiss callback doesn't fire. mMediator.setBackgroundAlpha(255); - if (buttonData != null) { - buttonData.setBackgroundResource( - isIncognito - ? R.drawable.optional_button_background_baseline - : R.drawable.optional_button_background); - } + mMediator.setIsIncognitoBranded(isIncognito); mMediator.updateButton(buttonData); }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonCoordinatorTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonCoordinatorTest.java index 8c6bbecd..41e10a3 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonCoordinatorTest.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonCoordinatorTest.java
@@ -210,7 +210,6 @@ AdaptiveToolbarButtonVariant.UNKNOWN, /* actionChipLabelResId= */ 0, /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ false, /* hasErrorBadge= */ true); ButtonDataImpl buttonData = new ButtonDataImpl(); buttonData.setButtonSpec(buttonSpec); @@ -238,8 +237,7 @@ mockIphCommandBuilder, /* isEnabled= */ isEnabled, AdaptiveToolbarButtonVariant.UNKNOWN, - /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ false); + /* tooltipTextResId= */ Resources.ID_NULL); View backgroundView = Mockito.mock(View.class); doReturn(View.VISIBLE).when(backgroundView).getVisibility(); @@ -276,8 +274,7 @@ mockIphCommandBuilder, /* isEnabled= */ isEnabled, AdaptiveToolbarButtonVariant.UNKNOWN, - /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ false); + /* tooltipTextResId= */ Resources.ID_NULL); View backgroundView = Mockito.mock(View.class); doReturn(View.GONE).when(backgroundView).getVisibility(); @@ -315,8 +312,7 @@ mockIphCommandBuilder, /* isEnabled= */ isEnabled, AdaptiveToolbarButtonVariant.UNKNOWN, - /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ false); + /* tooltipTextResId= */ Resources.ID_NULL); ArgumentCaptor<Runnable> onShowCallbackCaptor = ArgumentCaptor.forClass(Runnable.class); ArgumentCaptor<Runnable> onDismissCallbackCaptor = ArgumentCaptor.forClass(Runnable.class); @@ -361,8 +357,7 @@ mockIphCommandBuilder, /* isEnabled= */ isEnabled, AdaptiveToolbarButtonVariant.TEST_BUTTON, - /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ false); + /* tooltipTextResId= */ Resources.ID_NULL); mOptionalButtonCoordinator.updateButton(buttonData, /* isIncognito= */ false); @@ -402,8 +397,7 @@ mockIphCommandBuilder, /* isEnabled= */ isEnabled, AdaptiveToolbarButtonVariant.TEST_BUTTON, - /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ false); + /* tooltipTextResId= */ Resources.ID_NULL); mOptionalButtonCoordinator.updateButton(buttonData, /* isIncognito= */ false); @@ -443,8 +437,7 @@ mockIphCommandBuilder, /* isEnabled= */ isEnabled, AdaptiveToolbarButtonVariant.TEST_BUTTON, - /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ false); + /* tooltipTextResId= */ Resources.ID_NULL); mOptionalButtonCoordinator.updateButton(buttonData, /* isIncognito= */ false); @@ -471,8 +464,7 @@ /* iphCommandBuilder= */ null, /* isEnabled= */ true, AdaptiveToolbarButtonVariant.UNKNOWN, - /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ false); + /* tooltipTextResId= */ Resources.ID_NULL); // Call update button with an enabled button. mOptionalButtonCoordinator.updateButton(buttonData, /* isIncognito= */ false); @@ -513,7 +505,6 @@ AdaptiveToolbarButtonVariant.UNKNOWN, /* actionChipLabelResId= */ 0, /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ false, /* hasErrorBadge= */ false); ButtonDataImpl buttonData = new ButtonDataImpl(); buttonData.setButtonSpec(buttonSpec);
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonMediator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonMediator.java index d7badf8f9..8c1dd31 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonMediator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonMediator.java
@@ -44,6 +44,10 @@ mModel.set(OptionalButtonProperties.ICON_BACKGROUND_ALPHA, alpha); } + void setIsIncognitoBranded(boolean isIncognitoBranded) { + mModel.set(OptionalButtonProperties.IS_INCOGNITO_BRANDED, isIncognitoBranded); + } + public void setOnBeforeHideTransitionCallback(Runnable onBeforeHideTransitionCallback) { mModel.set( OptionalButtonProperties.ON_BEFORE_HIDE_TRANSITION_CALLBACK,
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonProperties.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonProperties.java index 7b12feb..fcb847d 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonProperties.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonProperties.java
@@ -25,6 +25,8 @@ public static final WritableObjectPropertyKey<ButtonData> BUTTON_DATA = new WritableObjectPropertyKey<>(/* skipEquality= */ true); public static final WritableBooleanPropertyKey IS_ENABLED = new WritableBooleanPropertyKey(); + public static final WritableBooleanPropertyKey IS_INCOGNITO_BRANDED = + new WritableBooleanPropertyKey(); public static final WritableObjectPropertyKey<Callback<Integer>> TRANSITION_STARTED_CALLBACK = new WritableObjectPropertyKey<>(); public static final WritableObjectPropertyKey<Callback<Integer>> TRANSITION_FINISHED_CALLBACK = @@ -46,6 +48,7 @@ public static final PropertyKey[] ALL_KEYS = { BUTTON_DATA, IS_ENABLED, + IS_INCOGNITO_BRANDED, TRANSITION_STARTED_CALLBACK, TRANSITION_FINISHED_CALLBACK, ON_BEFORE_HIDE_TRANSITION_CALLBACK,
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonView.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonView.java index 20bcb1e6..ffefe33 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonView.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonView.java
@@ -21,7 +21,6 @@ import android.transition.TransitionManager; import android.transition.TransitionSet; import android.util.AttributeSet; -import android.util.TypedValue; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; @@ -32,6 +31,7 @@ import android.widget.TextView; import androidx.annotation.DimenRes; +import androidx.annotation.DrawableRes; import androidx.annotation.IntDef; import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.widget.TooltipCompat; @@ -160,6 +160,14 @@ setPaddingRelative(paddingStart, getPaddingTop(), getPaddingEnd(), getPaddingBottom()); } + public void setIsIncognitoBranded(boolean isIncognitoBranded) { + @DrawableRes int backgroundDrawableRes = R.drawable.optional_button_background; + if (isIncognitoBranded) { + backgroundDrawableRes = R.drawable.optional_button_background_baseline; + } + mButton.setBackgroundResource(backgroundDrawableRes); + } + public void cancelTransition() { if (isRunningTransition()) { TransitionManager.endTransitions(mTransitionRoot); @@ -255,20 +263,6 @@ mButton.setEnabled(buttonData.isEnabled()); mActionChipLabel.setEnabled(buttonData.isEnabled()); - // Set circular highlight for optional button when button variant is profile, share, voice - // search and new tab. Set box highlight for the rest of button variants. - int resId = buttonData.getBackgroundResource(); - if (buttonData.getButtonSpec().shouldShowBackgroundHighlight() - && resId != Resources.ID_NULL) { - mButton.setBackgroundResource(resId); - } else { - TypedValue themeRes = new TypedValue(); - getContext() - .getTheme() - .resolveAttribute(R.attr.selectableItemBackground, themeRes, true); - mButton.setBackgroundResource(themeRes.resourceId); - } - // Set hover state tooltip text for optional toolbar buttons(e.g. share, voice search, new // tab and profile). if (buttonSpec.getHoverTooltipTextId() != ButtonSpec.INVALID_TOOLTIP_TEXT_ID
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonViewBinder.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonViewBinder.java index 4666c4b..3500862 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonViewBinder.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonViewBinder.java
@@ -44,6 +44,8 @@ } else if (OptionalButtonProperties.IS_ANIMATION_ALLOWED_PREDICATE.equals(propertyKey)) { view.setIsAnimationAllowedPredicate( model.get(OptionalButtonProperties.IS_ANIMATION_ALLOWED_PREDICATE)); + } else if (OptionalButtonProperties.IS_INCOGNITO_BRANDED.equals(propertyKey)) { + view.setIsIncognitoBranded(model.get(OptionalButtonProperties.IS_INCOGNITO_BRANDED)); } } }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonViewTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonViewTest.java index 419bb5b..49b924e 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonViewTest.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonViewTest.java
@@ -144,7 +144,6 @@ /* buttonVariant= */ AdaptiveToolbarButtonVariant.NEW_TAB, /* actionChipLabelResId= */ Resources.ID_NULL, /* tooltipTextResId= */ R.string.new_tab_title, - /* showBackgroundHighlight= */ true, /* hasErrorBadge= */ false); ButtonDataImpl buttonData = new ButtonDataImpl(); buttonData.setButtonSpec(buttonSpec); @@ -173,7 +172,6 @@ /* buttonVariant= */ AdaptiveToolbarButtonVariant.READER_MODE, /* actionChipLabelResId= */ Resources.ID_NULL, /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ false, /* hasErrorBadge= */ false); ButtonDataImpl buttonData = new ButtonDataImpl(); buttonData.setButtonSpec(buttonSpec); @@ -201,7 +199,6 @@ /* buttonVariant= */ AdaptiveToolbarButtonVariant.READER_MODE, /* actionChipLabelResId= */ actionChipLabelResId, /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ false, /* hasErrorBadge= */ false); ButtonDataImpl buttonData = new ButtonDataImpl(); buttonData.setButtonSpec(buttonSpec); @@ -228,7 +225,6 @@ /* buttonVariant= */ buttonVariant, 0, tooltipTextIdRes, - /* showBackgroundHighlight= */ true, /* hasErrorBadge= */ false); ButtonDataImpl buttonData = new ButtonDataImpl(); buttonData.setButtonSpec(buttonSpec); @@ -254,7 +250,6 @@ /* buttonVariant= */ AdaptiveToolbarButtonVariant.UNKNOWN, /* actionChipLabelResId= */ Resources.ID_NULL, /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ false, /* hasErrorBadge= */ false); ButtonDataImpl buttonData = new ButtonDataImpl(); buttonData.setButtonSpec(buttonSpec); @@ -827,7 +822,6 @@ originalButtonSpec.getButtonVariant(), originalButtonSpec.getActionChipLabelResId(), originalButtonSpec.getHoverTooltipTextId(), - originalButtonSpec.shouldShowBackgroundHighlight(), originalButtonSpec.hasErrorBadge())); mOptionalButtonView.updateButtonWithAnimation(readerModeButtonData);
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/OptionalBrowsingModeButtonControllerTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/OptionalBrowsingModeButtonControllerTest.java index e0e78685..3226eab 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/OptionalBrowsingModeButtonControllerTest.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/OptionalBrowsingModeButtonControllerTest.java
@@ -212,7 +212,6 @@ /* iphCommandBuilder= */ null, /* isEnabled= */ true, buttonVariant, - /* tooltipTextResId= */ Resources.ID_NULL, - /* showBackgroundHighlight= */ false); + /* tooltipTextResId= */ Resources.ID_NULL); } }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/PhoneCaptureStateTokenTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/PhoneCaptureStateTokenTest.java index 3b52e23..2133aa2 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/PhoneCaptureStateTokenTest.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/PhoneCaptureStateTokenTest.java
@@ -47,7 +47,16 @@ private static ButtonData makeButtonDate() { // Uses default equals impl, reference quality, to compare. Values do not matter. - return new ButtonDataImpl(false, null, null, "", false, null, false, 0, 0, false); + return new ButtonDataImpl( + /* canShow= */ false, + /* drawable= */ null, + /* onClickListener= */ null, + /* contentDescription= */ "", + /* supportsTinting= */ false, + /* iphCommandBuilder= */ null, + /* isEnabled= */ false, + /* buttonVariant= */ 0, + /* tooltipTextResId= */ 0); } @Before
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java index 3680c42..84f6604 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java
@@ -15,7 +15,6 @@ import android.content.Context; import android.content.res.ColorStateList; import android.util.AttributeSet; -import android.util.TypedValue; import android.view.View; import android.view.ViewStub; import android.view.accessibility.AccessibilityEvent; @@ -485,20 +484,10 @@ ButtonSpec buttonSpec = buttonData.getButtonSpec(); - // Set hover highlight for buttons requesting a custom highlight. Set - // box hover highlight for the rest of button variants. - if (buttonData.getButtonSpec().shouldShowBackgroundHighlight()) { - mOptionalButton.setBackgroundResource( - isIncognitoBranded() - ? R.drawable.default_icon_background_baseline - : R.drawable.default_icon_background); - } else { - TypedValue themeRes = new TypedValue(); - getContext() - .getTheme() - .resolveAttribute(R.attr.selectableItemBackground, themeRes, true); - mOptionalButton.setBackgroundResource(themeRes.resourceId); - } + mOptionalButton.setBackgroundResource( + isIncognitoBranded() + ? R.drawable.default_icon_background_baseline + : R.drawable.default_icon_background); // Set hover tooltip text for voice search, share and new tab button on tablets. if (buttonSpec.getHoverTooltipTextId() != ButtonSpec.INVALID_TOOLTIP_TEXT_ID) {
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTabletUnitTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTabletUnitTest.java index 02e07b1..2a2acab 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTabletUnitTest.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTabletUnitTest.java
@@ -410,7 +410,6 @@ /* buttonVariant= */ AdaptiveToolbarButtonVariant.READER_MODE, 0, 0, - false, /* hasErrorBadge= */ false); buttonData.setButtonSpec(buttonSpec); mToolbarTablet.updateOptionalButton(buttonData); @@ -429,7 +428,6 @@ /* buttonVariant= */ AdaptiveToolbarButtonVariant.SHARE, 0, R.string.adaptive_toolbar_button_preference_share, - true, /* hasErrorBadge= */ false); buttonData.setButtonSpec(buttonSpec); mToolbarTablet.updateOptionalButton(buttonData); @@ -451,7 +449,6 @@ /* buttonVariant= */ AdaptiveToolbarButtonVariant.VOICE, 0, R.string.adaptive_toolbar_button_preference_voice_search, - true, /* hasErrorBadge= */ false); buttonData.setButtonSpec(buttonSpec); mToolbarTablet.updateOptionalButton(buttonData); @@ -473,7 +470,6 @@ /* buttonVariant= */ AdaptiveToolbarButtonVariant.NEW_TAB, 0, R.string.new_tab_title, - true, /* hasErrorBadge= */ false); buttonData.setButtonSpec(buttonSpec); mToolbarTablet.updateOptionalButton(buttonData); @@ -501,7 +497,6 @@ /* buttonVariant= */ AdaptiveToolbarButtonVariant.READER_MODE, 0, 0, - false, /* hasErrorBadge= */ false); buttonData.setButtonSpec(buttonSpec); mToolbarTablet.updateOptionalButton(buttonData); @@ -530,7 +525,6 @@ /* buttonVariant= */ AdaptiveToolbarButtonVariant.SHARE, 0, 0, - false, /* hasErrorBadge= */ true); buttonData.setButtonSpec(buttonSpec); mToolbarTablet.updateOptionalButton(buttonData); @@ -674,7 +668,6 @@ /* buttonVariant= */ AdaptiveToolbarButtonVariant.NEW_TAB, 0, R.string.adaptive_toolbar_button_preference_new_tab, - true, /* hasErrorBadge= */ false); buttonData.setButtonSpec(buttonSpec); mToolbarTablet.updateOptionalButton(buttonData);
diff --git a/chrome/browser/ui/ash/capture_mode/sunfish_browsertest.cc b/chrome/browser/ui/ash/capture_mode/sunfish_browsertest.cc index dc2fe95..6dbfd601 100644 --- a/chrome/browser/ui/ash/capture_mode/sunfish_browsertest.cc +++ b/chrome/browser/ui/ash/capture_mode/sunfish_browsertest.cc
@@ -98,7 +98,8 @@ VerifyActiveBehavior(BehaviorType::kSunfish); // Simulate showing the panel while the session is active. - controller->ShowSearchResultsPanel(gfx::ImageSkia(), GURL("kTestUrl1")); + controller->ShowSearchResultsPanel(gfx::ImageSkia()); + controller->NavigateSearchResultsPanel(GURL("kTestUrl1")); ASSERT_TRUE(controller->IsActive()); auto* search_results_view = controller->GetSearchResultsPanel()->search_results_view(); @@ -157,7 +158,8 @@ VerifyActiveBehavior(BehaviorType::kSunfish); // Simulate showing the panel while the session is active. - controller->ShowSearchResultsPanel(gfx::ImageSkia(), GURL("kTestUrl1")); + controller->ShowSearchResultsPanel(gfx::ImageSkia()); + controller->NavigateSearchResultsPanel(GURL("kTestUrl1")); ASSERT_TRUE(controller->IsActive()); auto* search_results_view = controller->GetSearchResultsPanel()->search_results_view();
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 68389dd..0654215e 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -1907,6 +1907,11 @@ return window()->PreHandleMouseEvent(event); } +void Browser::PreHandleDragUpdate(const content::DropData& drop_data, + const gfx::PointF& client_pt) { + window()->PreHandleDragUpdate(drop_data, client_pt); +} + content::KeyboardEventProcessingResult Browser::PreHandleKeyboardEvent( content::WebContents* source, const NativeWebKeyboardEvent& event) {
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index 70de622..8722fba 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h
@@ -101,6 +101,7 @@ } namespace content { +struct DropData; class NavigationHandle; class SessionStorageNamespace; } // namespace content @@ -775,6 +776,8 @@ void SetFocusToLocationBar() override; bool PreHandleMouseEvent(content::WebContents* source, const blink::WebMouseEvent& event) override; + void PreHandleDragUpdate(const content::DropData& drop_data, + const gfx::PointF& client_pt) override; content::KeyboardEventProcessingResult PreHandleKeyboardEvent( content::WebContents* source, const input::NativeWebKeyboardEvent& event) override;
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index 6a94d43..3185b25 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h
@@ -529,7 +529,11 @@ // Allows the BrowserWindow object to handle the specified mouse event // before sending it to the renderer. virtual bool PreHandleMouseEvent(const blink::WebMouseEvent& event) = 0; - + // Allows the BrowserWindow object to handle a mouse drag update + // before sending it to the renderer. + // `point` is relative to the content view. + virtual void PreHandleDragUpdate(const content::DropData& drop_data, + const gfx::PointF& point) = 0; // Allows the BrowserWindow object to handle the specified keyboard event // before sending it to the renderer. virtual content::KeyboardEventProcessingResult PreHandleKeyboardEvent(
diff --git a/chrome/browser/ui/commerce/product_specifications_entry_point_controller.cc b/chrome/browser/ui/commerce/product_specifications_entry_point_controller.cc index 4865d8f..f7ad00c 100644 --- a/chrome/browser/ui/commerce/product_specifications_entry_point_controller.cc +++ b/chrome/browser/ui/commerce/product_specifications_entry_point_controller.cc
@@ -184,7 +184,8 @@ std::set<GURL> urls; auto candidate_products = current_entry_point_info_->similar_candidate_products; - for (auto url_info : shopping_service_->GetUrlInfosForActiveWebWrappers()) { + for (const auto& url_info : + shopping_service_->GetUrlInfosForActiveWebWrappers()) { if (base::Contains(candidate_products, url_info.url)) { urls.insert(url_info.url); }
diff --git a/chrome/browser/ui/global_media_controls/media_notification_service.cc b/chrome/browser/ui/global_media_controls/media_notification_service.cc index 6bb92e0..dd9c010 100644 --- a/chrome/browser/ui/global_media_controls/media_notification_service.cc +++ b/chrome/browser/ui/global_media_controls/media_notification_service.cc
@@ -340,8 +340,9 @@ // notification items and Remote Playback presentation routes should be shown // as media session notification items. std::optional<std::string> cast_presentation_route_id; - for (auto route : media_router::WebContentsPresentationManager::Get(contents) - ->GetMediaRoutes()) { + for (const auto& route : + media_router::WebContentsPresentationManager::Get(contents) + ->GetMediaRoutes()) { if (route.media_source().IsCastPresentationUrl()) { cast_presentation_route_id = route.media_route_id(); break;
diff --git a/chrome/browser/ui/hats/hats_service_desktop.cc b/chrome/browser/ui/hats/hats_service_desktop.cc index 2dcfc08..d60f599 100644 --- a/chrome/browser/ui/hats/hats_service_desktop.cc +++ b/chrome/browser/ui/hats/hats_service_desktop.cc
@@ -734,7 +734,7 @@ // trigger. If fields are set for a trigger, they must be provided. CHECK_EQ(product_specific_bits_data.size(), survey_config.product_specific_bits_data_fields.size()); - for (auto field_value : product_specific_bits_data) { + for (const auto& field_value : product_specific_bits_data) { CHECK(base::Contains(survey_config.product_specific_bits_data_fields, field_value.first)); } @@ -743,7 +743,7 @@ // trigger. If fields are set for a trigger, they must be provided. CHECK_EQ(product_specific_string_data.size(), survey_config.product_specific_string_data_fields.size()); - for (auto field_value : product_specific_string_data) { + for (const auto& field_value : product_specific_string_data) { CHECK(base::Contains(survey_config.product_specific_string_data_fields, field_value.first)); }
diff --git a/chrome/browser/ui/lens/BUILD.gn b/chrome/browser/ui/lens/BUILD.gn index f72e3f8..fea398e 100644 --- a/chrome/browser/ui/lens/BUILD.gn +++ b/chrome/browser/ui/lens/BUILD.gn
@@ -15,6 +15,7 @@ "lens_overlay_entry_point_controller.h", "lens_overlay_gen204_controller.h", "lens_overlay_image_helper.h", + "lens_searchbox_controller.h", "lens_overlay_side_panel_navigation_throttle.h", "lens_overlay_untrusted_ui.h", "lens_search_controller.h", @@ -44,7 +45,6 @@ "lens_permission_bubble_controller.h", "lens_preselection_bubble.h", "lens_search_contextualization_controller.h", - "lens_searchbox_controller.h", "page_content_type_conversions.h", "ref_counted_lens_overlay_client_logs.h", ]
diff --git a/chrome/browser/ui/lens/lens_overlay_controller.cc b/chrome/browser/ui/lens/lens_overlay_controller.cc index 620e377db..73c26c6a 100644 --- a/chrome/browser/ui/lens/lens_overlay_controller.cc +++ b/chrome/browser/ui/lens/lens_overlay_controller.cc
@@ -53,6 +53,7 @@ #include "chrome/browser/ui/lens/lens_permission_bubble_controller.h" #include "chrome/browser/ui/lens/lens_preselection_bubble.h" #include "chrome/browser/ui/lens/lens_search_controller.h" +#include "chrome/browser/ui/lens/lens_searchbox_controller.h" #include "chrome/browser/ui/lens/page_content_type_conversions.h" #include "chrome/browser/ui/search/omnibox_utils.h" #include "chrome/browser/ui/tabs/public/tab_features.h" @@ -63,7 +64,6 @@ #include "chrome/browser/ui/views/side_panel/side_panel_enums.h" #include "chrome/browser/ui/views/side_panel/side_panel_ui.h" #include "chrome/browser/ui/views/side_panel/side_panel_util.h" -#include "chrome/browser/ui/webui/util/image_util.h" #include "chrome/browser/ui/webui/webui_embedding_context.h" #include "chrome/common/chrome_render_frame.mojom.h" #include "chrome/common/pref_names.h" @@ -79,7 +79,6 @@ #include "components/optimization_guide/content/browser/page_content_proto_provider.h" #include "components/optimization_guide/content/browser/page_context_eligibility.h" #include "components/permissions/permission_request_manager.h" -#include "components/sessions/content/session_tab_helper.h" #include "components/signin/public/identity_manager/identity_manager.h" #include "components/tabs/public/tab_interface.h" #include "components/viz/common/frame_timing_details.h" @@ -95,7 +94,6 @@ #include "content/public/browser/web_contents_user_data.h" #include "content/public/browser/web_ui.h" #include "net/base/network_change_notifier.h" -#include "net/base/url_util.h" #include "pdf/buildflags.h" #include "services/metrics/public/cpp/ukm_builders.h" #include "services/metrics/public/cpp/ukm_source_id.h" @@ -145,9 +143,6 @@ // Currently 50 MB constexpr int kMaxDomTextLengthForOcrSimilarity = 50 * 1000 * 1000; -// The url query param key for the search query. -inline constexpr char kTextQueryParameterKey[] = "q"; - // Copy the objects of a vector into another without transferring // ownership. std::vector<lens::mojom::OverlayObjectPtr> CopyObjects( @@ -458,20 +453,6 @@ side_panel_ghost_loader_page_.Bind(std::move(page)); } -void LensOverlayController::SetSidePanelSearchboxHandler( - std::unique_ptr<LensSearchboxHandler> handler) { - side_panel_searchbox_handler_ = std::move(handler); -} - -void LensOverlayController::SetContextualSearchboxHandler( - std::unique_ptr<LensSearchboxHandler> handler) { - overlay_searchbox_handler_ = std::move(handler); -} - -void LensOverlayController::ResetSidePanelSearchboxHandler() { - side_panel_searchbox_handler_.reset(); -} - uint64_t LensOverlayController::GetInvocationTimeSinceEpoch() { return invocation_time_since_epoch_.InMillisecondsSinceUnixEpoch(); } @@ -555,18 +536,6 @@ return state_ == State::kClosing || state_ == State::kClosingSidePanel; } -bool LensOverlayController::IsContextualSearchbox() { - // TODO(crbug.com/405441183): This logic will break the side panel searchbox - // if there is no overlay, so it should be moved to a shared location. - return GetPageClassification() == - metrics::OmniboxEventProto::CONTEXTUAL_SEARCHBOX; -} - -void LensOverlayController::GetIsContextualSearchbox( - GetIsContextualSearchboxCallback callback) { - std::move(callback).Run(IsContextualSearchbox()); -} - bool LensOverlayController::IsScreenshotPossible( content::RenderWidgetHostView* view) { return view && view->IsSurfaceAvailableForCopy(); @@ -678,7 +647,7 @@ const std::string& source_language, const std::string& target_language) { // Remove the selection thumbnail, if it exists. - SetSearchboxThumbnail(std::string()); + GetLensSearchboxController()->SetSearchboxThumbnail(std::string()); ClearRegionSelection(); // Set the coachmark text. if (preselection_widget_) { @@ -865,11 +834,11 @@ } const GURL& LensOverlayController::GetPageURLForTesting() { - return GetPageURL(); + return lens_search_controller_->GetPageURL(); } SessionID LensOverlayController::GetTabIdForTesting() { - return GetTabId(); + return GetLensSearchboxController()->GetTabId(); } metrics::OmniboxEventProto::PageClassification @@ -878,19 +847,19 @@ } const std::string& LensOverlayController::GetThumbnailForTesting() { - return GetThumbnail(); + return GetLensSearchboxController()->GetThumbnail(); } void LensOverlayController::OnTextModifiedForTesting() { - OnTextModified(); + GetLensSearchboxController()->OnTextModified(); } void LensOverlayController::OnThumbnailRemovedForTesting() { - OnThumbnailRemoved(); + GetLensSearchboxController()->OnThumbnailRemoved(); } void LensOverlayController::OnFocusChangedForTesting(bool focused) { - OnFocusChanged(focused); + GetLensSearchboxController()->OnFocusChanged(focused); } void LensOverlayController::OnZeroSuggestShownForTesting() { @@ -1079,7 +1048,8 @@ // TODO(crbug.com/401583049): Revisit if this should go through the // OnSuggestionAccepted flow or if there should be a more direct contextual // search flow. - OnSuggestionAccepted(destination_url, match_type, is_zero_prefix_suggestion); + GetLensSearchboxController()->OnSuggestionAccepted( + destination_url, match_type, is_zero_prefix_suggestion); } void LensOverlayController::StartContextualizationWithoutOverlay( @@ -1139,36 +1109,27 @@ initialization_data_->selected_region_ = std::move(box); } -void LensOverlayController::SetSearchboxInputText(const std::string& text) { - if (side_panel_searchbox_handler_ && - side_panel_searchbox_handler_->IsRemoteBound()) { - side_panel_searchbox_handler_->SetInputText(text); - } else { - // If the side panel was not bound at the time of request, we store the - // query as pending to send it to the searchbox on bind. - pending_text_query_ = text; - } -} - -void LensOverlayController::SetSearchboxThumbnail( - const std::string& thumbnail_uri) { - if (side_panel_searchbox_handler_ && - side_panel_searchbox_handler_->IsRemoteBound()) { - side_panel_searchbox_handler_->SetThumbnail(thumbnail_uri); - selected_region_thumbnail_uri_ = thumbnail_uri; - } else { - // If the side panel was not bound at the time of request, we store the - // thumbnail as pending to send it to the searchbox on bind. - pending_thumbnail_uri_ = thumbnail_uri; - } -} - void LensOverlayController::SetAdditionalSearchQueryParams( std::map<std::string, std::string> additional_search_query_params) { initialization_data_->additional_search_query_params_ = additional_search_query_params; } +void LensOverlayController::ClearTextSelection() { + if (initialization_data_->selected_text_.has_value()) { + initialization_data_->selected_text_.reset(); + page_->ClearTextSelection(); + } +} + +void LensOverlayController::ClearRegionSelection() { + GetLensSearchboxController()->SetSearchboxThumbnail(""); + lens_selection_type_ = lens::UNKNOWN_SELECTION_TYPE; + initialization_data_->selected_region_.reset(); + initialization_data_->selected_region_bitmap_.reset(); + page_->ClearRegionSelection(); +} + void LensOverlayController::ClearAllSelections() { page_->ClearAllSelections(); initialization_data_->selected_region_.reset(); @@ -1179,13 +1140,64 @@ } } +void LensOverlayController::OnSearchboxFocusChanged(bool focused) { + if (!focused) { + return; + } + + if (IsContextualSearchbox()) { + if (!csb_session_end_metrics_.searchbox_focused_) { + // This is the first time the searchbox is focused in this session. + // Record the time between the overlay being invoked and the searchbox + // being focused. + lens::RecordContextualSearchboxTimeToFirstFocus( + base::TimeTicks::Now() - invocation_time_, + initialization_data_->primary_content_type_); + } else { + RecordContextualSearchboxTimeToFocusAfterNavigation(); + } + csb_session_end_metrics_.searchbox_focused_ = true; + + if (state() == State::kLivePageAndResults) { + // If the live page is showing and the searchbox becomes focused, showing + // intent to issue a new query, upload the new page content for + // contextualization. + TryUpdatePageContextualization(); + } + } +} + +void LensOverlayController::ShowGhostLoaderErrorState() { + if (!IsContextualSearchbox()) { + return; + } + if (overlay_ghost_loader_page_) { + overlay_ghost_loader_page_->ShowErrorState(); + } + if (side_panel_ghost_loader_page_) { + side_panel_ghost_loader_page_->ShowErrorState(); + } +} + +void LensOverlayController::OnZeroSuggestShown() { + if (!IsContextualSearchbox()) { + return; + } + + if (state() == State::kOverlay) { + csb_session_end_metrics_.zps_shown_on_initial_query_ = true; + } else { + csb_session_end_metrics_.zps_shown_on_follow_up_query_ = true; + } +} + void LensOverlayController::IssueLensRequest( lens::mojom::CenterRotatedBoxPtr region, lens::LensOverlaySelectionType selection_type, std::optional<SkBitmap> region_bytes) { CHECK(initialization_data_); CHECK(region); - SetSearchboxInputText(std::string()); + GetLensSearchboxController()->SetSearchboxInputText(std::string()); initialization_data_->selected_region_ = region.Clone(); initialization_data_->selected_text_.reset(); initialization_data_->additional_search_query_params_.clear(); @@ -1220,6 +1232,41 @@ } } +void LensOverlayController::IssueSearchBoxRequest( + const std::string& search_box_text, + AutocompleteMatchType::Type match_type, + bool is_zero_prefix_suggestion, + std::map<std::string, std::string> additional_query_params) { + // Log the interaction time here so the time to fetch new page bytes is not + // intcluded. + RecordContextualSearchboxTimeToInteractionAfterNavigation(); + RecordTimeToFirstInteraction( + lens::LensOverlayFirstInteractionType::kSearchbox); + + // Do not attempt to contextualize if CSB is disabled, if recontextualization + // on each query is disabled, if the live page is not being displayed, or if + // the user is not in the contextual search flow (aka, issues an image request + // already). + if (!lens::features::IsLensOverlayContextualSearchboxEnabled() || + !lens::features::ShouldLensOverlayRecontextualizeOnQuery() || + state() != State::kLivePageAndResults || !IsContextualSearchbox()) { + IssueSearchBoxRequestPart2(search_box_text, match_type, + is_zero_prefix_suggestion, + additional_query_params); + return; + } + + // If contextual searchbox is enabled, make sure the page bytes are current + // prior to issuing the search box request. + GetPageContextualization( + base::BindOnce(&LensOverlayController::UpdatePageContextualization, + weak_factory_.GetWeakPtr()) + .Then(base::BindOnce( + &LensOverlayController::IssueSearchBoxRequestPart2, + weak_factory_.GetWeakPtr(), search_box_text, match_type, + is_zero_prefix_suggestion, additional_query_params))); +} + void LensOverlayController::IssueContextualTextRequest( const std::string& text_query, lens::LensOverlaySelectionType selection_type) { @@ -1233,9 +1280,9 @@ void LensOverlayController::AddOverlayStateToSearchQuery( lens::SearchQuery& search_query) { // In the case where a query was triggered by a selection on the overlay or - // use of the searchbox, initialization_data_, additional_search_query_params_ - // and selected_region_thumbnail_uri_ will have already been set. Record - // that state in a search query struct. + // use of the searchbox, initialization_data_ and + // additional_search_query_params_ will have already been set. Record that + // state in a search query struct. if (initialization_data_->selected_region_) { search_query.selected_region_ = initialization_data_->selected_region_->Clone(); @@ -1244,7 +1291,6 @@ search_query.selected_region_bitmap_ = initialization_data_->selected_region_bitmap_; } - search_query.selected_region_thumbnail_uri_ = selected_region_thumbnail_uri_; if (initialization_data_->selected_text_.has_value()) { search_query.selected_text_ = initialization_data_->selected_text_.value(); } @@ -1449,7 +1495,7 @@ const auto& tab_url = tab_->GetContents()->GetLastCommittedURL(); auto bitmap_to_send = bitmap; - auto page_url = GetPageURL(); + auto page_url = lens_search_controller_->GetPageURL(); auto page_title = GetPageTitle(); if (!IsPageContextEligible( tab_url, {}, lens_search_controller_->page_context_eligibility())) { @@ -1517,8 +1563,8 @@ } auto initialization_data = std::make_unique<OverlayInitializationData>( - screenshot, std::move(rgb_screenshot), color_palette, GetPageURL(), - GetPageTitle()); + screenshot, std::move(rgb_screenshot), color_palette, + lens_search_controller_->GetPageURL(), GetPageTitle()); initialization_data->significant_region_boxes_ = ConvertSignificantRegionBoxes(all_bounds); initialization_data->last_retrieved_most_visible_page_ = pdf_current_page; @@ -2016,7 +2062,8 @@ is_first_upload_handler_event_ = true; lens_overlay_query_controller_->SendUpdatedPageContent( initialization_data_->page_contents_, - initialization_data_->primary_content_type_, GetPageURL(), GetPageTitle(), + initialization_data_->primary_content_type_, + lens_search_controller_->GetPageURL(), GetPageTitle(), initialization_data_->last_retrieved_most_visible_page_, sending_bitmap ? bitmap : SkBitmap()); @@ -2186,7 +2233,6 @@ } permission_bubble_controller_.reset(); - side_panel_searchbox_handler_.reset(); results_side_panel_coordinator_ = nullptr; side_panel_in_use_.reset(); pre_initialization_suggest_inputs_.reset(); @@ -2218,19 +2264,19 @@ page_.reset(); languages_controller_.reset(); scoped_tab_modal_ui_.reset(); - pending_text_query_.reset(); - pending_thumbnail_uri_.reset(); - selected_region_thumbnail_uri_.clear(); pending_region_.reset(); fullscreen_observation_.Reset(); immersive_mode_observer_.Reset(); lens_overlay_blur_layer_delegate_.reset(); - overlay_searchbox_handler_.reset(); last_navigation_time_.reset(); #if BUILDFLAG(IS_MAC) pref_change_registrar_.Reset(); #endif // BUILDFLAG(IS_MAC) + // Notify the searchbox controller to reset its handlers before the overlay + // is cleaned up. This is needed to prevent a dangling ptr. + GetLensSearchboxController()->ResetOverlaySearchboxHandler(); + // Cleanup all of the lens overlay related views. The overlay view is owned by // the browser view and is reused for each Lens overlay session. Clean it up // so it is ready for the next invocation. @@ -2320,8 +2366,9 @@ // original StartQueryFlow call. lens_overlay_query_controller_->SendUpdatedPageContent( initialization_data_->page_contents_, - initialization_data_->primary_content_type_, GetPageURL(), - GetPageTitle(), initialization_data_->last_retrieved_most_visible_page_, + initialization_data_->primary_content_type_, + lens_search_controller_->GetPageURL(), GetPageTitle(), + initialization_data_->last_retrieved_most_visible_page_, should_send_screenshot_on_init_ ? initialization_data_->initial_screenshot_ : SkBitmap()); @@ -2438,6 +2485,11 @@ lens::RecordInvocation(invocation_source_, initial_document_type_); } +bool LensOverlayController::IsContextualSearchbox() { + return lens_search_controller_->lens_searchbox_controller() + ->IsContextualSearchbox(); +} + raw_ptr<views::View> LensOverlayController::CreateViewForOverlay() { // Grab the host view for the overlay which is owned by the browser view. auto* host_view = tab_->GetBrowserWindowInterface()->LensOverlayView(); @@ -2634,32 +2686,10 @@ pending_suggest_inputs_callbacks_.Notify(GetLensSuggestInputs()); } -const GURL& LensOverlayController::GetPageURL() const { - if (lens::CanSharePageURLWithLensOverlay(pref_service_)) { - return tab_->GetContents()->GetVisibleURL(); - } - return GURL::EmptyGURL(); -} - -SessionID LensOverlayController::GetTabId() const { - return sessions::SessionTabHelper::IdForTab(tab_->GetContents()); -} - metrics::OmniboxEventProto::PageClassification LensOverlayController::GetPageClassification() const { - // There are two cases where we are assuming to be in a contextual flow: - // 1) We are in the zero state with the overlay CSB showing. - // 2) A user has made a contextual query and the live page is now showing. - if (state_ == State::kLivePageAndResults || state_ == State::kOverlay) { - return metrics::OmniboxEventProto::CONTEXTUAL_SEARCHBOX; - } - return selected_region_thumbnail_uri_.empty() - ? metrics::OmniboxEventProto::SEARCH_SIDE_PANEL_SEARCHBOX - : metrics::OmniboxEventProto::LENS_SIDE_PANEL_SEARCHBOX; -} - -std::string& LensOverlayController::GetThumbnail() { - return selected_region_thumbnail_uri_; + return lens_search_controller_->lens_searchbox_controller() + ->GetPageClassification(); } const lens::proto::LensOverlaySuggestInputs& @@ -2671,123 +2701,6 @@ : pre_initialization_suggest_inputs_.value(); } -void LensOverlayController::OnTextModified() { - if (initialization_data_->selected_text_.has_value()) { - initialization_data_->selected_text_.reset(); - page_->ClearTextSelection(); - } -} - -void LensOverlayController::ClearRegionSelection() { - selected_region_thumbnail_uri_.clear(); - lens_selection_type_ = lens::UNKNOWN_SELECTION_TYPE; - initialization_data_->selected_region_.reset(); - initialization_data_->selected_region_bitmap_.reset(); - page_->ClearRegionSelection(); -} - -void LensOverlayController::OnThumbnailRemoved() { - // This is called by the searchbox after the thumbnail is - // removed from there, so no need to manually replace the - // searchbox thumbnail uri here. - ClearRegionSelection(); -} - -void LensOverlayController::OnSuggestionAccepted( - const GURL& destination_url, - AutocompleteMatchType::Type match_type, - bool is_zero_prefix_suggestion) { - std::string query_text = ""; - std::map<std::string, std::string> additional_query_parameters; - - net::QueryIterator query_iterator(destination_url); - while (!query_iterator.IsAtEnd()) { - std::string_view key = query_iterator.GetKey(); - std::string_view value = query_iterator.GetUnescapedValue(); - if (kTextQueryParameterKey == key) { - query_text = value; - } else { - additional_query_parameters.insert(std::make_pair( - query_iterator.GetKey(), query_iterator.GetUnescapedValue())); - } - query_iterator.Advance(); - } - - IssueSearchBoxRequest(query_text, match_type, is_zero_prefix_suggestion, - additional_query_parameters); -} - -void LensOverlayController::OnFocusChanged(bool focused) { - if (!focused) { - return; - } - - if (IsContextualSearchbox()) { - if (!csb_session_end_metrics_.searchbox_focused_) { - // This is the first time the searchbox is focused in this session. - // Record the time between the overlay being invoked and the searchbox - // being focused. - lens::RecordContextualSearchboxTimeToFirstFocus( - base::TimeTicks::Now() - invocation_time_, - initialization_data_->primary_content_type_); - } else { - RecordContextualSearchboxTimeToFocusAfterNavigation(); - } - csb_session_end_metrics_.searchbox_focused_ = true; - - if (state() == State::kLivePageAndResults) { - // If the live page is showing and the searchbox becomes focused, showing - // intent to issue a new query, upload the new page content for - // contextualization. - TryUpdatePageContextualization(); - } - } -} - -void LensOverlayController::OnPageBound() { - // If the side panel closes before the remote gets bound, - // side_panel_searchbox_handler_ could become unset. Verify it is set before - // sending to the side panel. - if (!side_panel_searchbox_handler_ || - !side_panel_searchbox_handler_->IsRemoteBound()) { - return; - } - - // Send any pending inputs for the searchbox. - if (pending_text_query_.has_value()) { - side_panel_searchbox_handler_->SetInputText(*pending_text_query_); - pending_text_query_.reset(); - } - if (pending_thumbnail_uri_.has_value()) { - SetSearchboxThumbnail(*pending_thumbnail_uri_); - pending_thumbnail_uri_.reset(); - } -} - -void LensOverlayController::ShowGhostLoaderErrorState() { - if (!IsContextualSearchbox()) { - return; - } - if (overlay_ghost_loader_page_) { - overlay_ghost_loader_page_->ShowErrorState(); - } - if (side_panel_ghost_loader_page_) { - side_panel_ghost_loader_page_->ShowErrorState(); - } -} - -void LensOverlayController::OnZeroSuggestShown() { - if (!IsContextualSearchbox()) { - return; - } - - if (state() == State::kOverlay) { - csb_session_end_metrics_.zps_shown_on_initial_query_ = true; - } else { - csb_session_end_metrics_.zps_shown_on_follow_up_query_ = true; - } -} - base::CallbackListSubscription LensOverlayController::GetLensSuggestInputsWhenReady( LensOverlaySuggestInputsCallback callback) { @@ -3108,12 +3021,11 @@ int selection_end_index) { initialization_data_->selected_region_.reset(); initialization_data_->selected_region_bitmap_.reset(); - selected_region_thumbnail_uri_.clear(); initialization_data_->selected_text_ = std::make_pair(selection_start_index, selection_end_index); - SetSearchboxInputText(query); - SetSearchboxThumbnail(std::string()); + GetLensSearchboxController()->SetSearchboxInputText(query); + GetLensSearchboxController()->SetSearchboxThumbnail(std::string()); lens_overlay_query_controller_->SendTextOnlyQuery( query, lens_selection_type_, @@ -3235,41 +3147,6 @@ } } -void LensOverlayController::IssueSearchBoxRequest( - const std::string& search_box_text, - AutocompleteMatchType::Type match_type, - bool is_zero_prefix_suggestion, - std::map<std::string, std::string> additional_query_params) { - // Log the interaction time here so the time to fetch new page bytes is not - // intcluded. - RecordContextualSearchboxTimeToInteractionAfterNavigation(); - RecordTimeToFirstInteraction( - lens::LensOverlayFirstInteractionType::kSearchbox); - - // Do not attempt to contextualize if CSB is disabled, if recontextualization - // on each query is disabled, if the live page is not being displayed, or if - // the user is not in the contextual search flow (aka, issues an image request - // already). - if (!lens::features::IsLensOverlayContextualSearchboxEnabled() || - !lens::features::ShouldLensOverlayRecontextualizeOnQuery() || - state() != State::kLivePageAndResults || !IsContextualSearchbox()) { - IssueSearchBoxRequestPart2(search_box_text, match_type, - is_zero_prefix_suggestion, - additional_query_params); - return; - } - - // If contextual searchbox is enabled, make sure the page bytes are current - // prior to issuing the search box request. - GetPageContextualization( - base::BindOnce(&LensOverlayController::UpdatePageContextualization, - weak_factory_.GetWeakPtr()) - .Then(base::BindOnce( - &LensOverlayController::IssueSearchBoxRequestPart2, - weak_factory_.GetWeakPtr(), search_box_text, match_type, - is_zero_prefix_suggestion, additional_query_params))); -} - void LensOverlayController::IssueSearchBoxRequestPart2( const std::string& search_box_text, AutocompleteMatchType::Type match_type, @@ -3352,7 +3229,7 @@ // The searchbox text is set once the URL loads in the results frame, however, // adding it here allows the user to see the text query in the searchbox while // a long query loads. - SetSearchboxInputText(search_box_text); + GetLensSearchboxController()->SetSearchboxInputText(search_box_text); MaybeOpenSidePanel(); // Only set the side panel to loading if the page is context eligible because @@ -3477,13 +3354,6 @@ total > 0 ? static_cast<float>(position) / total : 1.0f); } -void LensOverlayController::HandleThumbnailCreated( - const std::string& thumbnail_bytes) { - selected_region_thumbnail_uri_ = - webui::MakeDataURIForImage(base::as_byte_span(thumbnail_bytes), "jpeg"); - SetSearchboxThumbnail(selected_region_thumbnail_uri_); -} - void LensOverlayController::RecordTimeToFirstInteraction( lens::LensOverlayFirstInteractionType interaction_type) { if (search_performed_in_session_) { @@ -3866,3 +3736,8 @@ ->UpdateEntryPointsState( /*hide_toolbar_entrypoint=*/false); } + +lens::LensSearchboxController* +LensOverlayController::GetLensSearchboxController() { + return lens_search_controller_->lens_searchbox_controller(); +}
diff --git a/chrome/browser/ui/lens/lens_overlay_controller.h b/chrome/browser/ui/lens/lens_overlay_controller.h index 01faf49..0df117a 100644 --- a/chrome/browser/ui/lens/lens_overlay_controller.h +++ b/chrome/browser/ui/lens/lens_overlay_controller.h
@@ -82,6 +82,7 @@ class LensOverlayQueryController; class LensOverlaySidePanelCoordinator; class LensPermissionBubbleController; +class LensSearchboxController; class LensOverlayEventHandler; struct SearchQuery; class SidePanelInUse; @@ -132,14 +133,10 @@ lens::MimeType primary_content_type, std::optional<uint32_t> pdf_page_count)>; -using GetIsContextualSearchboxCallback = - lens::mojom::LensSidePanelPageHandler::GetIsContextualSearchboxCallback; - // Manages all state associated with the lens overlay. // This class is not thread safe. It should only be used from the browser // thread. -class LensOverlayController : public LensSearchboxClient, - public lens::mojom::LensPageHandler, +class LensOverlayController : public lens::mojom::LensPageHandler, public content::WebContentsDelegate, public FullscreenObserver, public views::ViewObserver, @@ -194,24 +191,6 @@ void BindSidePanelGhostLoader( mojo::PendingRemote<lens::mojom::LensGhostLoaderPage> page); - // This method is used to set up communication between this instance and the - // searchbox WebUI. This is called by the WebUIController when the WebUI is - // executing javascript and has bound the handler. Takes ownership of - // `handler`. - void SetSidePanelSearchboxHandler( - std::unique_ptr<LensSearchboxHandler> handler); - - // Passes ownership of the lens serachbox handler to the search bubble - // controller. This is called by the WebUIController when the WebUI is - // executing javascript and has bound the handler. - void SetContextualSearchboxHandler( - std::unique_ptr<LensSearchboxHandler> handler); - - // This method is used to release the owned `SearchboxHandler`. It should be - // called before the embedding web contents is destroyed since it contains a - // reference to that web contents. - void ResetSidePanelSearchboxHandler(); - // Shows a toast in the side panel with the string provided in `message`. If // the side panel connection has not been established or was reset this is a // no-op. @@ -345,9 +324,6 @@ // Pass a result frame URL to load in the side panel. void LoadURLInResultsFrame(const GURL& url); - // Returns whether the searchbox is in contextual mode. - void GetIsContextualSearchbox(GetIsContextualSearchboxCallback callback); - // Whether it's possible to capture a screenshot. virtual for testing. virtual bool IsScreenshotPossible(content::RenderWidgetHostView* view); @@ -516,6 +492,7 @@ protected: friend class LensSearchController; + friend class lens::LensSearchboxController; friend class lens::LensOverlaySidePanelCoordinator; // This is entry point for showing the overlay UI. This has no effect if state @@ -587,27 +564,30 @@ // Sets the post region selection on the overlay. void SetPostRegionSelection(lens::mojom::CenterRotatedBoxPtr); - // Sets the input text for the searchbox. If the searchbox has not been bound, - // it stores it in `pending_text_query_` instead. - // TODO(crbug.com/404941800): This method should be removed once the searchbox - // is owned by the side panel or search controller. - void SetSearchboxInputText(const std::string& text); - - // Sets the thumbnail URI values on the searchbox if it is - // bound. If it hasn't yet been bound, stores the value in - // `pending_thumbnail_uri_` instead. - // TODO(crbug.com/404941800): This method should be removed once the searchbox - // is owned by the side panel or search controller. - void SetSearchboxThumbnail(const std::string& thumbnail_uri); - // Stores the additional query parameters to pass to the query controller for // generating urls, set by the search box. void SetAdditionalSearchQueryParams( std::map<std::string, std::string> additional_search_query_params); + // Clears the selected text from the overlay if there is any. + void ClearTextSelection(); + + // Clears the selected region. + void ClearRegionSelection(); + // Clears any selections currently made in the overlay. void ClearAllSelections(); + // Called by the searchbox controller when the focus on the searchbox changes. + void OnSearchboxFocusChanged(bool focused); + + // Called by the searchbox controller when the ghost loader error state should + // be shown. + void ShowGhostLoaderErrorState(); + + // Called by the searchbox controller when zero suggest is shown. + void OnZeroSuggestShown(); + // Makes a Lens request and updates all state related to the Lens request. If // region_bitmap is provided, it will use those bytes to send to the Lens // server instead of cropping the region from the full page screenshot. @@ -621,6 +601,13 @@ lens::LensOverlaySelectionType selection_type, std::optional<SkBitmap> region_bitmap); + // Tries to update the page content and then issues a searchbox request. + void IssueSearchBoxRequest( + const std::string& search_box_text, + AutocompleteMatchType::Type match_type, + bool is_zero_prefix_suggestion, + std::map<std::string, std::string> additional_query_params); + // Issues a contextual text request to the query controller. void IssueContextualTextRequest( const std::string& text_query, @@ -655,9 +642,6 @@ // to update the progress bar. void HandlePageContentUploadProgress(uint64_t position, uint64_t total); - // Handles the creation of a new thumbnail based on the user selection. - void HandleThumbnailCreated(const std::string& thumbnail_bytes); - private: // Data class for constructing overlay and storing overlay state for // kSuspended state. @@ -965,9 +949,6 @@ // Called when the UI needs to create the view to show in the overlay. raw_ptr<views::View> CreateViewForOverlay(); - // Clears the selected region. - void ClearRegionSelection(); - // content::WebContentsDelegate: bool HandleContextMenu(content::RenderFrameHost& render_frame_host, const content::ContextMenuParams& params) override; @@ -1006,23 +987,10 @@ // Called when the Lens backend handshake is complete. void OnHandshakeComplete(); - // Overridden from LensSearchboxClient: - const GURL& GetPageURL() const override; - SessionID GetTabId() const override; - metrics::OmniboxEventProto::PageClassification GetPageClassification() - const override; - std::string& GetThumbnail() override; - const lens::proto::LensOverlaySuggestInputs& GetLensSuggestInputs() - const override; - void OnTextModified() override; - void OnThumbnailRemoved() override; - void OnSuggestionAccepted(const GURL& destination_url, - AutocompleteMatchType::Type match_type, - bool is_zero_prefix_suggestion) override; - void OnFocusChanged(bool focused) override; - void OnPageBound() override; - void ShowGhostLoaderErrorState() override; - void OnZeroSuggestShown() override; + // Gets the page classification from the searchbox controller. + metrics::OmniboxEventProto::PageClassification GetPageClassification() const; + + const lens::proto::LensOverlaySuggestInputs& GetLensSuggestInputs() const; // Adds a callback to be called when the Lens backend handshake is finished. // If the handshake is already finished, the callback will be called @@ -1123,13 +1091,6 @@ int selection_start_index, int selection_end_index); - // Tries to update the page content and then issues a searchbox request. - void IssueSearchBoxRequest( - const std::string& search_box_text, - AutocompleteMatchType::Type match_type, - bool is_zero_prefix_suggestion, - std::map<std::string, std::string> additional_query_params); - // Handles a request (either region or multimodal) trigger by sending // the request to the query controller. void IssueSearchBoxRequestPart2( @@ -1198,6 +1159,9 @@ // points since the state of the overlay has changed. void UpdateEntryPointsState(); + // Shorthand to grab the LensSearchboxController for this instance of Lens. + lens::LensSearchboxController* GetLensSearchboxController(); + // Owns the LensSearchController which owns this class raw_ptr<tabs::TabInterface> tab_; @@ -1231,14 +1195,6 @@ // shown. See StartContextualizationWithoutOverlay todo for more details. bool should_show_overlay_ = true; - // A pending text query to be loaded in the side panel. Needed when the side - // panel is not bound at the time of a text request. - std::optional<std::string> pending_text_query_ = std::nullopt; - - // A pending thumbnail URI to be loaded in the side panel. Needed when the - // side panel is not bound at the time of a region request. - std::optional<std::string> pending_thumbnail_uri_ = std::nullopt; - // A contextual search request to be issued once the overlay is initialized. base::OnceClosure pending_contextual_search_request_; @@ -1255,11 +1211,6 @@ // side panel is done closing and the callback is invoked. std::optional<lens::LensOverlayDismissalSource> last_dismissal_source_; - // Thumbnail URI referencing the data defined by the user image selection on - // the overlay. If the user hasn't made any selection or has made a text - // selection this will contain an empty string. Returned by GetThumbnail(). - std::string selected_region_thumbnail_uri_; - // The selection type of the current Lens request. If the // user is not currently viewing results for a Lens query, this will be // set to UNKNOWN_SELECTION_TYPE. @@ -1467,29 +1418,6 @@ // requests to be sent upon query end. std::unique_ptr<lens::LensOverlayGen204Controller> gen204_controller_; - // Searchbox handler for passing in image and text selections. The handler is - // null if the WebUI containing the searchbox has not been initialized yet, - // like in the case of side panel opening. In addition, the handler may be - // initialized, but the remote not yet set because the WebUI calls SetPage() - // once it is ready to receive data from C++. Therefore, we must always check - // that: - // 1) searchbox_handler_ exists and - // 2) searchbox_handler_->IsRemoteBound() is true. - // TODO(crbug.com/404941800): This should be owned by the side panel - // coordinator (or maybe the LensSearchController?). However, this would - // require making the coordinator a LensSearchboxHandler, so it is to be done - // in its own CL. - std::unique_ptr<LensSearchboxHandler> side_panel_searchbox_handler_; - - // Handler for the contextual searchbox in the overlay. The handler is - // null if the WebUI containing the searchbox has not been initialized yet. - // In addition, the handler may be initialized, but the remote not yet set - // because the WebUI calls SetPage() once it is ready to receive data from - // C++. Therefore, we must always check that: - // 1) contextual_searchbox_handler_ exists and - // 2) contextual_searchbox_handler_->IsRemoteBound() is true. - std::unique_ptr<LensSearchboxHandler> overlay_searchbox_handler_; - // The controller for sending requests to get the list of supported languages. // Requests are only made if the WebUI has not already cached the languages // and none of the update cache conditions are met.
diff --git a/chrome/browser/ui/lens/lens_overlay_proto_converter.cc b/chrome/browser/ui/lens/lens_overlay_proto_converter.cc index ebb68f5..ecdddbe 100644 --- a/chrome/browser/ui/lens/lens_overlay_proto_converter.cc +++ b/chrome/browser/ui/lens/lens_overlay_proto_converter.cc
@@ -85,7 +85,7 @@ lens::mojom::PolygonPtr polygon = lens::mojom::Polygon::New(); std::vector<lens::mojom::VertexPtr> vertices; - for (auto vertex : proto_polygon.vertex()) { + for (const auto& vertex : proto_polygon.vertex()) { vertices.push_back(lens::mojom::Vertex::New(vertex.x(), vertex.y())); } polygon->vertex = std::move(vertices); @@ -133,7 +133,7 @@ geometry->bounding_box = std::move(center_rotated_box); std::vector<lens::mojom::PolygonPtr> polygons; - for (auto polygon : response_geometry.segmentation_polygon()) { + for (const auto& polygon : response_geometry.segmentation_polygon()) { polygons.push_back(CreatePolygonMojomFromProto(polygon)); } geometry->segmentation_polygon = std::move(polygons); @@ -170,7 +170,7 @@ lens::WritingDirection writing_direction) { lens::mojom::LinePtr line = lens::mojom::Line::New(); std::vector<lens::mojom::WordPtr> words; - for (auto word : proto_line.words()) { + for (const auto& word : proto_line.words()) { words.push_back( CreateWordMojomFromProto(word, region_crop_box, writing_direction)); } @@ -348,7 +348,7 @@ lens::mojom::ParagraphPtr paragraph = lens::mojom::Paragraph::New(); paragraph->content_language = proto_paragraph.content_language(); std::vector<lens::mojom::LinePtr> lines; - for (auto line : proto_paragraph.lines()) { + for (const auto& line : proto_paragraph.lines()) { lines.push_back(CreateLineMojomFromProto( line, region_crop_box, proto_paragraph.writing_direction())); } @@ -414,7 +414,7 @@ } auto response_objects = response.objects_response().overlay_objects(); - for (auto response_object : response_objects) { + for (const auto& response_object : response_objects) { if (!response_object.has_interaction_properties() || !response_object.interaction_properties().select_on_tap()) { continue;
diff --git a/chrome/browser/ui/lens/lens_overlay_side_panel_coordinator.cc b/chrome/browser/ui/lens/lens_overlay_side_panel_coordinator.cc index e8827807..575a285e 100644 --- a/chrome/browser/ui/lens/lens_overlay_side_panel_coordinator.cc +++ b/chrome/browser/ui/lens/lens_overlay_side_panel_coordinator.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/ui/lens/lens_overlay_side_panel_web_view.h" #include "chrome/browser/ui/lens/lens_overlay_url_builder.h" #include "chrome/browser/ui/lens/lens_search_controller.h" +#include "chrome/browser/ui/lens/lens_searchbox_controller.h" #include "chrome/browser/ui/lens/page_content_type_conversions.h" #include "chrome/browser/ui/tabs/public/tab_features.h" #include "chrome/browser/ui/views/side_panel/side_panel_content_proxy.h" @@ -192,7 +193,7 @@ // This is called from the destructor of the WebView. Synchronously clear all // state associated with the WebView. if (side_panel_web_view_) { - GetLensOverlayController()->ResetSidePanelSearchboxHandler(); + GetLensSearchboxController()->ResetSidePanelSearchboxHandler(); side_panel_web_view_ = nullptr; } } @@ -276,15 +277,16 @@ if (lens_mode.empty()) { GetLensOverlayController()->SetAdditionalSearchQueryParams( /*additional_search_query_params=*/{}); - GetLensOverlayController()->SetSearchboxThumbnail(""); + GetLensSearchboxController()->SetSearchboxThumbnail(""); GetLensOverlayController()->ClearAllSelections(); - GetLensOverlayController()->SetSearchboxThumbnail(std::string()); + GetLensSearchboxController()->SetSearchboxThumbnail(std::string()); } // Grab the current state of the overlay and use it to update populate the // query stack and currently loaded query. lens::SearchQuery search_query(query, search_url); GetLensOverlayController()->AddOverlayStateToSearchQuery(search_query); + GetLensSearchboxController()->AddSearchboxStateToSearchQuery(search_query); // Add what was the currently loaded search query to the query stack, // if it is present. @@ -299,7 +301,7 @@ initialization_data_->currently_loaded_search_query_ = search_query; // Update searchbox and selection state to match the new query. - GetLensOverlayController()->SetSearchboxInputText(query); + GetLensSearchboxController()->SetSearchboxInputText(query); } void LensOverlaySidePanelCoordinator::PopAndLoadQueryFromHistory() { if (initialization_data_->search_query_history_stack_.empty()) { @@ -337,8 +339,8 @@ } GetLensOverlayController()->SetAdditionalSearchQueryParams( query.additional_search_query_params_); - GetLensOverlayController()->SetSearchboxInputText(query.search_query_text_); - GetLensOverlayController()->SetSearchboxThumbnail( + GetLensSearchboxController()->SetSearchboxInputText(query.search_query_text_); + GetLensSearchboxController()->SetSearchboxThumbnail( query.selected_region_thumbnail_uri_); const bool is_contextual_query = @@ -406,7 +408,7 @@ void LensOverlaySidePanelCoordinator::GetIsContextualSearchbox( GetIsContextualSearchboxCallback callback) { - GetLensOverlayController()->GetIsContextualSearchbox(std::move(callback)); + GetLensSearchboxController()->GetIsContextualSearchbox(std::move(callback)); } void LensOverlaySidePanelCoordinator::RequestSendFeedback() {
diff --git a/chrome/browser/ui/lens/lens_overlay_side_panel_coordinator.h b/chrome/browser/ui/lens/lens_overlay_side_panel_coordinator.h index 6dcb705f..e6fedf6 100644 --- a/chrome/browser/ui/lens/lens_overlay_side_panel_coordinator.h +++ b/chrome/browser/ui/lens/lens_overlay_side_panel_coordinator.h
@@ -43,6 +43,7 @@ namespace lens { class LensOverlaySidePanelNavigationThrottle; +class LensSearchboxController; // Data struct representing a previous search query. struct SearchQuery { @@ -132,6 +133,11 @@ return lens_search_controller_->lens_overlay_controller(); } + // Return the LensSearchboxController that is part of this tab. + LensSearchboxController* GetLensSearchboxController() { + return lens_search_controller_->lens_searchbox_controller(); + } + // Handles rendering text highlights on the main browser window based on // navigations from the side panel. Returns true if handled, false otherwise. // `nav_url` refers to the URL that the side panel was set to navigate to. It
diff --git a/chrome/browser/ui/lens/lens_overlay_untrusted_ui.cc b/chrome/browser/ui/lens/lens_overlay_untrusted_ui.cc index 7c292b9..af9ce9f 100644 --- a/chrome/browser/ui/lens/lens_overlay_untrusted_ui.cc +++ b/chrome/browser/ui/lens/lens_overlay_untrusted_ui.cc
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. - #include "chrome/browser/ui/lens/lens_overlay_untrusted_ui.h" #include "base/strings/strcat.h" @@ -11,6 +10,8 @@ #include "chrome/browser/ui/browser_element_identifiers.h" #include "chrome/browser/ui/lens/lens_overlay_controller.h" #include "chrome/browser/ui/lens/lens_overlay_theme_utils.h" +#include "chrome/browser/ui/lens/lens_search_controller.h" +#include "chrome/browser/ui/lens/lens_searchbox_controller.h" #include "chrome/browser/ui/webui/searchbox/lens_searchbox_handler.h" #include "chrome/common/pref_names.h" #include "chrome/common/webui_url_constants.h" @@ -315,13 +316,14 @@ void LensOverlayUntrustedUI::BindInterface( mojo::PendingReceiver<searchbox::mojom::PageHandler> receiver) { - LensOverlayController& controller = GetLensOverlayController(); + LensSearchboxController* controller = + GetLensSearchController().lens_searchbox_controller(); auto handler = std::make_unique<LensSearchboxHandler>( std::move(receiver), Profile::FromWebUI(web_ui()), web_ui()->GetWebContents(), - /*metrics_reporter=*/nullptr, /*lens_searchbox_client=*/&controller); - controller.SetContextualSearchboxHandler(std::move(handler)); + /*metrics_reporter=*/nullptr, /*lens_searchbox_client=*/controller); + controller->SetContextualSearchboxHandler(std::move(handler)); } void LensOverlayUntrustedUI::BindInterface( @@ -339,6 +341,13 @@ help_bubble_handler_factory_receiver_.Bind(std::move(pending_receiver)); } +LensSearchController& LensOverlayUntrustedUI::GetLensSearchController() { + LensSearchController* controller = + LensSearchController::FromWebUIWebContents(web_ui()->GetWebContents()); + CHECK(controller); + return *controller; +} + LensOverlayController& LensOverlayUntrustedUI::GetLensOverlayController() { LensOverlayController* controller = LensOverlayController::FromWebUIWebContents(web_ui()->GetWebContents());
diff --git a/chrome/browser/ui/lens/lens_overlay_untrusted_ui.h b/chrome/browser/ui/lens/lens_overlay_untrusted_ui.h index f478dff..14a0b3b 100644 --- a/chrome/browser/ui/lens/lens_overlay_untrusted_ui.h +++ b/chrome/browser/ui/lens/lens_overlay_untrusted_ui.h
@@ -18,6 +18,7 @@ #include "ui/webui/resources/cr_components/help_bubble/help_bubble.mojom.h" #include "ui/webui/resources/cr_components/searchbox/searchbox.mojom-forward.h" +class LensSearchController; class LensOverlayController; namespace ui { @@ -81,6 +82,7 @@ static constexpr std::string GetWebUIName() { return "LensOverlayUntrusted"; } private: + LensSearchController& GetLensSearchController(); LensOverlayController& GetLensOverlayController(); // lens::mojom::LensPageHandlerFactory:
diff --git a/chrome/browser/ui/lens/lens_overlay_url_builder.cc b/chrome/browser/ui/lens/lens_overlay_url_builder.cc index 3bd6fe1..c3e35a7 100644 --- a/chrome/browser/ui/lens/lens_overlay_url_builder.cc +++ b/chrome/browser/ui/lens/lens_overlay_url_builder.cc
@@ -469,7 +469,7 @@ GURL RemoveIgnoredSearchURLParameters(const GURL& url) { GURL processed_url = url; - for (std::string query_param : kIgnoredSearchUrlQueryParameters) { + for (const std::string& query_param : kIgnoredSearchUrlQueryParameters) { processed_url = net::AppendOrReplaceQueryParameter( processed_url, query_param, std::nullopt); }
diff --git a/chrome/browser/ui/lens/lens_search_controller.cc b/chrome/browser/ui/lens/lens_search_controller.cc index fce4034..b6270577 100644 --- a/chrome/browser/ui/lens/lens_search_controller.cc +++ b/chrome/browser/ui/lens/lens_search_controller.cc
@@ -17,12 +17,20 @@ #include "chrome/browser/ui/lens/lens_searchbox_controller.h" #include "chrome/browser/ui/tabs/public/tab_features.h" #include "chrome/browser/ui/webui/webui_embedding_context.h" +#include "components/lens/lens_overlay_permission_utils.h" #include "components/omnibox/browser/autocomplete_match_type.h" #include "components/optimization_guide/content/browser/page_context_eligibility.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/geometry/rect.h" namespace { + +void CheckInitialized(bool initialized) { + CHECK(initialized) + << "The LensSearchController has not been initialized. Initialize() must " + "be called before using the LensSearchController."; +} + LensSearchController* GetLensSearchControllerFromTabInterface( tabs::TabInterface* tab_interface) { return tab_interface @@ -47,6 +55,7 @@ initialized_ = true; variations_client_ = variations_client; identity_manager_ = identity_manager; + pref_service_ = pref_service; theme_service_ = theme_service; // Create Gen204 controller first as query controller depends on it. @@ -80,9 +89,7 @@ void LensSearchController::OpenLensOverlay( lens::LensOverlayInvocationSource invocation_source) { - CHECK(initialized_) - << "The LensSearchController has not been initialized. Initialize() must " - "be called before using the LensSearchController."; + CheckInitialized(initialized_); // The UI should only show if the tab is in the foreground or if the tab web // contents is not in a crash state. @@ -246,30 +253,38 @@ return tab_; } +const GURL& LensSearchController::GetPageURL() const { + if (lens::CanSharePageURLWithLensOverlay(pref_service_)) { + return tab_->GetContents()->GetVisibleURL(); + } + return GURL::EmptyGURL(); +} + base::WeakPtr<LensSearchController> LensSearchController::GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } LensOverlayController* LensSearchController::lens_overlay_controller() { - CHECK(initialized_) << "The LensSearchController has not been initialized. " - "Initialize() must " - "be called before using the LensSearchController."; + CheckInitialized(initialized_); return lens_overlay_controller_.get(); } lens::LensOverlaySidePanelCoordinator* LensSearchController::lens_overlay_side_panel_coordinator() { - CHECK(initialized_) << "The LensSearchController has not been initialized. " - "Initialize() must " - "be called before using the LensSearchController."; + CheckInitialized(initialized_); + return lens_overlay_side_panel_coordinator_.get(); } +lens::LensSearchboxController* +LensSearchController::lens_searchbox_controller() { + CheckInitialized(initialized_); + return lens_searchbox_controller_.get(); +} + optimization_guide::PageContextEligibility* LensSearchController::page_context_eligibility() { - CHECK(initialized_) << "The LensSearchController has not been initialized. " - "Initialize() must " - "be called before using the LensSearchController."; + CheckInitialized(initialized_); if (page_context_eligibility_) { return page_context_eligibility_; } @@ -370,6 +385,8 @@ void LensSearchController::CloseLensPart2() { // Cleanup the query controller. lens_overlay_query_controller_.reset(); + // Let the controllers know to cleanup. + lens_searchbox_controller_->CloseUI(); state_ = State::kOff; } @@ -403,5 +420,5 @@ void LensSearchController::HandleThumbnailCreated( const std::string& thumbnail_bytes) { - lens_overlay_controller_->HandleThumbnailCreated(thumbnail_bytes); + lens_searchbox_controller_->HandleThumbnailCreated(thumbnail_bytes); }
diff --git a/chrome/browser/ui/lens/lens_search_controller.h b/chrome/browser/ui/lens/lens_search_controller.h index 4336b7c..d4beb3ca 100644 --- a/chrome/browser/ui/lens/lens_search_controller.h +++ b/chrome/browser/ui/lens/lens_search_controller.h
@@ -129,6 +129,9 @@ // Returns the tab interface that owns this controller. tabs::TabInterface* GetTabInterface(); + // Returns the page URL of the tab if Lens has access to it. + const GURL& GetPageURL() const; + // Returns the weak pointer to this class. base::WeakPtr<LensSearchController> GetWeakPtr(); @@ -141,6 +144,9 @@ // Returns the LensOverlaySidePanelCoordinator. lens::LensOverlaySidePanelCoordinator* lens_overlay_side_panel_coordinator(); + // Returns the LensSearchboxController. + lens::LensSearchboxController* lens_searchbox_controller(); + optimization_guide::PageContextEligibility* page_context_eligibility(); // Testing function for setting the page context eligibility API for this @@ -306,6 +312,10 @@ // incognito profiles. raw_ptr<signin::IdentityManager> identity_manager_; + // The pref service associated with the current profile. Owned by Profile, + // and thus guaranteed to outlive this instance. + raw_ptr<PrefService> pref_service_; + // The theme service associated with the current profile. Owned by Profile, // and thus guaranteed to outlive this instance. raw_ptr<ThemeService> theme_service_;
diff --git a/chrome/browser/ui/lens/lens_searchbox_controller.cc b/chrome/browser/ui/lens/lens_searchbox_controller.cc index d057ecde..b59c6ee27 100644 --- a/chrome/browser/ui/lens/lens_searchbox_controller.cc +++ b/chrome/browser/ui/lens/lens_searchbox_controller.cc
@@ -4,12 +4,22 @@ #include "chrome/browser/ui/lens/lens_searchbox_controller.h" +#include "chrome/browser/ui/lens/lens_overlay_controller.h" +#include "chrome/browser/ui/lens/lens_overlay_side_panel_coordinator.h" #include "chrome/browser/ui/lens/lens_search_controller.h" +#include "chrome/browser/ui/webui/util/image_util.h" #include "components/lens/proto/server/lens_overlay_response.pb.h" +#include "components/sessions/content/session_tab_helper.h" #include "components/sessions/core/session_id.h" +#include "net/base/url_util.h" #include "third_party/metrics_proto/omnibox_event.pb.h" #include "url/gurl.h" +namespace { +// The url query param key for the search query. +inline constexpr char kTextQueryParameterKey[] = "q"; +} // namespace + namespace lens { LensSearchboxController::LensSearchboxController( @@ -17,62 +27,197 @@ : lens_search_controller_(lens_search_controller) {} LensSearchboxController::~LensSearchboxController() = default; +void LensSearchboxController::SetSidePanelSearchboxHandler( + std::unique_ptr<LensSearchboxHandler> handler) { + side_panel_searchbox_handler_ = std::move(handler); +} + +void LensSearchboxController::SetContextualSearchboxHandler( + std::unique_ptr<LensSearchboxHandler> handler) { + overlay_searchbox_handler_ = std::move(handler); +} + +void LensSearchboxController::ResetOverlaySearchboxHandler() { + overlay_searchbox_handler_.reset(); +} + +void LensSearchboxController::ResetSidePanelSearchboxHandler() { + side_panel_searchbox_handler_.reset(); +} + +void LensSearchboxController::SetSearchboxInputText(const std::string& text) { + if (side_panel_searchbox_handler_ && + side_panel_searchbox_handler_->IsRemoteBound()) { + side_panel_searchbox_handler_->SetInputText(text); + } else { + // If the side panel was not bound at the time of request, we store the + // query as pending to send it to the searchbox on bind. + pending_text_query_ = text; + } +} + +void LensSearchboxController::SetSearchboxThumbnail( + const std::string& thumbnail_uri) { + if (side_panel_searchbox_handler_ && + side_panel_searchbox_handler_->IsRemoteBound()) { + side_panel_searchbox_handler_->SetThumbnail(thumbnail_uri); + selected_region_thumbnail_uri_ = thumbnail_uri; + } else { + // If the side panel was not bound at the time of request, we store the + // thumbnail as pending to send it to the searchbox on bind. + pending_thumbnail_uri_ = thumbnail_uri; + } +} + +void LensSearchboxController::HandleThumbnailCreated( + const std::string& thumbnail_bytes) { + selected_region_thumbnail_uri_ = + webui::MakeDataURIForImage(base::as_byte_span(thumbnail_bytes), "jpeg"); + SetSearchboxThumbnail(selected_region_thumbnail_uri_); +} + +void LensSearchboxController::CloseUI() { + overlay_searchbox_handler_.reset(); + side_panel_searchbox_handler_.reset(); + selected_region_thumbnail_uri_ = ""; + pending_text_query_ = std::nullopt; + pending_thumbnail_uri_ = std::nullopt; +} + +bool LensSearchboxController::IsContextualSearchbox() const { + // TODO(crbug.com/405441183): This logic will break the side panel searchbox + // if there is no overlay, so it should be moved to a shared location. + return GetPageClassification() == + metrics::OmniboxEventProto::CONTEXTUAL_SEARCHBOX; +} + +void LensSearchboxController::GetIsContextualSearchbox( + GetIsContextualSearchboxCallback callback) { + std::move(callback).Run(IsContextualSearchbox()); +} + const GURL& LensSearchboxController::GetPageURL() const { - // TODO(crbug.com/413138792): Implement this method. - return GURL::EmptyGURL(); + return lens_search_controller_->GetPageURL(); } SessionID LensSearchboxController::GetTabId() const { - // TODO(crbug.com/413138792): Implement this method. - return SessionID::InvalidValue(); + return sessions::SessionTabHelper::IdForTab(GetTabWebContents()); } metrics::OmniboxEventProto::PageClassification LensSearchboxController::GetPageClassification() const { - // TODO(crbug.com/413138792): Implement this method. - return metrics::OmniboxEventProto::INVALID_SPEC; + // There are two cases where we are assuming to be in a contextual flow: + // 1) We are in the zero state with the overlay CSB showing. + // 2) A user has made a contextual query and the live page is now showing. + // TODO(crbug.com/404941800): Remove dependency on LensOverlayController. + // Instead, it should check if contextualization is currently active. + const LensOverlayController::State state = + lens_search_controller_->lens_overlay_controller()->state(); + if (state == LensOverlayController::State::kLivePageAndResults || + state == LensOverlayController::State::kOverlay) { + return metrics::OmniboxEventProto::CONTEXTUAL_SEARCHBOX; + } + return selected_region_thumbnail_uri_.empty() + ? metrics::OmniboxEventProto::SEARCH_SIDE_PANEL_SEARCHBOX + : metrics::OmniboxEventProto::LENS_SIDE_PANEL_SEARCHBOX; } std::string& LensSearchboxController::GetThumbnail() { - // TODO(crbug.com/413138792): Implement this method. return selected_region_thumbnail_uri_; } const lens::proto::LensOverlaySuggestInputs& LensSearchboxController::GetLensSuggestInputs() const { - // TODO(crbug.com/413138792): Implement this method. - return lens::proto::LensOverlaySuggestInputs().default_instance(); + // TODO(crbug.com/413138792): Implement suggest inputs tracking in this class. + return lens_search_controller_->lens_overlay_controller() + ->GetLensSuggestInputs(); } void LensSearchboxController::OnTextModified() { - // TODO(crbug.com/413138792): Implement this method. + // TOOD(crbug.com/404941800): Verify this doesn't break if the overlay is + // off. + lens_search_controller_->lens_overlay_controller()->ClearTextSelection(); } void LensSearchboxController::OnThumbnailRemoved() { - // TODO(crbug.com/413138792): Implement this method. + // TOOD(crbug.com/404941800): Verify this doesn't break if the overlay is + // off. + lens_search_controller_->lens_overlay_controller()->ClearRegionSelection(); } void LensSearchboxController::OnSuggestionAccepted( const GURL& destination_url, AutocompleteMatchType::Type match_type, bool is_zero_prefix_suggestion) { - // TODO(crbug.com/413138792): Implement this method. + std::string query_text = ""; + std::map<std::string, std::string> additional_query_parameters; + + net::QueryIterator query_iterator(destination_url); + while (!query_iterator.IsAtEnd()) { + std::string_view key = query_iterator.GetKey(); + std::string_view value = query_iterator.GetUnescapedValue(); + if (kTextQueryParameterKey == key) { + query_text = value; + } else { + additional_query_parameters.insert(std::make_pair( + query_iterator.GetKey(), query_iterator.GetUnescapedValue())); + } + query_iterator.Advance(); + } + + // TODO(crbug.com/413138792): Move the logic to issue a searchbox query to + // this class. + lens_search_controller_->lens_overlay_controller()->IssueSearchBoxRequest( + query_text, match_type, is_zero_prefix_suggestion, + additional_query_parameters); } void LensSearchboxController::OnFocusChanged(bool focused) { - // TODO(crbug.com/413138792): Implement this method. + // TOOD(crbug.com/404941800): Implement OnSearchboxFocusChanged logic in this + // class. + lens_search_controller_->lens_overlay_controller()->OnSearchboxFocusChanged( + focused); } void LensSearchboxController::OnPageBound() { - // TODO(crbug.com/413138792): Implement this method. + // If the side panel closes before the remote gets bound, + // side_panel_searchbox_handler_ could become unset. Verify it is set before + // sending to the side panel. + if (!side_panel_searchbox_handler_ || + !side_panel_searchbox_handler_->IsRemoteBound()) { + return; + } + + // Send any pending inputs for the searchbox. + if (pending_text_query_.has_value()) { + side_panel_searchbox_handler_->SetInputText(*pending_text_query_); + pending_text_query_.reset(); + } + if (pending_thumbnail_uri_.has_value()) { + SetSearchboxThumbnail(*pending_thumbnail_uri_); + pending_thumbnail_uri_.reset(); + } } void LensSearchboxController::ShowGhostLoaderErrorState() { - // TODO(crbug.com/413138792): Implement this method. + // TODO(crbug.com/413138792): Move ghost loader handling logic to this class. + lens_search_controller_->lens_overlay_controller() + ->ShowGhostLoaderErrorState(); } void LensSearchboxController::OnZeroSuggestShown() { - // TODO(crbug.com/413138792): Implement this method. + // TODO(crbug.com/413138792): Move the OnZeroSuggestShown() logic to this + // class. + lens_search_controller_->lens_overlay_controller()->OnZeroSuggestShown(); +} + +content::WebContents* LensSearchboxController::GetTabWebContents() const { + return lens_search_controller_->GetTabInterface()->GetContents(); +} + +void LensSearchboxController::AddSearchboxStateToSearchQuery( + lens::SearchQuery& search_query) { + search_query.selected_region_thumbnail_uri_ = selected_region_thumbnail_uri_; } } // namespace lens
diff --git a/chrome/browser/ui/lens/lens_searchbox_controller.h b/chrome/browser/ui/lens/lens_searchbox_controller.h index d12faea..ff52349 100644 --- a/chrome/browser/ui/lens/lens_searchbox_controller.h +++ b/chrome/browser/ui/lens/lens_searchbox_controller.h
@@ -5,16 +5,24 @@ #ifndef CHROME_BROWSER_UI_LENS_LENS_SEARCHBOX_CONTROLLER_H_ #define CHROME_BROWSER_UI_LENS_LENS_SEARCHBOX_CONTROLLER_H_ +#include "chrome/browser/lens/core/mojom/lens_side_panel.mojom.h" #include "chrome/browser/ui/webui/searchbox/lens_searchbox_client.h" +#include "chrome/browser/ui/webui/searchbox/lens_searchbox_handler.h" #include "components/lens/proto/server/lens_overlay_response.pb.h" #include "components/sessions/core/session_id.h" +#include "content/public/browser/web_contents.h" #include "third_party/metrics_proto/omnibox_event.pb.h" #include "url/gurl.h" class LensSearchController; +using GetIsContextualSearchboxCallback = + lens::mojom::LensSidePanelPageHandler::GetIsContextualSearchboxCallback; + namespace lens { +struct SearchQuery; + // Controller for the Lens searchbox. This class is responsible for handling // communications between the Lens WebUI searchbox and other Lens components. // This class is responsible for both the overlay and side panel searchboxes. @@ -24,7 +32,51 @@ LensSearchController* lens_search_controller); ~LensSearchboxController() override; - private: + // This method is used to set up communication between this instance and the + // searchbox WebUI. This is called by the WebUIController when the WebUI is + // executing javascript and has bound the handler. Takes ownership of + // `handler`. + void SetSidePanelSearchboxHandler( + std::unique_ptr<LensSearchboxHandler> handler); + + // Passes ownership of the lens searchbox handler to the search bubble + // controller. This is called by the WebUIController when the WebUI is + // executing javascript and has bound the handler. + void SetContextualSearchboxHandler( + std::unique_ptr<LensSearchboxHandler> handler); + + // This method is used to release the owned `SearchboxHandler` for the + // overlay. It should be called before the overlay web contents is destroyed + // since it contains a reference to that web contents. + void ResetOverlaySearchboxHandler(); + + // This method is used to release the owned `SearchboxHandler`. It should be + // called before the side panel web contents is destroyed since it contains a + // reference to that web contents. + void ResetSidePanelSearchboxHandler(); + + // Sets the input text for the searchbox. If the searchbox has not been bound, + // it stores it in `pending_text_query_` instead. + void SetSearchboxInputText(const std::string& text); + + // Sets the thumbnail URI values on the searchbox if it is + // bound. If it hasn't yet been bound, stores the value in + // `pending_thumbnail_uri_` instead. + void SetSearchboxThumbnail(const std::string& thumbnail_uri); + + // Handles the creation of a new thumbnail based on the user selection. + void HandleThumbnailCreated(const std::string& thumbnail_bytes); + + // Cleans up internal state associated with the searchbox. + void CloseUI(); + + // Gets whether this is currently a contextual searchbox. + bool IsContextualSearchbox() const; + + // Returns whether the searchbox is in contextual mode by passing the result + // of IsContextualSearchbox() to the callback. + void GetIsContextualSearchbox(GetIsContextualSearchboxCallback callback); + // Overridden from LensSearchboxClient: const GURL& GetPageURL() const override; SessionID GetTabId() const override; @@ -43,11 +95,49 @@ void ShowGhostLoaderErrorState() override; void OnZeroSuggestShown() override; + // Adds searchbox related state to the search query. + void AddSearchboxStateToSearchQuery(lens::SearchQuery& search_query); + + // Returns the WebContents associated with the tab this instance of Lens is + // invoked on. + content::WebContents* GetTabWebContents() const; + // Owns this. const raw_ptr<LensSearchController> lens_search_controller_; - // TODO(crbug.com/413138792): Implement temporary placeholder. + // Searchbox handler for passing in image and text selections. The handler is + // null if the WebUI containing the searchbox has not been initialized yet, + // like in the case of side panel opening. In addition, the handler may be + // initialized, but the remote not yet set because the WebUI calls SetPage() + // once it is ready to receive data from C++. Therefore, we must always check + // that: + // 1) searchbox_handler_ exists and + // 2) searchbox_handler_->IsRemoteBound() is true. + std::unique_ptr<LensSearchboxHandler> side_panel_searchbox_handler_; + + // Handler for the contextual searchbox in the overlay. The handler is + // null if the WebUI containing the searchbox has not been initialized yet. + // In addition, the handler may be initialized, but the remote not yet set + // because the WebUI calls SetPage() once it is ready to receive data from + // C++. Therefore, we must always check that: + // 1) contextual_searchbox_handler_ exists and + // 2) contextual_searchbox_handler_->IsRemoteBound() is true. + // TODO(crbug.com/404941800): Does this actually need to be kept alive? Its + // currently unused. + std::unique_ptr<LensSearchboxHandler> overlay_searchbox_handler_; + + // Thumbnail URI referencing the data defined by the user image selection on + // the overlay. If the user hasn't made any selection or has made a text + // selection this will contain an empty string. Returned by GetThumbnail(). std::string selected_region_thumbnail_uri_; + + // A pending text query to be loaded in the side panel. Needed when the side + // panel is not bound at the time of a text request. + std::optional<std::string> pending_text_query_ = std::nullopt; + + // A pending thumbnail URI to be loaded in the side panel. Needed when the + // side panel is not bound at the time of a region request. + std::optional<std::string> pending_thumbnail_uri_ = std::nullopt; }; } // namespace lens
diff --git a/chrome/browser/ui/lens/lens_side_panel_untrusted_ui.cc b/chrome/browser/ui/lens/lens_side_panel_untrusted_ui.cc index 512add2..d604642c 100644 --- a/chrome/browser/ui/lens/lens_side_panel_untrusted_ui.cc +++ b/chrome/browser/ui/lens/lens_side_panel_untrusted_ui.cc
@@ -4,7 +4,6 @@ #include "chrome/browser/ui/lens/lens_side_panel_untrusted_ui.h" - #include "base/strings/strcat.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/themes/theme_service_factory.h" @@ -13,6 +12,7 @@ #include "chrome/browser/ui/lens/lens_overlay_side_panel_coordinator.h" #include "chrome/browser/ui/lens/lens_overlay_theme_utils.h" #include "chrome/browser/ui/lens/lens_search_controller.h" +#include "chrome/browser/ui/lens/lens_searchbox_controller.h" #include "chrome/browser/ui/webui/searchbox/lens_searchbox_handler.h" #include "chrome/common/pref_names.h" #include "chrome/grit/branded_strings.h" @@ -168,13 +168,14 @@ void LensSidePanelUntrustedUI::BindInterface( mojo::PendingReceiver<searchbox::mojom::PageHandler> receiver) { - LensOverlayController& controller = GetLensOverlayController(); + LensSearchboxController* controller = + GetLensSearchController().lens_searchbox_controller(); auto handler = std::make_unique<LensSearchboxHandler>( std::move(receiver), Profile::FromWebUI(web_ui()), web_ui()->GetWebContents(), - /*metrics_reporter=*/nullptr, /*lens_searchbox_client=*/&controller); - controller.SetSidePanelSearchboxHandler(std::move(handler)); + /*metrics_reporter=*/nullptr, /*lens_searchbox_client=*/controller); + controller->SetSidePanelSearchboxHandler(std::move(handler)); } void LensSidePanelUntrustedUI::BindInterface(
diff --git a/chrome/browser/ui/omnibox/chrome_omnibox_client.cc b/chrome/browser/ui/omnibox/chrome_omnibox_client.cc index 57f4deb6..06f5cc5 100644 --- a/chrome/browser/ui/omnibox/chrome_omnibox_client.cc +++ b/chrome/browser/ui/omnibox/chrome_omnibox_client.cc
@@ -59,8 +59,8 @@ #include "chrome/browser/ui/hats/hats_service.h" #include "chrome/browser/ui/hats/hats_service_factory.h" #include "chrome/browser/ui/layout_constants.h" -#include "chrome/browser/ui/lens/lens_overlay_controller.h" #include "chrome/browser/ui/lens/lens_search_controller.h" +#include "chrome/browser/ui/lens/lens_searchbox_controller.h" #include "chrome/browser/ui/location_bar/location_bar.h" #include "chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.h" #include "chrome/browser/ui/omnibox/omnibox_tab_helper.h" @@ -117,12 +117,6 @@ using predictors::AutocompleteActionPredictor; -LensOverlayController* GetLensOverlayController( - content::WebContents* web_contents) { - return web_contents ? LensOverlayController::FromTabWebContents(web_contents) - : nullptr; -} - LensSearchController* GetLensSearchController( content::WebContents* web_contents) { return web_contents ? LensSearchController::FromTabWebContents(web_contents) @@ -792,9 +786,10 @@ std::optional<lens::proto::LensOverlaySuggestInputs> ChromeOmniboxClient::GetLensOverlaySuggestInputs() const { - if (LensSearchboxClient* lens_overlay_controller = - GetLensOverlayController(location_bar_->GetWebContents())) { - return lens_overlay_controller->GetLensSuggestInputs(); + if (LensSearchController* lens_search_controller = + GetLensSearchController(location_bar_->GetWebContents())) { + return lens_search_controller->lens_searchbox_controller() + ->GetLensSuggestInputs(); } return std::nullopt; }
diff --git a/chrome/browser/ui/plus_addresses/BUILD.gn b/chrome/browser/ui/plus_addresses/BUILD.gn index 174e46a4..c7cc493d 100644 --- a/chrome/browser/ui/plus_addresses/BUILD.gn +++ b/chrome/browser/ui/plus_addresses/BUILD.gn
@@ -9,11 +9,10 @@ # TODO(crbug.com/413572035): Pull in android and views impl and test code. source_set("plus_addresses") { - sources = [ + public = [ "plus_address_creation_controller.h", "plus_address_creation_view.h", ] - public_deps = [ "//components/plus_addresses:types", "//content/public/browser", @@ -22,12 +21,11 @@ ] if (toolkit_views) { - sources += [ + public += [ "plus_address_creation_controller_desktop.h", "plus_address_error_dialog.h", "plus_address_menu_model.h", ] - public_deps += [ "//base", "//components/autofill/core/browser", @@ -37,44 +35,13 @@ "//ui/menus", ] - deps = [ - "//components/constrained_window", - "//components/plus_addresses/resources/strings", - "//components/plus_addresses/resources/strings:strings_grit", - ] - } -} - -source_set("impl") { - sources = [] - public_deps = [ - "//chrome/browser:browser_public_dependencies", - "//components/plus_addresses:types", - "//content/public/browser", - "//ui/base", - "//url", - ] - - if (toolkit_views) { - sources += [ + sources = [ "plus_address_error_dialog.cc", "plus_address_menu_model.cc", ] - - public_deps += [ - "//base", - "//components/autofill/core/browser", - "//components/autofill/core/common", - "//components/plus_addresses/metrics", - "//components/plus_addresses/settings", - "//ui/menus", - ] - deps = [ - ":plus_addresses", "//components/constrained_window", "//components/plus_addresses/resources/strings", - "//components/plus_addresses/resources/strings:strings_grit", ] } } @@ -91,7 +58,6 @@ defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] deps = [ ":plus_addresses", - "//base", "//base/test:test_support", "//chrome/browser/plus_addresses", "//chrome/test:test_support", @@ -129,12 +95,9 @@ "//components/plus_addresses:features", "//components/plus_addresses:prefs", "//components/plus_addresses:test_support", - "//components/plus_addresses:types", - "//components/plus_addresses/metrics", "//components/plus_addresses/settings:test_support", "//components/signin/public/identity_manager:test_support", "//components/sync_preferences:test_support", - "//content/public/browser", "//content/test:test_support", "//testing/gmock", "//testing/gtest",
diff --git a/chrome/browser/ui/safety_hub/notification_permission_review_service.cc b/chrome/browser/ui/safety_hub/notification_permission_review_service.cc index 9dc5c31..2f9d813a 100644 --- a/chrome/browser/ui/safety_hub/notification_permission_review_service.cc +++ b/chrome/browser/ui/safety_hub/notification_permission_review_service.cc
@@ -118,7 +118,7 @@ std::set<ContentSettingsPattern> NotificationPermissionsReviewService:: NotificationPermissionsResult::GetOrigins() const { std::set<ContentSettingsPattern> origins; - for (NotificationPermissions permission : notification_permissions_) { + for (const auto& permission : notification_permissions_) { origins.insert(permission.primary_pattern); } return origins; @@ -134,7 +134,7 @@ NotificationPermissionsResult::ToDictValue() const { base::Value::Dict result = BaseToDictValue(); base::Value::List notification_permissions; - for (NotificationPermissions permission : notification_permissions_) { + for (const auto& permission : notification_permissions_) { base::Value::Dict permission_dict; permission_dict.Set(kSafetyHubOriginKey, permission.primary_pattern.ToString());
diff --git a/chrome/browser/ui/safety_hub/revoked_permissions_service.cc b/chrome/browser/ui/safety_hub/revoked_permissions_service.cc index 68b8ba9..f407ce2 100644 --- a/chrome/browser/ui/safety_hub/revoked_permissions_service.cc +++ b/chrome/browser/ui/safety_hub/revoked_permissions_service.cc
@@ -269,7 +269,7 @@ std::set<ContentSettingsPattern> RevokedPermissionsService::RevokedPermissionsResult::GetRevokedOrigins() const { std::set<ContentSettingsPattern> origins; - for (auto permission : revoked_permissions_) { + for (const auto& permission : revoked_permissions_) { origins.insert(permission.primary_pattern); } return origins; @@ -279,7 +279,7 @@ RevokedPermissionsService::RevokedPermissionsResult::ToDictValue() const { base::Value::Dict result = BaseToDictValue(); base::Value::List revoked_origins; - for (auto permission : revoked_permissions_) { + for (const auto& permission : revoked_permissions_) { revoked_origins.Append(permission.primary_pattern.ToString()); } result.Set(kRevokedPermissionsResultKey, std::move(revoked_origins));
diff --git a/chrome/browser/ui/tabs/organization/tab_declutter_controller.cc b/chrome/browser/ui/tabs/organization/tab_declutter_controller.cc index d6d6bb5e..5a63f2c 100644 --- a/chrome/browser/ui/tabs/organization/tab_declutter_controller.cc +++ b/chrome/browser/ui/tabs/organization/tab_declutter_controller.cc
@@ -240,7 +240,7 @@ } int duplicate_tabs_decluttered = 0; - for (GURL url : urls) { + for (const GURL& url : urls) { // Sort the tabs with `url` based on the last committed navigation time and // close all the tabs except the oldest tab. std::vector<std::pair<tabs::TabInterface*, base::Time>> url_matching_tabs;
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_observer.cc b/chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_observer.cc index adffb2d..96ba3e0 100644 --- a/chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_observer.cc +++ b/chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_observer.cc
@@ -227,7 +227,7 @@ void CollaborationMessagingObserver::OnMessagingBackendServiceInitialized() { CHECK(service_); auto messages = service_->GetMessages(std::nullopt); - for (auto message : messages) { + for (const auto& message : messages) { DispatchMessage(message, MessageDisplayStatus::kDisplay); } }
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.cc b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.cc index 4d63e2e..feebf72 100644 --- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.cc +++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.cc
@@ -533,7 +533,8 @@ ConnectLocalTabGroup(local_group_id, saved_guid); } - for (SavedTabGroup group : restored_groups_to_save_on_load_) { + for (SavedTabGroup& group : restored_groups_to_save_on_load_) { + // Move from vector about to be cleared below. SaveRestoredGroup(std::move(group)); }
diff --git a/chrome/browser/ui/tabs/tab_strip_collection.cc b/chrome/browser/ui/tabs/tab_strip_collection.cc index 8e5ead0..bd0d81a 100644 --- a/chrome/browser/ui/tabs/tab_strip_collection.cc +++ b/chrome/browser/ui/tabs/tab_strip_collection.cc
@@ -276,8 +276,7 @@ TabGroupTabCollection* TabStripCollection::AddTabGroup( std::unique_ptr<TabGroupTabCollection> group, int index) { - group_mapping_.insert({group->GetTabGroupId(), group.get()}); - + AddCollectionMapping(group.get()); const int dst_index = (index == static_cast<int>(TabCountRecursive())) ? unpinned_collection_->ChildCount() @@ -291,8 +290,7 @@ std::unique_ptr<TabGroupTabCollection> TabStripCollection::RemoveGroup( TabGroupTabCollection* group) { CHECK(group_mapping_.contains(group->GetTabGroupId())); - group_mapping_.erase(group->GetTabGroupId()); - + RemoveCollectionMapping(group); return base::WrapUnique(static_cast<TabGroupTabCollection*>( unpinned_collection_->MaybeRemoveCollection(group).release())); } @@ -400,7 +398,7 @@ } // Insert split back into the parent. - split_mapping_.insert({split_id, split.get()}); + AddCollectionMapping(split.get()); parent_collection->AddCollection(std::move(split), dst_index); } @@ -421,7 +419,7 @@ parent_collection->AddTab(split->MaybeRemoveTab(tab), dst_index); } - split_mapping_.erase(split->GetSplitTabId()); + RemoveCollectionMapping(split); parent_collection->MaybeRemoveCollection(split).reset(); } @@ -489,4 +487,49 @@ } } +void TabStripCollection::AddCollectionMapping(TabCollection* root_collection) { + if (root_collection->type() == TabCollection::Type::GROUP) { + TabGroupTabCollection* group_collection = + static_cast<TabGroupTabCollection*>(root_collection); + group_mapping_.insert( + {group_collection->GetTabGroupId(), group_collection}); + + for (const tabs::TabInterface* tab : *group_collection) { + if (tab->IsSplit()) { + const split_tabs::SplitTabId split_id = tab->GetSplit().value(); + if (!split_mapping_.contains(split_id)) { + split_mapping_.insert( + {split_id, static_cast<SplitTabCollection*>( + tab->GetParentCollection(GetPassKey()))}); + } + } + } + } else if (root_collection->type() == TabCollection::Type::SPLIT) { + SplitTabCollection* split_collection = + static_cast<SplitTabCollection*>(root_collection); + split_mapping_.insert( + {split_collection->GetSplitTabId(), split_collection}); + } +} + +void TabStripCollection::RemoveCollectionMapping( + TabCollection* root_collection) { + if (root_collection->type() == TabCollection::Type::GROUP) { + TabGroupTabCollection* group_collection = + static_cast<TabGroupTabCollection*>(root_collection); + group_mapping_.erase(group_collection->GetTabGroupId()); + + for (const tabs::TabInterface* tab : *group_collection) { + if (tab->IsSplit()) { + split_mapping_.erase(tab->GetSplit().value()); + } + } + + } else if (root_collection->type() == TabCollection::Type::SPLIT) { + SplitTabCollection* split_collection = + static_cast<SplitTabCollection*>(root_collection); + split_mapping_.erase(split_collection->GetSplitTabId()); + } +} + } // namespace tabs
diff --git a/chrome/browser/ui/tabs/tab_strip_collection.h b/chrome/browser/ui/tabs/tab_strip_collection.h index 5a3d3a52..bd72308 100644 --- a/chrome/browser/ui/tabs/tab_strip_collection.h +++ b/chrome/browser/ui/tabs/tab_strip_collection.h
@@ -131,6 +131,12 @@ ChildrenPtrs GetTabsAndCollectionsForMove( const std::vector<int>& tab_indices); + // Helper to centralize updates to `group_mapping_` and `split_mapping_`. If + // `root_collection` is a group, the appropriate splits need to group need to + // be updated in the `split_mapping_`. + void AddCollectionMapping(TabCollection* root_collection); + void RemoveCollectionMapping(TabCollection* root_collection); + // All of the pinned tabs for this tabstrip is present in this collection. // This should be below `impl_` to avoid being a dangling pointer during // destruction.
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc index 54a0471c..fc6133f 100644 --- a/chrome/browser/ui/tabs/tab_strip_model.cc +++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -460,6 +460,10 @@ // Calculate the next selected index before fixing openers. std::optional<int> next_selected_index = DetermineNewSelectedIndex(group_id); + std::map<split_tabs::SplitTabId, + std::vector<std::pair<tabs::TabInterface*, int>>> + splits_in_group; + for (int index = static_cast<int>(tabs_in_group.end()) - 1; index >= static_cast<int>(tabs_in_group.start()); --index) { tabs::TabModel* tab = GetTabModelAtIndex(index); @@ -470,6 +474,13 @@ active_tab_model->WillEnterBackground(base::PassKey<TabStripModel>()); } + if (tab->IsSplit()) { + split_tabs::SplitTabId split_id = tab->GetSplit().value(); + if (!splits_in_group.contains(split_id)) { + splits_in_group[split_id] = GetTabsAndIndicesInSplit(split_id); + } + } + // Track whether any of these tabs are selected. if (IsTabSelected(index)) { selected_tabs_removed = true; @@ -494,6 +505,13 @@ tabs::TabInterface::DetachReason::kInsertIntoOtherWindow, std::nullopt); } + // Remove the group collection before selection model update. + // This is because the selection model update includes looking into + // `contents_data_` for split tabs. + std::unique_ptr<tabs::TabGroupTabCollection> group_collection = + contents_data_->RemoveGroup( + contents_data_->GetTabGroupCollection(group_id)); + // Selection model update should be done as a bulk operation. if (closing_all_tabs) { selection_model_.Clear(); @@ -515,15 +533,19 @@ } } - // Remove the group collection. - std::unique_ptr<tabs::TabGroupTabCollection> group_collection = - contents_data_->RemoveGroup( - contents_data_->GetTabGroupCollection(group_id)); - // Send group detach notification. OnTabGroupDetached(group_collection.get()); group_model_->RemoveTabGroup(group_id, base::PassKey<TabStripModel>()); + // Send possible split detach notification. + for (auto const& [split_id, tabs_with_indices] : splits_in_group) { + for (TabStripModelObserver& observer : observers_) { + observer.OnSplitTabRemoved(tabs_with_indices, split_id, + TabStripModelObserver::SplitTabRemoveReason:: + kDetachedToAnotherTabstrip); + } + } + // Notify tab is removed from model for (tabs::TabInterface* tab : *group_collection) { static_cast<tabs::TabModel*>(tab)->OnRemovedFromModel(); @@ -580,7 +602,8 @@ index); for (int i = index; - i < index + static_cast<int>(group_collection->ChildCount()); i++) { + i < index + static_cast<int>(group_collection->TabCountRecursive()); + i++) { selection_model_.IncrementFrom(index); } @@ -593,9 +616,14 @@ ValidateTabStripModel(); + std::set<split_tabs::SplitTabId> splits_in_group; for (tabs::TabInterface* tab : *group_collection) { static_cast<tabs::TabModel*>(tab)->DidInsert( base::PassKey<TabStripModel>()); + + if (tab->IsSplit()) { + splits_in_group.insert(tab->GetSplit().value()); + } } // Send add notifications for tabs. @@ -620,6 +648,16 @@ // Send group attach notification. OnTabGroupAttached(group_collection); + // Send split attach notification + for (const split_tabs::SplitTabId& split_id : splits_in_group) { + for (TabStripModelObserver& observer : observers_) { + observer.OnSplitTabCreated(GetTabsAndIndicesInSplit(split_id), split_id, + TabStripModelObserver::SplitTabAddReason:: + kInsertedFromAnotherTabstrip, + *GetSplitData(split_id)->visual_data()); + } + } + return tabs_in_group; } @@ -3798,7 +3836,7 @@ int index, int to_position, tabs::TabInterface* tab, - TabStripSelectionChange& selection_change) { + const TabStripSelectionChange& selection_change) { TabStripModelChange::Move move; move.tab = tab; move.contents = tab->GetContents(); @@ -4036,7 +4074,7 @@ UpdateSelectionModelForMoves(tab_indices, destination_index); - for (auto notification : notifications) { + for (const auto& notification : notifications) { const int final_index = GetIndexOfTab(notification.tab); tabs::TabInterface* tab = GetTabAtIndex(final_index); if (notification.initial_index != final_index) {
diff --git a/chrome/browser/ui/tabs/tab_strip_model.h b/chrome/browser/ui/tabs/tab_strip_model.h index e66bd93f..bd9e5ee7 100644 --- a/chrome/browser/ui/tabs/tab_strip_model.h +++ b/chrome/browser/ui/tabs/tab_strip_model.h
@@ -1051,10 +1051,11 @@ // pinned tabs placement, group contiguity and selected tabs validity. void ValidateTabStripModel(); - void SendMoveNotificationForTab(int index, - int to_position, - tabs::TabInterface* tab, - TabStripSelectionChange& selection_change); + void SendMoveNotificationForTab( + int index, + int to_position, + tabs::TabInterface* tab, + const TabStripSelectionChange& selection_change); void UpdateSelectionModelForMove(int initial_index, int final_index,
diff --git a/chrome/browser/ui/tabs/tab_strip_model_unittest.cc b/chrome/browser/ui/tabs/tab_strip_model_unittest.cc index b2e88e1..2542bc00 100644 --- a/chrome/browser/ui/tabs/tab_strip_model_unittest.cc +++ b/chrome/browser/ui/tabs/tab_strip_model_unittest.cc
@@ -454,6 +454,7 @@ void SetUp() override { tabstrip_ = std::make_unique<TabStripModel>(delegate(), profile()); + scoped_feature_list_.InitAndEnableFeature(features::kSideBySide); tabstrip()->AddObserver(observer()); ASSERT_TRUE(tabstrip()->empty()); } @@ -989,6 +990,43 @@ EXPECT_EQ(tabstrip()->active_index(), 3); } +TEST_F(TabStripModelTest, TestDetachAndInsertGroupWithSplit) { + ASSERT_NO_FATAL_FAILURE( + PrepareTabstripForSelectionTest(tabstrip(), 5, 0, {2})); + + tab_groups::TabGroupId group_id = + tabstrip()->AddToNewGroup(std::vector<int>{1, 2, 3}); + + tabstrip()->ActivateTabAt( + 2, TabStripUserGestureDetails( + TabStripUserGestureDetails::GestureType::kOther)); + split_tabs::SplitTabId split_id = + tabstrip()->AddToNewSplit({3}, split_tabs::SplitTabLayout::kVertical); + + std::unique_ptr<DetachedTabGroup> detached_group = + tabstrip()->DetachTabGroupForInsertion(group_id); + + EXPECT_EQ(detached_group->collection_->TabCountRecursive(), 3u); + EXPECT_FALSE(tabstrip()->group_model()->ContainsTabGroup(group_id)); + EXPECT_EQ(tabstrip()->count(), 2); + + // Reinsert the detached group. + tabstrip()->InsertDetachedTabGroupAt(std::move(detached_group), 0); + + EXPECT_TRUE(tabstrip()->group_model()->ContainsTabGroup(group_id)); + EXPECT_EQ( + tabstrip()->group_model()->GetTabGroup(group_id)->ListTabs().length(), + 3u); + EXPECT_EQ(tabstrip()->group_model()->GetTabGroup(group_id)->ListTabs(), + gfx::Range(0, 3)); + std::vector<tabs::TabInterface*> expected_split_tabs = { + tabstrip()->GetTabAtIndex(1), tabstrip()->GetTabAtIndex(2)}; + EXPECT_EQ(tabstrip()->GetSplitData(split_id)->ListTabs(), + expected_split_tabs); + EXPECT_EQ(tabstrip()->count(), 5); + EXPECT_EQ("1 2s 3s 0 4", GetTabStripStateString(tabstrip())); +} + TEST_F(TabStripModelTest, InsertDetachedGroupSelectionObserver) { tabstrip()->AppendWebContents(CreateWebContentsWithID(1), false); tabstrip()->AppendWebContents(CreateWebContentsWithID(2), true); @@ -3470,7 +3508,6 @@ } TEST_F(TabStripModelTest, MoveSelectedTabsToWithSplit) { - scoped_feature_list()->InitAndEnableFeature(features::kSideBySide); ASSERT_NO_FATAL_FAILURE( PrepareTabstripForSelectionTest(tabstrip(), 10, 5, {2, 3, 6, 7})); @@ -3487,7 +3524,6 @@ } TEST_F(TabStripModelTest, MoveSelectedTabsToWithGroupAndSplit) { - scoped_feature_list()->InitAndEnableFeature(features::kSideBySide); ASSERT_NO_FATAL_FAILURE( PrepareTabstripForSelectionTest(tabstrip(), 13, 5, {2, 3})); @@ -5581,7 +5617,6 @@ } TEST_F(TabStripModelTest, SplitSelectionTestFromModel) { - scoped_feature_list()->InitAndEnableFeature(features::kSideBySide); TestTabStripModelDelegate delegate; TabStripModel tabstrip(&delegate, profile()); EXPECT_TRUE(tabstrip.empty());
diff --git a/chrome/browser/ui/ui_features.cc b/chrome/browser/ui/ui_features.cc index baa62c6..25a35fdf 100644 --- a/chrome/browser/ui/ui_features.cc +++ b/chrome/browser/ui/ui_features.cc
@@ -133,6 +133,11 @@ base::FEATURE_ENABLED_BY_DEFAULT); BASE_FEATURE(kSideBySide, "SideBySide", base::FEATURE_DISABLED_BY_DEFAULT); + +BASE_FEATURE(kSideBySideLinkMenuNewBadge, + "SideBySideLinkMenuNewBadge", + base::FEATURE_DISABLED_BY_DEFAULT); + bool IsNtpFooterEnabledWithoutSideBySide() { return (base::FeatureList::IsEnabled(ntp_features::kNtpFooter) && !base::FeatureList::IsEnabled(features::kSideBySide));
diff --git a/chrome/browser/ui/ui_features.h b/chrome/browser/ui/ui_features.h index b94f5cb..1adaa40 100644 --- a/chrome/browser/ui/ui_features.h +++ b/chrome/browser/ui/ui_features.h
@@ -102,6 +102,9 @@ BASE_DECLARE_FEATURE(KScrimForTabModal); BASE_DECLARE_FEATURE(kSideBySide); + +BASE_DECLARE_FEATURE(kSideBySideLinkMenuNewBadge); + bool IsNtpFooterEnabledWithoutSideBySide(); BASE_DECLARE_FEATURE(kTabDuplicateMetrics);
diff --git a/chrome/browser/ui/views/data_sharing/collaboration_controller_delegate_desktop.cc b/chrome/browser/ui/views/data_sharing/collaboration_controller_delegate_desktop.cc index 2c037d4..e0e50c8 100644 --- a/chrome/browser/ui/views/data_sharing/collaboration_controller_delegate_desktop.cc +++ b/chrome/browser/ui/views/data_sharing/collaboration_controller_delegate_desktop.cc
@@ -50,6 +50,12 @@ ok_button_text_id = IDS_DATA_SHARING_NEED_SIGN_IN_CONTINUE_BUTTON; valid = true; break; + case collaboration::SigninStatus::kSigninDisabled: + title_id = IDS_DATA_SHARING_SIGNED_OUT; + body_id = IDS_DATA_SHARING_SIGNED_OUT_BODY; + ok_button_text_id = IDS_DATA_SHARING_SETTINGS; + valid = true; + break; case collaboration::SigninStatus::kSignedInPaused: title_id = IDS_DATA_SHARING_NEED_VERIFY_ACCOUNT; body_id = IDS_DATA_SHARING_NEED_VERIFY_ACCOUNT_BODY; @@ -384,6 +390,9 @@ case collaboration::SigninStatus::kNotSignedIn: ShowSignInAndSyncUi(profile); break; + case collaboration::SigninStatus::kSigninDisabled: + chrome::ShowSettingsSubPage(browser_, chrome::kSyncSetupSubPage); + break; case collaboration::SigninStatus::kSignedInPaused: signin_ui_util::ShowReauthForAccount( profile, GetAccountInfoFromProfile(profile).email,
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc index 16fe8fe7..cfc7e1c7 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc
@@ -400,7 +400,7 @@ CHECK_IS_TEST(); std::vector<extensions::ExtensionId> extensions; extensions.reserve(requests_entries_.size()); - for (auto entry : requests_entries_) { + for (const auto& entry : requests_entries_) { extensions.push_back(entry.first); } return extensions;
diff --git a/chrome/browser/ui/views/extensions/extensions_request_access_button.cc b/chrome/browser/ui/views/extensions/extensions_request_access_button.cc index b9dfbcc0..eeb5391 100644 --- a/chrome/browser/ui/views/extensions/extensions_request_access_button.cc +++ b/chrome/browser/ui/views/extensions/extensions_request_access_button.cc
@@ -46,7 +46,7 @@ const extensions::ExtensionSet& enabled_extensions = extensions::ExtensionRegistry::Get(profile)->enabled_extensions(); std::vector<const extensions::Extension*> extensions; - for (auto extension_id : extension_ids) { + for (const auto& extension_id : extension_ids) { extensions.push_back(enabled_extensions.GetByID(extension_id)); } return extensions;
diff --git a/chrome/browser/ui/views/extensions/extensions_request_access_hover_card_coordinator.cc b/chrome/browser/ui/views/extensions/extensions_request_access_hover_card_coordinator.cc index d6419e53..9797535 100644 --- a/chrome/browser/ui/views/extensions/extensions_request_access_hover_card_coordinator.cc +++ b/chrome/browser/ui/views/extensions/extensions_request_access_hover_card_coordinator.cc
@@ -50,7 +50,7 @@ dialog_builder.AddParagraph(ui::DialogModelLabel::CreateWithReplacement( IDS_EXTENSIONS_REQUEST_ACCESS_BUTTON_TOOLTIP_MULTIPLE_EXTENSIONS, ui::DialogModelLabel::CreateEmphasizedText(url))); - for (auto extension_id : extension_ids) { + for (const auto& extension_id : extension_ids) { ToolbarActionViewController* action = extensions_container->GetActionForId(extension_id); dialog_builder.AddMenuItem(
diff --git a/chrome/browser/ui/views/file_system_access/file_system_access_restore_permission_bubble_view.cc b/chrome/browser/ui/views/file_system_access/file_system_access_restore_permission_bubble_view.cc index bdb125c..bf43e27 100644 --- a/chrome/browser/ui/views/file_system_access/file_system_access_restore_permission_bubble_view.cc +++ b/chrome/browser/ui/views/file_system_access/file_system_access_restore_permission_bubble_view.cc
@@ -55,7 +55,7 @@ // Add file/directory list. std::vector<base::FilePath> file_paths; - for (auto file : file_data) { + for (const auto& file : file_data) { file_paths.push_back(file.path_info.path); } AddChildView(FileSystemAccessScrollPanel::Create(file_paths));
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 559a149..3278a02 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -123,6 +123,7 @@ #include "chrome/browser/ui/views/frame/contents_layout_manager.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller.h" #include "chrome/browser/ui/views/frame/multi_contents_view.h" +#include "chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.h" #include "chrome/browser/ui/views/frame/native_browser_frame.h" #include "chrome/browser/ui/views/frame/scrim_view.h" #include "chrome/browser/ui/views/frame/tab_strip_region_view.h" @@ -3598,11 +3599,11 @@ } DownloadBubbleUIController* BrowserView::GetDownloadBubbleUIController() { - if (auto* download_controller = - browser_->GetFeatures().download_toolbar_ui_controller()) { - return download_controller->bubble_controller(); - } - return nullptr; + if (auto* download_controller = + browser_->GetFeatures().download_toolbar_ui_controller()) { + return download_controller->bubble_controller(); + } + return nullptr; } void BrowserView::ConfirmBrowserCloseWithPendingDownloads( @@ -3651,6 +3652,14 @@ return false; } +void BrowserView::PreHandleDragUpdate(const content::DropData& drop_data, + const gfx::PointF& point) { + if (multi_contents_view_) { + multi_contents_view_->drop_target_controller().OnWebContentsDragUpdate( + drop_data, point); + } +} + content::KeyboardEventProcessingResult BrowserView::PreHandleKeyboardEvent( const NativeWebKeyboardEvent& event) { if ((event.GetType() != blink::WebInputEvent::Type::kRawKeyDown) && @@ -3909,12 +3918,15 @@ std::vector<std::pair<tabs::TabInterface*, int>> tabs, split_tabs::SplitTabId split_id, SplitTabRemoveReason reason) { - const bool is_split_active = std::any_of( - tabs.begin(), tabs.end(), [](std::pair<tabs::TabInterface*, int>& tab) { - return tab.first->IsActivated(); - }); + CHECK(multi_contents_view_); + content::WebContents* active_web_contents = + multi_contents_view_->GetActiveContentsView()->web_contents(); - if (is_split_active) { + if (std::any_of(tabs.begin(), tabs.end(), + [active_web_contents]( + const std::pair<tabs::TabInterface*, int>& pair) { + return pair.first->GetContents() == active_web_contents; + })) { HideSplitView(); } }
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index fa2306f..c6900fb 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -72,6 +72,7 @@ class BookmarkBarView; class Browser; class ContentsLayoutManager; +struct DropData; class ExclusiveAccessBubbleViews; class FullscreenControlHost; class InfoBarContainerView; @@ -662,6 +663,8 @@ void UserChangedTheme(BrowserThemeChangeType theme_change_type) override; void ShowAppMenu() override; bool PreHandleMouseEvent(const blink::WebMouseEvent& event) override; + void PreHandleDragUpdate(const content::DropData& drop_data, + const gfx::PointF& point) override; content::KeyboardEventProcessingResult PreHandleKeyboardEvent( const input::NativeWebKeyboardEvent& event) override; bool HandleKeyboardEvent(const input::NativeWebKeyboardEvent& event) override;
diff --git a/chrome/browser/ui/views/frame/multi_contents_view.cc b/chrome/browser/ui/views/frame/multi_contents_view.cc index ca90a3fa..5ab73de 100644 --- a/chrome/browser/ui/views/frame/multi_contents_view.cc +++ b/chrome/browser/ui/views/frame/multi_contents_view.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/contents_web_view.h" #include "chrome/browser/ui/views/frame/multi_contents_resize_area.h" +#include "chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.h" #include "chrome/browser/ui/views/frame/top_container_background.h" #include "chrome/browser/ui/views/status_bubble_views.h" #include "content/public/browser/web_contents.h" @@ -24,6 +25,8 @@ #include "ui/views/layout/flex_layout_types.h" #include "ui/views/view_class_properties.h" +DEFINE_ELEMENT_IDENTIFIER_VALUE(kMultiContentsViewDropTargetElementId); + DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(MultiContentsView, kMultiContentsViewElementId); @@ -60,6 +63,14 @@ SetProperty(views::kElementIdentifierKey, kMultiContentsViewElementId); SetLayoutManager(std::make_unique<views::FlexLayout>()) ->SetOrientation(views::LayoutOrientation::kHorizontal); + + views::View* drop_target_view = AddChildView(std::make_unique<views::View>()); + drop_target_view->SetProperty(views::kElementIdentifierKey, + kMultiContentsViewDropTargetElementId); + drop_target_view->SetVisible(false); + drop_target_controller_ = + std::make_unique<MultiContentsViewDropTargetController>( + *drop_target_view); } MultiContentsView::~MultiContentsView() = default;
diff --git a/chrome/browser/ui/views/frame/multi_contents_view.h b/chrome/browser/ui/views/frame/multi_contents_view.h index 8ad29b28..76a61915 100644 --- a/chrome/browser/ui/views/frame/multi_contents_view.h +++ b/chrome/browser/ui/views/frame/multi_contents_view.h
@@ -18,6 +18,7 @@ class BrowserView; class ContentsWebView; class MultiContentsResizeArea; +class MultiContentsViewDropTargetController; namespace blink { class WebMouseEvent; @@ -35,6 +36,10 @@ class WebView; } // namespace views +// TODO(crbug.com/394369035): The drop target view will eventually have its +// own class. Move this declaration into the class once ready. +DECLARE_ELEMENT_IDENTIFIER_VALUE(kMultiContentsViewDropTargetElementId); + // MultiContentsView shows up to two contents web views side by side, and // manages their layout relative to each other. class MultiContentsView : public views::View, public views::ResizeAreaDelegate { @@ -105,6 +110,10 @@ void OnPaint(gfx::Canvas* canvas) override; void OnThemeChanged() override; + MultiContentsViewDropTargetController& drop_target_controller() { + return *drop_target_controller_; + } + void SetMinWidthForTesting(int width) { min_contents_width_for_testing_ = std::make_optional(width); } @@ -175,6 +184,11 @@ // each other. raw_ptr<MultiContentsResizeArea> resize_area_ = nullptr; + // Handles incoming drag events to show/hide the drop target for entering + // split view. + std::unique_ptr<MultiContentsViewDropTargetController> + drop_target_controller_; + // The index in contents_views_ of the active contents view. int active_index_ = 0;
diff --git a/chrome/browser/ui/views/frame/multi_contents_view_drag_entrypoint_controller.cc b/chrome/browser/ui/views/frame/multi_contents_view_drag_entrypoint_controller.cc deleted file mode 100644 index 800c929..0000000 --- a/chrome/browser/ui/views/frame/multi_contents_view_drag_entrypoint_controller.cc +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2025 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/views/frame/multi_contents_view_drag_entrypoint_controller.h" - -#include "content/public/common/drop_data.h" -#include "ui/views/view_class_properties.h" - -DEFINE_ELEMENT_IDENTIFIER_VALUE(kMultiContentsViewDropTargetElementId); - -MultiContentsViewDragEntrypointController:: - MultiContentsViewDragEntrypointController(views::View& multi_contents_view) - : multi_contents_view_(multi_contents_view), - drop_target_view_( - *multi_contents_view.AddChildView(std::make_unique<views::View>())) { - drop_target_view_->SetProperty(views::kElementIdentifierKey, - kMultiContentsViewDropTargetElementId); - drop_target_view_->SetVisible(false); -} - -void MultiContentsViewDragEntrypointController::OnWebContentsDragUpdate( - const content::DropData& data, - const gfx::PointF& point) { - CHECK_LE(point.x(), multi_contents_view_->width()); - - // TODO(crbug.com/394369035): Settle on an appropriate value for this. - constexpr int kDropEntryPointWidth = 100; - - const bool should_show_drop_zone = - data.url.is_valid() && - point.x() >= multi_contents_view_->width() - kDropEntryPointWidth; - // TODO(crbug.com/394369035): Add a timer to delay showing the drop zone. - drop_target_view_->SetVisible(should_show_drop_zone); -}
diff --git a/chrome/browser/ui/views/frame/multi_contents_view_drag_entrypoint_controller.h b/chrome/browser/ui/views/frame/multi_contents_view_drag_entrypoint_controller.h deleted file mode 100644 index e7c59be..0000000 --- a/chrome/browser/ui/views/frame/multi_contents_view_drag_entrypoint_controller.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2025 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_VIEWS_FRAME_MULTI_CONTENTS_VIEW_DRAG_ENTRYPOINT_CONTROLLER_H_ -#define CHROME_BROWSER_UI_VIEWS_FRAME_MULTI_CONTENTS_VIEW_DRAG_ENTRYPOINT_CONTROLLER_H_ - -#include "ui/base/interaction/element_identifier.h" -#include "ui/views/view.h" - -namespace content { -struct DropData; -} // namespace content - -// TODO(crbug.com/394369035): The drop target view will eventually have its -// own class. Move this declaration into the class once ready. -DECLARE_ELEMENT_IDENTIFIER_VALUE(kMultiContentsViewDropTargetElementId); - -// `MultiContentsViewDragEntrypointController` is responsible for handling -// the drag-entrypoint of a single `MultiContentsView`. This includes dragging -// links, bookmarks, or tab headers to create a split view. -// There exists one `MultiContentsViewDragEntrypointController` per -// `MultiContentesView`. -class MultiContentsViewDragEntrypointController final { - public: - explicit MultiContentsViewDragEntrypointController( - views::View& multi_contents_view); - ~MultiContentsViewDragEntrypointController() = default; - MultiContentsViewDragEntrypointController( - const MultiContentsViewDragEntrypointController&) = delete; - MultiContentsViewDragEntrypointController& operator=( - const MultiContentsViewDragEntrypointController&) = delete; - - // Handles a drag within the web contents area. - // `point` should be relative to the multi contents view. - void OnWebContentsDragUpdate(const content::DropData& data, - const gfx::PointF& point); - - private: - const raw_ref<views::View> multi_contents_view_; - - // The view that is displayed when drags hover over the "drop" region of - // the content area. - const raw_ref<views::View> drop_target_view_; -}; - -#endif // CHROME_BROWSER_UI_VIEWS_FRAME_MULTI_CONTENTS_VIEW_DRAG_ENTRYPOINT_CONTROLLER_H_
diff --git a/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.cc b/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.cc new file mode 100644 index 0000000..42cf722e --- /dev/null +++ b/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.cc
@@ -0,0 +1,29 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.h" + +#include "content/public/common/drop_data.h" +#include "ui/views/view_class_properties.h" + +MultiContentsViewDropTargetController::MultiContentsViewDropTargetController( + views::View& drop_target_view) + : drop_target_view_(drop_target_view) { + CHECK_NE(nullptr, drop_target_view.parent()); +} + +void MultiContentsViewDropTargetController::OnWebContentsDragUpdate( + const content::DropData& data, + const gfx::PointF& point) { + CHECK_LE(point.x(), drop_target_view_->parent()->width()); + + // TODO(crbug.com/394369035): Settle on an appropriate value for this. + constexpr int kDropEntryPointWidth = 100; + + const bool should_show_drop_zone = + data.url.is_valid() && + point.x() >= drop_target_view_->parent()->width() - kDropEntryPointWidth; + // TODO(crbug.com/394369035): Add a timer to delay showing the drop zone. + drop_target_view_->SetVisible(should_show_drop_zone); +}
diff --git a/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.h b/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.h new file mode 100644 index 0000000..f2fb90f --- /dev/null +++ b/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.h
@@ -0,0 +1,40 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_FRAME_MULTI_CONTENTS_VIEW_DROP_TARGET_CONTROLLER_H_ +#define CHROME_BROWSER_UI_VIEWS_FRAME_MULTI_CONTENTS_VIEW_DROP_TARGET_CONTROLLER_H_ + +#include "ui/base/interaction/element_identifier.h" +#include "ui/views/view.h" + +namespace content { +struct DropData; +} // namespace content + +// `MultiContentsViewDropTargetController` is responsible for handling +// the drag-entrypoint of a single `MultiContentsView`. This includes dragging +// links, bookmarks, or tab headers to create a split view. +// There exists one `MultiContentsViewDropTargetController` per +// `MultiContentesView`. +class MultiContentsViewDropTargetController final { + public: + explicit MultiContentsViewDropTargetController(views::View& drop_target_view); + ~MultiContentsViewDropTargetController() = default; + MultiContentsViewDropTargetController( + const MultiContentsViewDropTargetController&) = delete; + MultiContentsViewDropTargetController& operator=( + const MultiContentsViewDropTargetController&) = delete; + + // Handles a drag within the web contents area. + // `point` should be relative to the multi contents view. + void OnWebContentsDragUpdate(const content::DropData& data, + const gfx::PointF& point); + + private: + // The view that is displayed when drags hover over the "drop" region of + // the content area. + const raw_ref<views::View> drop_target_view_; +}; + +#endif // CHROME_BROWSER_UI_VIEWS_FRAME_MULTI_CONTENTS_VIEW_DROP_TARGET_CONTROLLER_H_
diff --git a/chrome/browser/ui/views/frame/multi_contents_view_drag_entrypoint_controller_unittest.cc b/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller_unittest.cc similarity index 66% rename from chrome/browser/ui/views/frame/multi_contents_view_drag_entrypoint_controller_unittest.cc rename to chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller_unittest.cc index 8f1aa23..36202ba9 100644 --- a/chrome/browser/ui/views/frame/multi_contents_view_drag_entrypoint_controller_unittest.cc +++ b/chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/views/frame/multi_contents_view_drag_entrypoint_controller.h" +#include "chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.h" #include <memory> @@ -17,28 +17,18 @@ static constexpr gfx::PointF kDragPointForDropTargetShow(450, 450); -views::View* FindChildWithElementId(views::View* parent, - ui::ElementIdentifier id) { - for (views::View* child : parent->children()) { - if (child->GetProperty(views::kElementIdentifierKey) == id) { - return child; - } - } - return nullptr; -} - -class MultiContentsViewDragEntrypointControllerTest : public testing::Test { +class MultiContentsViewDropTargetControllerTest : public testing::Test { public: - MultiContentsViewDragEntrypointControllerTest() = default; - ~MultiContentsViewDragEntrypointControllerTest() override = default; + MultiContentsViewDropTargetControllerTest() = default; + ~MultiContentsViewDropTargetControllerTest() override = default; void SetUp() override { multi_contents_view_ = std::make_unique<views::View>(); - controller_ = std::make_unique<MultiContentsViewDragEntrypointController>( - *multi_contents_view_.get()); - - drop_target_view_ = FindChildWithElementId( - multi_contents_view_.get(), kMultiContentsViewDropTargetElementId); + drop_target_view_ = + multi_contents_view_->AddChildView(std::make_unique<views::View>()); + drop_target_view_->SetVisible(false); + controller_ = std::make_unique<MultiContentsViewDropTargetController>( + *drop_target_view_); multi_contents_view_->SetSize(kMultiContentsViewSize); } @@ -49,21 +39,19 @@ multi_contents_view_.reset(); } - MultiContentsViewDragEntrypointController& controller() { - return *controller_; - } + MultiContentsViewDropTargetController& controller() { return *controller_; } views::View& drop_target_view() { return *drop_target_view_; } private: - std::unique_ptr<MultiContentsViewDragEntrypointController> controller_; + std::unique_ptr<MultiContentsViewDropTargetController> controller_; std::unique_ptr<views::View> multi_contents_view_; raw_ptr<views::View> drop_target_view_; }; // Tests that the drop target is shown when a drag reaches enters the "drop // area" and a valid url is being dragged. -TEST_F(MultiContentsViewDragEntrypointControllerTest, +TEST_F(MultiContentsViewDropTargetControllerTest, OnWebContentsDragUpdate_ShowDropTarget) { ASSERT_FALSE(drop_target_view().GetVisible()); @@ -76,7 +64,7 @@ } // Tests that the drop target is hidden when an invalid url is being dragged. -TEST_F(MultiContentsViewDragEntrypointControllerTest, +TEST_F(MultiContentsViewDropTargetControllerTest, OnWebContentsDragUpdate_HideDropTargetOnInvalidURL) { drop_target_view().SetVisible(true); ASSERT_TRUE(drop_target_view().GetVisible()); @@ -88,7 +76,7 @@ } // Tests that the drop target is hidden when a drag is not in the "drop area". -TEST_F(MultiContentsViewDragEntrypointControllerTest, +TEST_F(MultiContentsViewDropTargetControllerTest, OnWebContentsDragUpdate_HideDropTargetOnOutOfBounds) { drop_target_view().SetVisible(true); ASSERT_TRUE(drop_target_view().GetVisible());
diff --git a/chrome/browser/ui/views/frame/multi_contents_view_interactive_uitest.cc b/chrome/browser/ui/views/frame/multi_contents_view_interactive_uitest.cc index 4b6aa7c..a84bef99 100644 --- a/chrome/browser/ui/views/frame/multi_contents_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/frame/multi_contents_view_interactive_uitest.cc
@@ -4,16 +4,23 @@ #include "base/numerics/clamped_math.h" #include "base/test/scoped_feature_list.h" +#include "chrome/browser/bookmarks/bookmark_model_factory.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_element_identifiers.h" #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/tabs/test/split_tabs_interactive_test_mixin.h" #include "chrome/browser/ui/ui_features.h" +#include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" +#include "chrome/browser/ui/views/bookmarks/bookmark_button.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/multi_contents_resize_area.h" #include "chrome/browser/ui/views/frame/multi_contents_view.h" +#include "chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.h" #include "chrome/common/webui_url_constants.h" #include "chrome/test/base/interactive_test_utils.h" #include "chrome/test/interaction/interactive_browser_test.h" +#include "components/bookmarks/browser/bookmark_model.h" +#include "components/bookmarks/common/bookmark_pref_names.h" #include "components/tabs/public/split_tab_collection.h" #include "components/tabs/public/split_tab_visual_data.h" #include "content/public/test/browser_test.h" @@ -409,3 +416,185 @@ WaitForState(kMultiContentsViewSwapObserver, true), CheckTabIsActive(1), CheckActiveContentsHasFocus()); } + +// TODO(crbug.com/414590951): There's limited support for testing drag and drop +// on various platforms. These should be re-enabled as support is added. +#if !BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_WIN) && !BUILDFLAG(IS_CHROMEOS) + +gfx::Point PointForDropTargetFromView(views::View* view) { + return view->GetBoundsInScreen().right_center() - gfx::Vector2d(10, 0); +} + +class MultiContentsViewDragEntrypointsUiTest : public MultiContentsViewUiTest { + public: + using MultiContentsViewUiTest::MultiContentsViewUiTest; + + void SetUp() override { + http_server_.ServeFilesFromSourceDirectory(GetChromeTestDataDir()); + ASSERT_TRUE(http_server_.InitializeAndListen()); + MultiContentsViewUiTest::SetUp(); + } + + void SetUpOnMainThread() override { + http_server_.StartAcceptingConnections(); + InteractiveBrowserTest::SetUpOnMainThread(); + } + + GURL GetURL(std::string path) { return http_server_.GetURL(path); } + + auto PointForDropTarget() const { + return base::BindLambdaForTesting( + [](views::View* view) { return PointForDropTargetFromView(view); }); + } + + // The standard DragMouseTo verb waits for the mouse to reach the + // destination. This version does not, since the mouse position sometimes + // doesn't get reported immediately (see `WaitForDropTargetVisible`). + auto DragMouseToWithoutWait( + ElementSpecifier target_view, + base::RepeatingCallback<gfx::Point(views::View*)> pos) { + return WithView(target_view, [pos = std::move(pos)](views::View* view) { + base::RunLoop press_loop(base::RunLoop::Type::kNestableTasksAllowed); + EXPECT_TRUE(ui_controls::SendMouseEventsNotifyWhenDone( + ui_controls::MouseButton::LEFT, ui_controls::MouseButtonState::DOWN, + press_loop.QuitClosure())); + press_loop.Run(); + gfx::Point target_location = std::move(pos).Run(view); + + EXPECT_TRUE( + ui_controls::SendMouseMove(target_location.x(), target_location.y())); + }); + } + + auto WaitForDropTargetVisible() { + // This method waits for the drop target to be visible, but also sends + // periodic mouse movement events while waiting. The mouse movements are + // needed to deflake this test on some Mac platforms: in the normal case, + // the initial mouse movement initiates a drag session, which later + // receives "drag updated" events from the OS. However, for some of the + // flakes, these updates are never sent by the OS. Manually generating + // the events seems to fix this. + // We really only need one event timed to execute after the drag session + // starts; an alternative approach would be to add observation to the + // Mac DnD client. Until then, periodic events does the trick. + // + // Note, both branches of AnyOf end with WaitForShow to ensure that the + // only way this step terminates successfully is if the view is shown. + return AnyOf( + RunSubsequence(WaitForShow(kMultiContentsViewDropTargetElementId)), + RunSubsequence( + Steps( + // Programmatically generate a list of mouse movement steps. + []() { + constexpr int kMouseMovements = 20; + constexpr base::TimeDelta kMovementDelay = + base::Milliseconds(250); + MultiStep mouse_moves; + // Jitter applied to the mouse move destination to ensure it + // changes between each step. + int jitter = 3; + for (int mouse_move_events = 0; + mouse_move_events < kMouseMovements; + ++mouse_move_events) { + jitter *= -1; + AddStep(mouse_moves, Do([kMovementDelay] { + base::PlatformThread::Sleep(kMovementDelay); + })); + AddStep( + mouse_moves, + WithView(MultiContentsView::kMultiContentsViewElementId, + [jitter](views::View* view) { + gfx::Point target = + PointForDropTargetFromView(view); + EXPECT_TRUE(ui_controls::SendMouseMove( + target.x() + jitter, target.y())); + })); + } + return mouse_moves; + }()), + // This branch also waits for visibility to prevent it from exiting + // prematurely. + WaitForShow(kMultiContentsViewDropTargetElementId))); + } + + private: + net::EmbeddedTestServer http_server_; +}; + +IN_PROC_BROWSER_TEST_F(MultiContentsViewDragEntrypointsUiTest, + ShowsDropTargetOnLinkDragged) { + RunTestSequence( + AddInstrumentedTab(kNewTab, GetURL("/links.html"), 0), + CheckTabIsActive(0), + // Drag an href element to the drop target area. The drop + // target should be shown. + MoveMouseTo(kNewTab, DeepQuery{"#title1"}), + DragMouseToWithoutWait(MultiContentsView::kMultiContentsViewElementId, + PointForDropTarget()), + WaitForDropTargetVisible()); +} + +IN_PROC_BROWSER_TEST_F(MultiContentsViewDragEntrypointsUiTest, + DoesNotShowDropTargetOnNonURLDragged) { + RunTestSequence( + AddInstrumentedTab(kNewTab, GetURL("/button.html"), 0), + CheckTabIsActive(0), + // Dragging a non-url to the drop target area should have no + // effect. + MoveMouseTo(kNewTab, DeepQuery{"#button"}), + DragMouseToWithoutWait(MultiContentsView::kMultiContentsViewElementId, + PointForDropTarget()), + WaitForHide(kMultiContentsViewDropTargetElementId)); +} + +class MultiContentsViewBookmarkDragEntrypointsUiTest + : public MultiContentsViewDragEntrypointsUiTest { + public: + using MultiContentsViewDragEntrypointsUiTest:: + MultiContentsViewDragEntrypointsUiTest; + + void SetUpOnMainThread() override { + MultiContentsViewDragEntrypointsUiTest::SetUpOnMainThread(); + browser()->profile()->GetPrefs()->SetBoolean( + bookmarks::prefs::kShowBookmarkBar, true); + } + + // Names the bookmark bar button for the given bookmark folder. + auto NameBookmarkButton(std::string assigned_name, + std::u16string node_title) { + return NameViewRelative( + kBookmarkBarElementId, assigned_name, + base::BindLambdaForTesting([=](views::View* view) -> views::View* { + auto* const bookmark_bar = views::AsViewClass<BookmarkBarView>(view); + CHECK(bookmark_bar); + for (views::View* child : bookmark_bar->children()) { + auto* bookmark_button = views::AsViewClass<BookmarkButton>(child); + if (bookmark_button && bookmark_button->GetText() == node_title) { + return bookmark_button; + } + } + NOTREACHED() << "Bookmark button with title " << node_title + << " not found."; + })); + } +}; + +IN_PROC_BROWSER_TEST_F(MultiContentsViewBookmarkDragEntrypointsUiTest, + ShowsDropTargetOnBookmarkedLinkDragged) { + bookmarks::BookmarkModel* const model = + BookmarkModelFactory::GetForBrowserContext(browser()->profile()); + const std::u16string bookmark_title = u"Bookmark"; + model->AddNewURL(model->bookmark_bar_node(), 0, u"Bookmark", + GetURL("/links.html")); + + const std::string kBookmarkButtonId = "bookmark_button"; + RunTestSequence( + AddInstrumentedTab(kNewTab, GURL(chrome::kChromeUISettingsURL), 0), + CheckTabIsActive(0), WaitForShow(kBookmarkBarElementId), + NameBookmarkButton(kBookmarkButtonId, bookmark_title), + MoveMouseTo(kBookmarkButtonId), + DragMouseToWithoutWait(MultiContentsView::kMultiContentsViewElementId, + PointForDropTarget()), + WaitForDropTargetVisible()); +} +#endif // !BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_WIN) && !BUILDFLAG(IS_CHROMEOS)
diff --git a/chrome/browser/ui/views/frame/scrim_view.cc b/chrome/browser/ui/views/frame/scrim_view.cc index 63735dc..3ad6fc5 100644 --- a/chrome/browser/ui/views/frame/scrim_view.cc +++ b/chrome/browser/ui/views/frame/scrim_view.cc
@@ -10,23 +10,22 @@ #include "ui/compositor/layer_type.h" #include "ui/gfx/geometry/rounded_corners_f.h" #include "ui/views/accessibility/view_accessibility.h" +#include "ui/views/background.h" ScrimView::ScrimView() { SetCanProcessEventsWithinSubtree(false); // This view must be painted to a layer so that it can be drawn on top of the // contents view. Otherwise, the scrim is drawn on the BrowserView's layer, // which always stays behind the content's layer. - SetPaintToLayer(ui::LAYER_SOLID_COLOR); + SetPaintToLayer(); + layer()->SetFillsBoundsOpaquely(false); GetViewAccessibility().SetIsInvisible(true); - SetVisible(false); -} - -void ScrimView::AddedToWidget() { // Maybe consider using a different color for the scrim? // kColorSysStateScrim is a semi-transparent black which has no effect on a // pure black background. In contrast, macOS sheet uses a semi-transparent // grey scrim which lightens a dark background. - layer()->SetColor(GetColorProvider()->GetColor(ui::kColorSysStateScrim)); + SetBackground(views::CreateSolidBackground(ui::kColorSysStateScrim)); + SetVisible(false); } void ScrimView::SetRoundedCorners(const gfx::RoundedCornersF& radii) {
diff --git a/chrome/browser/ui/views/frame/scrim_view.h b/chrome/browser/ui/views/frame/scrim_view.h index 7a164fa5..3ddff36e 100644 --- a/chrome/browser/ui/views/frame/scrim_view.h +++ b/chrome/browser/ui/views/frame/scrim_view.h
@@ -24,9 +24,6 @@ ~ScrimView() override = default; - // views::View: - void AddedToWidget() override; - void SetRoundedCorners(const gfx::RoundedCornersF& radii); };
diff --git a/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc b/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc index 50f25677..72f39f8 100644 --- a/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc +++ b/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc
@@ -445,10 +445,10 @@ } MediaDialogView::~MediaDialogView() { - for (auto item_pair : observed_items_) { + for (auto& item_pair : observed_items_) { item_pair.second->RemoveObserver(this); } - for (auto item_pair : updated_items_) { + for (auto& item_pair : updated_items_) { item_pair.second->RemoveObserver(this); } }
diff --git a/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view.cc b/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view.cc index 08f04f88..c02b1f3 100644 --- a/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view.cc +++ b/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view.cc
@@ -238,7 +238,7 @@ current_audio_device_entry_view_ = nullptr; bool current_device_still_exists = false; - for (auto description : device_descriptions) { + for (const auto& description : device_descriptions) { auto device_entry_view = std::make_unique<AudioDeviceEntryView>( base::BindRepeating( &MediaItemUIDeviceSelectorDelegate::OnAudioSinkChosen,
diff --git a/chrome/browser/ui/views/performance_controls/tab_list_view.cc b/chrome/browser/ui/views/performance_controls/tab_list_view.cc index 11169ce1..1feeee6 100644 --- a/chrome/browser/ui/views/performance_controls/tab_list_view.cc +++ b/chrome/browser/ui/views/performance_controls/tab_list_view.cc
@@ -26,8 +26,7 @@ views::View::SetLayoutManager(std::make_unique<views::FlexLayout>()); flex_layout->SetOrientation(views::LayoutOrientation::kVertical); - for (resource_attribution::PageContext context : - tab_list_model->page_contexts()) { + for (const auto& context : tab_list_model->page_contexts()) { AddChildView(std::make_unique<TabListRowView>( context, tab_list_model, base::BindOnce(&TabListView::RemoveRow, base::Unretained(this),
diff --git a/chrome/browser/ui/views/site_data/page_specific_site_data_dialog.cc b/chrome/browser/ui/views/site_data/page_specific_site_data_dialog.cc index 2c31697..a56bbc2 100644 --- a/chrome/browser/ui/views/site_data/page_specific_site_data_dialog.cc +++ b/chrome/browser/ui/views/site_data/page_specific_site_data_dialog.cc
@@ -229,7 +229,7 @@ } std::vector<PageSpecificSiteDataDialogSite> sites; - for (auto site : sites_map) { + for (const auto& site : sites_map) { sites.push_back(site.second); }
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index 12a35b0..cca8929 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -1120,7 +1120,7 @@ std::vector<std::pair<int, TabRendererData>> tabs_datas) { std::vector<TabContainer::TabInsertionParams> tabs_params; - for (auto tab_data : tabs_datas) { + for (const auto& tab_data : tabs_datas) { const int model_index = tab_data.first; CHECK(IsValidModelIndex(model_index)) << "Attempted to add a tab with an invalid model index.";
diff --git a/chrome/browser/ui/views/tabs/tab_strip_action_container.cc b/chrome/browser/ui/views/tabs/tab_strip_action_container.cc index c271096..26e150e5 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_action_container.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_action_container.cc
@@ -35,7 +35,7 @@ #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/gfx/animation/tween.h" #include "ui/views/accessibility/view_accessibility.h" -#include "ui/views/layout/box_layout.h" +#include "ui/views/layout/flex_layout.h" #include "ui/views/mouse_watcher.h" #include "ui/views/mouse_watcher_view_host.h" #include "ui/views/view_class_properties.h" @@ -283,7 +283,7 @@ #if !BUILDFLAG(IS_MAC) std::unique_ptr<views::Separator> separator = std::make_unique<views::Separator>(); - separator->SetBorderRadius(TabStyle::Get()->GetSeparatorMargins().right()); + separator->SetBorderRadius(TabStyle::Get()->GetSeparatorCornerRadius()); separator->SetPreferredSize(TabStyle::Get()->GetSeparatorSize()); separator->SetColorId(kColorTabDividerFrameActive); @@ -305,13 +305,11 @@ #endif // !BUILDFLAG(IS_MAC) } #endif // BUILDFLAG(ENABLE_GLIC) - - auto* const layout_manager = - SetLayoutManager(std::make_unique<views::BoxLayout>()); - layout_manager->set_main_axis_alignment( - views::BoxLayout::MainAxisAlignment::kStart); - layout_manager->set_cross_axis_alignment( - views::BoxLayout::CrossAxisAlignment::kCenter); + SetLayoutManager(std::make_unique<views::FlexLayout>()) + ->SetOrientation(views::LayoutOrientation::kHorizontal) + .SetMainAxisAlignment(views::LayoutAlignment::kStart) + .SetCrossAxisAlignment(views::LayoutAlignment::kCenter) + .SetCollapseMargins(false); } TabStripActionContainer::~TabStripActionContainer() {
diff --git a/chrome/browser/ui/views/tabs/tab_strip_combo_button.cc b/chrome/browser/ui/views/tabs/tab_strip_combo_button.cc index 9358784..2f219a6 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_combo_button.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_combo_button.cc
@@ -38,9 +38,6 @@ // LINT.ThenChange(//tools/metrics/histograms/metadata/tab/enums.xml:AccidentalClickType) constexpr int kButtonGapNoBackground = 14; -constexpr int kSeparatorBorderRadius = 2; -constexpr int kSeparatorWidth = 2; -constexpr int kSeparatorHeight = 16; constexpr base::TimeDelta kAccidentalClickThreshold = base::Seconds(1); constexpr char kNewTabButtonAccidentalClickName[] = "Tabs.NewTabButton.AccidentalClicks"; @@ -105,8 +102,8 @@ std::unique_ptr<views::Separator> separator = std::make_unique<views::Separator>(); - separator->SetBorderRadius(kSeparatorBorderRadius); - separator->SetPreferredSize(gfx::Size(kSeparatorWidth, kSeparatorHeight)); + separator->SetBorderRadius(TabStyle::Get()->GetSeparatorCornerRadius()); + separator->SetPreferredSize(TabStyle::Get()->GetSeparatorSize()); subscriptions_.push_back(browser->RegisterDidBecomeActive(base::BindRepeating( &TabStripComboButton::DidBecomeActive, base::Unretained(this)))); subscriptions_.push_back(
diff --git a/chrome/browser/ui/views/translate/partial_translate_bubble_view.cc b/chrome/browser/ui/views/translate/partial_translate_bubble_view.cc index ff6f17f..0c5d493a 100644 --- a/chrome/browser/ui/views/translate/partial_translate_bubble_view.cc +++ b/chrome/browser/ui/views/translate/partial_translate_bubble_view.cc
@@ -551,7 +551,8 @@ views::MaximumFlexSizeRule::kPreferred)); padding_view->SetProperty( views::kFlexBehaviorKey, - views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero, + views::FlexSpecification(views::LayoutOrientation::kHorizontal, + views::MinimumFlexSizeRule::kScaleToZero, views::MaximumFlexSizeRule::kUnbounded) .WithOrder(2)); options_menu->SetProperty(views::kElementIdentifierKey, kOptionsMenuButton); @@ -628,7 +629,8 @@ error_message_label->SetProperty(views::kElementIdentifierKey, kErrorMessage); error_message_label->SetProperty( views::kFlexBehaviorKey, - views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero, + views::FlexSpecification(views::LayoutOrientation::kHorizontal, + views::MinimumFlexSizeRule::kScaleToZero, views::MaximumFlexSizeRule::kUnbounded)); title_row->AddChildView(std::move(error_message_label)); @@ -840,8 +842,8 @@ horizontal_spacing * 4)); language_title_label->SetProperty(views::kCrossAxisAlignmentKey, views::LayoutAlignment::kStart); - auto* title_row = form_view->AddChildView(std::make_unique<views::View>()); - title_row->SetLayoutManager(std::make_unique<views::FlexLayout>()); + auto* title_row = + form_view->AddChildView(std::make_unique<views::FlexLayoutView>()); auto* title_label = title_row->AddChildView(std::move(language_title_label)); auto* padding_view = title_row->AddChildView(std::make_unique<views::View>()); title_row->AddChildView(CreateCloseButton()); @@ -854,7 +856,8 @@ // when the bubble expands. padding_view->SetProperty( views::kFlexBehaviorKey, - views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero, + views::FlexSpecification(views::LayoutOrientation::kHorizontal, + views::MinimumFlexSizeRule::kScaleToZero, views::MaximumFlexSizeRule::kUnbounded) .WithOrder(2));
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 8f458af..25f3f391 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
@@ -1753,6 +1753,12 @@ 141, "emshack@chromium.org", "Shown in the tab context menu when the user enters or exits split " "view."))); + + registry.RegisterFeature(user_education::NewBadgeSpecification( + features::kSideBySideLinkMenuNewBadge, + user_education::Metadata(141, "emshack@chromium.org", + "Shown in the link context menu to open the " + "link in a new split tab."))); } std::unique_ptr<user_education::FeaturePromoControllerCommon>
diff --git a/chrome/browser/ui/views/web_apps/deprecated_apps_dialog_view.cc b/chrome/browser/ui/views/web_apps/deprecated_apps_dialog_view.cc index bc98e81..71c0ccc 100644 --- a/chrome/browser/ui/views/web_apps/deprecated_apps_dialog_view.cc +++ b/chrome/browser/ui/views/web_apps/deprecated_apps_dialog_view.cc
@@ -54,7 +54,7 @@ content::WebContents* web_contents, base::RepeatingClosure on_icon_updated) : on_icon_updated_(on_icon_updated) { - for (extensions::ExtensionId app_id : deprecated_app_ids) { + for (const extensions::ExtensionId& app_id : deprecated_app_ids) { auto* browser_context = web_contents->GetBrowserContext(); const extensions::Extension* extension = extensions::ExtensionRegistry::Get(browser_context) @@ -255,7 +255,7 @@ } void DeprecatedAppsDialogView::OnAccept() { - for (extensions::ExtensionId id : deprecated_app_ids_) { + for (const extensions::ExtensionId& id : deprecated_app_ids_) { extensions::ExtensionRegistrar::Get(web_contents_->GetBrowserContext()) ->UninstallExtension(id, extensions::UNINSTALL_REASON_USER_INITIATED, /*error=*/nullptr);
diff --git a/chrome/browser/ui/views/webauthn/authenticator_hybrid_and_security_key_sheet_view.cc b/chrome/browser/ui/views/webauthn/authenticator_hybrid_and_security_key_sheet_view.cc index 4f459c4..f23d57b 100644 --- a/chrome/browser/ui/views/webauthn/authenticator_hybrid_and_security_key_sheet_view.cc +++ b/chrome/browser/ui/views/webauthn/authenticator_hybrid_and_security_key_sheet_view.cc
@@ -64,7 +64,7 @@ header_view->SetMultiLine(true); header_view->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); - for (auto description_text : descriptions) { + for (const auto& description_text : descriptions) { auto* description_view = description_column->AddChildView(std::make_unique<views::Label>( description_text, views::style::CONTEXT_DIALOG_BODY_TEXT));
diff --git a/chrome/browser/ui/webui/accessibility/accessibility_ui.cc b/chrome/browser/ui/webui/accessibility/accessibility_ui.cc index ce38400..d7a9cff6 100644 --- a/chrome/browser/ui/webui/accessibility/accessibility_ui.cc +++ b/chrome/browser/ui/webui/accessibility/accessibility_ui.cc
@@ -340,7 +340,7 @@ std::string line = node_delegate->GetData().ToString(); std::vector<std::string> attributes = base::SplitString( line, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - for (std::string attribute : attributes) { + for (const std::string& attribute : attributes) { if (ui::AXTreeFormatter::MatchesPropertyFilters(property_filters, attribute, false)) { str += attribute + " "; @@ -988,7 +988,7 @@ StopRecording(web_contents); std::string event_logs_str; - for (std::string log : event_logs_) { + for (const std::string& log : event_logs_) { event_logs_str += log; event_logs_str += "\n"; }
diff --git a/chrome/browser/ui/webui/commerce/product_specifications_disclosure_dialog.cc b/chrome/browser/ui/webui/commerce/product_specifications_disclosure_dialog.cc index 3bb3af72..cd43e2c 100644 --- a/chrome/browser/ui/webui/commerce/product_specifications_disclosure_dialog.cc +++ b/chrome/browser/ui/webui/commerce/product_specifications_disclosure_dialog.cc
@@ -108,7 +108,7 @@ base::Value::Dict DialogArgs::ToValue() { base::Value::Dict dialog_args_value; base::Value::List product_spec_urls; - for (auto url : urls) { + for (const auto& url : urls) { product_spec_urls.Append(url.spec()); } dialog_args_value.Set(kDialogArgsName, std::move(name));
diff --git a/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc b/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc index d1fb8f1..9a0097d 100644 --- a/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc +++ b/chrome/browser/ui/webui/omnibox/omnibox_page_handler.cc
@@ -436,7 +436,7 @@ BitmapFetcherService* bitmap_fetcher_service = BitmapFetcherServiceFactory::GetForBrowserContext(profile_); - for (std::string image_url : image_urls) { + for (const std::string& image_url : image_urls) { if (image_url.empty()) { continue; }
diff --git a/chrome/browser/ui/webui/searchbox/lens_searchbox_handler.cc b/chrome/browser/ui/webui/searchbox/lens_searchbox_handler.cc index 4595d56..1835254 100644 --- a/chrome/browser/ui/webui/searchbox/lens_searchbox_handler.cc +++ b/chrome/browser/ui/webui/searchbox/lens_searchbox_handler.cc
@@ -27,7 +27,7 @@ namespace { // Interface that allows the Lens searchbox to interact with its embedder -// (i.e., LensOverlayController). +// (i.e., LensSearchboxController). class LensOmniboxClient : public OmniboxClient { public: LensOmniboxClient(Profile* profile,
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc index c29607f..689fb3f 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler.cc +++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -460,9 +460,9 @@ // site eTLD+1 : {owner site eTLD+1, # of sites in that related website set} std::map<std::string, std::pair<std::string, int>> rws_map; - for (auto rws : rws_owner_to_members) { + for (const auto& rws : rws_owner_to_members) { // Set rws owner and count of members for each eTLD+1 - for (auto member : rws.second) { + for (const auto& member : rws.second) { rws_map[member] = {rws.first, rws.second.size()}; } }
diff --git a/chrome/browser/vr/BUILD.gn b/chrome/browser/vr/BUILD.gn index bea0012..5e2e667c 100644 --- a/chrome/browser/vr/BUILD.gn +++ b/chrome/browser/vr/BUILD.gn
@@ -14,6 +14,12 @@ import("//build/config/android/rules.gni") } +if (translate_genders) { + _gender_suffix = "_OTHER" +} else { + _gender_suffix = "" +} + assert(enable_vr) component("vr_ui") { @@ -400,9 +406,9 @@ repack("vr_test_pak") { sources = [ - "$root_gen_dir/chrome/generated_resources_en-US.pak", + "$root_gen_dir/chrome/generated_resources_en-US${_gender_suffix}.pak", "$root_gen_dir/components/components_resources.pak", - "$root_gen_dir/components/strings/components_strings_en-US.pak", + "$root_gen_dir/components/strings/components_strings_en-US${_gender_suffix}.pak", ] output = "$root_out_dir/vr_test.pak"
diff --git a/chrome/browser/web_applications/extensions/extension_status_utils.cc b/chrome/browser/web_applications/extensions/extension_status_utils.cc index 5b859199..b420b43 100644 --- a/chrome/browser/web_applications/extensions/extension_status_utils.cc +++ b/chrome/browser/web_applications/extensions/extension_status_utils.cc
@@ -131,7 +131,7 @@ std::vector<std::string> allowed_extension_ids = base::SplitString(kChromeAppAllowlist.Get(), ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - for (std::string allowed_extension_id : allowed_extension_ids) { + for (const std::string& allowed_extension_id : allowed_extension_ids) { if (extension_id == allowed_extension_id) return false; }
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_update_manager.cc b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_update_manager.cc index ac57bb7..6db25ac 100644 --- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_update_manager.cc +++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_update_manager.cc
@@ -310,7 +310,7 @@ return; } - for (WebApp web_app : provider_->registrar_unsafe().GetApps()) { + for (const WebApp& web_app : provider_->registrar_unsafe().GetApps()) { if (!web_app.isolation_data().has_value() || !web_app.isolation_data()->pending_update_info().has_value()) { continue;
diff --git a/chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest_fetcher.cc b/chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest_fetcher.cc index ae0faee..8087c5e 100644 --- a/chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest_fetcher.cc +++ b/chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest_fetcher.cc
@@ -102,31 +102,13 @@ void UpdateManifestFetcher::ParseUpdateManifest( const std::string& update_manifest_content) { - InitializeJsonParser(); + base::JSONReader::Result result = + base::JSONReader::ReadAndReturnValueWithError(update_manifest_content, + base::JSON_PARSE_RFC); - json_parser_->Parse( - update_manifest_content, base::JSON_PARSE_RFC, - base::BindOnce(&UpdateManifestFetcher::OnUpdateManifestParsed, - base::Unretained(this))); -} - -void UpdateManifestFetcher::InitializeJsonParser() { - CHECK(!json_parser_); - data_decoder_.GetService()->BindJsonParser( - json_parser_.BindNewPipeAndPassReceiver()); - json_parser_.set_disconnect_handler(base::BindOnce( - &UpdateManifestFetcher::OnUpdateManifestParsed, base::Unretained(this), - std::nullopt, "JsonParser terminated unexpectedly")); -} - -void UpdateManifestFetcher::OnUpdateManifestParsed( - std::optional<base::Value> result, - const std::optional<std::string>& error) { if (!result.has_value()) { - if (error.has_value()) { - LOG(ERROR) << "Unable to parse IWA Update Manifest JSON for URL " << url_ - << ". Error: was" << *error; - } + LOG(ERROR) << "Unable to parse IWA Update Manifest JSON for URL " << url_ + << ". Error: was" << result.error().message; std::move(fetch_callback_).Run(base::unexpected(Error::kInvalidJson)); return; }
diff --git a/chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest_fetcher.h b/chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest_fetcher.h index 8e0fba52..2bc19cc 100644 --- a/chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest_fetcher.h +++ b/chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest_fetcher.h
@@ -5,17 +5,11 @@ #ifndef CHROME_BROWSER_WEB_APPLICATIONS_ISOLATED_WEB_APPS_UPDATE_MANIFEST_UPDATE_MANIFEST_FETCHER_H_ #define CHROME_BROWSER_WEB_APPLICATIONS_ISOLATED_WEB_APPS_UPDATE_MANIFEST_UPDATE_MANIFEST_FETCHER_H_ -#include <optional> - #include "base/functional/callback.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/types/expected.h" -#include "base/values.h" -#include "mojo/public/cpp/bindings/remote.h" #include "net/traffic_annotation/network_traffic_annotation.h" -#include "services/data_decoder/public/cpp/data_decoder.h" -#include "services/data_decoder/public/mojom/json_parser.mojom.h" #include "url/gurl.h" namespace network { @@ -57,11 +51,6 @@ void ParseUpdateManifest(const std::string& update_manifest_content); - void InitializeJsonParser(); - - void OnUpdateManifestParsed(std::optional<base::Value> result, - const std::optional<std::string>& error); - GURL url_; net::PartialNetworkTrafficAnnotationTag partial_traffic_annotation_; scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; @@ -70,9 +59,6 @@ std::unique_ptr<network::SimpleURLLoader> simple_url_loader_; - data_decoder::DataDecoder data_decoder_; - mojo::Remote<data_decoder::mojom::JsonParser> json_parser_; - base::WeakPtrFactory<UpdateManifestFetcher> weak_factory_{this}; };
diff --git a/chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest_fetcher_unittest.cc b/chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest_fetcher_unittest.cc index ec054a2..ecec125 100644 --- a/chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest_fetcher_unittest.cc +++ b/chrome/browser/web_applications/isolated_web_apps/update_manifest/update_manifest_fetcher_unittest.cc
@@ -16,7 +16,6 @@ #include "net/http/http_status_code.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" -#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/public/mojom/url_response_head.mojom.h" @@ -90,7 +89,6 @@ } base::test::TaskEnvironment task_environment_; - data_decoder::test::InProcessDataDecoder in_process_data_decoder_; network::TestURLLoaderFactory test_factory_; scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_; };
diff --git a/chrome/browser/web_applications/user_uninstalled_preinstalled_web_app_prefs.cc b/chrome/browser/web_applications/user_uninstalled_preinstalled_web_app_prefs.cc index eabd0f1..2962b83 100644 --- a/chrome/browser/web_applications/user_uninstalled_preinstalled_web_app_prefs.cc +++ b/chrome/browser/web_applications/user_uninstalled_preinstalled_web_app_prefs.cc
@@ -41,9 +41,9 @@ AppendExistingInstallUrlsPerAppId(app_id, install_urls); - for (auto install_url : install_urls) + for (const auto& install_url : install_urls) { url_list.Append(install_url.spec()); - + } if (!DoesAppIdExist(app_id)) { base::RecordAction( base::UserMetricsAction(kUserUninstalledPreinstalledAppAction)); @@ -191,7 +191,7 @@ existing_urls.emplace(url.GetString()); } - for (auto it : url_map) { + for (const auto& it : url_map) { if (only_default && !(it.first == WebAppManagement::kDefault)) continue;
diff --git a/chrome/browser/web_applications/web_app.cc b/chrome/browser/web_applications/web_app.cc index a2e7d21..869b4a1 100644 --- a/chrome/browser/web_applications/web_app.cc +++ b/chrome/browser/web_applications/web_app.cc
@@ -1116,7 +1116,7 @@ OptionalToStringValue(latest_install_source_)); base::Value::Dict external_map; - for (auto it : management_to_external_config_map_) { + for (const auto& it : management_to_external_config_map_) { external_map.Set(base::ToString(it.first), it.second.AsDebugValue()); }
diff --git a/chrome/browser/web_applications/web_app_icon_manager.cc b/chrome/browser/web_applications/web_app_icon_manager.cc index d8373d6..31aea62 100644 --- a/chrome/browser/web_applications/web_app_icon_manager.cc +++ b/chrome/browser/web_applications/web_app_icon_manager.cc
@@ -613,7 +613,7 @@ TRACE_EVENT0("ui", "web_app_icon_manager::CheckForEmptyOrMissingIconFilesBlocking"); WebAppIconManager::IconFilesCheck result; - for (auto it : purpose_to_sizes) { + for (const auto& it : purpose_to_sizes) { const IconPurpose& purpose = it.first; const SortedSizesPx& square_sizes = it.second; for (SquareSizePx size : square_sizes) {
diff --git a/chrome/browser/web_applications/web_app_registrar.cc b/chrome/browser/web_applications/web_app_registrar.cc index 29bced9..a9c75ef 100644 --- a/chrome/browser/web_applications/web_app_registrar.cc +++ b/chrome/browser/web_applications/web_app_registrar.cc
@@ -763,7 +763,7 @@ std::optional<webapps::AppId> WebAppRegistrar::LookUpAppIdByInstallUrl( const GURL& install_url) const { for (const WebApp& web_app : GetApps()) { - for (auto it : web_app.management_to_external_config_map()) { + for (const auto& it : web_app.management_to_external_config_map()) { if (base::Contains(it.second.install_urls, install_url)) { return web_app.app_id(); }
diff --git a/chrome/browser/webauthn/chrome_web_authentication_delegate.cc b/chrome/browser/webauthn/chrome_web_authentication_delegate.cc index d8e7793..810a8f6 100644 --- a/chrome/browser/webauthn/chrome_web_authentication_delegate.cc +++ b/chrome/browser/webauthn/chrome_web_authentication_delegate.cc
@@ -194,7 +194,7 @@ PasskeyModelFactory::GetInstance()->GetForProfile( Profile::FromBrowserContext(web_contents->GetBrowserContext())); bool is_passkey_deleted = false; - for (auto passkey : + for (const auto& passkey : passkey_store->GetPasskeysForRelyingPartyId(relying_party_id)) { if (std::vector<uint8_t>(passkey.user_id().begin(), passkey.user_id().end()) == user_id &&
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt index e50eb21..4de393b2 100644 --- a/chrome/build/android-arm32.pgo.txt +++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@ -chrome-android32-main-1746727053-c006a3a875b245a51c092aeb67b377805c30708e-8a7e3eb58b861bad419563c7eab04a42cd628814.profdata +chrome-android32-main-1746748670-2ec1d34d52d69562137d213db1c31c74f5cd066f-1207e2173d79ef83a8e573890fa04e804afca8de.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt index 9b87470..b05e3f8 100644 --- a/chrome/build/android-arm64.pgo.txt +++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@ -chrome-android64-main-1746726018-ef891a08c418460a6c677b527a250b14a21e205a-25859c3ed77222679ee9535931365b4e8531cdeb.profdata +chrome-android64-main-1746748670-e30c706e068b0e4acf605ef75468e713d1723c88-1207e2173d79ef83a8e573890fa04e804afca8de.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 6c7babc..ca0d68f 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1746705526-d3b858f55d3cb04e6c9c7e52b6464d531736ef8a-d85876276c358c68ff50521bcaa24e5d3998dc14.profdata +chrome-linux-main-1746727053-8bffbdf05c0e2a814cf7e11b77bd671857ac0e9a-8a7e3eb58b861bad419563c7eab04a42cd628814.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 40d6783..5be0e9a 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1746727053-d8e673618cc0fda4407fdb86ef3cc8b00db58b8c-8a7e3eb58b861bad419563c7eab04a42cd628814.profdata +chrome-mac-arm-main-1746748670-a98f730b785ee81b3fc972377e3fb791da3dda8f-1207e2173d79ef83a8e573890fa04e804afca8de.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 6d2f30d..95ce86e4 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1746705526-e440c23f778167c962a6909421e8516330996a14-d85876276c358c68ff50521bcaa24e5d3998dc14.profdata +chrome-mac-main-1746727053-a3d66ff1fe809b42166d1a8ecea42b77ac02ce2a-8a7e3eb58b861bad419563c7eab04a42cd628814.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt index e44e7275..96ec547 100644 --- a/chrome/build/win-arm64.pgo.txt +++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@ -chrome-win-arm64-main-1746705526-85979f5b75f8352c207553c64967b8f1cfe8d570-d85876276c358c68ff50521bcaa24e5d3998dc14.profdata +chrome-win-arm64-main-1746727053-9915f3cafb45e9b9e2f98fcd1d5170db100e5af0-8a7e3eb58b861bad419563c7eab04a42cd628814.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index cb3d110..0eaaef3 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1746705526-40334b70257e603470ff093884495a1ac7a52dbc-d85876276c358c68ff50521bcaa24e5d3998dc14.profdata +chrome-win32-main-1746727053-8236c72987ba273680c6f01e32b6737857aea696-8a7e3eb58b861bad419563c7eab04a42cd628814.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index dd84077..17b73c02 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1746694515-0ede87d31ffde351912da9e2bd0803f2b55eb044-06dbc4719305742aa3f7c09eec1b2bc5f2612f5e.profdata +chrome-win64-main-1746705526-0d35afe1bf28d770dc921d45bfb35fab421ede29-d85876276c358c68ff50521bcaa24e5d3998dc14.profdata
diff --git a/chrome/renderer/accessibility/phrase_segmentation/dependency_tree.cc b/chrome/renderer/accessibility/phrase_segmentation/dependency_tree.cc index 77213255fa..5c0a69f 100644 --- a/chrome/renderer/accessibility/phrase_segmentation/dependency_tree.cc +++ b/chrome/renderer/accessibility/phrase_segmentation/dependency_tree.cc
@@ -38,7 +38,7 @@ bool updated = true; while (updated) { updated = false; - for (auto token : dep_head_array_) { + for (const auto& token : dep_head_array_) { // Expand parent boundary to include all child boundaries, and repeat // until all boundaries have been updated. if (token.dependency_head != token.absolute_index) {
diff --git a/chrome/renderer/accessibility/phrase_segmentation/token_boundaries.cc b/chrome/renderer/accessibility/phrase_segmentation/token_boundaries.cc index 5a7aa40..e521376 100644 --- a/chrome/renderer/accessibility/phrase_segmentation/token_boundaries.cc +++ b/chrome/renderer/accessibility/phrase_segmentation/token_boundaries.cc
@@ -47,7 +47,7 @@ // tokens to become stranded. void TokenBoundaries::InitializeBoundaryWeightsFromTree( const DependencyTree& tree) { - for (auto token : tree.dep_head_array()) { + for (const auto& token : tree.dep_head_array()) { int weight = abs(token.dependency_head - token.absolute_index); if (weight == 0) { continue;
diff --git a/chrome/renderer/accessibility/read_anything/read_aloud_app_model.cc b/chrome/renderer/accessibility/read_anything/read_aloud_app_model.cc index e0203e6..39606fcc 100644 --- a/chrome/renderer/accessibility/read_anything/read_aloud_app_model.cc +++ b/chrome/renderer/accessibility/read_anything/read_aloud_app_model.cc
@@ -256,7 +256,7 @@ // Reconstruct the tokenized sentence using the tokens. std::vector<std::u16string> u16string_tokens; - for (auto token : tokens) { + for (const auto& token : tokens) { u16string_tokens.emplace_back(base::UTF8ToUTF16(token)); } @@ -628,8 +628,7 @@ if (base::Contains(current_granularity.segments, id)) { return true; } - for (a11y::ReadAloudCurrentGranularity granularity : - processed_granularities_on_current_page_) { + for (const auto& granularity : processed_granularities_on_current_page_) { if (base::Contains(granularity.segments, id)) { return true; }
diff --git a/chrome/renderer/accessibility/read_anything/read_anything_node_utils_unittest.cc b/chrome/renderer/accessibility/read_anything/read_anything_node_utils_unittest.cc index 2595f7d..23138afd 100644 --- a/chrome/renderer/accessibility/read_anything/read_anything_node_utils_unittest.cc +++ b/chrome/renderer/accessibility/read_anything/read_anything_node_utils_unittest.cc
@@ -112,6 +112,49 @@ EXPECT_NE(text.find('\r'), std::string::npos); } +TEST_F(ReadAnythingNodeUtilsTest, IsIgnored_ReturnsTrueWhenAXNodeIsIgnored) { + static constexpr ui::AXNodeID kId = 2; + ui::AXNodeData data = test::TextNode(kId); + data.role = ax::mojom::Role::kNone; + ui::AXTree tree; + ui::AXNode node(&tree, nullptr, kId, 0); + node.SetData(std::move(data)); + + EXPECT_TRUE(node.IsIgnored()); + // The node should be ignored regardless of whether it is a PDF. + EXPECT_TRUE(a11y::IsIgnored(&node, /*is_pdf=*/false)); + EXPECT_TRUE(a11y::IsIgnored(&node, /*is_pdf=*/true)); +} + +TEST_F(ReadAnythingNodeUtilsTest, IsIgnored_ControlElementsIgnored) { + const std::u16string sentence = u"One day more!"; + + static constexpr ui::AXNodeID kId = 2; + ui::AXNodeData control_not_text_field_data = test::TextNode(kId, sentence); + control_not_text_field_data.role = ax::mojom::Role::kSpinButton; + + ui::AXNodeData text_field_data = test::TextNode(kId, sentence); + text_field_data.role = ax::mojom::Role::kTextField; + + ui::AXNodeData select_data = test::TextNode(kId, sentence); + select_data.role = ax::mojom::Role::kRadioGroup; + + ui::AXTree tree; + ui::AXNode node(&tree, nullptr, kId, 0); + + // Control nodes are ignored. + node.SetData(std::move(control_not_text_field_data)); + EXPECT_TRUE(a11y::IsIgnored(&node, false)); + + // Text field nodes are not ignored. + node.SetData(std::move(text_field_data)); + EXPECT_FALSE(a11y::IsIgnored(&node, false)); + + // Select field nodes are ignored + node.SetData(std::move(select_data)); + EXPECT_TRUE(a11y::IsIgnored(&node, false)); +} + TEST_F(ReadAnythingNodeUtilsTest, IsSuperscript) { const std::u16string sentence = u"This is a superscript: <sup>superscript</sup>"; @@ -125,3 +168,104 @@ node.SetData(std::move(data)); EXPECT_TRUE(a11y::IsSuperscript(&node)); } + +TEST_F(ReadAnythingNodeUtilsTest, GetHtmlTag_ReturnsDivForTextField) { + const std::u16string sentence1 = + u"Why do you write like it\'s going out of style?"; + const std::u16string sentence2 = + u"Why do you write like you\'re running out of time?"; + + ui::AXNodeData data_with_html_tag = test::TextNode(2, sentence1); + data_with_html_tag.AddStringAttribute(ax::mojom::StringAttribute::kHtmlTag, + "p"); + data_with_html_tag.role = ax::mojom::Role::kTextField; + + ui::AXNodeData data_with_no_html_tag = test::TextNode(2, sentence2); + data_with_no_html_tag.AddStringAttribute(ax::mojom::StringAttribute::kHtmlTag, + ""); + data_with_no_html_tag.role = ax::mojom::Role::kTextField; + + ui::AXTree tree; + ui::AXNode node(&tree, nullptr, 2, 0); + node.SetData(std::move(data_with_html_tag)); + EXPECT_EQ(a11y::GetHtmlTag(&node, false, false), "div"); + + node.SetData(std::move(data_with_no_html_tag)); + EXPECT_EQ(a11y::GetHtmlTag(&node, false, false), "div"); +} + +TEST_F(ReadAnythingNodeUtilsTest, GetHtmlTag_ReturnsHeadingTag) { + const std::u16string sentence1 = u"Heading 1"; + const std::u16string sentence2 = u"Heading 2"; + + ui::AXNodeData heading_data = test::TextNode(2, sentence1); + heading_data.AddIntAttribute(ax::mojom::IntAttribute::kHierarchicalLevel, 1); + heading_data.role = ax::mojom::Role::kHeading; + + ui::AXTree tree; + ui::AXNode node(&tree, nullptr, 2, 0); + node.SetData(std::move(heading_data)); + EXPECT_EQ(a11y::GetHtmlTag(&node, false, false), "h1"); + + heading_data.AddIntAttribute(ax::mojom::IntAttribute::kHierarchicalLevel, 2); + node.SetData(std::move(heading_data)); + EXPECT_EQ(a11y::GetHtmlTag(&node, false, false), "h2"); +} + +TEST_F(ReadAnythingNodeUtilsTest, GetHtmlTag_MarkElementReturnsBold) { + const std::u16string sentence = u"Mark element"; + + ui::AXNodeData data = test::TextNode(2, sentence); + data.AddStringAttribute(ax::mojom::StringAttribute::kHtmlTag, "mark"); + + ui::AXTree tree; + ui::AXNode node(&tree, nullptr, 2, 0); + node.SetData(std::move(data)); + EXPECT_EQ(a11y::GetHtmlTag(&node, false, false), "b"); +} + +TEST_F(ReadAnythingNodeUtilsTest, GetHtmlTag_ReturnsHtmlTagForDocs) { + const std::u16string sentence = u"Google docs document"; + + ui::AXNodeData data = test::TextNode(2, sentence); + data.AddStringAttribute(ax::mojom::StringAttribute::kHtmlTag, "svg"); + + ui::AXTree tree; + ui::AXNode node(&tree, nullptr, 2, 0); + node.SetData(std::move(data)); + + // SVG elements should be changed to div tags for Docs. + EXPECT_EQ(a11y::GetHtmlTag(&node, /* is_pdf= */ false, /* is_docs= */ true), + "div"); + + // Paragraphs with the g tag should be changed to the p tag for Docs. + data.AddStringAttribute(ax::mojom::StringAttribute::kHtmlTag, "g"); + data.role = ax::mojom::Role::kParagraph; + node.SetData(std::move(data)); + EXPECT_EQ(a11y::GetHtmlTag(&node, /* is_pdf= */ false, /* is_docs= */ true), + "p"); +} + +TEST_F(ReadAnythingNodeUtilsTest, GetHtmlTag_ReturnsExpectedTag) { + const std::u16string sentence = u"Tomorrow is another day"; + + ui::AXNodeData data = test::TextNode(2, sentence); + data.AddStringAttribute(ax::mojom::StringAttribute::kHtmlTag, "p"); + + ui::AXTree tree; + ui::AXNode node(&tree, nullptr, 2, 0); + node.SetData(std::move(data)); + EXPECT_EQ(a11y::GetHtmlTag(&node, false, false), "p"); + + data.AddStringAttribute(ax::mojom::StringAttribute::kHtmlTag, "b"); + node.SetData(std::move(data)); + EXPECT_EQ(a11y::GetHtmlTag(&node, false, false), "b"); + + data.AddStringAttribute(ax::mojom::StringAttribute::kHtmlTag, "head"); + node.SetData(std::move(data)); + EXPECT_EQ(a11y::GetHtmlTag(&node, false, false), "head"); + + data.AddStringAttribute(ax::mojom::StringAttribute::kHtmlTag, "img"); + node.SetData(std::move(data)); + EXPECT_EQ(a11y::GetHtmlTag(&node, false, false), "img"); +}
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 09daa5a..ef8918c 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -10134,7 +10134,7 @@ "../browser/ui/views/frame/browser_non_client_frame_view_unittest.cc", "../browser/ui/views/frame/browser_view_layout_unittest.cc", "../browser/ui/views/frame/browser_view_unittest.cc", - "../browser/ui/views/frame/multi_contents_view_drag_entrypoint_controller_unittest.cc", + "../browser/ui/views/frame/multi_contents_view_drop_target_controller_unittest.cc", "../browser/ui/views/frame/tab_strip_region_view_unittest.cc", "../browser/ui/views/frame/web_contents_close_handler_unittest.cc", "../browser/ui/views/global_media_controls/cast_device_footer_view_unittest.cc",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/MessageFacility.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/MessageFacility.java index e257900..5be4687 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/MessageFacility.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/MessageFacility.java
@@ -12,14 +12,12 @@ import android.os.Build; import android.view.View; -import androidx.annotation.CallSuper; import androidx.test.espresso.action.GeneralLocation; import androidx.test.espresso.action.GeneralSwipeAction; import androidx.test.espresso.action.Press; import androidx.test.espresso.action.Swipe; import androidx.test.espresso.action.ViewActions; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Facility; import org.chromium.base.test.transit.Station; import org.chromium.base.test.transit.Transition; @@ -48,16 +46,12 @@ public ViewElement<View> bannerElement; public ViewElement<View> iconElement; - @CallSuper - @Override - public void declareElements(Elements.Builder elements) { + public MessageFacility() { // Unscoped because other messages can appear and fail the exit condition. bannerElement = - elements.declareView( - viewSpec(withId(R.id.message_banner)), ViewElement.unscopedOption()); + declareView(viewSpec(withId(R.id.message_banner)), ViewElement.unscopedOption()); iconElement = - elements.declareView( - viewSpec(withId(R.id.message_icon)), ViewElement.unscopedOption()); + declareView(viewSpec(withId(R.id.message_icon)), ViewElement.unscopedOption()); } /** Dismiss the message banner. */
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/SnackbarFacility.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/SnackbarFacility.java index 567265c..df04b94 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/SnackbarFacility.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/SnackbarFacility.java
@@ -15,7 +15,6 @@ import androidx.annotation.Nullable; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Facility; import org.chromium.base.test.transit.Station; import org.chromium.base.test.transit.ViewElement; @@ -31,36 +30,27 @@ public class SnackbarFacility<HostStationT extends Station<?>> extends Facility<HostStationT> { public static final String NO_BUTTON = "__NO_BUTTON__"; - private final String mExpectedMessageSubstring; - private final String mExpectedButtonText; public ViewElement<View> messageElement; public ViewElement<View> buttonElement; public SnackbarFacility( @Nullable String expectedMessageSubstring, @Nullable String expectedButtonText) { - super(); - mExpectedMessageSubstring = expectedMessageSubstring; - mExpectedButtonText = expectedButtonText; - } - - @Override - public void declareElements(Elements.Builder elements) { - messageElement = elements.declareView(viewSpec(withId(R.id.snackbar_message))); - if (mExpectedMessageSubstring != null) { - elements.declareEnterCondition( + messageElement = declareView(viewSpec(withId(R.id.snackbar_message))); + if (expectedMessageSubstring != null) { + declareEnterCondition( new ViewElementMatchesCondition( - messageElement, withText(containsString(mExpectedMessageSubstring)))); + messageElement, withText(containsString(expectedMessageSubstring)))); } ViewSpec<View> buttonSpec = viewSpec(withId(R.id.snackbar_button)); - if (NO_BUTTON.equals(mExpectedButtonText)) { - elements.declareNoView(buttonSpec); + if (NO_BUTTON.equals(expectedButtonText)) { + declareNoView(buttonSpec); } else { - buttonElement = elements.declareView(buttonSpec); - if (mExpectedButtonText != null) { - elements.declareEnterCondition( + buttonElement = declareView(buttonSpec); + if (expectedButtonText != null) { + declareEnterCondition( new ViewElementMatchesCondition( - buttonElement, withText(mExpectedButtonText))); + buttonElement, withText(expectedButtonText))); } } }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/SoftKeyboardFacility.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/SoftKeyboardFacility.java index 75aec37..81a6003 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/SoftKeyboardFacility.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/SoftKeyboardFacility.java
@@ -6,7 +6,6 @@ import androidx.test.espresso.Espresso; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Facility; import org.chromium.base.test.transit.Station; import org.chromium.base.test.transit.Transition; @@ -15,12 +14,12 @@ /** Represents the soft keyboard shown, expecting it to hide after exiting the Facility. */ public class SoftKeyboardFacility extends Facility<Station<?>> { - private SoftKeyboardElement mSoftKeyboardElement; + public SoftKeyboardElement softKeyboardElement; @Override - public void declareElements(Elements.Builder elements) { - mSoftKeyboardElement = - elements.declareElement(new SoftKeyboardElement(mHostStation.getActivityElement())); + public void declareExtraElements() { + softKeyboardElement = + declareElement(new SoftKeyboardElement(mHostStation.getActivityElement())); } /** @@ -34,7 +33,7 @@ public void close(ViewElement... viewElementsToSettle) { assertInPhase(Phase.ACTIVE); - if (mSoftKeyboardElement.get()) { + if (softKeyboardElement.get()) { // Keyboard was expected to be shown // If this fails, the keyboard was closed before, but not by this facility.
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/dom_distiller/ReaderModePreferencesDialog.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/dom_distiller/ReaderModePreferencesDialog.java index a29fae2..b67f61eb 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/dom_distiller/ReaderModePreferencesDialog.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/dom_distiller/ReaderModePreferencesDialog.java
@@ -22,7 +22,6 @@ import org.chromium.base.test.transit.CarryOn; import org.chromium.base.test.transit.Condition; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.ViewElement; import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.test.R; @@ -40,8 +39,7 @@ public ViewElement<Spinner> fontFamilySpinnerElement; public ViewElement<SeekBar> fontSizeSliderElement; - @Override - public void declareElements(Elements.Builder elements) { + public ReaderModePreferencesDialog() { /* DecorView ╰── LinearLayout @@ -64,13 +62,11 @@ ├── @id/font_size | AppCompatSeekBar ╰── "A" | MaterialTextView */ - darkButtonElement = elements.declareView(viewSpec(Button.class, withText("Dark"))); - sepiaButtonElement = elements.declareView(viewSpec(Button.class, withText("Sepia"))); - lightButtonElement = elements.declareView(viewSpec(Button.class, withText("Light"))); - fontFamilySpinnerElement = - elements.declareView(viewSpec(Spinner.class, withId(R.id.font_family))); - fontSizeSliderElement = - elements.declareView(viewSpec(SeekBar.class, withId(R.id.font_size))); + darkButtonElement = declareView(viewSpec(Button.class, withText("Dark"))); + sepiaButtonElement = declareView(viewSpec(Button.class, withText("Sepia"))); + lightButtonElement = declareView(viewSpec(Button.class, withText("Light"))); + fontFamilySpinnerElement = declareView(viewSpec(Spinner.class, withId(R.id.font_family))); + fontSizeSliderElement = declareView(viewSpec(SeekBar.class, withId(R.id.font_size))); } public void pickColorLight(Condition condition) {
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/edge_to_edge/EdgeToEdgeBottomChinFacility.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/edge_to_edge/EdgeToEdgeBottomChinFacility.java index 508477e..899bc72 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/edge_to_edge/EdgeToEdgeBottomChinFacility.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/edge_to_edge/EdgeToEdgeBottomChinFacility.java
@@ -7,7 +7,6 @@ import org.chromium.base.test.transit.Condition; import org.chromium.base.test.transit.ConditionStatus; import org.chromium.base.test.transit.Element; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Facility; import org.chromium.base.test.transit.Station; import org.chromium.base.test.transit.UiThreadCondition; @@ -43,19 +42,19 @@ } @Override - public void declareElements(Elements.Builder elements) { + public void declareExtraElements() { edgeToEdgeControllerElement = - elements.declareEnterConditionAsElement( + declareEnterConditionAsElement( new EdgeToEdgeControllerCondition(mHostStation.getActivityElement())); bottomControlsStackerElement = - elements.declareEnterConditionAsElement( + declareEnterConditionAsElement( new BottomControlsStackerCondition(mHostStation.getActivityElement())); bottomChinElement = - elements.declareEnterConditionAsElement( + declareEnterConditionAsElement( new BottomChinCondition(bottomControlsStackerElement)); if (mExpectPageOptIn != null) { - elements.declareEnterCondition( + declareEnterCondition( UiThreadCondition.from( "Expected page opt-in edge to edge: " + mExpectPageOptIn, this::isPageOptInEdgeToEdge));
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/edge_to_edge/ViewportFitCoverPageStation.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/edge_to_edge/ViewportFitCoverPageStation.java index 81a41b7..84e859b 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/edge_to_edge/ViewportFitCoverPageStation.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/edge_to_edge/ViewportFitCoverPageStation.java
@@ -8,7 +8,6 @@ import org.chromium.base.supplier.Supplier; import org.chromium.base.test.transit.ConditionStatus; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.LogicalElement; import org.chromium.chrome.browser.browser_controls.BottomControlsStacker; import org.chromium.chrome.browser.browser_controls.BottomControlsStacker.LayerType; @@ -53,24 +52,22 @@ } @Override - public void declareElements(Elements.Builder elements) { - super.declareElements(elements); + public void declareExtraElements() { + super.declareExtraElements(); // Ensure the web page elements are drawn and visible. - mAvoidBottomElement = - elements.declareElement(new HtmlElement(AVOID_BOTTOM_DIV, webContentsElement)); + mAvoidBottomElement = declareElement(new HtmlElement(AVOID_BOTTOM_DIV, webContentsElement)); mFullScreenButtonElement = - elements.declareElement( - new HtmlElement(FULLSCREEN_MAIN_BUTTON, webContentsElement)); + declareElement(new HtmlElement(FULLSCREEN_MAIN_BUTTON, webContentsElement)); // Declare requiring EdgeToEdgeController, meaning #setDecorFitsSystemWindows(false) - elements.declareEnterCondition(new EdgeToEdgeControllerCondition(mActivityElement)); + declareEnterCondition(new EdgeToEdgeControllerCondition(mActivityElement)); // Ensure the bottom chin is on display. Supplier<BottomControlsStacker> bottomControlsStacker = - elements.declareEnterConditionAsElement( + declareEnterConditionAsElement( new BottomControlsStackerCondition(mActivityElement)); - elements.declareElement( + declareElement( LogicalElement.uiThreadLogicalElement( "Bottom chin is not on display", this::isBottomChinShowing,
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/IncognitoTabSwitcherStation.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/IncognitoTabSwitcherStation.java index cf7ce2c..acbff50 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/IncognitoTabSwitcherStation.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/IncognitoTabSwitcherStation.java
@@ -6,7 +6,6 @@ import static androidx.test.espresso.matcher.ViewMatchers.isSelected; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.ViewElementMatchesCondition; import org.chromium.chrome.browser.hub.PaneId; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -34,10 +33,10 @@ } @Override - public void declareElements(Elements.Builder elements) { - super.declareElements(elements); + public void declareExtraElements() { + super.declareExtraElements(); assert incognitoTabsButtonElement != null; - elements.declareEnterCondition( + declareEnterCondition( new ViewElementMatchesCondition(incognitoTabsButtonElement, isSelected())); }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/NewTabGroupDialogFacility.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/NewTabGroupDialogFacility.java index 581375e..bd85084 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/NewTabGroupDialogFacility.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/NewTabGroupDialogFacility.java
@@ -24,7 +24,6 @@ import org.hamcrest.Matcher; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Facility; import org.chromium.base.test.transit.Transition; import org.chromium.base.test.transit.ViewElement; @@ -75,23 +74,23 @@ } @Override - public void declareElements(Elements.Builder elements) { + public void declareExtraElements() { dialogElement = - elements.declareView( + declareView( viewSpec(withId(R.id.visual_data_dialog_layout)), ViewElement.displayingAtLeastOption(80)); - elements.declareView( + declareView( viewSpec(allOf(withId(R.id.visual_data_dialog_title), withText("New tab group")))); titleInputElement = - elements.declareView( + declareView( viewSpec( withId(R.id.title_input_text), isAssignableFrom(EditText.class), withText(mTitle))); // TODO(crbug.com/346377124): Partially cut off in android_30_google_apis_x86.textpb - elements.declareView( + declareView( viewSpec(withId(R.id.color_picker_container)), ViewElement.displayingAtLeastOption(50)); @TabGroupColorId List<Integer> colors = TabGroupColorUtils.getTabGroupColorIdList(); @@ -101,18 +100,18 @@ @TabGroupColorId Integer color = colors.get(i); if (mSelectedColor != null) { colorElements[i] = - elements.declareView( + declareView( colorPickerIconSpec(color, color.equals(mSelectedColor)), ViewElement.newOptions().unscoped().displayingAtLeast(60).build()); } else { colorElements[i] = - elements.declareView( + declareView( colorPickerIconSpec(color, /* selected= */ null), ViewElement.newOptions().unscoped().displayingAtLeast(60).build()); } } - doneButtonElement = elements.declareView(viewSpec(withId(R.id.positive_button))); + doneButtonElement = declareView(viewSpec(withId(R.id.positive_button))); } private ViewSpec<View> colorPickerIconSpec(
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/RegularTabSwitcherStation.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/RegularTabSwitcherStation.java index be111d97..16006ccd 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/RegularTabSwitcherStation.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/RegularTabSwitcherStation.java
@@ -9,7 +9,6 @@ import static org.chromium.base.test.transit.ViewSpec.viewSpec; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.ViewElementMatchesCondition; import org.chromium.base.test.transit.ViewSpec; import org.chromium.chrome.browser.hub.PaneId; @@ -41,13 +40,13 @@ } @Override - public void declareElements(Elements.Builder elements) { - super.declareElements(elements); + public void declareExtraElements() { + super.declareExtraElements(); assert regularTabsButtonElement != null; - elements.declareEnterCondition( + declareEnterCondition( new ViewElementMatchesCondition(regularTabsButtonElement, isSelected())); if (!mRegularTabsExist) { - elements.declareView(EMPTY_STATE_TEXT); + declareView(EMPTY_STATE_TEXT); } }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabGroupDialogFacility.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabGroupDialogFacility.java index 90e2b33d..e1da271 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabGroupDialogFacility.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabGroupDialogFacility.java
@@ -18,7 +18,6 @@ import androidx.annotation.Nullable; import org.chromium.base.ThreadUtils; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Facility; import org.chromium.base.test.transit.Station; import org.chromium.base.test.transit.ViewElement; @@ -102,7 +101,7 @@ } @Override - public void declareElements(Elements.Builder elements) { + public void declareExtraElements() { if (ChromeFeatureList.isEnabled(ChromeFeatureList.DATA_SHARING)) { // TODO(ckitagawa): Add handling for an already shared group. if (isAllowedToShare()) {
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabSwitcherCardFacility.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabSwitcherCardFacility.java index 98491ec7..046152e 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabSwitcherCardFacility.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabSwitcherCardFacility.java
@@ -21,7 +21,6 @@ import org.hamcrest.Matcher; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Facility; import org.chromium.base.test.transit.ViewElement; import org.chromium.base.test.transit.ViewSpec; @@ -43,23 +42,23 @@ @Override @CallSuper - public void declareElements(Elements.Builder elements) { + public void declareExtraElements() { Matcher<View> cardTitleMatcher = allOf(withText(mTitle), withId(R.id.tab_title), withParent(withId(R.id.card_view))); - titleElement = elements.declareView(viewSpec(cardTitleMatcher)); + titleElement = declareView(viewSpec(cardTitleMatcher)); ViewSpec<View> cardSpec = viewSpec(isAssignableFrom(TabGridView.class), hasDescendant(cardTitleMatcher)); - cardViewElement = elements.declareView(cardSpec); + cardViewElement = declareView(cardSpec); if (mCardIndex != null) { - elements.declareEnterCondition( + declareEnterCondition( new CardAtPositionCondition( mCardIndex, mHostStation.recyclerViewElement, cardViewElement)); } } - protected ViewElement<View> declareActionButton(Elements.Builder elements) { - return elements.declareView(cardViewElement.descendant(withId(R.id.action_button))); + protected ViewElement<View> declareActionButton() { + return declareView(cardViewElement.descendant(withId(R.id.action_button))); } }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabSwitcherGroupCardFacility.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabSwitcherGroupCardFacility.java index 9060f10..1a71b4c 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabSwitcherGroupCardFacility.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabSwitcherGroupCardFacility.java
@@ -18,7 +18,6 @@ import androidx.annotation.Nullable; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Facility; import org.chromium.base.test.transit.ViewElement; import org.chromium.base.test.transit.ViewSpec; @@ -68,11 +67,11 @@ } @Override - public void declareElements(Elements.Builder elements) { - super.declareElements(elements); - menuButtonElement = declareActionButton(elements); + public void declareExtraElements() { + super.declareExtraElements(); + menuButtonElement = declareActionButton(); - elements.declareEnterCondition( + declareEnterCondition( new TabGroupExistsCondition( mHostStation.isIncognito(), mTabIdsToGroup,
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabSwitcherSearchStation.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabSwitcherSearchStation.java index af30dea..ac42047 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabSwitcherSearchStation.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabSwitcherSearchStation.java
@@ -21,7 +21,6 @@ import org.hamcrest.Matcher; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Station; import org.chromium.base.test.transit.ViewElement; import org.chromium.base.test.transit.ViewSpec; @@ -45,12 +44,7 @@ public TabSwitcherSearchStation(boolean isIncognito) { super(SearchActivity.class); mIsIncognito = isIncognito; - } - - @Override - public void declareElements(Elements.Builder elements) { - super.declareElements(elements); - urlBarElement = elements.declareView(viewSpec(UrlBar.class, withId(R.id.url_bar))); + urlBarElement = declareView(viewSpec(UrlBar.class, withId(R.id.url_bar))); } public boolean isIncognito() {
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabSwitcherTabCardFacility.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabSwitcherTabCardFacility.java index 66038e3..02207dc 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabSwitcherTabCardFacility.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/TabSwitcherTabCardFacility.java
@@ -8,7 +8,6 @@ import androidx.annotation.Nullable; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.ViewElement; import org.chromium.chrome.test.transit.page.PageStation; @@ -23,9 +22,9 @@ } @Override - public void declareElements(Elements.Builder elements) { - super.declareElements(elements); - closeButtonElement = declareActionButton(elements); + public void declareExtraElements() { + super.declareExtraElements(); + closeButtonElement = declareActionButton(); } /** Clicks the tab card to show the page. */
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/ntp/IncognitoNewTabPageStation.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/ntp/IncognitoNewTabPageStation.java index ffc0f59..10ffcf4e 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/ntp/IncognitoNewTabPageStation.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/ntp/IncognitoNewTabPageStation.java
@@ -14,7 +14,6 @@ import android.view.View; import org.chromium.base.test.transit.Element; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.SimpleConditions; import org.chromium.base.test.transit.ViewElement; import org.chromium.chrome.R; @@ -46,17 +45,16 @@ } @Override - public void declareElements(Elements.Builder elements) { - super.declareElements(elements); + public void declareExtraElements() { + super.declareExtraElements(); - urlBarElement = elements.declareView(URL_BAR); - iconElement = elements.declareView(viewSpec(withId(R.id.new_tab_incognito_icon))); - goneIncognitoTextElement = - elements.declareView(viewSpec(withText("You’ve gone Incognito"))); + urlBarElement = declareView(URL_BAR); + iconElement = declareView(viewSpec(withId(R.id.new_tab_incognito_icon))); + goneIncognitoTextElement = declareView(viewSpec(withText("You’ve gone Incognito"))); nativePageElement = - elements.declareEnterConditionAsElement( + declareEnterConditionAsElement( new NativePageCondition<>(IncognitoNewTabPage.class, loadedTabElement)); - elements.declareEnterCondition( + declareEnterCondition( SimpleConditions.uiThreadCondition( "Incognito NTP is loaded", nativePageElement,
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/ntp/MvtsFacility.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/ntp/MvtsFacility.java index 6ad2b85d..9f8cccad 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/ntp/MvtsFacility.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/ntp/MvtsFacility.java
@@ -13,7 +13,6 @@ import android.view.View; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.MoreViewConditions.ViewHasChildrenCountCondition; import org.chromium.base.test.transit.ScrollableFacility; import org.chromium.base.test.transit.ViewElement; @@ -50,16 +49,18 @@ } @Override - public void declareElements(Elements.Builder elements) { + public void declareExtraElements() { // 1% visibility is enough because this layout is clipped by being inside scroll view in // tablets. tilesLayoutElement = - elements.declareView( + declareView( viewSpec(withId(R.id.mv_tiles_layout)), ViewElement.displayingAtLeastOption(1)); - elements.declareEnterCondition( + declareEnterCondition( new ViewHasChildrenCountCondition(tilesLayoutElement, mSiteSuggestions.size())); - super.declareElements(elements); + + // Will call declareItems() + super.declareExtraElements(); } @Override
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/ntp/RegularNewTabPageStation.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/ntp/RegularNewTabPageStation.java index 7dc84bb..8d7ab94 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/ntp/RegularNewTabPageStation.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/ntp/RegularNewTabPageStation.java
@@ -13,7 +13,6 @@ import android.view.View; import org.chromium.base.test.transit.Element; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.SimpleConditions; import org.chromium.base.test.transit.ViewElement; import org.chromium.chrome.R; @@ -48,10 +47,10 @@ } @Override - public void declareElements(Elements.Builder elements) { - super.declareElements(elements); + public void declareExtraElements() { + super.declareExtraElements(); - elements.declareElementFactory( + declareElementFactory( mActivityElement, delayedElements -> { if (mActivityElement.get().isTablet()) { @@ -61,13 +60,13 @@ } }); - logoElement = elements.declareView(viewSpec(withId(R.id.search_provider_logo))); - searchBoxElement = elements.declareView(viewSpec(withId(R.id.search_box))); + logoElement = declareView(viewSpec(withId(R.id.search_provider_logo))); + searchBoxElement = declareView(viewSpec(withId(R.id.search_box))); nativePageElement = - elements.declareEnterConditionAsElement( + declareEnterConditionAsElement( new NativePageCondition<>(NewTabPage.class, loadedTabElement)); - elements.declareEnterCondition( + declareEnterCondition( SimpleConditions.uiThreadCondition( "Regular NTP is loaded", nativePageElement,
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/omnibox/OmniboxEnteredTextFacility.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/omnibox/OmniboxEnteredTextFacility.java index 3eec4742..1749c87 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/omnibox/OmniboxEnteredTextFacility.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/omnibox/OmniboxEnteredTextFacility.java
@@ -8,7 +8,6 @@ import android.view.View; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Facility; import org.chromium.base.test.transit.Station; import org.chromium.base.test.transit.ViewElement; @@ -28,15 +27,11 @@ public OmniboxEnteredTextFacility(OmniboxFacility omniboxFacility, String text) { mOmniboxFacility = omniboxFacility; mText = text; - } - @Override - public void declareElements(Elements.Builder elements) { - urlBarElement = elements.declareView(OmniboxFacility.URL_FIELD.and(withText(mText))); + urlBarElement = declareView(OmniboxFacility.URL_FIELD.and(withText(mText))); deleteButtonElement = - elements.declareView( - OmniboxFacility.DELETE_BUTTON, ViewElement.displayingAtLeastOption(50)); - elements.declareNoView(OmniboxFacility.MIC_BUTTON); + declareView(OmniboxFacility.DELETE_BUTTON, ViewElement.displayingAtLeastOption(50)); + declareNoView(OmniboxFacility.MIC_BUTTON); } /** Enter text into the omnibox. */
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/omnibox/OmniboxFacility.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/omnibox/OmniboxFacility.java index d52506a..61c56d91 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/omnibox/OmniboxFacility.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/omnibox/OmniboxFacility.java
@@ -14,7 +14,6 @@ import androidx.test.espresso.Espresso; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Facility; import org.chromium.base.test.transit.ViewElement; import org.chromium.base.test.transit.ViewSpec; @@ -48,37 +47,36 @@ } @Override - public void declareElements(Elements.Builder elements) { - elements.declareView(viewSpec(instanceOf(ScrimView.class))); + public void declareExtraElements() { + declareView(viewSpec(instanceOf(ScrimView.class))); // Unscoped elements exist in PageStations too. // Action buttons are 71% displayed in tablets (though the actual image is fully displayed). if (!mIncognito) { // Regular tab - statusIconElement = elements.declareView(STATUS_ICON, ViewElement.unscopedOption()); - urlBarElement = elements.declareView(URL_FIELD, ViewElement.unscopedOption()); + statusIconElement = declareView(STATUS_ICON, ViewElement.unscopedOption()); + urlBarElement = declareView(URL_FIELD, ViewElement.unscopedOption()); actionContainerElement = - elements.declareView( + declareView( ACTION_CONTAINER, ViewElement.newOptions().unscoped().displayingAtLeast(50).build()); - micButtonElement = - elements.declareView(MIC_BUTTON, ViewElement.displayingAtLeastOption(50)); - elements.declareNoView(DELETE_BUTTON); + micButtonElement = declareView(MIC_BUTTON, ViewElement.displayingAtLeastOption(50)); + declareNoView(DELETE_BUTTON); } else { if (mHostStation.getActivity().isTablet()) { // Incognito tab in tablet - statusIconElement = elements.declareView(STATUS_ICON, ViewElement.unscopedOption()); - urlBarElement = elements.declareView(URL_FIELD, ViewElement.unscopedOption()); - elements.declareNoView(ACTION_CONTAINER); - elements.declareNoView(MIC_BUTTON); - elements.declareNoView(DELETE_BUTTON); + statusIconElement = declareView(STATUS_ICON, ViewElement.unscopedOption()); + urlBarElement = declareView(URL_FIELD, ViewElement.unscopedOption()); + declareNoView(ACTION_CONTAINER); + declareNoView(MIC_BUTTON); + declareNoView(DELETE_BUTTON); } else { // Incognito tab in phone - elements.declareNoView(STATUS_ICON); - urlBarElement = elements.declareView(URL_FIELD, ViewElement.unscopedOption()); - elements.declareNoView(ACTION_CONTAINER); - elements.declareNoView(MIC_BUTTON); - elements.declareNoView(DELETE_BUTTON); + declareNoView(STATUS_ICON); + urlBarElement = declareView(URL_FIELD, ViewElement.unscopedOption()); + declareNoView(ACTION_CONTAINER); + declareNoView(MIC_BUTTON); + declareNoView(DELETE_BUTTON); } } }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/BasePageStation.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/BasePageStation.java index 1835437..9ab1e5a 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/BasePageStation.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/BasePageStation.java
@@ -14,7 +14,6 @@ import org.chromium.base.test.transit.ConditionStatusWithResult; import org.chromium.base.test.transit.ConditionWithResult; import org.chromium.base.test.transit.Element; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Facility; import org.chromium.base.test.transit.Station; import org.chromium.base.test.transit.Transition; @@ -198,26 +197,24 @@ } @Override - public void declareElements(Elements.Builder elements) { - super.declareElements(elements); + public void declareExtraElements() { + super.declareExtraElements(); if (mNumTabsBeingOpened > 0) { - elements.declareEnterCondition( - new TabAddedCondition(mNumTabsBeingOpened, mActivityElement)); + declareEnterCondition(new TabAddedCondition<>(mNumTabsBeingOpened, mActivityElement)); } if (mIsEntryPoint) { // In entry points we just match the first ActivityTab we see, instead of waiting for // callbacks. activityTabElement = - elements.declareEnterConditionAsElement( - new AnyActivityTabCondition(mActivityElement)); + declareEnterConditionAsElement(new AnyActivityTabCondition<>(mActivityElement)); } else { if (mNumTabsBeingSelected > 0) { // The last tab of N opened is the Tab that mSelectedTabSupplier will supply. - TabSelectedCondition tabSelectedCondition = - new TabSelectedCondition(mNumTabsBeingSelected, mActivityElement); - elements.declareEnterCondition(tabSelectedCondition); + TabSelectedCondition<HostActivity> tabSelectedCondition = + new TabSelectedCondition<>(mNumTabsBeingSelected, mActivityElement); + declareEnterCondition(tabSelectedCondition); mSelectedTabSupplier = tabSelectedCondition; } else { // The Tab already created and provided to the constructor is the one that is @@ -226,24 +223,23 @@ } // Only returns the tab when it is the activityTab. activityTabElement = - elements.declareEnterConditionAsElement( - new CorrectActivityTabCondition( + declareEnterConditionAsElement( + new CorrectActivityTabCondition<>( mActivityElement, mSelectedTabSupplier)); } loadedTabElement = - elements.declareEnterConditionAsElement( + declareEnterConditionAsElement( new PageLoadedCondition(activityTabElement, mIncognito)); - elements.declareEnterCondition(new PageInteractableOrHiddenCondition(loadedTabElement)); + declareEnterCondition(new PageInteractableOrHiddenCondition(loadedTabElement)); if (mExpectedUrlSubstring != null) { - elements.declareEnterCondition( + declareEnterCondition( new PageUrlContainsCondition(mExpectedUrlSubstring, loadedTabElement)); } if (mExpectedTitle != null) { - elements.declareEnterCondition( - new PageTitleCondition(mExpectedTitle, loadedTabElement)); + declareEnterCondition(new PageTitleCondition(mExpectedTitle, loadedTabElement)); } }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/CctPageStation.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/CctPageStation.java index 145eef8..623940c60 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/CctPageStation.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/CctPageStation.java
@@ -5,7 +5,6 @@ package org.chromium.chrome.test.transit.page; import org.chromium.base.test.transit.Element; -import org.chromium.base.test.transit.Elements; import org.chromium.chrome.browser.customtabs.CustomTabActivity; import org.chromium.content_public.browser.WebContents; @@ -44,14 +43,14 @@ } @Override - public void declareElements(Elements.Builder elements) { - super.declareElements(elements); + public void declareExtraElements() { + super.declareExtraElements(); if (!mIsNativePage) { webContentsElement = - elements.declareEnterConditionAsElement( + declareEnterConditionAsElement( new WebContentsPresentCondition(loadedTabElement)); - elements.declareEnterCondition(new FrameInfoUpdatedCondition(webContentsElement)); + declareEnterCondition(new FrameInfoUpdatedCondition(webContentsElement)); } } }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/PageAppMenuFacility.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/PageAppMenuFacility.java index 11a6bc51..2b733a8 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/PageAppMenuFacility.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/PageAppMenuFacility.java
@@ -4,9 +4,6 @@ package org.chromium.chrome.test.transit.page; -import androidx.annotation.CallSuper; - -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Station; import org.chromium.chrome.browser.tabbed_mode.TabbedAppMenuPropertiesDelegate; import org.chromium.chrome.test.transit.CtaAppMenuFacility; @@ -39,15 +36,8 @@ protected Item<SettingsStation> mSettings; @Override - @CallSuper - public void declareElements(Elements.Builder elements) { - super.declareElements(elements); - - // TODO: Declare top buttons (forward, reload, bookmark, etc.). - } - - @Override protected void declareItems(ItemsBuilder items) { + // TODO: Declare top buttons (forward, reload, bookmark, etc.). // TODO: Declare more common menu items mNewTab = declareMenuItemToStation(items, NEW_TAB_ID, this::createNewTabPageStation);
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/PageStation.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/PageStation.java index 51d8407..08e41f3 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/PageStation.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/PageStation.java
@@ -16,7 +16,6 @@ import androidx.test.platform.app.InstrumentationRegistry; import org.chromium.base.supplier.Supplier; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Transition; import org.chromium.base.test.transit.Transition.Trigger; import org.chromium.base.test.transit.ViewElement; @@ -78,10 +77,10 @@ } @Override - public void declareElements(Elements.Builder elements) { - super.declareElements(elements); + public void declareExtraElements() { + super.declareExtraElements(); - elements.declareEnterCondition( + declareEnterCondition( new LayoutTypeVisibleCondition(mActivityElement, LayoutType.BROWSING)); // TODO(crbug.com/41497463): These should be scoped, but for now they need to be unscoped @@ -89,17 +88,17 @@ // occluded by the tab switcher toolbar, but at least the tab_switcher_button is still // visible. toolbarElement = - elements.declareView( + declareView( viewSpec(ToolbarControlContainer.class, withId(R.id.control_container)), ViewElement.unscopedOption()); - elements.declareView( + declareView( viewSpec(HomeButton.class, withId(R.id.home_button)), ViewElement.unscopedOption()); tabSwitcherButtonElement = - elements.declareView( + declareView( viewSpec(ToggleTabStackButton.class, withId(R.id.tab_switcher_button)), ViewElement.unscopedOption()); menuButtonElement = - elements.declareView( + declareView( viewSpec(ImageButton.class, withId(R.id.menu_button)), ViewElement.unscopedOption()); }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/PopupBlockedMessageFacility.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/PopupBlockedMessageFacility.java index 88e8782..e1c6990b 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/PopupBlockedMessageFacility.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/PopupBlockedMessageFacility.java
@@ -6,7 +6,6 @@ import android.view.View; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.ViewElement; import org.chromium.chrome.test.transit.MessageFacility; @@ -17,26 +16,18 @@ */ public class PopupBlockedMessageFacility<HostStationT extends WebPageStation> extends MessageFacility<HostStationT> { - private final int mCount; public ViewElement<View> titleElement; public ViewElement<View> alwaysShowButtonElement; public PopupBlockedMessageFacility(int count) { - mCount = count; - } - - @Override - public void declareElements(Elements.Builder elements) { - super.declareElements(elements); - String title; - if (mCount == 1) { + if (count == 1) { title = "Pop-up blocked"; } else { - title = String.format("%s pop-ups blocked", mCount); + title = String.format("%s pop-ups blocked", count); } - titleElement = elements.declareView(titleViewSpec(title)); - alwaysShowButtonElement = elements.declareView(primaryButtonViewSpec("Always show")); + titleElement = declareView(titleViewSpec(title)); + alwaysShowButtonElement = declareView(primaryButtonViewSpec("Always show")); } public WebPageStation clickAlwaysAllow() {
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/SwipingToTabFacility.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/SwipingToTabFacility.java index 95c9f6b2..a75f14e 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/SwipingToTabFacility.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/SwipingToTabFacility.java
@@ -4,7 +4,6 @@ package org.chromium.chrome.test.transit.page; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Facility; import org.chromium.base.test.transit.Transition; import org.chromium.chrome.browser.layouts.LayoutType; @@ -19,8 +18,8 @@ } @Override - public void declareElements(Elements.Builder elements) { - elements.declareEnterCondition( + public void declareExtraElements() { + declareEnterCondition( new LayoutTypeVisibleCondition( mHostStation.getActivityElement(), LayoutType.TOOLBAR_SWIPE)); }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/TabSwitcherActionMenuFacility.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/TabSwitcherActionMenuFacility.java index 6c5d624f..cbb15d25 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/TabSwitcherActionMenuFacility.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/TabSwitcherActionMenuFacility.java
@@ -16,7 +16,6 @@ import android.view.View; import org.chromium.base.test.transit.Condition; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Facility; import org.chromium.base.test.transit.Station; import org.chromium.base.test.transit.Transition; @@ -40,7 +39,7 @@ public ViewElement<View> switchToIncognitoMenuItemElement; @Override - public void declareElements(Elements.Builder elements) { + public void declareExtraElements() { appMenuListElement = declareView(viewSpec(withId(R.id.app_menu_list))); closeTabMenuItemElement = declareView(appMenuListElement.descendant(withText(R.string.close_tab)));
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/WebPageStation.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/WebPageStation.java index fb44cc01..fb3e2c9 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/WebPageStation.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/page/WebPageStation.java
@@ -10,7 +10,6 @@ import org.chromium.base.test.transit.Condition; import org.chromium.base.test.transit.ConditionStatus; import org.chromium.base.test.transit.Element; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Transition; import org.chromium.base.test.transit.ViewElement; import org.chromium.chrome.browser.omnibox.UrlBar; @@ -63,24 +62,22 @@ } @Override - public void declareElements(Elements.Builder elements) { - super.declareElements(elements); + public void declareExtraElements() { + super.declareExtraElements(); webContentsElement = - elements.declareEnterConditionAsElement( - new WebContentsPresentCondition(loadedTabElement)); - elements.declareEnterCondition(new FrameInfoUpdatedCondition(webContentsElement)); + declareEnterConditionAsElement(new WebContentsPresentCondition(loadedTabElement)); + declareEnterCondition(new FrameInfoUpdatedCondition(webContentsElement)); if (!mIgnoreUrlBar) { // TODO(crbug.com/41497463): This should be shared, not unscoped, but the toolbar exists // in the tab switcher and it is not completely occluded. - urlBarElement = elements.declareView(URL_BAR, ViewElement.unscopedOption()); + urlBarElement = declareView(URL_BAR, ViewElement.unscopedOption()); } // Make sure that the new tab page is not considered a WebPageStation List<String> prohibitedUrls = List.of("chrome://newtab", "chrome-native://newtab"); - elements.declareEnterCondition( - new PageUrlDoesNotMatchCondition(prohibitedUrls, loadedTabElement)); + declareEnterCondition(new PageUrlDoesNotMatchCondition(prohibitedUrls, loadedTabElement)); } /** Condition to check the page url does not match any of the prohibited urls. */
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/settings/PreferenceFacility.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/settings/PreferenceFacility.java index 106eb7cb..5336b99f 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/settings/PreferenceFacility.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/settings/PreferenceFacility.java
@@ -8,23 +8,19 @@ import static androidx.test.espresso.matcher.ViewMatchers.withParent; import static androidx.test.espresso.matcher.ViewMatchers.withText; +import static org.hamcrest.Matchers.instanceOf; + import static org.chromium.base.test.transit.ViewSpec.viewSpec; import android.view.View; import androidx.recyclerview.widget.RecyclerView; -import org.hamcrest.Matchers; - -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Facility; import org.chromium.base.test.transit.ViewElement; -import org.chromium.base.test.transit.ViewSpec; /** The facility describing one setting preference item in the MainSettings fragment. */ public class PreferenceFacility extends Facility<SettingsStation<?>> { - private final ViewSpec<View> mPrefViewSpec; - public ViewElement<View> prefViewElement; /** @@ -33,14 +29,10 @@ * @param prefTitle The preference title. It's used to match the preference view on the screen. */ public PreferenceFacility(String prefTitle) { - mPrefViewSpec = - viewSpec( - hasDescendant(withText(prefTitle)), - withParent(Matchers.instanceOf(RecyclerView.class))); - } - - @Override - public void declareElements(Elements.Builder elements) { - prefViewElement = elements.declareView(mPrefViewSpec); + prefViewElement = + declareView( + viewSpec( + hasDescendant(withText(prefTitle)), + withParent(instanceOf(RecyclerView.class)))); } }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/settings/SettingsStation.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/settings/SettingsStation.java index 420b7db9..009bdfc 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/settings/SettingsStation.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/settings/SettingsStation.java
@@ -4,7 +4,6 @@ package org.chromium.chrome.test.transit.settings; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.FragmentElement; import org.chromium.base.test.transit.Station; import org.chromium.base.test.transit.Transition; @@ -18,30 +17,22 @@ */ public class SettingsStation<FragmentT extends ChromeBaseSettingsFragment> extends Station<SettingsActivity> { - private final Class<FragmentT> mFragmentClass; - private FragmentElement<FragmentT, SettingsActivity> mFragmentElement; + public final FragmentElement<FragmentT, SettingsActivity> fragmentElement; public SettingsStation(Class<FragmentT> fragmentClass) { super(SettingsActivity.class); - mFragmentClass = fragmentClass; - } - - @Override - public void declareElements(Elements.Builder elements) { - super.declareElements(elements); - mFragmentElement = - elements.declareElement(new FragmentElement<>(mFragmentClass, mActivityElement)); + fragmentElement = declareElement(new FragmentElement<>(fragmentClass, mActivityElement)); } public PreferenceFacility scrollToPref(String prefKey) { assertInPhase(Phase.ACTIVE); - String title = mFragmentElement.get().findPreference(prefKey).getTitle().toString(); + String title = fragmentElement.get().findPreference(prefKey).getTitle().toString(); return enterFacilitySync( new PreferenceFacility(title), Transition.newOptions() .withPossiblyAlreadyFulfilled() .withRunTriggerOnUiThread() .build(), - () -> mFragmentElement.get().scrollToPreference(prefKey)); + () -> fragmentElement.get().scrollToPreference(prefKey)); } }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/tabmodel/TabGroupUiFacility.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/tabmodel/TabGroupUiFacility.java index b9ce49c4..f35315e8 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/tabmodel/TabGroupUiFacility.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/tabmodel/TabGroupUiFacility.java
@@ -13,7 +13,6 @@ import org.hamcrest.Matcher; import org.chromium.base.supplier.Supplier; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Facility; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.tab_ui.R; @@ -50,13 +49,13 @@ } @Override - public void declareElements(Elements.Builder elements) { + public void declareExtraElements() { // Ensure the tab group UI is visible. - mTabGroupUiToolbarView = elements.declareView(viewSpec(BOTTOM_TAB_GROUP_LAYER)); + mTabGroupUiToolbarView = declareView(viewSpec(BOTTOM_TAB_GROUP_LAYER)); if (!mTabIds.isEmpty()) { // Ensure the number of tabs are in group. - elements.declareEnterCondition( + declareEnterCondition( new TabGroupExistsCondition( mHostStation.isIncognito(), mTabIds, mTabModelSelectorSupplier)); }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/testhtmls/PopupOnClickPageStation.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/testhtmls/PopupOnClickPageStation.java index 5ca68535..7267fc61 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/testhtmls/PopupOnClickPageStation.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/testhtmls/PopupOnClickPageStation.java
@@ -4,7 +4,6 @@ package org.chromium.chrome.test.transit.testhtmls; -import org.chromium.base.test.transit.Elements; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.transit.page.CctPageStation; import org.chromium.chrome.test.transit.page.PageStation; @@ -20,11 +19,8 @@ public class PopupOnClickPageStation extends WebPageStation { public static final String PATH = "/chrome/test/data/android/popup_on_click.html"; - public static final HtmlElementSpec LINK_TO_POPUP = new HtmlElementSpec("link"); - public static final HtmlElementSpec LINK_TO_POPUP_WITH_BOUNDS = - new HtmlElementSpec("link_with_bounds"); - private HtmlElement mLinkToPopup; - private HtmlElement mLinkToPopupWithBounds; + public HtmlElement linkToPopup; + public HtmlElement linkToPopupWithBounds; protected <T extends PopupOnClickPageStation> PopupOnClickPageStation(Builder<T> builder) { super(builder); @@ -40,13 +36,15 @@ } @Override - public void declareElements(Elements.Builder elements) { - super.declareElements(elements); + public void declareExtraElements() { + super.declareExtraElements(); - mLinkToPopup = elements.declareElement(new HtmlElement(LINK_TO_POPUP, webContentsElement)); - mLinkToPopupWithBounds = - elements.declareElement( - new HtmlElement(LINK_TO_POPUP_WITH_BOUNDS, webContentsElement)); + linkToPopup = + declareElement(new HtmlElement(new HtmlElementSpec("link"), webContentsElement)); + linkToPopupWithBounds = + declareElement( + new HtmlElement( + new HtmlElementSpec("link_with_bounds"), webContentsElement)); } /** Opens the same page as a pop-up (in Android, this means in a new tab). */ @@ -57,7 +55,7 @@ .withIsOpeningTabs(1) .withIsSelectingTabs(1) .build(); - return travelToSync(newPage, mLinkToPopup.getClickTrigger()); + return travelToSync(newPage, linkToPopup.getClickTrigger()); } /** Opens a sample page as a pop-up with bounds and expects a new window to open. */ @@ -68,7 +66,7 @@ .withExpectedUrlSubstring("simple.html") .withExpectedTitle("Simple") .build(); - return spawnSync(newPage, mLinkToPopupWithBounds.getClickTrigger()); + return spawnSync(newPage, linkToPopupWithBounds.getClickTrigger()); } /** @@ -78,6 +76,6 @@ public PopupBlockedMessageFacility clickLinkAndExpectPopupBlockedMessage() { return enterFacilitySync( new PopupBlockedMessageFacility<PopupOnClickPageStation>(1), - mLinkToPopup.getClickTrigger()); + linkToPopup.getClickTrigger()); } }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/testhtmls/TopBottomLinksPageStation.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/testhtmls/TopBottomLinksPageStation.java index 4652b62..8ef3ff13 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/testhtmls/TopBottomLinksPageStation.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/testhtmls/TopBottomLinksPageStation.java
@@ -7,7 +7,6 @@ import android.util.Pair; import android.view.View; -import org.chromium.base.test.transit.Elements; import org.chromium.base.test.transit.Facility; import org.chromium.base.test.transit.Transition; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; @@ -69,19 +68,17 @@ /** The page is scrolled to the top, and the top link is displayed. */ public static class TopFacility extends Facility<TopBottomLinksPageStation> { - protected HtmlElement mTopElement; + public HtmlElement topElement; @Override - public void declareElements(Elements.Builder elements) { - mTopElement = - elements.declareElement( - new HtmlElement(TOP_LINK, mHostStation.webContentsElement)); + public void declareExtraElements() { + topElement = declareElement(new HtmlElement(TOP_LINK, mHostStation.webContentsElement)); } /** Open context menu on the top link. */ public LinkContextMenuFacility openContextMenuOnTopLink() { return mHostStation.enterFacilitySync( - new LinkContextMenuFacility(), mTopElement.getLongPressTrigger()); + new LinkContextMenuFacility(), topElement.getLongPressTrigger()); } /** Scroll to the bottom of the page. */ @@ -93,21 +90,19 @@ /** The page is scrolled to the bottom, and the bottom link is displayed. */ public static class BottomFacility extends Facility<TopBottomLinksPageStation> { - protected HtmlElement mBottomElement; + public HtmlElement bottomElement; @Override - public void declareElements(Elements.Builder elements) { - mBottomElement = - elements.declareElement( - new HtmlElement(BOTTOM_LINK, mHostStation.webContentsElement)); - elements.declareEnterCondition( - new ScrollToBottomCondition(mHostStation.webContentsElement)); + public void declareExtraElements() { + bottomElement = + declareElement(new HtmlElement(BOTTOM_LINK, mHostStation.webContentsElement)); + declareEnterCondition(new ScrollToBottomCondition(mHostStation.webContentsElement)); } /** Open context menu on the bottom link. */ public LinkContextMenuFacility openContextMenuOnBottomLink() { return mHostStation.enterFacilitySync( - new LinkContextMenuFacility(), mBottomElement.getLongPressTrigger()); + new LinkContextMenuFacility(), bottomElement.getLongPressTrigger()); } } }
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h index b21bb15..da4c309 100644 --- a/chrome/test/base/test_browser_window.h +++ b/chrome/test/base/test_browser_window.h
@@ -144,6 +144,8 @@ void FocusWebContentsPane() override {} void ShowAppMenu() override {} bool PreHandleMouseEvent(const blink::WebMouseEvent& event) override; + void PreHandleDragUpdate(const content::DropData& drop_data, + const gfx::PointF& point) override {} content::KeyboardEventProcessingResult PreHandleKeyboardEvent( const input::NativeWebKeyboardEvent& event) override; bool HandleKeyboardEvent(const input::NativeWebKeyboardEvent& event) override;
diff --git a/chrome/test/data/pdf/ink2_viewer_toolbar_test.ts b/chrome/test/data/pdf/ink2_viewer_toolbar_test.ts index 6cf24f3..0a702cf 100644 --- a/chrome/test/data/pdf/ink2_viewer_toolbar_test.ts +++ b/chrome/test/data/pdf/ink2_viewer_toolbar_test.ts
@@ -8,7 +8,7 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {isMac} from 'chrome://resources/js/platform.js'; import {keyDownOn} from 'chrome://webui-test/keyboard_mock_interactions.js'; -import {eventToPromise, microtasksFinished} from 'chrome://webui-test/test_util.js'; +import {eventToPromise, isVisible, microtasksFinished} from 'chrome://webui-test/test_util.js'; import {assertCheckboxMenuButton, createTextBox, enterFullscreenWithUserGesture, finishInkStroke, getRequiredElement, openToolbarMenu, setupMockMetricsPrivate, setupTestMockPluginForInk} from './test_util.js'; @@ -422,13 +422,16 @@ // Create a textbox. The undo button should now be disabled. const textBox = viewer.shadowRoot.querySelector('ink-text-box'); assert(textBox); + chrome.test.assertFalse(isVisible(textBox)); await createTextBoxAndWaitForStateChange(textBox); + chrome.test.assertTrue(isVisible(textBox)); chrome.test.assertTrue(undoButton.disabled); chrome.test.assertTrue(redoButton.disabled); // Simulate closing the textbox with no changes. Now the undo button is // enabled again. await commitAnnotationAndWaitForStateChange(textBox); + chrome.test.assertFalse(isVisible(textBox)); chrome.test.assertFalse(undoButton.disabled); chrome.test.assertTrue(redoButton.disabled); @@ -445,6 +448,7 @@ // Add a textbox. The redo button is disabled. mockPlugin.clearMessages(); await createTextBoxAndWaitForStateChange(textBox); + chrome.test.assertTrue(isVisible(textBox)); chrome.test.assertTrue(undoButton.disabled); chrome.test.assertTrue(redoButton.disabled); @@ -459,6 +463,7 @@ await whenStateChanged; await microtasksFinished(); await commitAnnotationAndWaitForStateChange(textBox); + chrome.test.assertFalse(isVisible(textBox)); chrome.test.assertFalse(undoButton.disabled); chrome.test.assertTrue(redoButton.disabled);
diff --git a/chrome/test/data/pdf/test_util.ts b/chrome/test/data/pdf/test_util.ts index 2cb8643f..0556170 100644 --- a/chrome/test/data/pdf/test_util.ts +++ b/chrome/test/data/pdf/test_util.ts
@@ -4,11 +4,12 @@ // Utilities that are used in multiple tests. +// clang-format off import type {Bookmark, DocumentDimensions, LayoutOptions, PdfViewerElement, ViewerToolbarElement} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_wrapper.js'; import {resetForTesting as resetMetricsForTesting, UserAction, Viewport} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_wrapper.js'; // <if expr="enable_pdf_ink2"> import type {AnnotationBrush, BeforeUnloadProxy, InkBrushSelectorElement, InkColorSelectorElement, InkSizeSelectorElement, SelectableIconButtonElement, ViewerBottomToolbarDropdownElement} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_wrapper.js'; -import {AnnotationBrushType, BeforeUnloadProxyImpl, Ink2Manager, PluginController, PluginControllerEventType, SaveRequestType} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_wrapper.js'; +import {AnnotationBrushType, BeforeUnloadProxyImpl, DEFAULT_TEXTBOX_WIDTH, DEFAULT_TEXTBOX_HEIGHT, hexToColor, Ink2Manager, TEXT_COLORS, TextAlignment, TextStyle, PluginController, PluginControllerEventType, SaveRequestType} from 'chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/pdf_viewer_wrapper.js'; // </if> import {assert} from 'chrome://resources/js/assert.js'; import {CrLitElement, html} from 'chrome://resources/lit/v3_0/lit.rollup.js'; @@ -16,6 +17,7 @@ import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js'; // </if> import {eventToPromise, isVisible, microtasksFinished} from 'chrome://webui-test/test_util.js'; +// clang-format on export class MockElement { dir: string = ''; @@ -713,10 +715,38 @@ chrome.test.assertTrue(chrome.test.checkDeepEq(value1, value2)); } -// Simulates initializing a textbox with a click. +// Simulates initializing a textbox. To make this usable from tests that do +// not use a mock viewport, directly dispatch the event from the +// Ink2Manager. Otherwise, the real viewport and page layout can vary, and +// a textbox may not actually be created if a click event is simulated in a part +// of the viewport that doesn't contain a page. export function createTextBox() { - PluginController.getInstance().getEventTarget().dispatchEvent(new CustomEvent( - PluginControllerEventType.PLUGIN_MESSAGE, - {detail: {type: 'sendClickEvent', x: 50, y: 50}})); + Ink2Manager.getInstance().dispatchEvent( + new CustomEvent('initialize-text-box', { + detail: { + annotation: { + text: '', + textAttributes: { + size: 12, + typeface: 'sans-serif', + styles: { + [TextStyle.BOLD]: false, + [TextStyle.ITALIC]: false, + }, + alignment: TextAlignment.LEFT, + color: hexToColor(TEXT_COLORS[0]!.color), + }, + textBoxRect: { + height: DEFAULT_TEXTBOX_HEIGHT, + locationX: 50, + locationY: 50, + width: DEFAULT_TEXTBOX_WIDTH, + }, + id: 0, + pageNumber: 0, + }, + pageCoordinates: {x: 10, y: 3}, + }, + })); } // </if>
diff --git a/chrome/test/data/web_apps/navigation_capture_expectations_AppAStandaloneAppBBrowser_CaptureOff.json b/chrome/test/data/web_apps/navigation_capture_expectations_AppAStandaloneAppBBrowser_CaptureOff.json index 023d9aa5..ca50b3c8 100644 --- a/chrome/test/data/web_apps/navigation_capture_expectations_AppAStandaloneAppBBrowser_CaptureOff.json +++ b/chrome/test/data/web_apps/navigation_capture_expectations_AppAStandaloneAppBBrowser_CaptureOff.json
@@ -322,7 +322,7 @@ }, "AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOff_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -400,7 +400,7 @@ }, "AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOff_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -662,7 +662,7 @@ }, "AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOff_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -740,7 +740,7 @@ }, "AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOff_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1538,7 +1538,7 @@ }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOff_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1607,7 +1607,7 @@ }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOff_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1677,7 +1677,7 @@ }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOff_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1746,7 +1746,7 @@ }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOff_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2028,7 +2028,7 @@ }, "Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOff_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2089,7 +2089,7 @@ }, "Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOff_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2297,7 +2297,7 @@ }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOff_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2358,7 +2358,7 @@ }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOff_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL",
diff --git a/chrome/test/data/web_apps/navigation_capture_expectations_AppAStandaloneAppBBrowser_CaptureOn.json b/chrome/test/data/web_apps/navigation_capture_expectations_AppAStandaloneAppBBrowser_CaptureOn.json index 61a905b..aeeddbd 100644 --- a/chrome/test/data/web_apps/navigation_capture_expectations_AppAStandaloneAppBBrowser_CaptureOn.json +++ b/chrome/test/data/web_apps/navigation_capture_expectations_AppAStandaloneAppBBrowser_CaptureOn.json
@@ -345,7 +345,7 @@ }, "AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOn_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -424,7 +424,7 @@ }, "AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOn_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -688,7 +688,7 @@ }, "AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOn_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -767,7 +767,7 @@ }, "AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOn_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1575,7 +1575,7 @@ }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOn_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1650,7 +1650,7 @@ }, "FocusExisting_Tab_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1712,7 +1712,7 @@ }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1783,7 +1783,7 @@ }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOn_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1858,7 +1858,7 @@ }, "NavigateExisting_Tab_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1920,7 +1920,7 @@ }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1987,7 +1987,7 @@ }, "Tab_ScopeA2A_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2A_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2126,7 +2126,7 @@ }, "Tab_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2265,7 +2265,7 @@ }, "Tab_ScopeA2A_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2A_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2403,7 +2403,7 @@ }, "Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2465,7 +2465,7 @@ }, "Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2675,7 +2675,7 @@ }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2737,7 +2737,7 @@ }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2947,7 +2947,7 @@ }, "Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3081,7 +3081,7 @@ }, "Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3217,7 +3217,7 @@ }, "Tab_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3350,7 +3350,7 @@ }, "Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3483,7 +3483,7 @@ }, "Tab_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3616,7 +3616,7 @@ }, "Tab_ScopeA2X_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2X_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL",
diff --git a/chrome/test/data/web_apps/navigation_capture_expectations_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture.json b/chrome/test/data/web_apps/navigation_capture_expectations_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture.json index 2452738e..f372b53 100644 --- a/chrome/test/data/web_apps/navigation_capture_expectations_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture.json +++ b/chrome/test/data/web_apps/navigation_capture_expectations_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture.json
@@ -2,7 +2,7 @@ "tests": { "AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetBlank": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -44,12 +44,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -85,12 +87,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -127,12 +131,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -168,12 +174,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetBlank": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -209,12 +217,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled", "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -250,12 +260,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -292,12 +304,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -333,12 +347,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -375,12 +391,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "NotHandled" ] } }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -413,12 +431,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -451,12 +471,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "AppWindowOpened" ] } }, "FocusExisting_Tab_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -476,12 +498,14 @@ } ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -509,12 +533,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "NotHandled" ] } }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -535,12 +561,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -577,12 +605,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "NotHandled" ] } }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -615,12 +645,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -653,12 +685,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "AppWindowOpened" ] } }, "NavigateExisting_Tab_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -678,12 +712,14 @@ } ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -711,12 +747,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "NotHandled" ] } }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -737,12 +775,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2A_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -775,12 +815,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_A-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "SameContext" ] } }, "Tab_ScopeA2A_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -800,12 +842,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -838,12 +882,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "AppWindowOpened" ] } }, "Tab_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -869,12 +915,14 @@ } ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2A_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -907,12 +955,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_X-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "AppWindowOpened" ] } }, "Tab_ScopeA2A_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -932,12 +982,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetBlank": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -969,12 +1021,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1001,12 +1055,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-SELF-OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1034,12 +1090,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1066,12 +1124,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetBlank": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1098,12 +1158,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled", "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1130,12 +1192,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1163,12 +1227,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1195,12 +1261,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1228,12 +1296,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_A-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "AppBrowserTabOpened" ] } }, "Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1260,12 +1330,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_A-SELF-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1293,12 +1365,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "SameContext" ] } }, "Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1325,12 +1399,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1358,12 +1434,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_X-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1390,12 +1468,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_X-SELF-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1422,12 +1502,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "ReparentBrowserTabToBrowserTab" ] } }, "Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1447,12 +1529,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1479,12 +1563,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "SameContext" ] } }, "Tab_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1510,12 +1596,14 @@ } ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2X_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1542,12 +1630,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "SameContext" ] } }, "Tab_ScopeA2X_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1567,7 +1657,9 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } } }
diff --git a/chrome/test/data/web_apps/navigation_capture_expectations_BothBrowser_CaptureOn.json b/chrome/test/data/web_apps/navigation_capture_expectations_BothBrowser_CaptureOn.json index c7c970b..ce61ae9 100644 --- a/chrome/test/data/web_apps/navigation_capture_expectations_BothBrowser_CaptureOn.json +++ b/chrome/test/data/web_apps/navigation_capture_expectations_BothBrowser_CaptureOn.json
@@ -37,7 +37,7 @@ }, "FocusExisting_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothBrowser_CaptureOn_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -99,7 +99,7 @@ }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothBrowser_CaptureOn_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -161,7 +161,7 @@ }, "NavigateExisting_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothBrowser_CaptureOn_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -223,7 +223,7 @@ }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothBrowser_CaptureOn_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -285,7 +285,7 @@ }, "Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "BothBrowser_CaptureOn_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -385,7 +385,7 @@ }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "BothBrowser_CaptureOn_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL",
diff --git a/chrome/test/data/web_apps/navigation_capture_expectations_BothBrowser_CaptureOnWithSelfLinkCapture.json b/chrome/test/data/web_apps/navigation_capture_expectations_BothBrowser_CaptureOnWithSelfLinkCapture.json index 7955998..94ac17e5 100644 --- a/chrome/test/data/web_apps/navigation_capture_expectations_BothBrowser_CaptureOnWithSelfLinkCapture.json +++ b/chrome/test/data/web_apps/navigation_capture_expectations_BothBrowser_CaptureOnWithSelfLinkCapture.json
@@ -2,7 +2,7 @@ "tests": { "FocusExisting_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -30,12 +30,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_A-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "NotHandled" ] } }, "FocusExisting_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -55,12 +57,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -88,12 +92,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "NotHandled" ] } }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -114,12 +120,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -147,12 +155,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_A-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "NotHandled" ] } }, "NavigateExisting_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -172,12 +182,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -205,12 +217,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "NotHandled" ] } }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -231,12 +245,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -264,12 +280,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_A-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "BothBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -289,12 +307,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -322,12 +342,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "BothBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -354,7 +376,9 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } } }
diff --git a/chrome/test/data/web_apps/navigation_capture_expectations_BothStandalone_CaptureForSpecifiedClientMode.json b/chrome/test/data/web_apps/navigation_capture_expectations_BothStandalone_CaptureForSpecifiedClientMode.json index 36470f2..6c8fa0f 100644 --- a/chrome/test/data/web_apps/navigation_capture_expectations_BothStandalone_CaptureForSpecifiedClientMode.json +++ b/chrome/test/data/web_apps/navigation_capture_expectations_BothStandalone_CaptureForSpecifiedClientMode.json
@@ -42,7 +42,7 @@ }, "NavigateNew_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureForSpecifiedClientMode_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -143,7 +143,7 @@ }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureForSpecifiedClientMode_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL",
diff --git a/chrome/test/data/web_apps/navigation_capture_expectations_BothStandalone_CaptureOff.json b/chrome/test/data/web_apps/navigation_capture_expectations_BothStandalone_CaptureOff.json index 6e711f3..6c475b0 100644 --- a/chrome/test/data/web_apps/navigation_capture_expectations_BothStandalone_CaptureOff.json +++ b/chrome/test/data/web_apps/navigation_capture_expectations_BothStandalone_CaptureOff.json
@@ -6359,7 +6359,7 @@ }, "FocusExisting_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOff_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6437,7 +6437,7 @@ }, "FocusExisting_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOff_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6515,7 +6515,7 @@ }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOff_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6593,7 +6593,7 @@ }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOff_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6662,7 +6662,7 @@ }, "FocusExisting_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOff_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6723,7 +6723,7 @@ }, "FocusExisting_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOff_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6784,7 +6784,7 @@ }, "FocusExisting_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOff_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6845,7 +6845,7 @@ }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOff_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6915,7 +6915,7 @@ }, "NavigateExisting_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOff_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6993,7 +6993,7 @@ }, "NavigateExisting_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOff_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7071,7 +7071,7 @@ }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOff_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7149,7 +7149,7 @@ }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOff_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7218,7 +7218,7 @@ }, "NavigateExisting_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOff_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7279,7 +7279,7 @@ }, "NavigateExisting_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOff_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7340,7 +7340,7 @@ }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOff_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7401,7 +7401,7 @@ }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOff_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL",
diff --git a/chrome/test/data/web_apps/navigation_capture_expectations_BothStandalone_CaptureOn.json b/chrome/test/data/web_apps/navigation_capture_expectations_BothStandalone_CaptureOn.json index 86f6b4a..5f37e15 100644 --- a/chrome/test/data/web_apps/navigation_capture_expectations_BothStandalone_CaptureOn.json +++ b/chrome/test/data/web_apps/navigation_capture_expectations_BothStandalone_CaptureOn.json
@@ -7720,7 +7720,7 @@ }, "FocusExisting_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7804,7 +7804,7 @@ }, "FocusExisting_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7888,7 +7888,7 @@ }, "FocusExisting_AppWnd_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7972,7 +7972,7 @@ }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -8056,7 +8056,7 @@ }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -8131,7 +8131,7 @@ }, "FocusExisting_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOn_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -8198,7 +8198,7 @@ }, "FocusExisting_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOn_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -8265,7 +8265,7 @@ }, "FocusExisting_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOn_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -8332,7 +8332,7 @@ }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOn_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -8399,7 +8399,7 @@ }, "FocusExisting_Tab_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOn_Tab_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -8466,7 +8466,7 @@ }, "FocusExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOn_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -8527,7 +8527,7 @@ }, "FocusExisting_Tab_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOn_Tab_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -8588,7 +8588,7 @@ }, "FocusExisting_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOn_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -8664,7 +8664,7 @@ }, "NavigateExisting_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -8748,7 +8748,7 @@ }, "NavigateExisting_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -8832,7 +8832,7 @@ }, "NavigateExisting_AppWnd_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -8916,7 +8916,7 @@ }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -9000,7 +9000,7 @@ }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -9075,7 +9075,7 @@ }, "NavigateExisting_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -9142,7 +9142,7 @@ }, "NavigateExisting_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -9209,7 +9209,7 @@ }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -9276,7 +9276,7 @@ }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -9343,7 +9343,7 @@ }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_Tab_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -9410,7 +9410,7 @@ }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -9471,7 +9471,7 @@ }, "NavigateExisting_Tab_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_Tab_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -9532,7 +9532,7 @@ }, "NavigateExisting_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -9608,7 +9608,7 @@ }, "NavigateNew_AppWnd_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOn_AppWnd_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -9692,7 +9692,7 @@ }, "NavigateNew_AppWnd_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOn_AppWnd_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -9776,7 +9776,7 @@ }, "NavigateNew_AppWnd_ScopeA2B_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOn_AppWnd_ScopeA2B_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -9860,7 +9860,7 @@ }, "NavigateNew_AppWnd_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOn_AppWnd_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -9938,7 +9938,7 @@ }, "NavigateNew_AppWnd_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOn_AppWnd_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -10016,7 +10016,7 @@ }, "NavigateNew_AppWnd_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOn_AppWnd_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -10094,7 +10094,7 @@ }, "NavigateNew_AppWnd_ScopeA2X_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOn_AppWnd_ScopeA2X_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -10172,7 +10172,7 @@ }, "NavigateNew_AppWnd_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOn_AppWnd_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -10247,7 +10247,7 @@ }, "NavigateNew_Tab_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOn_Tab_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -10314,7 +10314,7 @@ }, "NavigateNew_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOn_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -10381,7 +10381,7 @@ }, "NavigateNew_Tab_ScopeA2B_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOn_Tab_ScopeA2B_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -10448,7 +10448,7 @@ }, "NavigateNew_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOn_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -10509,7 +10509,7 @@ }, "NavigateNew_Tab_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOn_Tab_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -10570,7 +10570,7 @@ }, "NavigateNew_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOn_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -10631,7 +10631,7 @@ }, "NavigateNew_Tab_ScopeA2X_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOn_Tab_ScopeA2X_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -10692,7 +10692,7 @@ }, "NavigateNew_Tab_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOn_Tab_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL",
diff --git a/chrome/test/data/web_apps/navigation_capture_expectations_BothStandalone_CaptureOnWithSelfLinkCapture.json b/chrome/test/data/web_apps/navigation_capture_expectations_BothStandalone_CaptureOnWithSelfLinkCapture.json index 71985340..a78a90c 100644 --- a/chrome/test/data/web_apps/navigation_capture_expectations_BothStandalone_CaptureOnWithSelfLinkCapture.json +++ b/chrome/test/data/web_apps/navigation_capture_expectations_BothStandalone_CaptureOnWithSelfLinkCapture.json
@@ -2,7 +2,7 @@ "tests": { "AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -43,12 +43,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-BTN-A_TO_A-BLANK-OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled", "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -77,12 +79,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -123,12 +127,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-BTN-A_TO_A-NO_FRAME-OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled", "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -156,12 +162,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -203,12 +211,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-BTN-A_TO_A-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -237,12 +247,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -285,12 +297,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-BTN-A_TO_A-NO_FRAME-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -318,12 +332,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -364,12 +380,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_A-BLANK-OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled", "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -398,12 +416,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -444,12 +464,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_A-NO_FRAME-OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled", "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -477,12 +499,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -524,12 +548,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_A-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -558,12 +584,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -606,12 +634,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_A-NO_FRAME-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -639,12 +669,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -686,12 +718,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -720,12 +754,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -768,12 +804,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -814,12 +852,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-SELF-OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -861,12 +901,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -895,12 +937,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -943,12 +987,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-NO_FRAME-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -989,12 +1035,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaButton_MiddleClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_MiddleClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1030,12 +1078,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2B_Direct_ViaButton_MiddleClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_MiddleClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1064,12 +1114,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaButton_MiddleClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_MiddleClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1106,12 +1158,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2B_Direct_ViaButton_MiddleClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_MiddleClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1152,12 +1206,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-SELF-NO_OPENER&click=Middle" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaButton_ShiftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_ShiftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1199,12 +1255,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-BLANK-NO_OPENER&click=Shift%20Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "ForcedContextAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2B_Direct_ViaButton_ShiftClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_ShiftClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1233,12 +1291,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaButton_ShiftClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_ShiftClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1281,12 +1341,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-NO_FRAME-NO_OPENER&click=Shift%20Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "ForcedContextAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2B_Direct_ViaButton_ShiftClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_ShiftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1327,12 +1389,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-SELF-NO_OPENER&click=Shift%20Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1373,12 +1437,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled", "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1407,12 +1473,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1453,12 +1521,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-NO_FRAME-OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled", "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1499,12 +1569,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1546,12 +1618,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1580,12 +1654,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1628,12 +1704,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-NO_FRAME-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1674,12 +1752,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_MiddleClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_MiddleClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1715,12 +1795,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_MiddleClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_MiddleClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1756,12 +1838,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_MiddleClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_MiddleClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1797,12 +1881,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_MiddleClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_MiddleClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1838,12 +1924,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_ShiftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_ShiftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1885,12 +1973,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Shift%20Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "ForcedContextAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_ShiftClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_ShiftClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1932,12 +2022,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-FRAME-NO_OPENER&click=Shift%20Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "ForcedContextAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_ShiftClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_ShiftClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1979,12 +2071,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-NO_FRAME-NO_OPENER&click=Shift%20Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "ForcedContextAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2B_Direct_ViaLink_ShiftClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_ShiftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2026,12 +2120,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Shift%20Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "ForcedContextAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2X_Direct_ViaButton_LeftClick_WithOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_Direct_ViaButton_LeftClick_WithOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2073,12 +2169,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2X_Direct_ViaButton_LeftClick_WithOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_Direct_ViaButton_LeftClick_WithOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2107,12 +2205,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2X_Direct_ViaButton_LeftClick_WithOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_Direct_ViaButton_LeftClick_WithOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2155,12 +2255,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2X_Direct_ViaButton_LeftClick_WithOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_Direct_ViaButton_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2188,12 +2290,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2X_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2229,12 +2333,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2X_Direct_ViaButton_LeftClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_Direct_ViaButton_LeftClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2263,12 +2369,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2X_Direct_ViaButton_LeftClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_Direct_ViaButton_LeftClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2305,12 +2413,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2X_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2338,12 +2448,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2X_Direct_ViaLink_LeftClick_WithOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_Direct_ViaLink_LeftClick_WithOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2380,12 +2492,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2X_Direct_ViaLink_LeftClick_WithOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_Direct_ViaLink_LeftClick_WithOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2414,12 +2528,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2X_Direct_ViaLink_LeftClick_WithOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_Direct_ViaLink_LeftClick_WithOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2457,12 +2573,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2X_Direct_ViaLink_LeftClick_WithOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_Direct_ViaLink_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2490,12 +2608,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2X_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2531,12 +2651,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2X_Direct_ViaLink_LeftClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_Direct_ViaLink_LeftClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2565,12 +2687,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppWnd_ScopeA2X_Direct_ViaLink_LeftClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_Direct_ViaLink_LeftClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2607,12 +2731,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2X_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2640,12 +2766,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "FocusExisting_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2687,12 +2815,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-BTN-A_TO_A-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "FocusExisting_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2720,12 +2850,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "FocusExisting_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2767,12 +2899,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_A-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "FocusExisting_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2800,12 +2934,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "FocusExisting_AppWnd_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2847,12 +2983,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "AppWindowOpened" ] } }, "FocusExisting_AppWnd_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2892,12 +3030,14 @@ } ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2939,12 +3079,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -2985,12 +3127,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3032,12 +3176,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3078,12 +3224,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3116,12 +3264,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-BTN-A_TO_A-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "FocusExisting_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3141,12 +3291,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3179,12 +3331,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_A-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "FocusExisting_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3204,12 +3358,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3242,12 +3398,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "FocusExisting_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3279,12 +3437,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3317,12 +3477,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3354,12 +3516,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3392,12 +3556,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_A-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "AppWindowOpened" ] } }, "FocusExisting_Tab_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3429,12 +3595,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_A-SELF-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3467,12 +3635,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_A-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "AppWindowOpened" ] } }, "FocusExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3504,12 +3674,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_A-SELF-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3536,12 +3708,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "ReparentBrowserTabToBrowserTab" ] } }, "FocusExisting_Tab_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3561,12 +3735,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3593,12 +3769,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "ReparentBrowserTabToBrowserTab" ] } }, "FocusExisting_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3618,12 +3796,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "NavigateExisting_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3665,12 +3845,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-BTN-A_TO_A-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "NavigateExisting_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3698,12 +3880,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "NavigateExisting_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3745,12 +3929,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_A-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "NavigateExisting_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3778,12 +3964,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "NavigateExisting_AppWnd_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3825,12 +4013,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "AppWindowOpened" ] } }, "NavigateExisting_AppWnd_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2A_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3870,12 +4060,14 @@ } ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3917,12 +4109,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -3963,12 +4157,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4010,12 +4206,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4056,12 +4254,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4094,12 +4294,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-BTN-A_TO_A-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "NavigateExisting_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4119,12 +4321,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4157,12 +4361,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_A-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "NavigateExisting_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4182,12 +4388,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4220,12 +4428,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4257,12 +4467,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4295,12 +4507,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4332,12 +4546,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4370,12 +4586,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_A-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "AppWindowOpened" ] } }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4407,12 +4625,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_A-SELF-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4445,12 +4665,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_A-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "AppWindowOpened" ] } }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4482,12 +4704,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_A-SELF-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4514,12 +4738,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "ReparentBrowserTabToBrowserTab" ] } }, "NavigateExisting_Tab_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4539,12 +4765,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4571,12 +4799,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "ReparentBrowserTabToBrowserTab" ] } }, "NavigateExisting_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4596,12 +4826,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "NavigateNew_AppWnd_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4643,12 +4875,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_A-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "AppWindowOpened" ] } }, "NavigateNew_AppWnd_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4689,12 +4923,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_A-SELF-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateNew_AppWnd_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4736,12 +4972,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_A-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "AppWindowOpened" ] } }, "NavigateNew_AppWnd_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4782,12 +5020,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_A-SELF-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateNew_AppWnd_ScopeA2B_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4829,12 +5069,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "SameContext" ] } }, "NavigateNew_AppWnd_ScopeA2B_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4875,12 +5117,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateNew_AppWnd_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4922,12 +5166,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "SameContext" ] } }, "NavigateNew_AppWnd_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -4968,12 +5214,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateNew_AppWnd_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5009,12 +5257,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "ReparentBrowserTabToBrowserTab" ] } }, "NavigateNew_AppWnd_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5042,12 +5292,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "NavigateNew_AppWnd_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5083,12 +5335,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "ReparentBrowserTabToBrowserTab" ] } }, "NavigateNew_AppWnd_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5116,12 +5370,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "NavigateNew_AppWnd_ScopeA2X_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5157,12 +5413,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "ReparentBrowserTabToBrowserTab" ] } }, "NavigateNew_AppWnd_ScopeA2X_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5202,12 +5460,14 @@ } ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateNew_AppWnd_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5243,12 +5503,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "ReparentBrowserTabToBrowserTab" ] } }, "NavigateNew_AppWnd_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5288,12 +5550,14 @@ } ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateNew_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5326,12 +5590,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "NavigateNew_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5363,12 +5629,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateNew_Tab_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5401,12 +5669,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_A-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "AppWindowOpened" ] } }, "NavigateNew_Tab_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5438,12 +5708,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_A-SELF-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateNew_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5476,12 +5748,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_A-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "AppWindowOpened" ] } }, "NavigateNew_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5513,12 +5787,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_A-SELF-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateNew_Tab_ScopeA2B_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5551,12 +5827,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "SameContext" ] } }, "NavigateNew_Tab_ScopeA2B_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5588,12 +5866,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateNew_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5626,12 +5906,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "SameContext" ] } }, "NavigateNew_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5663,12 +5945,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateNew_Tab_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5695,12 +5979,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "ReparentBrowserTabToBrowserTab" ] } }, "NavigateNew_Tab_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaA_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5720,12 +6006,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "NavigateNew_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5752,12 +6040,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "ReparentBrowserTabToBrowserTab" ] } }, "NavigateNew_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5777,12 +6067,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "NavigateNew_Tab_ScopeA2X_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5809,12 +6101,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "ReparentBrowserTabToBrowserTab" ] } }, "NavigateNew_Tab_ScopeA2X_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5845,12 +6139,14 @@ } ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateNew_Tab_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5877,12 +6173,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "ReparentBrowserTabToBrowserTab" ] } }, "NavigateNew_Tab_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateNew_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5913,12 +6211,14 @@ } ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5950,12 +6250,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-BTN-A_TO_A-BLANK-OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled", "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -5975,12 +6277,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6012,12 +6316,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-BTN-A_TO_A-NO_FRAME-OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled", "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6037,12 +6343,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6075,12 +6383,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-BTN-A_TO_A-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6100,12 +6410,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6139,12 +6451,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-BTN-A_TO_A-NO_FRAME-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6164,12 +6478,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6201,12 +6517,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_A-BLANK-OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled", "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6226,12 +6544,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6263,12 +6583,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_A-NO_FRAME-OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled", "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6288,12 +6610,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6326,12 +6650,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_A-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6351,12 +6677,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6390,12 +6718,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/destination.html?id-LINK-A_TO_A-NO_FRAME-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2A_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6415,12 +6745,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6452,12 +6784,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6477,12 +6811,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6515,12 +6851,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6552,12 +6890,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-SELF-OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6590,12 +6930,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6615,12 +6957,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6654,12 +6998,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-NO_FRAME-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6691,12 +7037,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaButton_MiddleClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_MiddleClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6723,12 +7071,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2B_Direct_ViaButton_MiddleClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_MiddleClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6748,12 +7098,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaButton_MiddleClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_MiddleClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6781,12 +7133,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2B_Direct_ViaButton_MiddleClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_MiddleClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6818,12 +7172,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-SELF-NO_OPENER&click=Middle" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaButton_ShiftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_ShiftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6854,12 +7210,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2B_Direct_ViaButton_ShiftClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_ShiftClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6879,12 +7237,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaButton_ShiftClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_ShiftClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6916,12 +7276,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2B_Direct_ViaButton_ShiftClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaButton_ShiftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6953,12 +7315,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-BTN-A_TO_B-SELF-NO_OPENER&click=Shift%20Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -6990,12 +7354,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled", "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7015,12 +7381,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7052,12 +7420,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-NO_FRAME-OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled", "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7089,12 +7459,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7127,12 +7499,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7152,12 +7526,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7191,12 +7567,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-NO_FRAME-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7228,12 +7606,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2B_Direct_ViaLink_MiddleClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_MiddleClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7260,12 +7640,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2B_Direct_ViaLink_MiddleClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_MiddleClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7292,12 +7674,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2B_Direct_ViaLink_MiddleClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_MiddleClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7324,12 +7708,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2B_Direct_ViaLink_MiddleClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_MiddleClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7356,12 +7742,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2B_Direct_ViaLink_ShiftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_ShiftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7392,12 +7780,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2B_Direct_ViaLink_ShiftClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_ShiftClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7428,12 +7818,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2B_Direct_ViaLink_ShiftClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_ShiftClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7464,12 +7856,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2B_Direct_ViaLink_ShiftClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_ShiftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7500,12 +7894,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2X_Direct_ViaButton_LeftClick_WithOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_Direct_ViaButton_LeftClick_WithOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7537,12 +7933,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2X_Direct_ViaButton_LeftClick_WithOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_Direct_ViaButton_LeftClick_WithOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7562,12 +7960,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2X_Direct_ViaButton_LeftClick_WithOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_Direct_ViaButton_LeftClick_WithOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7600,12 +8000,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2X_Direct_ViaButton_LeftClick_WithOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_Direct_ViaButton_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7625,12 +8027,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2X_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7657,12 +8061,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2X_Direct_ViaButton_LeftClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_Direct_ViaButton_LeftClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7682,12 +8088,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2X_Direct_ViaButton_LeftClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_Direct_ViaButton_LeftClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7715,12 +8123,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2X_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_Direct_ViaButton_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7740,12 +8150,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2X_Direct_ViaLink_LeftClick_WithOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_Direct_ViaLink_LeftClick_WithOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7773,12 +8185,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2X_Direct_ViaLink_LeftClick_WithOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_Direct_ViaLink_LeftClick_WithOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7798,12 +8212,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2X_Direct_ViaLink_LeftClick_WithOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_Direct_ViaLink_LeftClick_WithOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7832,12 +8248,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "Tab_ScopeA2X_Direct_ViaLink_LeftClick_WithOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_Direct_ViaLink_LeftClick_WithOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7857,12 +8275,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2X_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7889,12 +8309,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2X_Direct_ViaLink_LeftClick_WithoutOpener_TargetFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_Direct_ViaLink_LeftClick_WithoutOpener_TargetFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7914,12 +8336,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "Tab_ScopeA2X_Direct_ViaLink_LeftClick_WithoutOpener_TargetNoFrame": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_Direct_ViaLink_LeftClick_WithoutOpener_TargetNoFrame", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7947,12 +8371,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "Tab_ScopeA2X_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2X_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -7972,7 +8398,9 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } } }
diff --git a/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_AppAStandaloneAppBBrowser_CaptureOff.json b/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_AppAStandaloneAppBBrowser_CaptureOff.json index 90c2a8f..5ff85ae 100644 --- a/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_AppAStandaloneAppBBrowser_CaptureOff.json +++ b/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_AppAStandaloneAppBBrowser_CaptureOff.json
@@ -50,7 +50,7 @@ }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOff_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -133,7 +133,7 @@ }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOff_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -217,7 +217,7 @@ }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOff_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -300,7 +300,7 @@ }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOff_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL",
diff --git a/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_AppAStandaloneAppBBrowser_CaptureOn.json b/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_AppAStandaloneAppBBrowser_CaptureOn.json index 3adada0..1c7afc3 100644 --- a/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_AppAStandaloneAppBBrowser_CaptureOn.json +++ b/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_AppAStandaloneAppBBrowser_CaptureOn.json
@@ -42,7 +42,7 @@ }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOn_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -118,7 +118,7 @@ }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -192,7 +192,7 @@ }, "FocusExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -273,7 +273,7 @@ }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOn_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -353,7 +353,7 @@ }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -431,7 +431,7 @@ }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOn_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL",
diff --git a/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture.json b/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture.json index b4abccb..67cd386e 100644 --- a/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture.json +++ b/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture.json
@@ -2,7 +2,7 @@ "tests": { "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -35,12 +35,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "FocusExistingAppBrowserTab" ], + "redirection_result": [ ] } }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -73,12 +75,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -108,12 +112,14 @@ } ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "FocusExistingAppBrowserTab" ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -144,12 +150,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -179,12 +187,14 @@ } ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "FocusExistingAppBrowserTab" ] } }, "FocusExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -215,12 +225,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_A-SELF-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -257,12 +269,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NavigateExistingAppBrowserTab" ], + "redirection_result": [ "NotHandled" ] } }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -299,12 +313,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -338,12 +354,14 @@ } ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NavigateExistingAppBrowserTab" ], + "redirection_result": [ "NotHandled" ] } }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -374,12 +392,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -413,12 +433,14 @@ } ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow", "NotHandled" ], + "redirection_result": [ "NavigateExistingAppBrowserTab" ] } }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_AppAStandaloneAppBBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -449,7 +471,9 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_A-SELF-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } } }
diff --git a/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_BothBrowser_CaptureOn.json b/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_BothBrowser_CaptureOn.json index e2366be..fd2d065b 100644 --- a/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_BothBrowser_CaptureOn.json +++ b/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_BothBrowser_CaptureOn.json
@@ -39,7 +39,7 @@ }, "FocusExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothBrowser_CaptureOn_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -117,7 +117,7 @@ }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothBrowser_CaptureOn_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL",
diff --git a/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_BothBrowser_CaptureOnWithSelfLinkCapture.json b/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_BothBrowser_CaptureOnWithSelfLinkCapture.json index a78c69d9..1ddf0372 100644 --- a/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_BothBrowser_CaptureOnWithSelfLinkCapture.json +++ b/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_BothBrowser_CaptureOnWithSelfLinkCapture.json
@@ -2,7 +2,7 @@ "tests": { "FocusExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -32,12 +32,14 @@ } ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab" ], + "redirection_result": [ "FocusExistingAppBrowserTab" ] } }, "FocusExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -68,12 +70,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_A-SELF-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -107,12 +111,14 @@ } ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppBrowserTab", "NotHandled" ], + "redirection_result": [ "NavigateExistingAppBrowserTab" ] } }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothBrowser_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -143,7 +149,9 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_A-SELF-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } } }
diff --git a/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_BothStandalone_CaptureOn.json b/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_BothStandalone_CaptureOn.json index 22c3d4c..32fe8cd7 100644 --- a/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_BothStandalone_CaptureOn.json +++ b/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_BothStandalone_CaptureOn.json
@@ -50,7 +50,7 @@ }, "AppANavigateExistingAppBFocusExisting_AppWnd_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppANavigateExistingAppBFocusExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -145,7 +145,7 @@ }, "AppANavigateExistingAppBFocusExisting_AppWnd_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppANavigateExistingAppBFocusExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -240,7 +240,7 @@ }, "AppANavigateExistingAppBFocusExisting_AppWnd_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppANavigateExistingAppBFocusExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -326,7 +326,7 @@ }, "AppANavigateExistingAppBFocusExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppANavigateExistingAppBFocusExisting_BothStandalone_CaptureOn_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -404,7 +404,7 @@ }, "AppANavigateExistingAppBFocusExisting_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppANavigateExistingAppBFocusExisting_BothStandalone_CaptureOn_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -482,7 +482,7 @@ }, "AppANavigateExistingAppBFocusExisting_Tab_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppANavigateExistingAppBFocusExisting_BothStandalone_CaptureOn_Tab_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -569,7 +569,7 @@ }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -656,7 +656,7 @@ }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOn_Tab_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -747,7 +747,7 @@ }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -851,7 +851,7 @@ }, "NavigateExisting_AppWnd_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -950,7 +950,7 @@ }, "NavigateExisting_AppWnd_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1049,7 +1049,7 @@ }, "NavigateExisting_AppWnd_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1139,7 +1139,7 @@ }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_Tab_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1225,7 +1225,7 @@ }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1307,7 +1307,7 @@ }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1389,7 +1389,7 @@ }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_Tab_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL",
diff --git a/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_BothStandalone_CaptureOnWithSelfLinkCapture.json b/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_BothStandalone_CaptureOnWithSelfLinkCapture.json index 478d494..9dd073a7 100644 --- a/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_BothStandalone_CaptureOnWithSelfLinkCapture.json +++ b/chrome/test/data/web_apps/navigation_capture_expectations_with_b_launched_in_setup_BothStandalone_CaptureOnWithSelfLinkCapture.json
@@ -2,7 +2,7 @@ "tests": { "AppANavigateExistingAppBFocusExisting_AppWnd_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "AppANavigateExistingAppBFocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -43,12 +43,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "FocusExistingAppWindow" ] } }, "AppANavigateExistingAppBFocusExisting_AppWnd_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppANavigateExistingAppBFocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -89,12 +91,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppANavigateExistingAppBFocusExisting_AppWnd_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "AppANavigateExistingAppBFocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -135,12 +139,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "FocusExistingAppWindow" ], + "redirection_result": [ ] } }, "AppANavigateExistingAppBFocusExisting_AppWnd_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppANavigateExistingAppBFocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -181,12 +187,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppANavigateExistingAppBFocusExisting_AppWnd_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "AppANavigateExistingAppBFocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -227,12 +235,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "FocusExistingAppWindow" ] } }, "AppANavigateExistingAppBFocusExisting_AppWnd_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppANavigateExistingAppBFocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -273,12 +283,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppANavigateExistingAppBFocusExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "AppANavigateExistingAppBFocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -310,12 +322,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?dont_redirect", "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_A-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "FocusExistingAppWindow" ] } }, "AppANavigateExistingAppBFocusExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppANavigateExistingAppBFocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -347,12 +361,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?dont_redirect", "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_A-SELF-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppANavigateExistingAppBFocusExisting_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "AppANavigateExistingAppBFocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -384,12 +400,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?dont_redirect", "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "FocusExistingAppWindow" ], + "redirection_result": [ ] } }, "AppANavigateExistingAppBFocusExisting_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppANavigateExistingAppBFocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -421,12 +439,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?dont_redirect", "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "AppANavigateExistingAppBFocusExisting_Tab_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "AppANavigateExistingAppBFocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -458,12 +478,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?dont_redirect", "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_X-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "FocusExistingAppWindow" ] } }, "AppANavigateExistingAppBFocusExisting_Tab_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "AppANavigateExistingAppBFocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -495,12 +517,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?dont_redirect", "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_X-SELF-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -541,12 +565,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromMenu" ] + "launch_metric_buckets": [ "kFromMenu" ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -587,12 +613,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromMenu" ] + "launch_metric_buckets": [ "kFromMenu" ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -624,12 +652,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?dont_redirect", "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Right" ] } ] } ], - "launch_metric_buckets": [ "kFromMenu" ] + "launch_metric_buckets": [ "kFromMenu" ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -661,12 +691,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?dont_redirect", "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Right" ] } ] } ], - "launch_metric_buckets": [ "kFromMenu" ] + "launch_metric_buckets": [ "kFromMenu" ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -711,12 +743,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromMenu" ] + "launch_metric_buckets": [ "kFromMenu" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -761,12 +795,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromMenu" ] + "launch_metric_buckets": [ "kFromMenu" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_AppWnd_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -811,12 +847,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow", "NotHandled" ], + "redirection_result": [ "NavigateExistingAppWindow" ] } }, "NavigateExisting_AppWnd_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -861,12 +899,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_AppWnd_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -911,12 +951,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NavigateExistingAppWindow" ], + "redirection_result": [ "SameContext" ] } }, "NavigateExisting_AppWnd_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -961,12 +1003,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_AppWnd_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1011,12 +1055,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewTabRedirectionEligible", "NotHandled" ], + "redirection_result": [ "NavigateExistingAppWindow" ] } }, "NavigateExisting_AppWnd_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1061,12 +1107,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1102,12 +1150,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Right" ] } ] } ], - "launch_metric_buckets": [ "kFromMenu" ] + "launch_metric_buckets": [ "kFromMenu" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_RightClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1143,12 +1193,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Right" ] } ] } ], - "launch_metric_buckets": [ "kFromMenu" ] + "launch_metric_buckets": [ "kFromMenu" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1184,12 +1236,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_A-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewAppWindow", "NotHandled" ], + "redirection_result": [ "NavigateExistingAppWindow" ] } }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaA_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1225,12 +1279,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_A-SELF-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1266,12 +1322,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NavigateExistingAppWindow" ], + "redirection_result": [ "SameContext" ] } }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1307,12 +1365,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1348,12 +1408,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_X-BLANK-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NewTabRedirectionEligible", "NotHandled" ], + "redirection_result": [ "NavigateExistingAppWindow" ] } }, "NavigateExisting_Tab_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_ServerSideViaX_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -1389,7 +1451,9 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_X-SELF-NO_OPENER&click=Left&did_redirect" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } } }
diff --git a/chrome/test/data/web_apps/navigation_capturing_no_browser_BothStandalone_CaptureOnWithSelfLinkCapture.json b/chrome/test/data/web_apps/navigation_capturing_no_browser_BothStandalone_CaptureOnWithSelfLinkCapture.json index 4727617..3f7d2b11 100644 --- a/chrome/test/data/web_apps/navigation_capturing_no_browser_BothStandalone_CaptureOnWithSelfLinkCapture.json +++ b/chrome/test/data/web_apps/navigation_capturing_no_browser_BothStandalone_CaptureOnWithSelfLinkCapture.json
@@ -2,7 +2,7 @@ "tests": { "AppWnd_ScopeA2X_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_Direct_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "app_scope": "/banners/link_capturing/scope_a/", @@ -32,12 +32,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2X_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "app_scope": "/banners/link_capturing/scope_a/", @@ -67,12 +69,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2X_Direct_ViaServiceWorkerButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_Direct_ViaServiceWorkerButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "app_scope": "/banners/link_capturing/scope_a/", @@ -102,12 +106,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewTabRedirectionEligible" ], + "redirection_result": [ "NotHandled" ] } }, "AppWnd_ScopeA2X_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_ServerSideViaB_ViaButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "app_scope": "/banners/link_capturing/scope_a/", @@ -137,12 +143,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "ReparentBrowserTabToBrowserTab" ] } }, "AppWnd_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_ServerSideViaB_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "app_scope": "/banners/link_capturing/scope_a/", @@ -172,12 +180,14 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "ReparentBrowserTabToBrowserTab" ] } }, "AppWnd_ScopeA2X_ServerSideViaB_ViaServiceWorkerButton_LeftClick_WithoutOpener_TargetBlank": { "_params": "BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2X_ServerSideViaB_ViaServiceWorkerButton_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "app_scope": "/banners/link_capturing/scope_a/", @@ -207,7 +217,9 @@ } ] } ] } ], - "launch_metric_buckets": [ ] + "launch_metric_buckets": [ ], + "navigation_capturing_result": [ "NewAppWindow" ], + "redirection_result": [ "ReparentBrowserTabToBrowserTab" ] } } }
diff --git a/chrome/test/data/web_apps/navigation_capturing_with_b_lauched_and_browser_tab_BothStandalone_CaptureOn.json b/chrome/test/data/web_apps/navigation_capturing_with_b_lauched_and_browser_tab_BothStandalone_CaptureOn.json index 649fe95..3c7603b 100644 --- a/chrome/test/data/web_apps/navigation_capturing_with_b_lauched_and_browser_tab_BothStandalone_CaptureOn.json +++ b/chrome/test/data/web_apps/navigation_capturing_with_b_lauched_and_browser_tab_BothStandalone_CaptureOn.json
@@ -53,7 +53,7 @@ }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -151,7 +151,7 @@ }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOn_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -254,7 +254,7 @@ }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -356,7 +356,7 @@ }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOn_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL",
diff --git a/chrome/test/data/web_apps/navigation_capturing_with_b_lauched_and_browser_tab_BothStandalone_CaptureOnWithSelfLinkCapture.json b/chrome/test/data/web_apps/navigation_capturing_with_b_lauched_and_browser_tab_BothStandalone_CaptureOnWithSelfLinkCapture.json index 7e8e73e..7cfc0d7b 100644 --- a/chrome/test/data/web_apps/navigation_capturing_with_b_lauched_and_browser_tab_BothStandalone_CaptureOnWithSelfLinkCapture.json +++ b/chrome/test/data/web_apps/navigation_capturing_with_b_lauched_and_browser_tab_BothStandalone_CaptureOnWithSelfLinkCapture.json
@@ -2,7 +2,7 @@ "tests": { "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -46,12 +46,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "FocusExistingAppWindow" ], + "redirection_result": [ ] } }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -95,12 +97,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -141,12 +145,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?dont_redirect", "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "FocusExistingAppWindow" ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -187,12 +193,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?dont_redirect", "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ ], + "redirection_result": [ ] } }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -240,12 +248,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NavigateExistingAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -293,12 +303,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -343,12 +355,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-BLANK-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NavigateExistingAppWindow" ], + "redirection_result": [ "NotHandled" ] } }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -393,7 +407,9 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } } }
diff --git a/chrome/test/data/web_apps/navigation_capturing_with_extra_browser_tab_b_BothStandalone_CaptureOnWithSelfLinkCapture.json b/chrome/test/data/web_apps/navigation_capturing_with_extra_browser_tab_b_BothStandalone_CaptureOnWithSelfLinkCapture.json index b64903c..3dac6f1 100644 --- a/chrome/test/data/web_apps/navigation_capturing_with_extra_browser_tab_b_BothStandalone_CaptureOnWithSelfLinkCapture.json +++ b/chrome/test/data/web_apps/navigation_capturing_with_extra_browser_tab_b_BothStandalone_CaptureOnWithSelfLinkCapture.json
@@ -2,7 +2,7 @@ "tests": { "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -35,12 +35,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "FocusExistingAppBrowserTab" ], + "redirection_result": [ ] } }, "FocusExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -84,12 +86,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -119,12 +123,14 @@ } ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "FocusExistingAppBrowserTab" ], + "redirection_result": [ ] } }, "FocusExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "FocusExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -165,12 +171,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -207,12 +215,14 @@ "launchParams": [ "/banners/link_capturing/scope_a/start.html" ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NavigateExistingAppBrowserTab" ], + "redirection_result": [ "NotHandled" ] } }, "NavigateExisting_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_AppWnd_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -256,12 +266,14 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetBlank", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -295,12 +307,14 @@ } ] } ] } ], - "launch_metric_buckets": [ "kFromNavigationCapturing" ] + "launch_metric_buckets": [ "kFromNavigationCapturing" ], + "navigation_capturing_result": [ "NavigateExistingAppBrowserTab" ], + "redirection_result": [ "NotHandled" ] } }, "NavigateExisting_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf": { "_params": "NavigateExisting_BothStandalone_CaptureOnWithSelfLinkCapture_Tab_ScopeA2B_Direct_ViaLink_LeftClick_WithoutOpener_TargetSelf", - "disabled": true, + "disabled": false, "expected_state": { "browsers": [ { "browser_type": "TYPE_NORMAL", @@ -341,7 +355,9 @@ "launchParams": [ "/banners/link_capturing/scope_b/destination.html?id-LINK-A_TO_B-SELF-NO_OPENER&click=Left" ] } ] } ], - "launch_metric_buckets": [ "kFromLink" ] + "launch_metric_buckets": [ "kFromLink" ], + "navigation_capturing_result": [ "NotHandled" ], + "redirection_result": [ ] } } }
diff --git a/chrome/test/data/webui/chromeos/personalization_app/sea_pen_input_query_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/sea_pen_input_query_element_test.ts index 87a7d21..2ce82d8 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/sea_pen_input_query_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/sea_pen_input_query_element_test.ts
@@ -485,11 +485,12 @@ const inputElement = seaPenInputQueryElement.shadowRoot?.querySelector<CrTextareaElement>( - '#queryInput'); - assertTrue(!!inputElement?.value, 'input should show text'); + '#queryInput')!; + assertTrue(!!inputElement.value, 'input should show text'); const action = await personalizationStore.waitForAction( SeaPenActionName.BEGIN_SEARCH_SEA_PEN_THUMBNAILS) as BeginSearchSeaPenThumbnailsAction; + assertFalse(seaPenInputQueryElement.i18nExists(inputElement.value)); assertEquals( inputElement?.value, action.query.textQuery, 'search query should match input value');
diff --git a/chrome/test/data/webui/lens/lens_overlay_webui_browsertest.cc b/chrome/test/data/webui/lens/lens_overlay_webui_browsertest.cc index 4b233966..8122340c 100644 --- a/chrome/test/data/webui/lens/lens_overlay_webui_browsertest.cc +++ b/chrome/test/data/webui/lens/lens_overlay_webui_browsertest.cc
@@ -8,6 +8,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/lens/lens_overlay_controller.h" #include "chrome/browser/ui/lens/lens_search_controller.h" +#include "chrome/browser/ui/lens/lens_searchbox_controller.h" #include "chrome/browser/ui/tabs/public/tab_features.h" #include "chrome/common/webui_url_constants.h" #include "chrome/test/base/in_process_browser_test.h" @@ -94,7 +95,8 @@ // Clean up (the searchbox handler will leave a dangling pointer if not // explicitly destroyed). - overlay_controller->ResetSidePanelSearchboxHandler(); + search_controller->lens_searchbox_controller() + ->ResetSidePanelSearchboxHandler(); } // Lens overlay takes a screenshot of the tab. In order to take a screenshot
diff --git a/chrome/test/data/webui/side_panel/read_anything/fake_reading_mode.ts b/chrome/test/data/webui/side_panel/read_anything/fake_reading_mode.ts index 0bcbdd2..eab2a73 100644 --- a/chrome/test/data/webui/side_panel/read_anything/fake_reading_mode.ts +++ b/chrome/test/data/webui/side_panel/read_anything/fake_reading_mode.ts
@@ -390,6 +390,11 @@ // Signal that the page language has changed. languageChanged(): void {} + // Gets the accessible text boundary for the given string + getAccessibleBoundary(_text: string, _maxSpeechLength: number): number { + return 0; + } + // Requests the image in the form of bitmap. onImageDownloaded will be // called when the image has been downloaded. requestImageData(nodeId: number): void {
diff --git a/chrome/test/data/webui/side_panel/read_anything/speech_controller_test.ts b/chrome/test/data/webui/side_panel/read_anything/speech_controller_test.ts index 10f96396..eafc3a5 100644 --- a/chrome/test/data/webui/side_panel/read_anything/speech_controller_test.ts +++ b/chrome/test/data/webui/side_panel/read_anything/speech_controller_test.ts
@@ -13,7 +13,7 @@ suite('SpeechController', () => { let speech: TestSpeechBrowserProxy; let speechController: SpeechController; - let onPause: boolean; + let onStop: boolean; let isSpeechActiveChanged: boolean; let isAudioCurrentlyPlayingChanged: boolean; let onPreviewVoicePlaying: boolean; @@ -31,12 +31,12 @@ SpeechBrowserProxyImpl.setInstance(speech); isSpeechActiveChanged = false; isAudioCurrentlyPlayingChanged = false; - onPause = false; + onStop = false; onPreviewVoicePlaying = false; onEngineStateChange = false; const speechListener = { - onPause() { - onPause = true; + onStop() { + onStop = true; }, onIsSpeechActiveChange() { @@ -79,7 +79,7 @@ assertTrue(isSpeechActiveChanged); assertTrue(isAudioCurrentlyPlayingChanged); - assertFalse(onPause); + assertFalse(onStop); assertNotEquals(state, speechController.getState()); assertTrue(speechController.isSpeechActive()); assertTrue(speechController.isSpeechTreeInitialized()); @@ -105,7 +105,7 @@ assertTrue(isSpeechActiveChanged); assertTrue(isAudioCurrentlyPlayingChanged); - assertFalse(onPause); + assertFalse(onStop); assertFalse(speechController.isSpeechActive()); assertFalse(speechController.isSpeechTreeInitialized()); assertEquals(PauseActionSource.DEFAULT, speechController.getPauseSource()); @@ -302,7 +302,7 @@ speechController.stopSpeech(source); - assertTrue(onPause); + assertTrue(onStop); assertFalse(speechController.isSpeechActive()); assertFalse(speechController.isAudioCurrentlyPlaying()); assertEquals(source, speechController.getPauseSource()); @@ -310,6 +310,19 @@ assertEquals(0, speech.getCallCount('cancel')); }); + test('stopSpeech with button click logs play session', () => { + const source = PauseActionSource.BUTTON_CLICK; + speechController.onPlay(); + speechController.setIsSpeechActive(true); + + speechController.stopSpeech(source); + assertEquals(1, metrics.getCallCount('recordSpeechPlaybackLength')); + + // Calling it again without playing should not log again. + speechController.stopSpeech(source); + assertEquals(1, metrics.getCallCount('recordSpeechPlaybackLength')); + }); + test('stopSpeech without button click cancels', () => { const source = PauseActionSource.VOICE_SETTINGS_CHANGE; speechController.setIsSpeechActive(true); @@ -317,12 +330,13 @@ speechController.stopSpeech(source); - assertTrue(onPause); + assertTrue(onStop); assertFalse(speechController.isSpeechActive()); assertFalse(speechController.isAudioCurrentlyPlaying()); assertEquals(source, speechController.getPauseSource()); assertEquals(0, speech.getCallCount('pause')); assertEquals(1, speech.getCallCount('cancel')); + assertEquals(0, metrics.getCallCount('recordSpeechPlaybackLength')); }); test('onSpeechInterrupted while repositioning keeps playing speech', () => { @@ -332,7 +346,7 @@ speechController.onSpeechInterrupted(); - assertFalse(onPause); + assertFalse(onStop); assertTrue(speechController.isAudioCurrentlyPlaying()); assertTrue(speechController.isSpeechActive()); assertTrue(speechController.isSpeechBeingRepositioned()); @@ -344,7 +358,7 @@ speechController.onSpeechInterrupted(); - assertTrue(onPause); + assertTrue(onStop); assertEquals( PauseActionSource.ENGINE_INTERRUPT, speechController.getPauseSource()); assertFalse(speechController.isAudioCurrentlyPlaying()); @@ -354,4 +368,15 @@ chrome.readingMode.engineInterruptStopSource, await metrics.whenCalled('recordSpeechStopSource')); }); + test('onSpeechFinished', () => { + speechController.onPlay(); + speechController.setIsSpeechActive(true); + + speechController.onSpeechFinished(); + + assertTrue(onStop); + assertEquals(1, metrics.getCallCount('recordSpeechPlaybackLength')); + assertEquals(1, metrics.getCallCount('recordSpeechStopSource')); + assertFalse(speechController.isSpeechActive()); + }); });
diff --git a/chrome/test/data/webui/side_panel/read_anything/speech_test.ts b/chrome/test/data/webui/side_panel/read_anything/speech_test.ts index d42be456..1d17b6e 100644 --- a/chrome/test/data/webui/side_panel/read_anything/speech_test.ts +++ b/chrome/test/data/webui/side_panel/read_anything/speech_test.ts
@@ -428,7 +428,8 @@ selectedVoice: speech.getVoices()[0], }, }); - const accessibleTextLength = app.getAccessibleTextLength(longSentences); + const accessibleTextLength = + speechController.getUtteranceEndBoundary(longSentences, true); app.playSpeech(); assertEquals(longSentences, getSpokenText()); const utterance = speech.getArgs('speak')[0];
diff --git a/chrome/test/data/webui/side_panel/read_anything/speech_uses_max_text_length_test.ts b/chrome/test/data/webui/side_panel/read_anything/speech_uses_max_text_length_test.ts index 0550b43..d4b52d3 100644 --- a/chrome/test/data/webui/side_panel/read_anything/speech_uses_max_text_length_test.ts +++ b/chrome/test/data/webui/side_panel/read_anything/speech_uses_max_text_length_test.ts
@@ -4,7 +4,7 @@ import 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js'; import type {AppElement} from 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js'; -import {MAX_SPEECH_LENGTH, SpeechBrowserProxyImpl} from 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js'; +import {MAX_SPEECH_LENGTH, SpeechBrowserProxyImpl, SpeechController} from 'chrome-untrusted://read-anything-side-panel.top-chrome/read_anything.js'; import {assertEquals, assertGT, assertLT, assertNotEquals} from 'chrome-untrusted://webui-test/chai_assert.js'; import {createApp} from './common.js'; @@ -14,6 +14,7 @@ let app: AppElement; let maxSpeechLength: number; let speech: TestSpeechBrowserProxy; + let speechController: SpeechController; const shortSentence = 'The snow glows white on the mountain tonight, not a footprint to be ' + @@ -79,6 +80,8 @@ chrome.readingMode.onConnected = () => {}; speech = new TestSpeechBrowserProxy(); SpeechBrowserProxyImpl.setInstance(speech); + speechController = new SpeechController(); + SpeechController.setInstance(speechController); app = await createApp(); maxSpeechLength = MAX_SPEECH_LENGTH; @@ -103,7 +106,8 @@ suite('on long sentence', () => { test('accessible text boundary is before max speech length', () => { - const firstBoundary = app.getAccessibleTextLength(longSentence); + const firstBoundary = + speechController.getUtteranceEndBoundary(longSentence, true); assertLT(firstBoundary, maxSpeechLength); }); @@ -122,7 +126,8 @@ let firstBoundary: number; setup(() => { - firstBoundary = app.getAccessibleTextLength(longSentenceWithFewCommas); + firstBoundary = speechController.getUtteranceEndBoundary( + longSentenceWithFewCommas, true); }); @@ -134,7 +139,8 @@ test('next accessible text boundary is before end of string', () => { const afterFirstBoundary = longSentenceWithFewCommas.substring( firstBoundary, longSentenceWithFewCommas.length); - const secondBoundary = app.getAccessibleTextLength(afterFirstBoundary); + const secondBoundary = + speechController.getUtteranceEndBoundary(afterFirstBoundary, true); const afterSecondBoundary = longSentenceWithFewCommas.substring( secondBoundary, longSentenceWithFewCommas.length); @@ -150,13 +156,14 @@ // When there are no other commas in a phrase, we don't splice on the // commas within numbers. - let boundary = app.getAccessibleTextLength(invalidCommaSplices); + let boundary = + speechController.getUtteranceEndBoundary(invalidCommaSplices, true); assertEquals( invalidCommaSplices, invalidCommaSplices.substring(0, boundary)); // When there is a valid comma in a string, we splice on that instead of // on the commas within numbers - boundary = app.getAccessibleTextLength(validCommaSplice); + boundary = speechController.getUtteranceEndBoundary(validCommaSplice, true); assertEquals('525,600 minutes', validCommaSplice.substring(0, boundary)); }); @@ -164,17 +171,20 @@ let firstBoundary: number; setup(() => { - firstBoundary = app.getAccessibleTextLength(longSentenceWithLateComma); + firstBoundary = speechController.getUtteranceEndBoundary( + longSentenceWithLateComma, true); }); test('commas after max speech length aren\'t used', () => { const afterFirstBoundary = longSentenceWithFewCommas.substring( firstBoundary, longSentenceWithFewCommas.length); - const secondBoundary = app.getAccessibleTextLength(afterFirstBoundary); + const secondBoundary = + speechController.getUtteranceEndBoundary(afterFirstBoundary, true); const afterSecondBoundary = longSentenceWithFewCommas.substring( firstBoundary, longSentenceWithFewCommas.length); - const thirdBoundary = app.getAccessibleTextLength(afterSecondBoundary); + const thirdBoundary = + speechController.getUtteranceEndBoundary(afterSecondBoundary, true); assertLT(firstBoundary, maxSpeechLength); assertLT(secondBoundary, maxSpeechLength);
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc index a81b2e4..49635df 100644 --- a/chrome/updater/test/integration_tests.cc +++ b/chrome/updater/test/integration_tests.cc
@@ -5098,19 +5098,31 @@ } TEST_F(IntegrationTest, OfflineInstall) { + ScopedServer test_server(test_commands_); + ExpectInstallEvent(test_server, kUpdaterAppId); ASSERT_NO_FATAL_FAILURE(Install({kEnableCecaExperimentSwitch})); ASSERT_NO_FATAL_FAILURE(ExpectInstalled()); + + ExpectInstallEvent(test_server, "{CDABE316-39CD-43BA-8440-6D1E0547AEE6}"); ASSERT_NO_FATAL_FAILURE(RunOfflineInstall(/*is_legacy_install=*/false, /*is_silent_install=*/false)); + + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } TEST_F(IntegrationTest, OfflineInstallOsNotSupported) { + ScopedServer test_server(test_commands_); + ExpectInstallEvent(test_server, kUpdaterAppId); ASSERT_NO_FATAL_FAILURE(Install({kEnableCecaExperimentSwitch})); ASSERT_NO_FATAL_FAILURE(ExpectInstalled()); + + // OS not supported is handled by the client, hence no ping. ASSERT_NO_FATAL_FAILURE( RunOfflineInstallOsNotSupported(/*is_legacy_install=*/false, /*is_silent_install=*/false)); + + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } @@ -5135,44 +5147,71 @@ } TEST_F(IntegrationTest, OfflineInstallSilent) { + ScopedServer test_server(test_commands_); + ExpectInstallEvent(test_server, kUpdaterAppId); ASSERT_NO_FATAL_FAILURE(Install({kEnableCecaExperimentSwitch})); ASSERT_NO_FATAL_FAILURE(ExpectInstalled()); + + ExpectInstallEvent(test_server, "{CDABE316-39CD-43BA-8440-6D1E0547AEE6}"); ASSERT_NO_FATAL_FAILURE(RunOfflineInstall(/*is_legacy_install=*/false, /*is_silent_install=*/true)); + + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } TEST_F(IntegrationTest, OfflineInstallOsNotSupportedSilent) { + ScopedServer test_server(test_commands_); + ExpectInstallEvent(test_server, kUpdaterAppId); ASSERT_NO_FATAL_FAILURE(Install({kEnableCecaExperimentSwitch})); ASSERT_NO_FATAL_FAILURE(ExpectInstalled()); + + // OS not supported is handled by the client, hence no ping. ASSERT_NO_FATAL_FAILURE( RunOfflineInstallOsNotSupported(/*is_legacy_install=*/false, /*is_silent_install=*/true)); + + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } TEST_F(IntegrationTest, OfflineInstallSilentLegacy) { + ScopedServer test_server(test_commands_); + ExpectInstallEvent(test_server, kUpdaterAppId); ASSERT_NO_FATAL_FAILURE(Install({kEnableCecaExperimentSwitch})); ASSERT_NO_FATAL_FAILURE(ExpectInstalled()); + + ExpectInstallEvent(test_server, "{CDABE316-39CD-43BA-8440-6D1E0547AEE6}"); ASSERT_NO_FATAL_FAILURE(RunOfflineInstall(/*is_legacy_install=*/true, /*is_silent_install=*/true)); + + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } TEST_F(IntegrationTest, OfflineInstallOsNotSupportedSilentLegacy) { + ScopedServer test_server(test_commands_); + ExpectInstallEvent(test_server, kUpdaterAppId); ASSERT_NO_FATAL_FAILURE(Install({kEnableCecaExperimentSwitch})); ASSERT_NO_FATAL_FAILURE(ExpectInstalled()); + + // OS not supported is handled by the client, hence no ping. ASSERT_NO_FATAL_FAILURE( RunOfflineInstallOsNotSupported(/*is_legacy_install=*/true, /*is_silent_install=*/true)); + + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); } TEST_F(IntegrationTest, OfflineInstallEulaRequired) { + ScopedServer test_server(test_commands_); ASSERT_NO_FATAL_FAILURE(Install({kEulaRequiredSwitch})); ASSERT_NO_FATAL_FAILURE(ExpectInstalled()); + ASSERT_NO_FATAL_FAILURE(RunOfflineInstall(/*is_legacy_install=*/false, /*is_silent_install=*/false)); + ASSERT_NO_FATAL_FAILURE(Uninstall()); } @@ -5185,10 +5224,16 @@ ASSERT_NO_FATAL_FAILURE(ResetOemMode()); }; + ScopedServer test_server(test_commands_); + ExpectInstallEvent(test_server, kUpdaterAppId); ASSERT_NO_FATAL_FAILURE(Install({kOemSwitch})); ASSERT_NO_FATAL_FAILURE(ExpectInstalled()); + + ExpectInstallEvent(test_server, "{CDABE316-39CD-43BA-8440-6D1E0547AEE6}"); ASSERT_NO_FATAL_FAILURE(RunOfflineInstall(/*is_legacy_install=*/false, /*is_silent_install=*/false)); + + ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(&test_server)); ASSERT_NO_FATAL_FAILURE(Uninstall()); }
diff --git a/chrome/updater/update_service_impl_impl.cc b/chrome/updater/update_service_impl_impl.cc index d7c80d7..ec6a875 100644 --- a/chrome/updater/update_service_impl_impl.cc +++ b/chrome/updater/update_service_impl_impl.cc
@@ -676,7 +676,7 @@ VLOG(1) << "Starting an OTA installation of the enterprise companion app."; RegistrationRequest registration; registration.app_id = enterprise_companion::kCompanionAppId; - registration.version = base::Version("0.0.0.0"); + registration.version = base::Version(kNullVersion); RegisterApp( registration, base::BindOnce([](int registration_result) {}) @@ -754,7 +754,7 @@ ->GetProductVersion(request.app_id) .IsValid() && request.version.IsValid() && - request.version > base::Version("0") && + request.version > base::Version(kNullVersion) && !config_->GetUpdaterPersistedData()->GetEulaRequired(); config_->GetUpdaterPersistedData()->RegisterApp(request); if (send_event) {
diff --git a/chromecast/app/BUILD.gn b/chromecast/app/BUILD.gn index 4184134..65a3c1d 100644 --- a/chromecast/app/BUILD.gn +++ b/chromecast/app/BUILD.gn
@@ -149,13 +149,11 @@ ] } -grit("chromecast_settings") { +grit_strings("chromecast_settings") { source = "//chromecast/app/resources/chromecast_settings.grd" outputs = [ "grit/chromecast_settings.h" ] - foreach(locale, cast_locales) { - outputs += [ "chromecast_settings_${locale}.pak" ] - } + locales = cast_locales deps = [ ":verify_cast_locales" ] }
diff --git a/chromeos/strings/BUILD.gn b/chromeos/strings/BUILD.gn index 2c09b71..fa307af 100644 --- a/chromeos/strings/BUILD.gn +++ b/chromeos/strings/BUILD.gn
@@ -6,12 +6,10 @@ import("//tools/grit/grit_rule.gni") import("//tools/grit/repack.gni") -grit("strings") { +grit_strings("strings") { source = "../chromeos_strings.grd" - outputs = - [ "grit/chromeos_strings.h" ] + - process_file_template(all_chrome_locales, - [ "chromeos_strings_{{source_name_part}}.pak" ]) + outputs = [ "grit/chromeos_strings.h" ] + output_prefix = "chromeos_strings_" } repack("chromeos_test_strings") {
diff --git a/clank b/clank index 1881fd2..86901d8 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit 1881fd29e10d5d32e8b8f6ed892c860e43dded76 +Subproject commit 86901d8e9a33f78ccf07acfa57b63439e7cfa5f8
diff --git a/components/BUILD.gn b/components/BUILD.gn index 3c5bb6b..0d4b53b 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -34,6 +34,12 @@ import("//ios/build/config.gni") } +if (translate_genders) { + _gender_suffix = "_OTHER" +} else { + _gender_suffix = "" +} + if (is_ios) { bundle_data("components_tests_pak_bundle_data") { testonly = true @@ -916,11 +922,11 @@ "$root_gen_dir/components/autofill/core/browser/geo/autofill_address_rewriter_resources.pak", "$root_gen_dir/components/components_resources.pak", "$root_gen_dir/components/metrics/metrics_server_urls.pak", - "$root_gen_dir/components/omnibox/resources/omnibox_pedal_synonyms_en-US.pak", - "$root_gen_dir/components/plus_addresses/resources/strings/plus_addresses_strings_en-US.pak", - "$root_gen_dir/components/strings/components_branded_strings_en-US.pak", - "$root_gen_dir/components/strings/components_locale_settings_en-US.pak", - "$root_gen_dir/components/strings/components_strings_en-US.pak", + "$root_gen_dir/components/omnibox/resources/omnibox_pedal_synonyms_en-US${_gender_suffix}.pak", + "$root_gen_dir/components/plus_addresses/resources/strings/plus_addresses_strings_en-US${_gender_suffix}.pak", + "$root_gen_dir/components/strings/components_branded_strings_en-US${_gender_suffix}.pak", + "$root_gen_dir/components/strings/components_locale_settings_en-US${_gender_suffix}.pak", + "$root_gen_dir/components/strings/components_strings_en-US${_gender_suffix}.pak", ] output = "$root_out_dir/components_tests_resources.pak"
diff --git a/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/BrowserControlsVisibilityDelegate.java b/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/BrowserControlsVisibilityDelegate.java index a19a3ed..c1d0c42 100644 --- a/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/BrowserControlsVisibilityDelegate.java +++ b/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/BrowserControlsVisibilityDelegate.java
@@ -4,7 +4,6 @@ package org.chromium.components.browser_ui.util; -import org.chromium.base.lifetime.Destroyable; import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.build.annotations.NullMarked; import org.chromium.cc.input.BrowserControlsState; @@ -12,7 +11,7 @@ /** A delegate to determine visibility of the browser controls. */ @NullMarked public class BrowserControlsVisibilityDelegate - extends ObservableSupplierImpl<@BrowserControlsState Integer> implements Destroyable { + extends ObservableSupplierImpl<@BrowserControlsState Integer> { /** * Constructs a delegate that controls the visibility of the browser controls. * @@ -21,9 +20,4 @@ public BrowserControlsVisibilityDelegate(@BrowserControlsState int initialValue) { super.set(initialValue); } - - @Override - public void destroy() { - // This class has nothing to clean up, but derived classes may. - } }
diff --git a/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/ComposedBrowserControlsVisibilityDelegate.java b/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/ComposedBrowserControlsVisibilityDelegate.java index 6a0b186b..bd3f4ef0 100644 --- a/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/ComposedBrowserControlsVisibilityDelegate.java +++ b/components/browser_ui/util/android/java/src/org/chromium/components/browser_ui/util/ComposedBrowserControlsVisibilityDelegate.java
@@ -90,13 +90,6 @@ super.set(value); } - @Override - public void destroy() { - for (BrowserControlsVisibilityDelegate delegate : mDelegates) { - delegate.destroy(); - } - } - private @BrowserControlsState int calculateVisibilityConstraints() { boolean shouldBeShown = false; for (BrowserControlsVisibilityDelegate delegate : mDelegates) {
diff --git a/components/cast_streaming/renderer/frame/frame_injecting_demuxer.cc b/components/cast_streaming/renderer/frame/frame_injecting_demuxer.cc index 3aab391..2ba9135 100644 --- a/components/cast_streaming/renderer/frame/frame_injecting_demuxer.cc +++ b/components/cast_streaming/renderer/frame/frame_injecting_demuxer.cc
@@ -496,23 +496,14 @@ } // Not supported. -void FrameInjectingDemuxer::OnEnabledAudioTracksChanged( +void FrameInjectingDemuxer::OnTracksChanged( + media::DemuxerStream::Type track_type, const std::vector<media::MediaTrack::Id>& track_ids, base::TimeDelta curr_time, TrackChangeCB change_completed_cb) { - DLOG(WARNING) << "Track changes are not supported."; - std::vector<media::DemuxerStream*> streams; - std::move(change_completed_cb).Run(streams); -} - -// Not supported. -void FrameInjectingDemuxer::OnSelectedVideoTrackChanged( - const std::vector<media::MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - TrackChangeCB change_completed_cb) { - DLOG(WARNING) << "Track changes are not supported."; - std::vector<media::DemuxerStream*> streams; - std::move(change_completed_cb).Run(streams); + // TODO(crbug.com/416543891): Demuxers should have a way to report that they + // do not support exposing track switching to JS. + NOTREACHED(); } } // namespace cast_streaming
diff --git a/components/cast_streaming/renderer/frame/frame_injecting_demuxer.h b/components/cast_streaming/renderer/frame/frame_injecting_demuxer.h index 5a6559a..8fed71f5 100644 --- a/components/cast_streaming/renderer/frame/frame_injecting_demuxer.h +++ b/components/cast_streaming/renderer/frame/frame_injecting_demuxer.h
@@ -64,14 +64,10 @@ int64_t GetMemoryUsage() const override; std::optional<media::container_names::MediaContainerName> GetContainerForMetrics() const override; - void OnEnabledAudioTracksChanged( - const std::vector<media::MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - TrackChangeCB change_completed_cb) override; - void OnSelectedVideoTrackChanged( - const std::vector<media::MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - TrackChangeCB change_completed_cb) override; + void OnTracksChanged(media::DemuxerStream::Type track_type, + const std::vector<media::MediaTrack::Id>& track_ids, + base::TimeDelta curr_time, + TrackChangeCB change_completed_cb) override; void SetPlaybackRate(double rate) override {} // The number of initialized streams that have yet to call
diff --git a/components/collaboration/internal/collaboration_controller.cc b/components/collaboration/internal/collaboration_controller.cc index 6c5bf8f0..2c5bec3 100644 --- a/components/collaboration/internal/collaboration_controller.cc +++ b/components/collaboration/internal/collaboration_controller.cc
@@ -274,7 +274,7 @@ void HandleError() override { ServiceStatus status = controller->collaboration_service()->GetServiceStatus(); - if (status.signin_status == SigninStatus::kNotSignedIn) { + if (status.signin_status == SigninStatus::kSigninDisabled) { RecordJoinOrShareOrManageEvent( GetLogger(), controller->flow().type, CollaborationServiceJoinEvent::kDevicePolicyDisableSignin,
diff --git a/components/collaboration/internal/collaboration_controller_unittest.cc b/components/collaboration/internal/collaboration_controller_unittest.cc index f34ce7de..7f59111 100644 --- a/components/collaboration/internal/collaboration_controller_unittest.cc +++ b/components/collaboration/internal/collaboration_controller_unittest.cc
@@ -14,6 +14,7 @@ #include "components/collaboration/internal/metrics.h" #include "components/collaboration/public/collaboration_controller_delegate.h" #include "components/collaboration/public/collaboration_flow_type.h" +#include "components/collaboration/public/service_status.h" #include "components/collaboration/test_support/mock_collaboration_controller_delegate.h" #include "components/collaboration/test_support/mock_collaboration_service.h" #include "components/data_sharing/public/data_sharing_service.h" @@ -66,6 +67,8 @@ tab_group_sync_service_ = std::make_unique<tab_groups::MockTabGroupSyncService>(); sync_service_ = std::make_unique<syncer::MockSyncService>(); + EXPECT_CALL(*data_sharing_service_, GetLogger()) + .Times(::testing::AnyNumber()); } void TearDown() override {} @@ -270,7 +273,7 @@ // Simulate managed device. ServiceStatus status; - status.signin_status = SigninStatus::kNotSignedIn; + status.signin_status = SigninStatus::kSigninDisabled; status.sync_status = SyncStatus::kNotSyncing; status.collaboration_status = CollaborationStatus::kDisabledForPolicy; EXPECT_CALL(*collaboration_service_, GetServiceStatus()) @@ -327,7 +330,7 @@ // Simulate managed account with info not ready. ServiceStatus status; - status.signin_status = SigninStatus::kNotSignedIn; + status.signin_status = SigninStatus::kSigninDisabled; status.sync_status = SyncStatus::kNotSyncing; status.collaboration_status = CollaborationStatus::kDisabledPending; EXPECT_CALL(*collaboration_service_, GetServiceStatus()) @@ -341,6 +344,7 @@ StateId::kWaitingForPolicyUpdate); // The managed account info become available. + EXPECT_CALL(*collaboration_service_, RemoveObserver(_)); EXPECT_CALL(*delegate_, ShowError(ErrorInfo(ErrorInfo::Type::kSigninDisabledByPolicy), IsNotNullCallback()));
diff --git a/components/collaboration/internal/collaboration_service_impl.cc b/components/collaboration/internal/collaboration_service_impl.cc index e3b350f..02f2b83 100644 --- a/components/collaboration/internal/collaboration_service_impl.cc +++ b/components/collaboration/internal/collaboration_service_impl.cc
@@ -58,9 +58,14 @@ current_status_.collaboration_status = GetCollaborationStatus(); registrar_.Init(profile_prefs_); - registrar_.Add(prefs::kSharedTabGroupsManagedAccountSetting, - base::BindRepeating(&CollaborationServiceImpl::OnPrefChanged, - base::Unretained(this))); + registrar_.Add( + prefs::kSharedTabGroupsManagedAccountSetting, + base::BindRepeating(&CollaborationServiceImpl::RefreshServiceStatus, + base::Unretained(this))); + registrar_.Add( + ::prefs::kSigninAllowed, + base::BindRepeating(&CollaborationServiceImpl::RefreshServiceStatus, + base::Unretained(this))); } CollaborationServiceImpl::~CollaborationServiceImpl() { @@ -347,6 +352,8 @@ } else if (identity_manager_->HasPrimaryAccount( signin::ConsentLevel::kSignin)) { status = SigninStatus::kSignedInPaused; + } else if (!profile_prefs_->GetBoolean(::prefs::kSigninAllowed)) { + status = SigninStatus::kSigninDisabled; } return status; @@ -354,7 +361,8 @@ CollaborationStatus CollaborationServiceImpl::GetCollaborationStatus() { // Check if device policy allow signin. - if (!profile_prefs_->GetBoolean(::prefs::kSigninAllowed)) { + if (!profile_prefs_->GetBoolean(::prefs::kSigninAllowed) && + profile_prefs_->IsManagedPreference(::prefs::kSigninAllowed)) { return CollaborationStatus::kDisabledForPolicy; } @@ -500,8 +508,4 @@ std::move(callback).Run(/*success=*/false); } -void CollaborationServiceImpl::OnPrefChanged() { - RefreshServiceStatus(); -} - } // namespace collaboration
diff --git a/components/collaboration/internal/collaboration_service_impl.h b/components/collaboration/internal/collaboration_service_impl.h index f80432d..22267ef9 100644 --- a/components/collaboration/internal/collaboration_service_impl.h +++ b/components/collaboration/internal/collaboration_service_impl.h
@@ -116,7 +116,6 @@ const data_sharing::GroupId& group_id, base::OnceCallback<void(bool)> callback, data_sharing::DataSharingService::PeopleGroupActionOutcome result); - void OnPrefChanged(); ServiceStatus current_status_; base::ScopedObservation<syncer::SyncService, syncer::SyncServiceObserver>
diff --git a/components/collaboration/internal/collaboration_service_impl_unittest.cc b/components/collaboration/internal/collaboration_service_impl_unittest.cc index 5601097..d835b6f 100644 --- a/components/collaboration/internal/collaboration_service_impl_unittest.cc +++ b/components/collaboration/internal/collaboration_service_impl_unittest.cc
@@ -160,23 +160,21 @@ CollaborationStatus::kEnabledCreateAndJoin); } -TEST_F(CollaborationServiceImplTest, GetServiceStatus_ManagedDevice) { +TEST_F(CollaborationServiceImplTest, GetServiceStatus_SigninDisabled) { base::test::ScopedFeatureList feature_list; feature_list.InitAndEnableFeature( data_sharing::features::kDataSharingFeature); - // Set device policy to disable signin. + // Set signin preference to disable signin. pref_service_.SetBoolean(prefs::kSigninAllowed, false); InitService(); EXPECT_EQ(service_->GetServiceStatus().signin_status, - SigninStatus::kNotSignedIn); + SigninStatus::kSigninDisabled); EXPECT_EQ(service_->GetServiceStatus().collaboration_status, - CollaborationStatus::kDisabledForPolicy); - identity_test_env_.MakePrimaryAccountAvailable(kConsumerUserEmail, - signin::ConsentLevel::kSignin); - EXPECT_EQ(service_->GetServiceStatus().signin_status, - SigninStatus::kSignedIn); + CollaborationStatus::kEnabledCreateAndJoin); + + pref_service_.SetManagedPref(prefs::kSigninAllowed, base::Value(false)); EXPECT_EQ(service_->GetServiceStatus().collaboration_status, CollaborationStatus::kDisabledForPolicy); }
diff --git a/components/collaboration/internal/metrics.cc b/components/collaboration/internal/metrics.cc index fef689d..eb3069fb 100644 --- a/components/collaboration/internal/metrics.cc +++ b/components/collaboration/internal/metrics.cc
@@ -285,6 +285,7 @@ void RecordJoinEvent(data_sharing::Logger* logger, CollaborationServiceJoinEvent event) { + VLOG(1) << "RecordJoinEvent:" << (CreateJoinEventLogString(event)); base::UmaHistogramEnumeration("CollaborationService.JoinFlow", event); DATA_SHARING_LOG(logger_common::mojom::LogSource::CollaborationService, logger, CreateJoinEventLogString(event)); @@ -292,6 +293,8 @@ void RecordShareOrManageEvent(data_sharing::Logger* logger, CollaborationServiceShareOrManageEvent event) { + VLOG(1) << "RecordShareOrManageEvent:" + << (CreateShareOrManageEventLogString(event)); base::UmaHistogramEnumeration("CollaborationService.ShareOrManageFlow", event); DATA_SHARING_LOG(logger_common::mojom::LogSource::CollaborationService,
diff --git a/components/collaboration/public/service_status.h b/components/collaboration/public/service_status.h index 22302f4..0ef17d98 100644 --- a/components/collaboration/public/service_status.h +++ b/components/collaboration/public/service_status.h
@@ -11,8 +11,10 @@ // org.chromium.components.collaboration) enum class SigninStatus { kNotSignedIn = 0, - kSignedInPaused = 1, - kSignedIn = 2 + // Signin is disabled either in user setting or by enterprise policy. + kSigninDisabled = 1, + kSignedInPaused = 2, + kSignedIn = 3 }; // GENERATED_JAVA_ENUM_PACKAGE: (
diff --git a/components/collaboration_strings.grdp b/components/collaboration_strings.grdp index 0d7229ac..740ffd43 100644 --- a/components/collaboration_strings.grdp +++ b/components/collaboration_strings.grdp
@@ -158,8 +158,8 @@ <message name="IDS_DATA_SHARING_RECENT_ACTIVITY_UNKNOWN_USER" desc="The user name to show on the recent activity bottom sheet row if the user info cannot be found, e.g. deleted their account."> Deleted account </message> - <message name ="IDS_DATA_SHARING_SHARED_TAB_GROUP_ACTIVITY" desc="The text on the button to show the full recent activity logs and manage screen menu options." formatter_data="android_java"> - Shared tab group activity + <message name ="IDS_DATA_SHARING_SHARED_TAB_GROUPS_ACTIVITY" desc="The text on the button to show the full recent activity logs and manage screen menu options." formatter_data="android_java"> + Shared tab groups activity </message> <!-- Recent Activity -->
diff --git a/components/collaboration_strings_grdp/IDS_DATA_SHARING_SHARED_TAB_GROUPS_ACTIVITY.png.sha1 b/components/collaboration_strings_grdp/IDS_DATA_SHARING_SHARED_TAB_GROUPS_ACTIVITY.png.sha1 new file mode 100644 index 0000000..9070107 --- /dev/null +++ b/components/collaboration_strings_grdp/IDS_DATA_SHARING_SHARED_TAB_GROUPS_ACTIVITY.png.sha1
@@ -0,0 +1 @@ +f91992bb976e99cd15f326dfb6147fd952d2441a \ No newline at end of file
diff --git a/components/collaboration_strings_grdp/IDS_DATA_SHARING_SHARED_TAB_GROUP_ACTIVITY.png.sha1 b/components/collaboration_strings_grdp/IDS_DATA_SHARING_SHARED_TAB_GROUP_ACTIVITY.png.sha1 deleted file mode 100644 index d61607d0..0000000 --- a/components/collaboration_strings_grdp/IDS_DATA_SHARING_SHARED_TAB_GROUP_ACTIVITY.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -cf9b27802baddb7c506b71dc00ba116852a36e3f \ No newline at end of file
diff --git a/components/navigation_interception/intercept_navigation_delegate.cc b/components/navigation_interception/intercept_navigation_delegate.cc index d9564672..4ecedcb 100644 --- a/components/navigation_interception/intercept_navigation_delegate.cc +++ b/components/navigation_interception/intercept_navigation_delegate.cc
@@ -137,9 +137,8 @@ } // static -std::unique_ptr<content::NavigationThrottle> -InterceptNavigationDelegate::MaybeCreateThrottleFor( - content::NavigationHandle* handle, +void InterceptNavigationDelegate::MaybeCreateAndAdd( + content::NavigationThrottleRegistry& registry, navigation_interception::SynchronyMode mode) { // Navigations in a subframe or non-primary frame tree should not be // intercepted. As examples of a non-primary frame tree, a navigation @@ -153,26 +152,28 @@ // have been launched (without launching the intent). It's also not clear // what the right behavior for <portal> elements is. // https://crbug.com/1227659. - if (!handle->IsInPrimaryMainFrame()) - return nullptr; - - InterceptNavigationDelegate* intercept_navigation_delegate = - InterceptNavigationDelegate::Get(handle->GetWebContents()); - - if (!intercept_navigation_delegate) { - return std::make_unique<InterceptNavigationThrottle>( - handle, base::BindRepeating(&AllowNavigationToProceed), mode, - base::DoNothing()); + if (!registry.GetNavigationHandle().IsInPrimaryMainFrame()) { + return; } - return std::make_unique<InterceptNavigationThrottle>( - handle, + InterceptNavigationDelegate* intercept_navigation_delegate = + InterceptNavigationDelegate::Get( + registry.GetNavigationHandle().GetWebContents()); + + if (!intercept_navigation_delegate) { + registry.AddThrottle(std::make_unique<InterceptNavigationThrottle>( + registry, base::BindRepeating(&AllowNavigationToProceed), mode, + base::DoNothing())); + } else { + registry.AddThrottle(std::make_unique<InterceptNavigationThrottle>( + registry, base::BindRepeating(&InterceptNavigationDelegate::ShouldIgnoreNavigation, base::Unretained(intercept_navigation_delegate)), mode, base::BindRepeating( &InterceptNavigationDelegate::RequestFinishPendingShouldIgnoreCheck, - base::Unretained(intercept_navigation_delegate))); + base::Unretained(intercept_navigation_delegate)))); + } } InterceptNavigationDelegate::InterceptNavigationDelegate( @@ -278,21 +279,24 @@ GURL escaped_url = escape_external_handler_value_ ? GURL(base::EscapeExternalHandlerValue(url.spec())) : url; - if (!escaped_url.is_valid()) + if (!escaped_url.is_valid()) { return; + } JNIEnv* env = base::android::AttachCurrentThread(); ScopedJavaLocalRef<jobject> jdelegate = weak_jdelegate_.get(env); - if (jdelegate.is_null()) + if (jdelegate.is_null()) { return; + } ScopedJavaLocalRef<jobject> j_gurl = Java_InterceptNavigationDelegate_handleSubframeExternalProtocol( env, jdelegate, url::GURLAndroid::FromNativeGURL(env, escaped_url), page_transition, has_user_gesture, initiating_origin ? initiating_origin->ToJavaObject(env) : nullptr); - if (j_gurl.is_null()) + if (j_gurl.is_null()) { return; + } subframe_redirect_url_ = std::make_unique<GURL>(url::GURLAndroid::ToNativeGURL(env, j_gurl)); @@ -335,8 +339,9 @@ void InterceptNavigationDelegate::OnResourceRequestWithGesture() { JNIEnv* env = base::android::AttachCurrentThread(); ScopedJavaLocalRef<jobject> jdelegate = weak_jdelegate_.get(env); - if (jdelegate.is_null()) + if (jdelegate.is_null()) { return; + } Java_InterceptNavigationDelegate_onResourceRequestWithGesture(env, jdelegate); }
diff --git a/components/navigation_interception/intercept_navigation_delegate.h b/components/navigation_interception/intercept_navigation_delegate.h index 6a3d5e49..00dacc2 100644 --- a/components/navigation_interception/intercept_navigation_delegate.h +++ b/components/navigation_interception/intercept_navigation_delegate.h
@@ -79,9 +79,8 @@ // Creates a InterceptNavigationThrottle that will direct all callbacks to // the InterceptNavigationDelegate. - static std::unique_ptr<content::NavigationThrottle> MaybeCreateThrottleFor( - content::NavigationHandle* handle, - navigation_interception::SynchronyMode mode); + static void MaybeCreateAndAdd(content::NavigationThrottleRegistry& registry, + navigation_interception::SynchronyMode mode); void ShouldIgnoreNavigation( content::NavigationHandle* navigation_handle,
diff --git a/components/navigation_interception/intercept_navigation_throttle.cc b/components/navigation_interception/intercept_navigation_throttle.cc index 32dd931..1f7ed4fed 100644 --- a/components/navigation_interception/intercept_navigation_throttle.cc +++ b/components/navigation_interception/intercept_navigation_throttle.cc
@@ -19,11 +19,11 @@ base::FEATURE_ENABLED_BY_DEFAULT); InterceptNavigationThrottle::InterceptNavigationThrottle( - content::NavigationHandle* navigation_handle, + content::NavigationThrottleRegistry& registry, CheckCallback should_ignore_callback, SynchronyMode async_mode, std::optional<base::RepeatingClosure> request_finish_async_work_callback) - : content::NavigationThrottle(navigation_handle), + : content::NavigationThrottle(registry), should_ignore_callback_(should_ignore_callback), request_finish_async_work_callback_(request_finish_async_work_callback), ui_task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()),
diff --git a/components/navigation_interception/intercept_navigation_throttle.h b/components/navigation_interception/intercept_navigation_throttle.h index bfc20ca..31b865d6 100644 --- a/components/navigation_interception/intercept_navigation_throttle.h +++ b/components/navigation_interception/intercept_navigation_throttle.h
@@ -14,6 +14,7 @@ namespace content { class NavigationHandle; +class NavigationThrottleRegistry; } namespace navigation_interception { @@ -39,7 +40,7 @@ CheckCallback; InterceptNavigationThrottle( - content::NavigationHandle* navigation_handle, + content::NavigationThrottleRegistry& registry, CheckCallback should_ignore_callback, SynchronyMode async_mode, std::optional<base::RepeatingClosure> request_finish_async_work_callback);
diff --git a/components/navigation_interception/intercept_navigation_throttle_unittest.cc b/components/navigation_interception/intercept_navigation_throttle_unittest.cc index 7ba9d18..8a4f61f 100644 --- a/components/navigation_interception/intercept_navigation_throttle_unittest.cc +++ b/components/navigation_interception/intercept_navigation_throttle_unittest.cc
@@ -83,16 +83,17 @@ } } - std::unique_ptr<content::NavigationThrottle> CreateThrottle( + void CreateAndAddThrottle( InterceptNavigationThrottle::CheckCallback callback, base::RepeatingClosure request_finish_closure, - content::NavigationHandle* handle) { + content::NavigationThrottleRegistry& registry) { std::unique_ptr<InterceptNavigationThrottle> throttle = std::make_unique<InterceptNavigationThrottle>( - handle, callback, navigation_interception::SynchronyMode::kAsync, + registry, callback, + navigation_interception::SynchronyMode::kAsync, request_finish_closure); throttle_ = throttle.get()->GetWeakPtrForTesting(); - return throttle; + registry.AddThrottle(std::move(throttle)); } std::unique_ptr<content::TestNavigationThrottleInserter> @@ -100,7 +101,7 @@ return std::make_unique<content::TestNavigationThrottleInserter>( web_contents(), base::BindRepeating( - &InterceptNavigationThrottleTest::CreateThrottle, + &InterceptNavigationThrottleTest::CreateAndAddThrottle, base::Unretained(this), base::BindRepeating( &MockInterceptCallbackReceiver::ShouldIgnoreNavigation, @@ -120,16 +121,19 @@ NavigationThrottle::PROCEED; }; - if (is_post) + if (is_post) { simulator->SetMethod("POST"); + } simulator->Start(); - if (failed(simulator.get())) + if (failed(simulator.get())) { return simulator->GetLastThrottleCheckResult(); + } for (const GURL& redirect_url : redirect_chain) { simulator->Redirect(redirect_url); - if (failed(simulator.get())) + if (failed(simulator.get())) { return simulator->GetLastThrottleCheckResult(); + } } simulator->Commit(); return simulator->GetLastThrottleCheckResult();
diff --git a/components/omnibox/browser/autocomplete_result_unittest.cc b/components/omnibox/browser/autocomplete_result_unittest.cc index c3fbe08..4b653e1 100644 --- a/components/omnibox/browser/autocomplete_result_unittest.cc +++ b/components/omnibox/browser/autocomplete_result_unittest.cc
@@ -9,8 +9,6 @@ #pragma allow_unsafe_buffers #endif -#include "components/omnibox/browser/autocomplete_result.h" - #include <stddef.h> #include <algorithm> @@ -36,6 +34,7 @@ #include "components/omnibox/browser/autocomplete_match_type.h" #include "components/omnibox/browser/autocomplete_provider.h" #include "components/omnibox/browser/autocomplete_provider_client.h" +#include "components/omnibox/browser/autocomplete_result.h" #include "components/omnibox/browser/fake_autocomplete_provider.h" #include "components/omnibox/browser/fake_autocomplete_provider_client.h" #include "components/omnibox/browser/fake_tab_matcher.h"
diff --git a/components/omnibox/browser/clipboard_provider.cc b/components/omnibox/browser/clipboard_provider.cc index c8cf52e..d1e1fa92 100644 --- a/components/omnibox/browser/clipboard_provider.cc +++ b/components/omnibox/browser/clipboard_provider.cc
@@ -243,8 +243,7 @@ matches_.empty(), match.type, clipboard_contents_age); - if (is_android && - omnibox::IsNTPPage(input.current_page_classification())) { + if (is_android && omnibox::IsNTPPage(input.current_page_classification())) { // Assign the Clipboard to the PZPS group on NTP pages to improve the use // of the suggest space. match.suggestion_group_id = omnibox::GROUP_PERSONALIZED_ZERO_SUGGEST;
diff --git a/components/omnibox/browser/contextual_search_provider.h b/components/omnibox/browser/contextual_search_provider.h index 7a5c0a0..1b284974 100644 --- a/components/omnibox/browser/contextual_search_provider.h +++ b/components/omnibox/browser/contextual_search_provider.h
@@ -48,7 +48,7 @@ // Waits for the Lens suggest inputs to be ready and then sends the request to // the remote suggest server. If the inputs are already ready, the request is - //sent immediately. + // sent immediately. void StartSuggestRequest(AutocompleteInput input); // Attaches the lens suggest inputs to `input` and makes the suggest request.
diff --git a/components/omnibox/browser/document_provider_unittest.cc b/components/omnibox/browser/document_provider_unittest.cc index 85501d6..69d5c89 100644 --- a/components/omnibox/browser/document_provider_unittest.cc +++ b/components/omnibox/browser/document_provider_unittest.cc
@@ -124,7 +124,7 @@ } base::test::SingleThreadTaskEnvironment task_environment_{ - base::test::TaskEnvironment::TimeSource::MOCK_TIME}; + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; // Not enabled by default on mobile, so have to enable it explicitly. base::test::ScopedFeatureList feature_list_{omnibox::kDocumentProvider}; std::unique_ptr<FakeAutocompleteProviderClient> client_; @@ -1182,7 +1182,8 @@ { omnibox_feature_configs::ScopedConfigForTesting< - omnibox_feature_configs::DocumentProvider> scoped_config; + omnibox_feature_configs::DocumentProvider> + scoped_config; scoped_config.Get().enabled = true; scoped_config.Get().scope_backoff_to_profile = false; @@ -1199,7 +1200,8 @@ { omnibox_feature_configs::ScopedConfigForTesting< - omnibox_feature_configs::DocumentProvider> scoped_config; + omnibox_feature_configs::DocumentProvider> + scoped_config; scoped_config.Get().enabled = true; scoped_config.Get().scope_backoff_to_profile = true; scoped_config.Get().backoff_duration = base::Minutes(30);
diff --git a/components/omnibox/browser/featured_search_provider_unittest.cc b/components/omnibox/browser/featured_search_provider_unittest.cc index 4464f4ff..69eeed0 100644 --- a/components/omnibox/browser/featured_search_provider_unittest.cc +++ b/components/omnibox/browser/featured_search_provider_unittest.cc
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. - #include "components/omnibox/browser/featured_search_provider.h" #include <stddef.h>
diff --git a/components/omnibox/browser/most_visited_sites_provider_unittest.cc b/components/omnibox/browser/most_visited_sites_provider_unittest.cc index 716e203..a773c12 100644 --- a/components/omnibox/browser/most_visited_sites_provider_unittest.cc +++ b/components/omnibox/browser/most_visited_sites_provider_unittest.cc
@@ -99,10 +99,7 @@ constexpr const auto* WEB_URL = u"https://example.com/"; -enum class ExpectedUiType { - kAggregateMatch, - kIndividualTiles -}; +enum class ExpectedUiType { kAggregateMatch, kIndividualTiles }; const std::vector<TestData> DefaultTestData() { return {{false, {GURL("http://www.a.art/"), u"A art"}},
diff --git a/components/omnibox/browser/zero_suggest_provider.h b/components/omnibox/browser/zero_suggest_provider.h index a3a5dde..4051267 100644 --- a/components/omnibox/browser/zero_suggest_provider.h +++ b/components/omnibox/browser/zero_suggest_provider.h
@@ -24,7 +24,6 @@ class SimpleURLLoader; } - // Autocomplete provider for searches based on the current URL. // // The controller will call Start() when the user focuses the omnibox. After
diff --git a/components/omnibox/resources/BUILD.gn b/components/omnibox/resources/BUILD.gn index 668f4e1..4925760 100644 --- a/components/omnibox/resources/BUILD.gn +++ b/components/omnibox/resources/BUILD.gn
@@ -5,10 +5,7 @@ import("//build/config/locales.gni") import("//tools/grit/grit_rule.gni") -grit("omnibox_pedal_synonyms") { +grit_strings("omnibox_pedal_synonyms") { source = "omnibox_pedal_synonyms.grd" outputs = [ "grit/omnibox_pedal_synonyms.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "omnibox_pedal_synonyms_$locale.pak" ] - } }
diff --git a/components/optimization_guide/proto/features/common_quality_data.proto b/components/optimization_guide/proto/features/common_quality_data.proto index eb82e0c8..d5b93712 100644 --- a/components/optimization_guide/proto/features/common_quality_data.proto +++ b/components/optimization_guide/proto/features/common_quality_data.proto
@@ -311,6 +311,8 @@ int32 label_for_dom_node_id = 25; // The role of this ContentNode derived from the aria-role attribute. + // NOTE: This is enabled only for the experimental version of + // ANNOTATED_PAGE_CONTENT_VERSION_ONLY_ACTIONABLE_ELEMENTS_1_0. AXRole aria_role = 26; reserved 5, 6, 7, 17, 18, 1, 22;
diff --git a/components/payments/content/android/java/res/layout/secure_payment_confirmation_authn_ui.xml b/components/payments/content/android/java/res/layout/secure_payment_confirmation_authn_ui.xml index f48fc7fc..d5f1bb3e 100644 --- a/components/payments/content/android/java/res/layout/secure_payment_confirmation_authn_ui.xml +++ b/components/payments/content/android/java/res/layout/secure_payment_confirmation_authn_ui.xml
@@ -203,10 +203,22 @@ android:textAppearance="@style/TextAppearance.TextSmall.Secondary" android:text="@string/secure_payment_confirmation_opt_out_label"/> + <org.chromium.ui.widget.TextViewWithClickableSpans + android:id="@+id/secure_payment_confirmation_footnote" + android:layout_below="@id/secure_payment_confirmation_nocredmatch_opt_out" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerHorizontal="true" + android:gravity="center" + android:layout_marginHorizontal="@dimen/secure_payment_confirmation_ui_small_padding" + android:layout_marginBottom="@dimen/secure_payment_confirmation_ui_medium_padding" + android:textAppearance="@style/TextAppearance.TextSmall.Secondary" + android:text="@string/secure_payment_confirmation_footnote"/> + <!-- "Continue" button --> <org.chromium.ui.widget.ButtonCompat android:id="@+id/continue_button" - android:layout_below="@id/secure_payment_confirmation_nocredmatch_opt_out" + android:layout_below="@id/secure_payment_confirmation_footnote" android:layout_height="wrap_content" android:layout_width="match_parent" tools:text="Verify"
diff --git a/components/payments/content/android/spc/java/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnController.java b/components/payments/content/android/spc/java/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnController.java index d6954a42..1e222522 100644 --- a/components/payments/content/android/spc/java/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnController.java +++ b/components/payments/content/android/spc/java/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnController.java
@@ -11,9 +11,11 @@ import android.content.res.Resources; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.text.SpannableString; import android.util.Pair; import android.view.View; +import androidx.annotation.IntDef; import androidx.annotation.StringRes; import androidx.annotation.VisibleForTesting; import androidx.core.content.res.ResourcesCompat; @@ -39,8 +41,13 @@ import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; +import org.chromium.ui.text.ChromeClickableSpan; +import org.chromium.ui.text.SpanApplier; +import org.chromium.ui.text.SpanApplier.SpanInfo; import org.chromium.url.Origin; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.Locale; /** @@ -51,15 +58,32 @@ */ @NullMarked public class SecurePaymentConfirmationAuthnController { + @IntDef({ + SpcResponseStatus.UNKNOWN, + SpcResponseStatus.ACCEPT, + SpcResponseStatus.ANOTHER_WAY, + SpcResponseStatus.CANCEL + }) + @Retention(RetentionPolicy.SOURCE) + public @interface SpcResponseStatus { + int UNKNOWN = 0; + int ACCEPT = 1; + int ANOTHER_WAY = 2; + int CANCEL = 3; + int OPT_OUT = 4; + } + private final WebContents mWebContents; private @Nullable Runnable mHider; - private @Nullable Callback<Boolean> mResponseCallback; + private @Nullable Callback<Integer> mResponseCallback; private @Nullable Runnable mOptOutCallback; private @Nullable SecurePaymentConfirmationAuthnView mView; + private @Nullable Boolean mInformOnly; + private InputProtector mInputProtector = new InputProtector(); private final BottomSheetObserver mBottomSheetObserver = @@ -169,7 +193,7 @@ * @param paymentIcon The icon of the payment instrument. * @param paymentInstrumentLabel The label to display for the payment instrument. * @param total The total amount of the transaction. - * @param responseCallback The function to call on sheet dismiss; false if it failed. + * @param responseCallback The function to call on sheet dismiss; called with SpcResponseStatus. * @param optOutCallback The function to call on user opt out. * @param payeeName The name of the payee, or null if not specified. * @param payeeOrigin The origin of the payee, or null if not specified. @@ -183,7 +207,7 @@ Drawable paymentIcon, String paymentInstrumentLabel, PaymentItem total, - Callback<Boolean> responseCallback, + Callback<Integer> responseCallback, Runnable optOutCallback, @Nullable String payeeName, @Nullable Origin payeeOrigin, @@ -195,6 +219,7 @@ assert !informOnly || PaymentFeatureList.isEnabledOrExperimentalFeaturesEnabled( PaymentFeatureList.SECURE_PAYMENT_CONFIRMATION_FALLBACK); + mInformOnly = informOnly; if (mHider != null) return false; @@ -232,6 +257,26 @@ showsIssuerNetworkIcons = true; } + SpannableString footnote = null; + if (!mInformOnly + && PaymentFeatureList.isEnabledOrExperimentalFeaturesEnabled( + PaymentFeatureList.SECURE_PAYMENT_CONFIRMATION_FALLBACK)) { + footnote = + SpanApplier.applySpans( + context.getString(R.string.secure_payment_confirmation_footnote), + new SpanInfo( + "BEGIN_LINK", + "END_LINK", + new ChromeClickableSpan( + context, + (widget) -> { + hide(); + assumeNonNull(mResponseCallback); + mResponseCallback.onResult( + SpcResponseStatus.ANOTHER_WAY); + }))); + } + PropertyModel model = new PropertyModel.Builder(SecurePaymentConfirmationAuthnProperties.ALL_KEYS) .with( @@ -263,7 +308,7 @@ .with(SecurePaymentConfirmationAuthnProperties.NETWORK_ICON, networkIcon) .with( SecurePaymentConfirmationAuthnProperties.TITLE, - informOnly + mInformOnly ? context.getString( R.string .secure_payment_confirmation_inform_only_title) @@ -272,9 +317,10 @@ .secure_payment_confirmation_verify_purchase)) .with( SecurePaymentConfirmationAuthnProperties.CONTINUE_BUTTON_LABEL, - informOnly + mInformOnly ? context.getString(R.string.payments_confirm_button) : context.getString(R.string.payments_continue_button)) + .with(SecurePaymentConfirmationAuthnProperties.FOOTNOTE, footnote) .build(); bottomSheet.addObserver(mBottomSheetObserver); @@ -347,8 +393,13 @@ private void onConfirm() { hide(); + assumeNonNull(mInformOnly); assumeNonNull(mResponseCallback); - mResponseCallback.onResult(true); + if (mInformOnly) { + mResponseCallback.onResult(SpcResponseStatus.ANOTHER_WAY); + } else { + mResponseCallback.onResult(SpcResponseStatus.ACCEPT); + } } private void onConfirmPressed() { @@ -358,7 +409,12 @@ private void onCancel() { hide(); assumeNonNull(mResponseCallback); - mResponseCallback.onResult(false); + if (PaymentFeatureList.isEnabledOrExperimentalFeaturesEnabled( + PaymentFeatureList.SECURE_PAYMENT_CONFIRMATION_FALLBACK)) { + mResponseCallback.onResult(SpcResponseStatus.CANCEL); + } else { + mResponseCallback.onResult(SpcResponseStatus.ANOTHER_WAY); + } } private void onCancelPressed() {
diff --git a/components/payments/content/android/spc/java/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnProperties.java b/components/payments/content/android/spc/java/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnProperties.java index 17a02555..6050767 100644 --- a/components/payments/content/android/spc/java/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnProperties.java +++ b/components/payments/content/android/spc/java/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnProperties.java
@@ -5,6 +5,7 @@ package org.chromium.components.payments.secure_payment_confirmation; import android.graphics.drawable.Drawable; +import android.text.SpannableString; import android.util.Pair; import org.chromium.build.annotations.NullMarked; @@ -77,6 +78,10 @@ /* package */ static final ReadableObjectPropertyKey<String> CONTINUE_BUTTON_LABEL = new ReadableObjectPropertyKey<>(); + /** The footnote for the UI. */ + /* package */ static final ReadableObjectPropertyKey<SpannableString> FOOTNOTE = + new ReadableObjectPropertyKey<>(); + /* package */ static final PropertyKey[] ALL_KEYS = new PropertyKey[] { STORE_LABEL, @@ -92,6 +97,7 @@ NETWORK_ICON, TITLE, CONTINUE_BUTTON_LABEL, + FOOTNOTE, }; // Prevent instantiation.
diff --git a/components/payments/content/android/spc/java/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnView.java b/components/payments/content/android/spc/java/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnView.java index f3b97d10..ba9e9e7 100644 --- a/components/payments/content/android/spc/java/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnView.java +++ b/components/payments/content/android/spc/java/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnView.java
@@ -60,6 +60,7 @@ /* package */ final Button mContinueButton; /* package */ final Button mCancelButton; /* package */ final TextViewWithClickableSpans mOptOutText; + /* package */ final TextViewWithClickableSpans mFootnote; /* package */ SecurePaymentConfirmationAuthnView(Context context) { mContentView = @@ -86,9 +87,13 @@ (TextViewWithClickableSpans) mContentView.findViewById( R.id.secure_payment_confirmation_nocredmatch_opt_out); + mFootnote = + (TextViewWithClickableSpans) + mContentView.findViewById(R.id.secure_payment_confirmation_footnote); mHeaderImage.setImageResource(R.drawable.save_card); mOptOutText.setMovementMethod(LinkMovementMethod.getInstance()); + mFootnote.setMovementMethod(LinkMovementMethod.getInstance()); } /* package */ View getContentView() {
diff --git a/components/payments/content/android/spc/java/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnViewBinder.java b/components/payments/content/android/spc/java/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnViewBinder.java index 445a579..85b8a9b 100644 --- a/components/payments/content/android/spc/java/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnViewBinder.java +++ b/components/payments/content/android/spc/java/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnViewBinder.java
@@ -89,6 +89,14 @@ } else if (SecurePaymentConfirmationAuthnProperties.CONTINUE_BUTTON_LABEL == propertyKey) { view.mContinueButton.setText( model.get(SecurePaymentConfirmationAuthnProperties.CONTINUE_BUTTON_LABEL)); + } else if (SecurePaymentConfirmationAuthnProperties.FOOTNOTE == propertyKey) { + if (model.get(SecurePaymentConfirmationAuthnProperties.FOOTNOTE) == null) { + view.mFootnote.setVisibility(View.GONE); + } else { + view.mFootnote.setVisibility(View.VISIBLE); + view.mFootnote.setText( + model.get(SecurePaymentConfirmationAuthnProperties.FOOTNOTE)); + } } }
diff --git a/components/payments/content/android/spc/junit/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnTest.java b/components/payments/content/android/spc/junit/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnTest.java index 70e1b8ce..b864892 100644 --- a/components/payments/content/android/spc/junit/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnTest.java +++ b/components/payments/content/android/spc/junit/src/org/chromium/components/payments/secure_payment_confirmation/SecurePaymentConfirmationAuthnTest.java
@@ -39,6 +39,7 @@ import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerProvider; import org.chromium.components.payments.PaymentFeatureList; import org.chromium.components.payments.R; +import org.chromium.components.payments.secure_payment_confirmation.SecurePaymentConfirmationAuthnController.SpcResponseStatus; import org.chromium.components.payments.test_support.DefaultPaymentFeatureConfig; import org.chromium.components.payments.ui.CurrencyFormatter; import org.chromium.components.payments.ui.CurrencyFormatterJni; @@ -58,7 +59,11 @@ @Config( manifest = Config.NONE, shadows = {SecurePaymentConfirmationAuthnTest.ShadowBottomSheetControllerProvider.class}) -@EnableFeatures(BlinkFeatures.SECURE_PAYMENT_CONFIRMATION_NETWORK_AND_ISSUER_ICONS) +@EnableFeatures({ + BlinkFeatures.SECURE_PAYMENT_CONFIRMATION_NETWORK_AND_ISSUER_ICONS, + PaymentFeatureList.SECURE_PAYMENT_CONFIRMATION_FALLBACK +}) +@DisableFeatures(PaymentFeatureList.WEB_PAYMENTS_EXPERIMENTAL_FEATURES) public class SecurePaymentConfirmationAuthnTest { private static final long IGNORED_INPUT_DELAY = InputProtector.POTENTIALLY_UNINTENDED_INPUT_THRESHOLD - 100; @@ -70,10 +75,8 @@ @Mock(answer = Answers.RETURNS_DEEP_STUBS) private WebContents mWebContents; - private boolean mIsPaymentConfirmed; - private boolean mIsPaymentCancelled; private boolean mIsPaymentOptOut; - private Callback<Boolean> mResponseCallback; + private Callback<Integer> mResponseCallback; private Runnable mOptOutCallback; private String mPayeeName; @@ -84,6 +87,7 @@ private Drawable mNetworkIcon; private SecurePaymentConfirmationAuthnController mAuthnController; private FakeClock mClock = new FakeClock(); + private @SpcResponseStatus int mResponseStatus = SpcResponseStatus.UNKNOWN; /** The shadow of BottomSheetControllerProvider. Not to use outside the test. */ @Implements(BottomSheetControllerProvider.class) @@ -152,12 +156,8 @@ /* height= */ 1, Bitmap.Config.ARGB_8888)); mResponseCallback = - (response) -> { - if (response) { - mIsPaymentConfirmed = true; - } else { - mIsPaymentCancelled = true; - } + (responseStatus) -> { + mResponseStatus = responseStatus; }; mOptOutCallback = () -> { @@ -213,8 +213,6 @@ String payeeName, Origin payeeOrigin, boolean enableOptOut, boolean informOnly) { if (mAuthnController == null) return false; - mIsPaymentConfirmed = false; - mIsPaymentCancelled = false; mIsPaymentOptOut = false; String paymentInstrumentLabel = "My Card"; @@ -249,8 +247,10 @@ createAuthnController(); show(); mClock.advanceCurrentTimeMillis(SAFE_INPUT_DELAY); + mAuthnController.getView().mContinueButton.performClick(); - Assert.assertTrue(mIsPaymentConfirmed); + + Assert.assertEquals(SpcResponseStatus.ACCEPT, mResponseStatus); Assert.assertTrue(mAuthnController.isHidden()); } @@ -260,8 +260,24 @@ createAuthnController(); show(); mClock.advanceCurrentTimeMillis(SAFE_INPUT_DELAY); + mAuthnController.getView().mCancelButton.performClick(); - Assert.assertTrue(mIsPaymentCancelled); + + Assert.assertEquals(SpcResponseStatus.CANCEL, mResponseStatus); + Assert.assertTrue(mAuthnController.isHidden()); + } + + @Test + @Feature({"Payments"}) + @DisableFeatures(PaymentFeatureList.SECURE_PAYMENT_CONFIRMATION_FALLBACK) + public void testOnAuthnCancellationFeatureDisabled() { + createAuthnController(); + show(); + mClock.advanceCurrentTimeMillis(SAFE_INPUT_DELAY); + + mAuthnController.getView().mCancelButton.performClick(); + + Assert.assertEquals(SpcResponseStatus.ANOTHER_WAY, mResponseStatus); Assert.assertTrue(mAuthnController.isHidden()); } @@ -271,8 +287,10 @@ createAuthnController(); showWithOptOut(); mClock.advanceCurrentTimeMillis(SAFE_INPUT_DELAY); + SecurePaymentConfirmationAuthnView authnView = mAuthnController.getView(); authnView.mOptOutText.getClickableSpans()[0].onClick(authnView.mOptOutText); + Assert.assertTrue(mIsPaymentOptOut); Assert.assertTrue(mAuthnController.isHidden()); } @@ -285,11 +303,11 @@ // Clicking immediately is prevented. mAuthnController.getView().mContinueButton.performClick(); - Assert.assertFalse(mIsPaymentConfirmed); + Assert.assertEquals(SpcResponseStatus.UNKNOWN, mResponseStatus); Assert.assertFalse(mAuthnController.isHidden()); mAuthnController.getView().mCancelButton.performClick(); - Assert.assertFalse(mIsPaymentCancelled); + Assert.assertEquals(SpcResponseStatus.UNKNOWN, mResponseStatus); Assert.assertFalse(mAuthnController.isHidden()); SecurePaymentConfirmationAuthnView authnView = mAuthnController.getView(); @@ -301,11 +319,11 @@ mClock.advanceCurrentTimeMillis(IGNORED_INPUT_DELAY); mAuthnController.getView().mContinueButton.performClick(); - Assert.assertFalse(mIsPaymentConfirmed); + Assert.assertEquals(SpcResponseStatus.UNKNOWN, mResponseStatus); Assert.assertFalse(mAuthnController.isHidden()); mAuthnController.getView().mCancelButton.performClick(); - Assert.assertFalse(mIsPaymentCancelled); + Assert.assertEquals(SpcResponseStatus.UNKNOWN, mResponseStatus); Assert.assertFalse(mAuthnController.isHidden()); authnView.mOptOutText.getClickableSpans()[0].onClick(authnView.mOptOutText); @@ -315,12 +333,39 @@ // Clicking confirm after the threshold is no longer prevented and confirms the dialog. mClock.advanceCurrentTimeMillis(SAFE_INPUT_DELAY); mAuthnController.getView().mContinueButton.performClick(); - Assert.assertTrue(mIsPaymentConfirmed); + Assert.assertEquals(SpcResponseStatus.ACCEPT, mResponseStatus); Assert.assertTrue(mAuthnController.isHidden()); } @Test @Feature({"Payments"}) + public void testOnVerifyAnotherWay() { + createAuthnController(); + show(); + mClock.advanceCurrentTimeMillis(SAFE_INPUT_DELAY); + + SecurePaymentConfirmationAuthnView authnView = mAuthnController.getView(); + Assert.assertEquals(View.VISIBLE, authnView.mFootnote.getVisibility()); + authnView.mFootnote.getClickableSpans()[0].onClick(authnView.mFootnote); + + Assert.assertEquals(SpcResponseStatus.ANOTHER_WAY, mResponseStatus); + Assert.assertTrue(mAuthnController.isHidden()); + } + + @Test + @Feature({"Payments"}) + @DisableFeatures(PaymentFeatureList.SECURE_PAYMENT_CONFIRMATION_FALLBACK) + public void testOnVerifyAnotherWayFeatureDisabled() { + createAuthnController(); + + show(); + SecurePaymentConfirmationAuthnView authnView = mAuthnController.getView(); + + Assert.assertEquals(View.GONE, authnView.mFootnote.getVisibility()); + } + + @Test + @Feature({"Payments"}) public void testHide() { createAuthnController(); show(); @@ -533,9 +578,9 @@ @Test @Feature({"Payments"}) - @EnableFeatures({PaymentFeatureList.SECURE_PAYMENT_CONFIRMATION_FALLBACK}) public void testShowInformOnly() { createAuthnController(); + Assert.assertTrue(showInformOnly()); SecurePaymentConfirmationAuthnView view = mAuthnController.getView(); @@ -547,5 +592,40 @@ Assert.assertEquals( view.mContinueButton.getText(), context.getString(R.string.payments_confirm_button)); + Assert.assertEquals(View.GONE, view.mFootnote.getVisibility()); + } + + @Test + @Feature({"Payments"}) + @DisableFeatures(PaymentFeatureList.SECURE_PAYMENT_CONFIRMATION_FALLBACK) + public void testShowInformOnlyFeatureIsDisabled() { + createAuthnController(); + Assert.assertThrows(AssertionError.class, this::showInformOnly); + } + + @Test + @Feature({"Payments"}) + public void testShowInformOnlyOnConfirmation() { + createAuthnController(); + showInformOnly(); + mClock.advanceCurrentTimeMillis(SAFE_INPUT_DELAY); + + mAuthnController.getView().mContinueButton.performClick(); + + Assert.assertEquals(SpcResponseStatus.ANOTHER_WAY, mResponseStatus); + Assert.assertTrue(mAuthnController.isHidden()); + } + + @Test + @Feature({"Payments"}) + public void testShowInformOnlyOnCancellation() { + createAuthnController(); + showInformOnly(); + mClock.advanceCurrentTimeMillis(SAFE_INPUT_DELAY); + + mAuthnController.getView().mCancelButton.performClick(); + + Assert.assertEquals(SpcResponseStatus.CANCEL, mResponseStatus); + Assert.assertTrue(mAuthnController.isHidden()); } }
diff --git a/components/payments_strings.grdp b/components/payments_strings.grdp index ac08265..af8dabf 100644 --- a/components/payments_strings.grdp +++ b/components/payments_strings.grdp
@@ -552,6 +552,9 @@ <message name="IDS_NO_MATCHING_CREDENTIAL_DESCRIPTION" desc="Description on a dialog that appears when there are no matching payment credentials to authenticate. Informs users that additional steps are needed to verify the payment." formatter_data="android_java"> <ph name="URL">%1$s<ex>merchant.com</ex></ph> may need to take additional steps to verify your payment </message> + <message name="IDS_SECURE_PAYMENT_CONFIRMATION_FOOTNOTE" desc="Footnote on a secure payment confirmation dialog that explains what will happen next and provides a link to verify by another way." formatter_data="android_java"> + Unlock your screen in the next step, typically using your fingerprint. Or you can <ph name="BEGIN_LINK">BEGIN_LINK</ph>verify another way<ph name="END_LINK">END_LINK</ph>. + </message> </if> <if expr="not is_android"> <message name="IDS_NO_MATCHING_CREDENTIAL_DESCRIPTION" desc="Description on a dialog that appears when there are no matching payment credentials to authenticate. Informs users that additional steps are needed to verify the payment.">
diff --git a/components/payments_strings_grdp/IDS_SECURE_PAYMENT_CONFIRMATION_FOOTNOTE.png.sha1 b/components/payments_strings_grdp/IDS_SECURE_PAYMENT_CONFIRMATION_FOOTNOTE.png.sha1 new file mode 100644 index 0000000..84076a1a --- /dev/null +++ b/components/payments_strings_grdp/IDS_SECURE_PAYMENT_CONFIRMATION_FOOTNOTE.png.sha1
@@ -0,0 +1 @@ +bbb184bb399483cf53f83bfba6a3140893b8f9a2 \ No newline at end of file
diff --git a/components/plus_addresses/resources/strings/BUILD.gn b/components/plus_addresses/resources/strings/BUILD.gn index 413fbc52..de5d899 100644 --- a/components/plus_addresses/resources/strings/BUILD.gn +++ b/components/plus_addresses/resources/strings/BUILD.gn
@@ -10,20 +10,20 @@ import("//build/config/android/rules.gni") } -grit("strings") { +grit_strings("strings") { if (is_chrome_branded) { source = "../internal/strings/plus_addresses_internal_strings.grd" } else { source = "plus_addresses_strings.grd" } - outputs = [ "../../grit/plus_addresses_strings.h" ] + - process_file_template( - all_chrome_locales, - [ "plus_addresses_strings_{{source_name_part}}.pak" ]) + outputs = [ "../../grit/plus_addresses_strings.h" ] + if (is_android) { create_android_resources = true } + + output_prefix = "plus_addresses_strings_" } if (is_android) {
diff --git a/components/policy/content/policy_blocklist_navigation_throttle.cc b/components/policy/content/policy_blocklist_navigation_throttle.cc index cbce3a66..509afeaa 100644 --- a/components/policy/content/policy_blocklist_navigation_throttle.cc +++ b/components/policy/content/policy_blocklist_navigation_throttle.cc
@@ -27,19 +27,19 @@ // callback is safe because this object owns safe_sites_navigation_throttle_, // which runs the callback from within the object. PolicyBlocklistNavigationThrottle::PolicyBlocklistNavigationThrottle( - content::NavigationHandle* navigation_handle, + content::NavigationThrottleRegistry& registry, content::BrowserContext* context) - : content::NavigationThrottle(navigation_handle), + : content::NavigationThrottle(registry), blocklist_service_(PolicyBlocklistFactory::GetForBrowserContext(context)), prefs_(user_prefs::UserPrefs::Get(context)) { DCHECK(prefs_); auto safe_sites_navigation_throttle = - std::make_unique<SafeSitesNavigationThrottle>(navigation_handle, context); + std::make_unique<SafeSitesNavigationThrottle>(registry, context); if (base::FeatureList::IsEnabled( policy::features::kPolicyBlocklistProceedUntilResponse)) { safe_sites_navigation_throttle_ = std::make_unique<ProceedUntilResponseNavigationThrottle>( - navigation_handle, std::move(safe_sites_navigation_throttle), + registry, std::move(safe_sites_navigation_throttle), base::BindRepeating( &PolicyBlocklistNavigationThrottle::OnDeferredSafeSitesResult, base::Unretained(this)));
diff --git a/components/policy/content/policy_blocklist_navigation_throttle.h b/components/policy/content/policy_blocklist_navigation_throttle.h index 17502e3..0fc522e 100644 --- a/components/policy/content/policy_blocklist_navigation_throttle.h +++ b/components/policy/content/policy_blocklist_navigation_throttle.h
@@ -15,6 +15,7 @@ namespace content { class BrowserContext; +class NavigationThrottleRegistry; } // namespace content // PolicyBlocklistNavigationThrottle provides a simple way to block a navigation @@ -26,7 +27,7 @@ class PolicyBlocklistNavigationThrottle : public content::NavigationThrottle { public: PolicyBlocklistNavigationThrottle( - content::NavigationHandle* navigation_handle, + content::NavigationThrottleRegistry& registry, content::BrowserContext* context); PolicyBlocklistNavigationThrottle(const PolicyBlocklistNavigationThrottle&) = delete;
diff --git a/components/policy/content/policy_blocklist_navigation_throttle_unittest.cc b/components/policy/content/policy_blocklist_navigation_throttle_unittest.cc index cdbf515a..b182953 100644 --- a/components/policy/content/policy_blocklist_navigation_throttle_unittest.cc +++ b/components/policy/content/policy_blocklist_navigation_throttle_unittest.cc
@@ -29,6 +29,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/test/navigation_simulator.h" +#include "content/public/test/test_navigation_throttle_inserter.h" #include "content/public/test/test_renderer_host.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -44,8 +45,7 @@ // TODO(crbug.com/40156526): Break out the tests into separate files. The // SafeSites tests should be parameterized to run the same tests on both types. class SafeSitesNavigationThrottleTest - : public content::RenderViewHostTestHarness, - public content::WebContentsObserver { + : public content::RenderViewHostTestHarness { public: SafeSitesNavigationThrottleTest() = default; SafeSitesNavigationThrottleTest(const SafeSitesNavigationThrottleTest&) = @@ -69,10 +69,7 @@ SafeSearchFactory::GetInstance() ->GetForBrowserContext(browser_context()) ->SetSafeSearchURLCheckerForTest( - stub_url_checker_.BuildURLChecker(kCacheSize)); - - // Observe the WebContents to add the throttle. - Observe(RenderViewHostTestHarness::web_contents()); + stub_url_checker().BuildURLChecker(kCacheSize)); } void TearDown() override { @@ -82,20 +79,17 @@ } protected: - // content::WebContentsObserver: - void DidStartNavigation( - content::NavigationHandle* navigation_handle) override { - auto throttle = std::make_unique<SafeSitesNavigationThrottle>( - navigation_handle, browser_context()); - - navigation_handle->RegisterThrottleForTesting(std::move(throttle)); - } - std::unique_ptr<content::NavigationSimulator> StartNavigation( const GURL& first_url) { auto navigation_simulator = content::NavigationSimulator::CreateRendererInitiated(first_url, main_rfh()); + auto throttle_inserter = + std::make_unique<content::TestNavigationThrottleInserter>( + web_contents(), + base::BindRepeating( + &SafeSitesNavigationThrottleTest::CreateAndAddThrottle, + base::Unretained(this))); navigation_simulator->SetAutoAdvance(false); navigation_simulator->Start(); return navigation_simulator; @@ -116,6 +110,16 @@ void TestSafeSitesCachedSites(const char* expected_error_page_content, bool is_proceed_until_response_enabled = false); + safe_search_api::StubURLChecker& stub_url_checker() { + return stub_url_checker_; + } + + private: + virtual void CreateAndAddThrottle(content::NavigationThrottleRegistry& registry) { + registry.AddThrottle(std::make_unique<SafeSitesNavigationThrottle>( + registry, browser_context())); + } + safe_search_api::StubURLChecker stub_url_checker_; }; @@ -124,13 +128,10 @@ protected: static const char kErrorPageContent[]; - // content::WebContentsObserver: - void DidStartNavigation( - content::NavigationHandle* navigation_handle) override { - auto throttle = std::make_unique<SafeSitesNavigationThrottle>( - navigation_handle, browser_context(), kErrorPageContent); - - navigation_handle->RegisterThrottleForTesting(std::move(throttle)); + // SafeSitesNavigationThrottleTest: + void CreateAndAddThrottle(content::NavigationThrottleRegistry& registry) override { + registry.AddThrottle(std::make_unique<SafeSitesNavigationThrottle>( + registry, browser_context(), kErrorPageContent)); } }; @@ -159,13 +160,10 @@ } protected: - // content::WebContentsObserver: - void DidStartNavigation( - content::NavigationHandle* navigation_handle) override { - auto throttle = std::make_unique<PolicyBlocklistNavigationThrottle>( - navigation_handle, browser_context()); - - navigation_handle->RegisterThrottleForTesting(std::move(throttle)); + // SafeSitesNavigationThrottleTest: + void CreateAndAddThrottle(content::NavigationThrottleRegistry& registry) override { + registry.AddThrottle(std::make_unique<PolicyBlocklistNavigationThrottle>( + registry, browser_context())); } void SetBlocklistUrlPattern(const std::string& pattern) { @@ -235,7 +233,7 @@ base::HistogramTester histogram_tester; SetSafeSitesFilterBehavior(SafeSitesFilterBehavior::kSafeSitesFilterEnabled); - stub_url_checker_.SetUpValidResponse(false /* is_porn */); + stub_url_checker().SetUpValidResponse(false /* is_porn */); const GURL url = GURL("http://example.com/"); auto navigation_simulator = StartNavigation(url); @@ -260,7 +258,7 @@ base::HistogramTester histogram_tester; SetSafeSitesFilterBehavior(SafeSitesFilterBehavior::kSafeSitesFilterEnabled); - stub_url_checker_.SetUpValidResponse(true /* is_porn */); + stub_url_checker().SetUpValidResponse(true /* is_porn */); // Defer, then cancel a porn site. const GURL url = GURL("http://example.com/"); @@ -284,7 +282,7 @@ TEST_P(PolicyBlocklistNavigationThrottleTest, SafeSites_Allowlisted) { SetAllowlistUrlPattern("example.com"); SetSafeSitesFilterBehavior(SafeSitesFilterBehavior::kSafeSitesFilterEnabled); - stub_url_checker_.SetUpValidResponse(true /* is_porn */); + stub_url_checker().SetUpValidResponse(true /* is_porn */); // Even with SafeSites enabled, a allowlisted site is immediately allowed. auto navigation_simulator = StartNavigation(GURL("http://example.com/")); @@ -295,7 +293,7 @@ TEST_P(PolicyBlocklistNavigationThrottleTest, SafeSites_Schemes) { SetSafeSitesFilterBehavior(SafeSitesFilterBehavior::kSafeSitesFilterEnabled); - stub_url_checker_.SetUpValidResponse(true /* is_porn */); + stub_url_checker().SetUpValidResponse(true /* is_porn */); // The safe sites filter is only used for http(s) URLs. This test uses // browser-initiated navigation, since renderer-initiated navigations to @@ -311,7 +309,7 @@ } TEST_P(PolicyBlocklistNavigationThrottleTest, SafeSites_PolicyChange) { - stub_url_checker_.SetUpValidResponse(true /* is_porn */); + stub_url_checker().SetUpValidResponse(true /* is_porn */); // The safe sites filter is initially disabled. { @@ -349,7 +347,7 @@ TEST_P(PolicyBlocklistNavigationThrottleTest, SafeSites_Failure) { SetSafeSitesFilterBehavior(SafeSitesFilterBehavior::kSafeSitesFilterEnabled); - stub_url_checker_.SetUpFailedResponse(); + stub_url_checker().SetUpFailedResponse(); // If the Safe Search API request fails, the navigation is allowed. auto navigation_simulator = StartNavigation(GURL("http://example.com/")); @@ -379,7 +377,7 @@ const GURL safe_site = GURL("http://example.com/"); const GURL porn_site = GURL("http://example2.com/"); - stub_url_checker_.SetUpValidResponse(false /* is_porn */); + stub_url_checker().SetUpValidResponse(false /* is_porn */); { auto navigation_simulator = StartNavigation(safe_site); if (is_proceed_until_response_enabled) { @@ -396,7 +394,7 @@ .error_page_content()); } - stub_url_checker_.SetUpValidResponse(true /* is_porn */); + stub_url_checker().SetUpValidResponse(true /* is_porn */); { auto navigation_simulator = StartNavigation(porn_site); if (is_proceed_until_response_enabled) { @@ -420,7 +418,7 @@ } } - stub_url_checker_.ClearResponses(); + stub_url_checker().ClearResponses(); { // This check is synchronous since the site is in the cache. auto navigation_simulator = StartNavigation(safe_site); @@ -470,7 +468,7 @@ const GURL safe_site = GURL("http://example.com/"); const GURL porn_site = GURL("http://example2.com/"); - stub_url_checker_.SetUpValidResponse(false /* is_porn */); + stub_url_checker().SetUpValidResponse(false /* is_porn */); { auto navigation_simulator = StartNavigation(safe_site); if (is_proceed_until_response_enabled) { @@ -486,7 +484,7 @@ EXPECT_FALSE(navigation_simulator->GetLastThrottleCheckResult() .error_page_content()); - stub_url_checker_.SetUpValidResponse(true /* is_porn */); + stub_url_checker().SetUpValidResponse(true /* is_porn */); navigation_simulator->Redirect(porn_site); if (is_proceed_until_response_enabled) { // Proceed with running a background check, will defer on the subsequent @@ -509,7 +507,7 @@ } } - stub_url_checker_.ClearResponses(); + stub_url_checker().ClearResponses(); { // This check is synchronous since the site is in the cache. auto navigation_simulator = StartNavigation(safe_site);
diff --git a/components/policy/content/proceed_until_response_navigation_throttle.cc b/components/policy/content/proceed_until_response_navigation_throttle.cc index 892f2b6..5e32781 100644 --- a/components/policy/content/proceed_until_response_navigation_throttle.cc +++ b/components/policy/content/proceed_until_response_navigation_throttle.cc
@@ -8,14 +8,14 @@ #include "base/strings/strcat.h" ProceedUntilResponseNavigationThrottle::Client::Client( - content::NavigationHandle* navigation_handle) - : NavigationThrottle(navigation_handle) {} + content::NavigationThrottleRegistry& registry) + : NavigationThrottle(registry) {} ProceedUntilResponseNavigationThrottle::ProceedUntilResponseNavigationThrottle( - content::NavigationHandle* navigation_handle, + content::NavigationThrottleRegistry& registry, std::unique_ptr<Client> client, std::optional<DeferredResultCallback> deferred_result_callback) - : NavigationThrottle(navigation_handle), + : NavigationThrottle(registry), name_(base::StrCat({"ProceedUntilResponseNavigationThrottle::", client ? client->GetNameForLogging() : ""})), client_(std::move(client)),
diff --git a/components/policy/content/proceed_until_response_navigation_throttle.h b/components/policy/content/proceed_until_response_navigation_throttle.h index dd870ba..333b075 100644 --- a/components/policy/content/proceed_until_response_navigation_throttle.h +++ b/components/policy/content/proceed_until_response_navigation_throttle.h
@@ -11,10 +11,6 @@ #include "base/functional/callback_forward.h" #include "content/public/browser/navigation_throttle.h" -namespace content { -class NavigationHandle; -} // namespace content - // This class can be used to wrap internal throttles that trigger asynchronous // tasks on WillStartRequest or WillRedirectRequest and need to make a final // decision based on the result of the asynchronous tasks, but are actually OK @@ -36,12 +32,12 @@ // asynchronous tasks are done. class Client : public content::NavigationThrottle { public: - explicit Client(content::NavigationHandle* navigation_handle); + explicit Client(content::NavigationThrottleRegistry& registry); virtual void SetDeferredResultCallback( const DeferredResultCallback& deferred_result_callback) = 0; }; ProceedUntilResponseNavigationThrottle( - content::NavigationHandle* navigation_handle, + content::NavigationThrottleRegistry& registry, std::unique_ptr<Client> client, std::optional<DeferredResultCallback> deferred_result_callback); ProceedUntilResponseNavigationThrottle(
diff --git a/components/policy/content/proceed_until_response_navigation_throttle_unittest.cc b/components/policy/content/proceed_until_response_navigation_throttle_unittest.cc index ef1ef32..7e7067f2 100644 --- a/components/policy/content/proceed_until_response_navigation_throttle_unittest.cc +++ b/components/policy/content/proceed_until_response_navigation_throttle_unittest.cc
@@ -10,6 +10,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/test/navigation_simulator.h" +#include "content/public/test/test_navigation_throttle_inserter.h" #include "content/public/test/test_renderer_host.h" #include "testing/gtest/include/gtest/gtest.h" @@ -97,9 +98,9 @@ : public ProceedUntilResponseNavigationThrottle::Client { public: EventMonitorNavigationThrottleClient( - content::NavigationHandle* navigation_handle, + content::NavigationThrottleRegistry& registry, raw_ptr<EventExpectation> event_expectation) - : ProceedUntilResponseNavigationThrottle::Client(navigation_handle), + : ProceedUntilResponseNavigationThrottle::Client(registry), event_expectation_(event_expectation) {} private: @@ -130,8 +131,7 @@ } // namespace class ProceedUntilResponseNavigationThrottleTest - : public content::RenderViewHostTestHarness, - public content::WebContentsObserver { + : public content::RenderViewHostTestHarness { public: ProceedUntilResponseNavigationThrottleTest() = default; ProceedUntilResponseNavigationThrottleTest( @@ -145,6 +145,12 @@ const GURL& url) { auto navigation_simulator = content::NavigationSimulator::CreateRendererInitiated(url, main_rfh()); + auto throttle_inserter = std::make_unique< + content::TestNavigationThrottleInserter>( + web_contents(), + base::BindRepeating( + &ProceedUntilResponseNavigationThrottleTest::CreateAndAddThrottle, + base::Unretained(this))); navigation_simulator->SetAutoAdvance(false); navigation_simulator->Start(); return navigation_simulator; @@ -156,20 +162,16 @@ // content::RenderViewHostTestHarness implementation: void SetUp() override { content::RenderViewHostTestHarness::SetUp(); - Observe(content::RenderViewHostTestHarness::web_contents()); } - // content::WebContentsObserver implementation: - void DidStartNavigation( - content::NavigationHandle* navigation_handle) override { + void CreateAndAddThrottle(content::NavigationThrottleRegistry& registry) { std::unique_ptr<ProceedUntilResponseNavigationThrottle::Client> monitor_throttle = std::make_unique<EventMonitorNavigationThrottleClient>( - navigation_handle, &event_expectation_); - auto throttle = std::make_unique<ProceedUntilResponseNavigationThrottle>( - navigation_handle, std::move(monitor_throttle), std::nullopt); - - navigation_handle->RegisterThrottleForTesting(std::move(throttle)); + registry, &event_expectation_); + registry.AddThrottle( + std::make_unique<ProceedUntilResponseNavigationThrottle>( + registry, std::move(monitor_throttle), std::nullopt)); } EventExpectation event_expectation_;
diff --git a/components/policy/content/safe_sites_navigation_throttle.cc b/components/policy/content/safe_sites_navigation_throttle.cc index daf12af..1a86b8b 100644 --- a/components/policy/content/safe_sites_navigation_throttle.cc +++ b/components/policy/content/safe_sites_navigation_throttle.cc
@@ -13,10 +13,10 @@ // Use of Unretained for is safe because it is called synchronously from this // object. SafeSitesNavigationThrottle::SafeSitesNavigationThrottle( - content::NavigationHandle* navigation_handle, + content::NavigationThrottleRegistry& registry, content::BrowserContext* context, std::optional<std::string_view> safe_sites_error_page_content) - : Client(navigation_handle), + : Client(registry), safe_search_service_(SafeSearchFactory::GetForBrowserContext(context)), safe_sites_error_page_content_(std::move(safe_sites_error_page_content)) { SetDeferredResultCallback(base::BindRepeating(
diff --git a/components/policy/content/safe_sites_navigation_throttle.h b/components/policy/content/safe_sites_navigation_throttle.h index 265b7b08..e8b821f0 100644 --- a/components/policy/content/safe_sites_navigation_throttle.h +++ b/components/policy/content/safe_sites_navigation_throttle.h
@@ -18,7 +18,7 @@ namespace content { class BrowserContext; -class NavigationHandle; +class NavigationThrottleRegistry; } // namespace content // SafeSitesNavigationThrottle provides a simple way to block a navigation @@ -28,7 +28,7 @@ class SafeSitesNavigationThrottle : public ProceedUntilResponseNavigationThrottle::Client { public: - SafeSitesNavigationThrottle(content::NavigationHandle* navigation_handle, + SafeSitesNavigationThrottle(content::NavigationThrottleRegistry& registry, content::BrowserContext* context, std::optional<std::string_view> safe_sites_error_page_content = std::nullopt);
diff --git a/components/saved_tab_groups/internal/BUILD.gn b/components/saved_tab_groups/internal/BUILD.gn index 5c775a7..04789e90 100644 --- a/components/saved_tab_groups/internal/BUILD.gn +++ b/components/saved_tab_groups/internal/BUILD.gn
@@ -185,6 +185,7 @@ "//components/saved_tab_groups/proto", "//components/saved_tab_groups/public", "//components/saved_tab_groups/test_support", + "//components/saved_tab_groups/test_support:test_support_proto", "//components/signin/public/identity_manager:test_support", "//components/sync", "//components/sync:test_support",
diff --git a/components/saved_tab_groups/internal/shared_tab_group_data_sync_bridge.cc b/components/saved_tab_groups/internal/shared_tab_group_data_sync_bridge.cc index 19ef708..226db09 100644 --- a/components/saved_tab_groups/internal/shared_tab_group_data_sync_bridge.cc +++ b/components/saved_tab_groups/internal/shared_tab_group_data_sync_bridge.cc
@@ -906,9 +906,43 @@ SharedTabGroupDataSyncBridge::TrimAllSupportedFieldsFromRemoteSpecifics( const sync_pb::EntitySpecifics& entity_specifics) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - NOTIMPLEMENTED(); - return DataTypeSyncBridge::TrimAllSupportedFieldsFromRemoteSpecifics( - entity_specifics); + + // LINT.IfChange(TrimAllSupportedFieldsFromRemoteSpecifics) + sync_pb::SharedTabGroupDataSpecifics trimmed_specifics = + entity_specifics.shared_tab_group_data(); + trimmed_specifics.clear_guid(); + trimmed_specifics.clear_update_time_windows_epoch_micros(); + + if (trimmed_specifics.has_tab()) { + sync_pb::SharedTab* tab = trimmed_specifics.mutable_tab(); + tab->clear_url(); + tab->clear_title(); + tab->clear_shared_tab_group_guid(); + tab->clear_unique_position(); + + if (tab->ByteSizeLong() == 0) { + trimmed_specifics.clear_tab(); + } + } + + if (trimmed_specifics.has_tab_group()) { + sync_pb::SharedTabGroup* tab_group = trimmed_specifics.mutable_tab_group(); + tab_group->clear_title(); + tab_group->clear_color(); + tab_group->clear_originating_tab_group_guid(); + + if (tab_group->ByteSizeLong() == 0) { + trimmed_specifics.clear_tab_group(); + } + } + // LINT.ThenChange(//components/sync/protocol/shared_tab_group_data_specifics.proto:SharedTabGroupDataSpecifics) + + sync_pb::EntitySpecifics trimmed_entity_specifics; + if (trimmed_specifics.ByteSizeLong() > 0) { + *trimmed_entity_specifics.mutable_shared_tab_group_data() = + std::move(trimmed_specifics); + } + return trimmed_entity_specifics; } bool SharedTabGroupDataSyncBridge::IsEntityDataValid(
diff --git a/components/saved_tab_groups/internal/shared_tab_group_data_sync_bridge_unittest.cc b/components/saved_tab_groups/internal/shared_tab_group_data_sync_bridge_unittest.cc index 902bff7e..fc39f72 100644 --- a/components/saved_tab_groups/internal/shared_tab_group_data_sync_bridge_unittest.cc +++ b/components/saved_tab_groups/internal/shared_tab_group_data_sync_bridge_unittest.cc
@@ -32,6 +32,7 @@ #include "components/saved_tab_groups/public/saved_tab_group_tab.h" #include "components/saved_tab_groups/public/types.h" #include "components/saved_tab_groups/public/utils.h" +#include "components/saved_tab_groups/test_support/extended_shared_tab_group_data_specifics.pb.h" #include "components/saved_tab_groups/test_support/saved_tab_group_test_utils.h" #include "components/sync/base/client_tag_hash.h" #include "components/sync/base/data_type.h" @@ -72,6 +73,7 @@ using testing::InvokeWithoutArgs; using testing::IsEmpty; using testing::IsNull; +using testing::Not; using testing::NotNull; using testing::Pointee; using testing::Return; @@ -2369,6 +2371,117 @@ ElementsAre(HasTabMetadata("tab title", "http://google.com/1"))); } +TEST_F(SharedTabGroupDataSyncBridgeTest, + ShouldTrimAllSupportedFieldsFromRemoteTabGroupSpecifics) { + ASSERT_TRUE(InitializeBridgeAndModel()); + + sync_pb::EntitySpecifics remote_tab_group_specifics; + sync_pb::SharedTabGroupDataSpecifics* tab_group_specifics = + remote_tab_group_specifics.mutable_shared_tab_group_data(); + tab_group_specifics->set_guid("guid"); + tab_group_specifics->set_update_time_windows_epoch_micros(1234567890); + tab_group_specifics->mutable_tab_group()->set_title("title"); + tab_group_specifics->mutable_tab_group()->set_color( + sync_pb::SharedTabGroup::BLUE); + tab_group_specifics->mutable_tab_group()->set_originating_tab_group_guid( + "originating_guid"); + + EXPECT_THAT(bridge()->TrimAllSupportedFieldsFromRemoteSpecifics( + remote_tab_group_specifics), + EqualsProto(sync_pb::EntitySpecifics())); +} + +TEST_F(SharedTabGroupDataSyncBridgeTest, + ShouldKeepUnknownFieldsFromRemoteTabGroupSpecifics) { + ASSERT_TRUE(InitializeBridgeAndModel()); + + sync_pb::test_utils::SharedTabGroupDataSpecifics extended_tab_group_specifics; + extended_tab_group_specifics.set_guid("guid"); + extended_tab_group_specifics.set_update_time_windows_epoch_micros(1234567890); + extended_tab_group_specifics.mutable_tab_group()->set_title("title"); + extended_tab_group_specifics.mutable_tab_group()->set_color( + sync_pb::test_utils::SharedTabGroup::UNSPECIFIED); + extended_tab_group_specifics.mutable_tab_group() + ->set_originating_tab_group_guid("originating_guid"); + extended_tab_group_specifics.mutable_tab_group()->set_extra_field_for_testing( + "extra_field_for_testing"); + + // Serialize and deserialize the proto to get unknown fields. + sync_pb::EntitySpecifics remote_tab_group_specifics; + ASSERT_TRUE( + remote_tab_group_specifics.mutable_shared_tab_group_data() + ->ParseFromString(extended_tab_group_specifics.SerializeAsString())); + + sync_pb::EntitySpecifics trimmed_specifics = + bridge()->TrimAllSupportedFieldsFromRemoteSpecifics( + remote_tab_group_specifics); + EXPECT_THAT(trimmed_specifics, Not(EqualsProto(sync_pb::EntitySpecifics()))); + + // Verify that deserialized proto keeps unknown fields. + sync_pb::test_utils::SharedTabGroupDataSpecifics + deserialized_extended_specifics; + ASSERT_TRUE(deserialized_extended_specifics.ParseFromString( + trimmed_specifics.shared_tab_group_data().SerializeAsString())); + EXPECT_EQ( + deserialized_extended_specifics.tab_group().extra_field_for_testing(), + "extra_field_for_testing"); +} + +TEST_F(SharedTabGroupDataSyncBridgeTest, + ShouldTrimAllSupportedFieldsFromRemoteTabSpecifics) { + ASSERT_TRUE(InitializeBridgeAndModel()); + + sync_pb::EntitySpecifics remote_tab_specifics; + sync_pb::SharedTabGroupDataSpecifics* tab_specifics = + remote_tab_specifics.mutable_shared_tab_group_data(); + tab_specifics->set_guid("guid"); + tab_specifics->set_update_time_windows_epoch_micros(1234567890); + tab_specifics->mutable_tab()->set_url("http://google.com/1"); + tab_specifics->mutable_tab()->set_title("title"); + tab_specifics->mutable_tab()->set_shared_tab_group_guid("group_guid"); + *tab_specifics->mutable_tab()->mutable_unique_position() = + GenerateRandomUniquePosition().ToProto(); + + EXPECT_THAT( + bridge()->TrimAllSupportedFieldsFromRemoteSpecifics(remote_tab_specifics), + EqualsProto(sync_pb::EntitySpecifics())); +} + +TEST_F(SharedTabGroupDataSyncBridgeTest, + ShouldKeepUnknownFieldsFromRemoteTabSpecifics) { + ASSERT_TRUE(InitializeBridgeAndModel()); + + sync_pb::test_utils::SharedTabGroupDataSpecifics extended_tab_specifics; + extended_tab_specifics.set_guid("guid"); + extended_tab_specifics.set_update_time_windows_epoch_micros(1234567890); + extended_tab_specifics.mutable_tab()->set_url("http://google.com/1"); + extended_tab_specifics.mutable_tab()->set_title("title"); + extended_tab_specifics.mutable_tab()->set_shared_tab_group_guid("group_guid"); + *extended_tab_specifics.mutable_tab()->mutable_unique_position() = + GenerateRandomUniquePosition().ToProto(); + extended_tab_specifics.mutable_tab()->set_extra_field_for_testing( + "extra_field_for_testing"); + + // Serialize and deserialize the proto to get unknown fields. + sync_pb::EntitySpecifics remote_tab_specifics; + ASSERT_TRUE( + remote_tab_specifics.mutable_shared_tab_group_data()->ParseFromString( + extended_tab_specifics.SerializeAsString())); + + sync_pb::EntitySpecifics trimmed_specifics = + bridge()->TrimAllSupportedFieldsFromRemoteSpecifics(remote_tab_specifics); + + EXPECT_THAT(trimmed_specifics, Not(EqualsProto(sync_pb::EntitySpecifics()))); + + // Verify that deserialized proto keeps unknown fields. + sync_pb::test_utils::SharedTabGroupDataSpecifics + deserialized_extended_specifics; + ASSERT_TRUE(deserialized_extended_specifics.ParseFromString( + trimmed_specifics.shared_tab_group_data().SerializeAsString())); + EXPECT_EQ(deserialized_extended_specifics.tab().extra_field_for_testing(), + "extra_field_for_testing"); +} + // The number of tabs to test the correct ordering of remote updates. constexpr size_t kNumTabsForOrderTest = 5;
diff --git a/components/saved_tab_groups/test_support/BUILD.gn b/components/saved_tab_groups/test_support/BUILD.gn index 574983d..f3bc3835 100644 --- a/components/saved_tab_groups/test_support/BUILD.gn +++ b/components/saved_tab_groups/test_support/BUILD.gn
@@ -3,6 +3,18 @@ # found in the LICENSE file. import("//build/buildflag_header.gni") +import("//third_party/protobuf/proto_library.gni") + +proto_library("test_support_proto") { + testonly = true + proto_in_dir = "//" + sources = [ + "extended_shared_tab_group_data_specifics.proto", + ] + deps = [ + "//components/sync/protocol", + ] +} source_set("test_support") { testonly = true
diff --git a/components/saved_tab_groups/test_support/extended_shared_tab_group_data_specifics.proto b/components/saved_tab_groups/test_support/extended_shared_tab_group_data_specifics.proto new file mode 100644 index 0000000..291d282 --- /dev/null +++ b/components/saved_tab_groups/test_support/extended_shared_tab_group_data_specifics.proto
@@ -0,0 +1,43 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// This file is used for testing only. It contains a subset of fields from +// components/sync/protocol/shared_tab_group_data_specifics.proto with +// additional fields for testing purposes. +syntax = "proto2"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb.test_utils; + +import "components/sync/protocol/unique_position.proto"; + +message SharedTabGroupDataSpecifics { + optional string guid = 1; + oneof entity { + SharedTabGroup tab_group = 3; + SharedTab tab = 4; + } + optional int64 update_time_windows_epoch_micros = 5; +} + +message SharedTabGroup { + optional string title = 1; + enum Color { + UNSPECIFIED = 0; + } + optional Color color = 2; + optional string originating_tab_group_guid = 3; + + optional string extra_field_for_testing = 10000; +} + +message SharedTab { + optional string url = 1; + optional string title = 2; + optional string shared_tab_group_guid = 4; + optional UniquePosition unique_position = 5; + + optional string extra_field_for_testing = 10000; +}
diff --git a/components/strings/BUILD.gn b/components/strings/BUILD.gn index dd44c6a..774b976 100644 --- a/components/strings/BUILD.gn +++ b/components/strings/BUILD.gn
@@ -25,7 +25,7 @@ ] } -grit("components_strings") { +grit_strings("components_strings") { source = "../components_strings.grd" defines = [ "enable_arcore=$enable_arcore", @@ -40,10 +40,6 @@ ] outputs = [ "grit/components_strings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "components_strings_$locale.pak" ] - } - if (is_android) { create_android_resources = true } @@ -55,32 +51,23 @@ } } -grit("components_branded_strings") { +grit_strings("components_branded_strings") { source = "../components_${branding_path_product}_strings.grd" outputs = [ "grit/components_branded_strings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "components_branded_strings_$locale.pak" ] - } } -grit("components_locale_settings") { +grit_strings("components_locale_settings") { source = "../components_locale_settings.grd" outputs = [ "grit/components_locale_settings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "components_locale_settings_$locale.pak" ] - } if (is_android) { create_android_resources = true } } -grit("search_engine_descriptions_strings") { +grit_strings("search_engine_descriptions_strings") { source = "../search_engine_descriptions_strings.grd" outputs = [ "grit/search_engine_descriptions_strings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "search_engine_descriptions_strings_$locale.pak" ] - } } if (is_android) { @@ -89,12 +76,9 @@ } } -grit("privacy_sandbox_strings") { +grit_strings("privacy_sandbox_strings") { source = "../privacy_sandbox_strings.grd" outputs = [ "grit/privacy_sandbox_strings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "privacy_sandbox_strings_$locale.pak" ] - } if (is_android) { create_android_resources = true
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn index f003393..11f1385 100644 --- a/components/sync/BUILD.gn +++ b/components/sync/BUILD.gn
@@ -20,6 +20,8 @@ sources = [ "test/bookmark_entity_builder.cc", "test/bookmark_entity_builder.h", + "test/collaboration_group_util.cc", + "test/collaboration_group_util.h", "test/data_type_manager_mock.cc", "test/data_type_manager_mock.h", "test/data_type_store_test_util.cc",
diff --git a/components/sync/protocol/shared_tab_group_data_specifics.proto b/components/sync/protocol/shared_tab_group_data_specifics.proto index 7b769f1..ba0ada9 100644 --- a/components/sync/protocol/shared_tab_group_data_specifics.proto +++ b/components/sync/protocol/shared_tab_group_data_specifics.proto
@@ -18,6 +18,7 @@ import "components/sync/protocol/unique_position.proto"; +// LINT.IfChange(SharedTabGroupDataSpecifics) message SharedTabGroupDataSpecifics { // Unique identifier for this entity. optional string guid = 1; @@ -70,3 +71,4 @@ reserved 3; reserved "favicon_url"; } +// LINT.ThenChange(//components/saved_tab_groups/internal/shared_tab_group_data_sync_bridge.cc:TrimAllSupportedFieldsFromRemoteSpecifics)
diff --git a/components/sync/test/collaboration_group_util.cc b/components/sync/test/collaboration_group_util.cc new file mode 100644 index 0000000..ef9cb25f --- /dev/null +++ b/components/sync/test/collaboration_group_util.cc
@@ -0,0 +1,56 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/sync/test/collaboration_group_util.h" + +#include "components/sync/base/time.h" +#include "components/sync/model/entity_change.h" +#include "components/sync/protocol/collaboration_group_specifics.pb.h" +#include "components/sync/protocol/entity_data.h" +#include "components/sync/protocol/entity_specifics.pb.h" +#include "components/sync/test/entity_builder_factory.h" +#include "components/sync/test/fake_server.h" + +namespace collaboration_group_utils { + +sync_pb::CollaborationGroupSpecifics MakeCollaborationGroupSpecifics( + const std::string& group_id) { + sync_pb::CollaborationGroupSpecifics result; + result.set_collaboration_id(group_id); + + base::Time now = base::Time::Now(); + result.set_changed_at_timestamp_millis_since_unix_epoch( + now.InMillisecondsSinceUnixEpoch()); + result.set_consistency_token( + base::NumberToString(now.InMillisecondsSinceUnixEpoch())); + return result; +} + +syncer::EntityData EntityDataFromSpecifics( + const sync_pb::CollaborationGroupSpecifics& specifics) { + syncer::EntityData entity_data; + *entity_data.specifics.mutable_collaboration_group() = specifics; + entity_data.name = specifics.collaboration_id(); + return entity_data; +} + +std::unique_ptr<syncer::EntityChange> EntityChangeAddFromSpecifics( + const sync_pb::CollaborationGroupSpecifics& specifics) { + return syncer::EntityChange::CreateAdd(specifics.collaboration_id(), + EntityDataFromSpecifics(specifics)); +} + +std::unique_ptr<syncer::EntityChange> EntityChangeUpdateFromSpecifics( + const sync_pb::CollaborationGroupSpecifics& specifics) { + return syncer::EntityChange::CreateUpdate(specifics.collaboration_id(), + EntityDataFromSpecifics(specifics)); +} + +std::unique_ptr<syncer::EntityChange> EntityChangeDeleteFromSpecifics( + const sync_pb::CollaborationGroupSpecifics& specifics) { + return syncer::EntityChange::CreateDelete(specifics.collaboration_id(), + syncer::EntityData()); +} + +} // namespace collaboration_group_utils
diff --git a/components/sync/test/collaboration_group_util.h b/components/sync/test/collaboration_group_util.h new file mode 100644 index 0000000..6b3ac64 --- /dev/null +++ b/components/sync/test/collaboration_group_util.h
@@ -0,0 +1,38 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SYNC_TEST_COLLABORATION_GROUP_UTIL_H_ +#define COMPONENTS_SYNC_TEST_COLLABORATION_GROUP_UTIL_H_ + +#include "components/sync/base/time.h" +#include "components/sync/model/entity_change.h" +#include "components/sync/protocol/collaboration_group_specifics.pb.h" +#include "components/sync/protocol/entity_data.h" +#include "components/sync/protocol/entity_specifics.pb.h" +#include "components/sync/test/entity_builder_factory.h" +#include "components/sync/test/fake_server.h" + +// Util class with methods to facilitate writing unit tests for +// injecting/updating entities for collaboration group in fake +// sync server. +namespace collaboration_group_utils { + +sync_pb::CollaborationGroupSpecifics MakeCollaborationGroupSpecifics( + const std::string& id); + +syncer::EntityData EntityDataFromSpecifics( + const sync_pb::CollaborationGroupSpecifics& specifics); + +std::unique_ptr<syncer::EntityChange> EntityChangeAddFromSpecifics( + const sync_pb::CollaborationGroupSpecifics& specifics); + +std::unique_ptr<syncer::EntityChange> EntityChangeUpdateFromSpecifics( + const sync_pb::CollaborationGroupSpecifics& specifics); + +std::unique_ptr<syncer::EntityChange> EntityChangeDeleteFromSpecifics( + const sync_pb::CollaborationGroupSpecifics& specifics); + +} // namespace collaboration_group_utils + +#endif // COMPONENTS_SYNC_TEST_COLLABORATION_GROUP_UTIL_H_
diff --git a/components/user_education/custom-help-bubbles.md b/components/user_education/custom-help-bubbles.md index 80c817b5..9a0c70a 100644 --- a/components/user_education/custom-help-bubbles.md +++ b/components/user_education/custom-help-bubbles.md
@@ -117,9 +117,9 @@ 4. Use `DECLARE_TOP_CHROME_WEBUI_CONFIG(ClassName)` to automatically create a config for your WebUI. 5. Call `.AddWebUIConfig(ClassNameConfig)` in - [this file](//chrome/browser/ui/webui/chrome_web_ui_configs.cc). + [this file](/chrome/browser/ui/webui/chrome_web_ui_configs.cc). 6. Call or add to the appropriate `RegisterWebUIControllerInterfaceBinder()` in - [this file](//chrome/browser/chrome_browser_interface_binders_webui.cc). + [this file](/chrome/browser/chrome_browser_interface_binders_webui.cc). - This should include `CustomHelpBubbleHandlerFactory` and any additional mojo bindings you need.
diff --git a/content/browser/aggregation_service/aggregation_service_storage_sql.cc b/content/browser/aggregation_service/aggregation_service_storage_sql.cc index 3cb7a97..42604da 100644 --- a/content/browser/aggregation_service/aggregation_service_storage_sql.cc +++ b/content/browser/aggregation_service/aggregation_service_storage_sql.cc
@@ -241,9 +241,6 @@ CHECK(network::IsUrlPotentiallyTrustworthy(url)); CHECK_LE(keyset.keys.size(), PublicKeyset::kMaxNumberKeys); - // TODO(crbug.com/40190806): Add an allowlist for helper server urls and - // validate the url. - // Force the creation of the database if it doesn't exist, as we need to // persist the public keys. if (!EnsureDatabaseOpen(DbCreationPolicy::kCreateIfAbsent)) {
diff --git a/content/browser/data_decoder_browsertest.cc b/content/browser/data_decoder_browsertest.cc index 0d70114..6745b6d 100644 --- a/content/browser/data_decoder_browsertest.cc +++ b/content/browser/data_decoder_browsertest.cc
@@ -23,7 +23,6 @@ #include "services/data_decoder/public/cpp/decode_image.h" #include "services/data_decoder/public/mojom/data_decoder_service.mojom.h" #include "services/data_decoder/public/mojom/image_decoder.mojom.h" -#include "services/data_decoder/public/mojom/json_parser.mojom.h" #include "testing/gmock/include/gmock/gmock.h" using ::testing::Pair; @@ -129,25 +128,27 @@ ServiceProcessObserver observer; // Verifies that separate DataDecoder client objects will launch separate - // service processes. We also bind a JsonParser interface to ensure that the - // instances don't go idle. + // service processes. We also bind an ImageDecoder interface to ensure that + // the instances don't go idle. data_decoder::DataDecoder decoder1; - mojo::Remote<data_decoder::mojom::JsonParser> parser1; - decoder1.GetService()->BindJsonParser(parser1.BindNewPipeAndPassReceiver()); + mojo::Remote<data_decoder::mojom::ImageDecoder> image_decoder1; + decoder1.GetService()->BindImageDecoder( + image_decoder1.BindNewPipeAndPassReceiver()); observer.WaitForNextLaunch(); EXPECT_EQ(1, observer.instances_started()); data_decoder::DataDecoder decoder2; - mojo::Remote<data_decoder::mojom::JsonParser> parser2; - decoder2.GetService()->BindJsonParser(parser2.BindNewPipeAndPassReceiver()); + mojo::Remote<data_decoder::mojom::ImageDecoder> image_decoder2; + decoder2.GetService()->BindImageDecoder( + image_decoder2.BindNewPipeAndPassReceiver()); observer.WaitForNextLaunch(); EXPECT_EQ(2, observer.instances_started()); // Both interfaces should be connected end-to-end. - parser1.FlushForTesting(); - parser2.FlushForTesting(); - EXPECT_TRUE(parser1.is_connected()); - EXPECT_TRUE(parser2.is_connected()); + image_decoder1.FlushForTesting(); + image_decoder2.FlushForTesting(); + EXPECT_TRUE(image_decoder1.is_connected()); + EXPECT_TRUE(image_decoder2.is_connected()); } IN_PROC_BROWSER_TEST_F(DataDecoderBrowserTest, DecodeImageIsolated) {
diff --git a/content/browser/preloading/preloading_config.cc b/content/browser/preloading/preloading_config.cc index dac0689..9014b99 100644 --- a/content/browser/preloading/preloading_config.cc +++ b/content/browser/preloading/preloading_config.cc
@@ -32,31 +32,31 @@ [{ "preloading_type": "NoStatePrefetch", "preloading_predictor": "LinkRel", - "sampling_likelihood": 0.006667 + "sampling_likelihood": 0.005689 }, { "preloading_type": "Preconnect", "preloading_predictor": "PointerDownOnAnchor", - "sampling_likelihood": 0.000113 + "sampling_likelihood": 0.000100 }, { "preloading_type": "Prefetch", "preloading_predictor": "DefaultSearchEngine", - "sampling_likelihood": 0.006505 + "sampling_likelihood": 0.005785 }, { "preloading_type": "Prefetch", "preloading_predictor": "OmniboxMousePredictor", - "sampling_likelihood": 1.000000 + "sampling_likelihood": 0.357184 }, { "preloading_type": "Prefetch", "preloading_predictor": "OmniboxSearchPredictor", - "sampling_likelihood": 1.000000 + "sampling_likelihood": 0.670228 }, { "preloading_type": "Prefetch", "preloading_predictor": "OmniboxTouchDownPredirector", - "sampling_likelihood": 0.011505 + "sampling_likelihood": 0.010079 }, { "preloading_type": "Prefetch", "preloading_predictor": "SpeculationRules", - "sampling_likelihood": 0.001356 + "sampling_likelihood": 0.000892 }, { "preloading_type": "Prefetch", "preloading_predictor": "SpeculationRulesFromIsolatedWorld", @@ -64,43 +64,47 @@ }, { "preloading_type": "Prefetch", "preloading_predictor": "UrlPointerDownOnAnchor", - "sampling_likelihood": 0.027996 + "sampling_likelihood": 0.002821 }, { "preloading_type": "Prefetch", "preloading_predictor": "UrlPointerHoverOnAnchor", - "sampling_likelihood": 0.029942 + "sampling_likelihood": 0.033897 +}, { + "preloading_type": "Prefetch", + "preloading_predictor": "ViewportHeuristic", + "sampling_likelihood": 1.000000 }, { "preloading_type": "Prerender", "preloading_predictor": "BackButtonHover", - "sampling_likelihood": 0.007192 + "sampling_likelihood": 0.006551 }, { "preloading_type": "Prerender", "preloading_predictor": "BackGestureNavigation", - "sampling_likelihood": 0.232383 + "sampling_likelihood": 0.209279 }, { "preloading_type": "Prerender", "preloading_predictor": "DefaultSearchEngine", - "sampling_likelihood": 0.006344 + "sampling_likelihood": 0.005771 }, { "preloading_type": "Prerender", "preloading_predictor": "MouseBackButton", - "sampling_likelihood": 0.076308 + "sampling_likelihood": 0.070962 }, { "preloading_type": "Prerender", "preloading_predictor": "MouseHoverOrMouseDownOnBookmarkBar", - "sampling_likelihood": 0.023874 + "sampling_likelihood": 0.022187 }, { "preloading_type": "Prerender", "preloading_predictor": "MouseHoverOrMouseDownOnNewTabPage", - "sampling_likelihood": 0.033195 + "sampling_likelihood": 0.030196 }, { "preloading_type": "Prerender", "preloading_predictor": "OmniboxDirectURLInput", - "sampling_likelihood": 0.005746 + "sampling_likelihood": 0.005348 }, { "preloading_type": "Prerender", "preloading_predictor": "SpeculationRules", - "sampling_likelihood": 0.067464 + "sampling_likelihood": 0.046348 }, { "preloading_type": "Prerender", "preloading_predictor": "SpeculationRulesFromIsolatedWorld", @@ -108,15 +112,19 @@ }, { "preloading_type": "Prerender", "preloading_predictor": "TouchOnNewTabPage", - "sampling_likelihood": 0.034646 + "sampling_likelihood": 0.028625 }, { "preloading_type": "Prerender", "preloading_predictor": "UrlPointerDownOnAnchor", - "sampling_likelihood": 0.194379 + "sampling_likelihood": 0.132505 }, { "preloading_type": "Prerender", "preloading_predictor": "UrlPointerHoverOnAnchor", - "sampling_likelihood": 0.788890 + "sampling_likelihood": 0.525988 +}, { + "preloading_type": "Prerender", + "preloading_predictor": "ViewportHeuristic", + "sampling_likelihood": 1.000000 }] )"};
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc index dafc516..775c1d3 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc
@@ -8406,15 +8406,7 @@ did_receive_early_hints_before_cross_origin_redirect_); } - // Calculate origin in which this navigation would commit so it can be - // compared with what is generated by the renderer process and the browser - // process at commit time. - // TODO(crbug.com/40092527): Consider using this cached value everywhere - // we currently call `GetOriginToCommit()`, to prevent nonce mismatches. - browser_side_origin_to_commit_with_debug_info_ = - GetOriginToCommitWithDebugInfo(); - std::optional<url::Origin> origin_to_commit = - browser_side_origin_to_commit_with_debug_info_.first; + std::optional<url::Origin> origin_to_commit = GetOriginToCommit(); same_origin_ = (previous_render_frame_host->GetLastCommittedOrigin() == origin_to_commit); @@ -8501,26 +8493,13 @@ } std::optional<url::Origin> NavigationRequest::GetOriginToCommit() { - return GetOriginToCommitWithDebugInfo().first; -} - -std::pair<std::optional<url::Origin>, std::string> -NavigationRequest::GetOriginToCommitWithDebugInfo() { - return GetOriginForURLLoaderFactoryAfterResponseWithDebugInfo(); + return GetOriginForURLLoaderFactoryAfterResponse(); } url::Origin NavigationRequest::GetOriginForURLLoaderFactoryBeforeResponse( network::mojom::WebSandboxFlags sandbox_flags) { - return GetOriginForURLLoaderFactoryBeforeResponseWithDebugInfo(sandbox_flags) - .first; -} - -std::pair<url::Origin, std::string> -NavigationRequest::GetOriginForURLLoaderFactoryBeforeResponseWithDebugInfo( - network::mojom::WebSandboxFlags sandbox_flags) { // Calculate an approximation of the origin. The sandbox/csp are ignored. - std::pair<url::Origin, std::string> origin_and_debug_info = - GetOriginForURLLoaderFactoryUncheckedWithDebugInfo(); + url::Origin origin = GetOriginForURLLoaderFactoryUnchecked(); // Apply sandbox flags. // See https://html.spec.whatwg.org/#sandboxed-origin-browsing-context-flag @@ -8536,17 +8515,10 @@ (sandbox_flags & network::mojom::WebSandboxFlags::kOrigin) == network::mojom::WebSandboxFlags::kOrigin; if (use_opaque_origin) { - origin_and_debug_info = - std::pair(origin_and_debug_info.first.DeriveNewOpaqueOrigin(), - origin_and_debug_info.second + ", sandbox_flags"); + origin = origin.DeriveNewOpaqueOrigin(); } - return origin_and_debug_info; -} - -std::optional<url::Origin> -NavigationRequest::GetOriginForURLLoaderFactoryAfterResponse() { - return GetOriginForURLLoaderFactoryAfterResponseWithDebugInfo().first; + return origin; } // TODO(crbug.com/40065692): Remove. @@ -8584,8 +8556,8 @@ return "other"; } -std::pair<std::optional<url::Origin>, std::string> -NavigationRequest::GetOriginForURLLoaderFactoryAfterResponseWithDebugInfo() { +std::optional<url::Origin> +NavigationRequest::GetOriginForURLLoaderFactoryAfterResponse() { // The origin to commit is not known until we get the final network response. DCHECK_GE(state_, WILL_PROCESS_RESPONSE); @@ -8593,25 +8565,16 @@ // commit in (and therefore there is no origin that will get committed and we // indicate this by returning `nullopt`). if (!response_should_be_rendered_) { - return std::make_pair(std::nullopt, "no_commit"); + return std::nullopt; } if (IsSameDocument() || IsPageActivation()) { CHECK(HasRenderFrameHost()); - return std::make_pair(GetRenderFrameHost()->GetLastCommittedOrigin(), - "same_doc_or_page_activation"); + return GetRenderFrameHost()->GetLastCommittedOrigin(); } - std::pair<url::Origin, std::string> origin_with_debug_info = - GetOriginForURLLoaderFactoryBeforeResponseWithDebugInfo( - SandboxFlagsToCommit()); - - // Add the crash keys for debugging navigation crashes with data URL. - // TODO(crbug.com/40065692): Remove. - SCOPED_CRASH_KEY_STRING256("Bug1454273", "calculated_origin", - origin_with_debug_info.first.GetDebugString()); - SCOPED_CRASH_KEY_STRING256("Bug1454273", "origin_debug_info", - origin_with_debug_info.second); + url::Origin origin = + GetOriginForURLLoaderFactoryBeforeResponse(SandboxFlagsToCommit()); SCOPED_CRASH_KEY_BOOL("Bug1454273", "is_in_main_frame", IsInMainFrame()); SCOPED_CRASH_KEY_STRING256( @@ -8649,8 +8612,7 @@ // MHTML documents should commit as an opaque origin. They should not be able // to make network request on behalf of the real origin. // TODO(crbug.com/370979008): Migrate to CHECK. - DUMP_WILL_BE_CHECK(!IsMhtmlOrSubframe() || - origin_with_debug_info.first.opaque()); + DUMP_WILL_BE_CHECK(!IsMhtmlOrSubframe() || origin.opaque()); // If the target of this navigation will be rendered in a RenderFrameHost, // then verify that the chosen origin is allowed to be accessed from that @@ -8673,11 +8635,11 @@ int process_id = GetRenderFrameHost()->GetProcess()->GetDeprecatedID(); auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); CHECK(policy->CanAccessOrigin( - process_id, origin_with_debug_info.first, + process_id, origin, ChildProcessSecurityPolicyImpl::AccessType::kCanCommitNewOrigin)); } - return origin_with_debug_info; + return origin; } void NavigationRequest::WriteIntoTrace( @@ -11033,17 +10995,14 @@ } } -std::pair<url::Origin, std::string> -NavigationRequest::GetOriginForURLLoaderFactoryUncheckedWithDebugInfo() { +url::Origin NavigationRequest::GetOriginForURLLoaderFactoryUnchecked() { if (DidEncounterError()) { // Error pages commit in an opaque origin in the renderer process. If this // NavigationRequest resulted in committing an error page, return an // opaque origin that has precursor information consistent with the URL // being requested. Note: this is intentionally done first; cases like // errors in srcdoc frames need not inherit the parent's origin for errors. - return std::make_pair( - url::Origin::Create(common_params().url).DeriveNewOpaqueOrigin(), - "error"); + return url::Origin::Create(common_params().url).DeriveNewOpaqueOrigin(); } // Check if this is loadDataWithBaseUrl (which needs special treatment). @@ -11069,9 +11028,7 @@ // opaque origin), but commits that URL as if it came from // |common_params.base_url_for_data_url|. See also // https://crbug.com/976253. - return std::make_pair( - url::Origin::Create(common_params().base_url_for_data_url), - "load_data_with_base_url"); + return url::Origin::Create(common_params().base_url_for_data_url); } // Use the cached tentative data origin to commit in the data: URL case. When @@ -11080,8 +11037,7 @@ // us uniquely identify the correct data: SiteInstance. if (common_params().url.SchemeIs(url::kDataScheme) && tentative_data_origin_to_commit_.has_value()) { - return std::make_pair(tentative_data_origin_to_commit_.value(), - "data: URL"); + return tentative_data_origin_to_commit_.value(); } // Srcdoc subframes need to inherit their origin from their parent frame. @@ -11089,7 +11045,7 @@ RenderFrameHostImpl* parent = frame_tree_node()->parent(); if (parent) { - return std::make_pair(parent->GetLastCommittedOrigin(), "about_srcdoc"); + return parent->GetLastCommittedOrigin(); } else { // The only path for `parent` to be missing for a srcdoc navigation is if // a mainframe renderer executes `location = "about:srcdoc` instead of @@ -11099,9 +11055,7 @@ // encounters a COOP header. In that case we return the origin of the // page that executed the script, knowing that the navigation will fail // anyways. - return std::make_pair( - frame_tree_node()->current_frame_host()->GetLastCommittedOrigin(), - "about_srcdoc, no-parent"); + return frame_tree_node()->current_frame_host()->GetLastCommittedOrigin(); } } @@ -11112,15 +11066,12 @@ if (HasRenderFrameHost() && GetRenderFrameHost()->GetProcess()) { target_rph_id = GetRenderFrameHost()->GetProcess()->GetDeprecatedID(); } - return std::make_pair( - static_cast<StoragePartitionImpl*>( - GetStoragePartitionWithCurrentSiteInfo()) - ->GetBlobUrlRegistry() - ->GetOriginForNavigation( - GetURL(), - common_params().initiator_origin.value_or(url::Origin()), - target_rph_id), - "blob"); + return static_cast<StoragePartitionImpl*>( + GetStoragePartitionWithCurrentSiteInfo()) + ->GetBlobUrlRegistry() + ->GetOriginForNavigation( + GetURL(), common_params().initiator_origin.value_or(url::Origin()), + target_rph_id); } // In cases not covered above, URLLoaderFactory should be associated with the @@ -11134,11 +11085,7 @@ tentative_data_origin_to_commit_ = resolved_origin; } - return std::make_pair(resolved_origin, "url_or_initiator"); -} - -url::Origin NavigationRequest::GetOriginForURLLoaderFactoryUnchecked() { - return GetOriginForURLLoaderFactoryUncheckedWithDebugInfo().first; + return resolved_origin; } bool NavigationRequest::HasLoader() const {
diff --git a/content/browser/renderer_host/navigation_request.h b/content/browser/renderer_host/navigation_request.h index 0f9dc9f..92dabdb 100644 --- a/content/browser/renderer_host/navigation_request.h +++ b/content/browser/renderer_host/navigation_request.h
@@ -975,14 +975,6 @@ // possible. url::Origin GetTentativeOriginAtRequestTime(); - // Same as `GetOriginToCommit()`, except that includes information about how - // the origin gets calculated, to help debug if the browser-side calculated - // origin for this navigation differs from the origin calculated on the - // renderer side. - // TODO(crbug.com/40772732): Remove this. - std::pair<std::optional<url::Origin>, std::string> - GetOriginToCommitWithDebugInfo(); - // If this navigation fails with net::ERR_BLOCKED_BY_CLIENT, act as if it were // cancelled by the user and do not commit an error page. void SetSilentlyIgnoreBlockedByClient() { @@ -1258,11 +1250,6 @@ return navigation_or_document_handle_; } - const std::pair<std::optional<url::Origin>, std::string>& - browser_side_origin_to_commit_with_debug_info() { - return browser_side_origin_to_commit_with_debug_info_; - } - // Initializes state which is passed from the old Document to the new Document // for a ViewTransition. void SetViewTransitionState( @@ -2262,17 +2249,6 @@ // after the final response is received or ready. std::optional<url::Origin> GetOriginForURLLoaderFactoryAfterResponse(); - // These functions are the same as their non-WithDebugInfo counterparts, - // except that they include information about how the origin gets calculated, - // to help debug if the browser-side calculated origin for this navigation - // differs from the origin calculated on the renderer side. - // TODO(crbug.com/40772732): Remove this. - std::pair<url::Origin, std::string> - GetOriginForURLLoaderFactoryBeforeResponseWithDebugInfo( - network::mojom::WebSandboxFlags sandbox_flags); - std::pair<std::optional<url::Origin>, std::string> - GetOriginForURLLoaderFactoryAfterResponseWithDebugInfo(); - // Computes the CrossOriginIsolationKey to use for committing the navigation. // A nullopt result means that either the cross-origin isolation status of the // request cannot be determined because we do not have final headers for the @@ -2354,8 +2330,6 @@ void RecordEarlyRenderFrameHostSwapMetrics(); // Helpers for GetTentativeOriginAtRequestTime and GetOriginToCommit. - std::pair<url::Origin, std::string> - GetOriginForURLLoaderFactoryUncheckedWithDebugInfo(); url::Origin GetOriginForURLLoaderFactoryUnchecked(); void MaybeRecordTraceEventsAndHistograms(); @@ -2435,11 +2409,6 @@ blink::mojom::BeginNavigationParamsPtr begin_params_; blink::mojom::CommitNavigationParamsPtr commit_params_; bool same_origin_ = false; - // This member is calculated at ReadyToCommit time. It is used to compare - // against renderer calculated origin and browser calculated one at commit - // time. - std::pair<std::optional<url::Origin>, std::string> - browser_side_origin_to_commit_with_debug_info_; // Stores the NavigationUIData for this navigation until the NavigationHandle // is created. This can be null if the embedded did not provide a
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index f5534e1b..75e4229 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -766,117 +766,6 @@ network::mojom::WebSandboxFlags::kNone; } -// Verify that |browser_side_origin| and |renderer_side_origin| match. See also -// https://crbug.com/888079. -void VerifyThatBrowserAndRendererCalculatedOriginsToCommitMatch( - NavigationRequest* navigation_request, - const mojom::DidCommitProvisionalLoadParams& params) { - DCHECK(navigation_request); - - // This should be called only when a new document is created. Navigations in - // the same document and page activations do not create a new document. - DCHECK(!navigation_request->IsSameDocument()); - DCHECK(!navigation_request->IsPageActivation()); - - // Ignore for now cases where the NavigationRequest is in an unexpectedly - // early state. Triggered by the following tests: - // NavigationBrowserTest.OpenerNavigation_DownloadPolicy, - // WebContentsImplBrowserTest.NewNamedWindow. - if (navigation_request->state() < NavigationRequest::WILL_PROCESS_RESPONSE) - return; - - const url::Origin& renderer_side_origin = params.origin; - std::pair<std::optional<url::Origin>, std::string> - browser_side_origin_and_debug_info = - navigation_request->browser_side_origin_to_commit_with_debug_info(); - - // For non-opaque origins, we say the browser and renderer calculated origins - // match if they are exactly the same. - bool origins_match = (browser_side_origin_and_debug_info.first.value() == - renderer_side_origin); - - // For opaque origins, we can check for equality if the opaque origin is not - // newly created in the renderer. If the opaque origin can be known by the - // browser, e.g. if the opaque origin is inherited/copied from another - // document, or is from the browser-sent `origin_to_commit`, then the browser - // calculated origin must match the one used by the renderer in the end. On - // the other hand, if the opaque origin is newly created, e.g. a new sandboxed - // opaque origin, we can only match the precursor origin. The renderer will - // tell us if the origin is newly created in the renderer or not through - // appending "is_newly_created" in the end of `origin_calculation_debug_info`. - // See also `DocumentLoader::CalculateOrigin()`. - // TODO(crbug.com/40092527): Consider adding a separate boolean that - // tracks this instead of piggybacking `origin_calculation_debug_info`. - if (renderer_side_origin.opaque() && - browser_side_origin_and_debug_info.first->opaque() && - params.origin_calculation_debug_info.ends_with("is_newly_created")) { - origins_match = (renderer_side_origin.GetTupleOrPrecursorTupleIfOpaque() == - browser_side_origin_and_debug_info.first - ->GetTupleOrPrecursorTupleIfOpaque()); - } - - // For Blob URLs, it's possible that the renderer thinks the origin is opaque - // while the browser thinks it's not opaque if the Blob URL origin is - // registered in the BlobURLNullOriginMap by the document that the navigation - // is replacing, causing the origin to be de-registered just before the new - // document commits. In this case the browser actually has the correct origin, - // so just compare the precursor origin of the renderer side. - if (params.url.SchemeIsBlob() && renderer_side_origin.opaque() && - params.origin_calculation_debug_info.ends_with("is_newly_created") && - navigation_request->GetRenderFrameHost() - ->ShouldChangeRenderFrameHostOnSameSiteNavigation()) { - origins_match = (renderer_side_origin.GetTupleOrPrecursorTupleIfOpaque() == - browser_side_origin_and_debug_info.first - ->GetTupleOrPrecursorTupleIfOpaque()); - } - - // TODO(crbug.com/40092527): Remove the DumpWithoutCrashing below, once - // we are sure that the `browser_side_origin` is always the same as the - // `renderer_side_origin`. - if (!origins_match) { - NavigationRequest::ScopedCrashKeys navigation_request_crash_keys( - *navigation_request); - SCOPED_CRASH_KEY_STRING256( - "", "browser_origin", - browser_side_origin_and_debug_info.first->GetDebugString()); - SCOPED_CRASH_KEY_STRING256("", "browser_debug_info", - browser_side_origin_and_debug_info.second); - auto* parent_rfh = navigation_request->GetRenderFrameHost()->GetParent(); - SCOPED_CRASH_KEY_STRING256( - "", "parent_rfh_origin", - parent_rfh ? parent_rfh->GetLastCommittedOrigin().GetDebugString() - : ""); - SCOPED_CRASH_KEY_STRING256("", "parent_rs_origin", - parent_rfh ? parent_rfh->browsing_context_state() - ->current_replication_state() - .origin.GetDebugString() - : ""); - - SCOPED_CRASH_KEY_STRING256( - "", "browser_ready_to_commit_origin", - navigation_request->browser_side_origin_to_commit_with_debug_info() - .first->GetDebugString()); - SCOPED_CRASH_KEY_STRING256( - "", "browser_ready_to_commit_debug_info", - navigation_request->browser_side_origin_to_commit_with_debug_info() - .second); - - SCOPED_CRASH_KEY_STRING256("", "renderer_origin", - renderer_side_origin.GetDebugString()); - SCOPED_CRASH_KEY_STRING256("", "renderer_debug_info", - params.origin_calculation_debug_info); - CaptureTraceForNavigationDebugScenario( - DebugScenario::kDebugBrowserVsRendererOriginToCommit); - base::debug::DumpWithoutCrashing(); - DCHECK_EQ(browser_side_origin_and_debug_info.first.value(), - renderer_side_origin) - << "; navigation_request->GetURL() = " << navigation_request->GetURL(); - return; - } - - return; -} - // A simplified version of Blink's WebFrameLoadType, used to simulate renderer // calculations. See CalculateRendererLoadType() further below. // TODO(crbug.com/40150370): This should only be here temporarily. @@ -12233,12 +12122,11 @@ auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); const ProcessLock process_lock = ProcessLock::FromSiteInfo(GetSiteInstance()->GetSiteInfo()); - auto browser_calc_origin_to_commit = - navigation_request->GetOriginToCommitWithDebugInfo(); + auto browser_calc_origin_to_commit = navigation_request->GetOriginToCommit(); if (!process_lock.is_error_page() && !is_mhtml_subframe && !policy->CanAccessOrigin( GetProcess()->GetDeprecatedID(), - browser_calc_origin_to_commit.first.value(), + browser_calc_origin_to_commit.value(), ChildProcessSecurityPolicyImpl::AccessType::kCanCommitNewOrigin)) { SCOPED_CRASH_KEY_STRING64("CommitNavigation", "lock_url", process_lock.ToString()); @@ -12247,9 +12135,7 @@ common_params->url.DeprecatedGetOriginAsURL().spec()); SCOPED_CRASH_KEY_STRING64( "CommitNavigation", "browser_calc_origin", - browser_calc_origin_to_commit.first.value().GetDebugString()); - SCOPED_CRASH_KEY_STRING64("CommitNavigation", "origin_debug_info", - browser_calc_origin_to_commit.second); + browser_calc_origin_to_commit.value().GetDebugString()); SCOPED_CRASH_KEY_BOOL("CommitNavigation", "is_main_frame", is_main_frame()); // The reason this isn't is_outermost_main_frame is so that the full name of // the key does not exceed the 40 character limit. @@ -14775,8 +14661,7 @@ if (!bypass_checks_for_error_page && !ValidateURLAndOrigin(params->url, params->origin, - is_same_document_navigation, navigation_request, - params->origin_calculation_debug_info)) { + is_same_document_navigation, navigation_request)) { return false; } @@ -14914,8 +14799,7 @@ const GURL& url, const url::Origin& origin, bool is_same_document_navigation, - NavigationRequest* navigation_request, - std::string origin_calculation_debug_info) { + NavigationRequest* navigation_request) { // WebView's allow_universal_access_from_file_urls setting allows file origins // to access any other origin and bypass normal commit checks. If new // documents in the same process and origin may also bypass these checks after @@ -14988,8 +14872,7 @@ << " lock '" << process->GetProcessLock().ToString() << "'"; VLOG(1) << "Blocked URL " << url.spec(); LogCannotCommitUrlCrashKeys(url, origin, is_same_document_navigation, - navigation_request, - origin_calculation_debug_info); + navigation_request); // Kills the process. bad_message::ReceivedBadMessage(process, @@ -15171,9 +15054,9 @@ // DidCommitSameDocumentNavigation). // TODO(crbug.com/40150370): Make this a CHECK instead once we're // sure we never hit this case. - LogCannotCommitUrlCrashKeys( - params->url, params->origin, is_same_document_navigation, - navigation_request.get(), params->origin_calculation_debug_info); + LogCannotCommitUrlCrashKeys(params->url, params->origin, + is_same_document_navigation, + navigation_request.get()); base::debug::DumpWithoutCrashing(); } @@ -15196,9 +15079,9 @@ params->url, frame_tree_node_->is_on_initial_empty_document()); if (!navigation_request && !is_synchronous_about_blank_commit && !is_same_document_navigation) { - LogCannotCommitUrlCrashKeys( - params->url, params->origin, is_same_document_navigation, - navigation_request.get(), params->origin_calculation_debug_info); + LogCannotCommitUrlCrashKeys(params->url, params->origin, + is_same_document_navigation, + navigation_request.get()); bad_message::ReceivedBadMessage( GetProcess(), @@ -16045,9 +15928,6 @@ base::ElapsedTimer timer; DCHECK_EQ(net::OK, navigation_request->GetNetErrorCode()); - CHECK_EQ(commit_params->origin_to_commit, - navigation_request->browser_side_origin_to_commit_with_debug_info() - .first.value()); IncreaseCommitNavigationCounter(); mojo::PendingRemote<blink::mojom::CodeCacheHost> code_cache_host; mojo::PendingRemote<blink::mojom::CodeCacheHost> @@ -16222,9 +16102,6 @@ subresource_loader_factories, const blink::DocumentToken& document_token, blink::mojom::PolicyContainerPtr policy_container) { - CHECK_EQ(commit_params->origin_to_commit, - navigation_request->browser_side_origin_to_commit_with_debug_info() - .first.value()); DCHECK(navigation_client && navigation_request); DCHECK_NE(GURL(), common_params->url); DCHECK_NE(net::OK, error_code); @@ -16660,8 +16537,7 @@ const GURL& url, const url::Origin& origin, bool is_same_document_navigation, - NavigationRequest* navigation_request, - std::string& origin_calculation_debug_info) { + NavigationRequest* navigation_request) { LogRendererKillCrashKeys(GetSiteInstance()->GetSiteInfo()); // Temporary instrumentation to debug the root cause of renderer process @@ -16789,12 +16665,6 @@ is_on_initial_empty_document_key, base::ToString(frame_tree_node_->is_on_initial_empty_document())); - static auto* const origin_calculation_debug_info_key = - base::debug::AllocateCrashKeyString("origin_calculation_debug_info", - base::debug::CrashKeySize::Size256); - base::debug::SetCrashKeyString(origin_calculation_debug_info_key, - origin_calculation_debug_info); - if (navigation_request && navigation_request->IsNavigationStarted()) { static auto* const is_renderer_initiated_key = base::debug::AllocateCrashKeyString("is_renderer_initiated", @@ -17444,10 +17314,6 @@ params.transition)); DCHECK_EQ(browser_history_list_was_cleared, params.history_list_was_cleared); - // TODO(crbug.com/40092527): The origin computed from the browser must - // match the one reported from the renderer process. - VerifyThatBrowserAndRendererCalculatedOriginsToCommitMatch(request, params); - if (!everything_except_origin_matches) { // It's possible to get here when everything except the origin matches. // If the origin doesn't match, we would do a DumpWithoutCrashing above.
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h index f053f85f..1eb87a93 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -3953,12 +3953,10 @@ // Validates whether we can commit |url| and |origin| for a navigation or a // document.open() URL update. // A return value of true means that the URL & origin can be committed. - bool ValidateURLAndOrigin( - const GURL& url, - const url::Origin& origin, - bool is_same_document_navigation, - NavigationRequest* navigation_request, - std::string origin_calculation_debug_info = std::string()); + bool ValidateURLAndOrigin(const GURL& url, + const url::Origin& origin, + bool is_same_document_navigation, + NavigationRequest* navigation_request); // The actual implementation of committing a navigation in the browser // process. Called by the DidCommitProvisionalLoad IPC handler. @@ -4129,8 +4127,7 @@ void LogCannotCommitUrlCrashKeys(const GURL& url, const url::Origin& origin, bool is_same_document_navigation, - NavigationRequest* navigation_request, - std::string& origin_calculation_debug_info); + NavigationRequest* navigation_request); void LogCannotCommitOriginCrashKeys(const GURL& url, const url::Origin& origin, const ProcessLock& process_lock,
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 6d39dcc1..55efc47d 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -4228,6 +4228,13 @@ return delegate_ ? delegate_->PreHandleMouseEvent(this, event) : false; } +void WebContentsImpl::PreHandleDragUpdate(const DropData& drop_data, + const gfx::PointF& client_pt) { + if (delegate_) { + delegate_->PreHandleDragUpdate(drop_data, client_pt); + } +} + KeyboardEventProcessingResult WebContentsImpl::PreHandleKeyboardEvent( const input::NativeWebKeyboardEvent& event) { OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"),
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 98fdc7f7..c6eafe5 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -1118,6 +1118,8 @@ double GetPendingZoomLevel(RenderWidgetHostImpl* rwh) override; bool PreHandleMouseEvent(const blink::WebMouseEvent& event) override; + void PreHandleDragUpdate(const DropData& drop_data, + const gfx::PointF& client_pt); KeyboardEventProcessingResult PreHandleKeyboardEvent( const input::NativeWebKeyboardEvent& event) override; bool HandleMouseEvent(const blink::WebMouseEvent& event) override;
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc index 330d2fe..90615f5 100644 --- a/content/browser/web_contents/web_contents_view_aura.cc +++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -1447,6 +1447,11 @@ if (!target) { return; } + + if (transformed_pt.has_value()) { + web_contents_->PreHandleDragUpdate(*drop_data, transformed_pt.value()); + } + RenderWidgetHostImpl* target_rwh = RenderWidgetHostImpl::From(target->GetRenderWidgetHost()); if (!drag_security_info_.IsValidDragTarget(target_rwh)) {
diff --git a/content/browser/web_contents/web_drag_dest_mac.mm b/content/browser/web_contents/web_drag_dest_mac.mm index b92e06b..495aa05 100644 --- a/content/browser/web_contents/web_drag_dest_mac.mm +++ b/content/browser/web_contents/web_drag_dest_mac.mm
@@ -308,6 +308,9 @@ return NSDragOperationNone; } + _webContents->PreHandleDragUpdate(*_dropDataUnfiltered, + info->location_in_view); + gfx::PointF transformedPt; content::RenderWidgetHostImpl* targetRWH = [self GetRenderWidgetHostAtPoint:info->location_in_view
diff --git a/content/common/navigation_client.mojom b/content/common/navigation_client.mojom index 1670df1..50602e7 100644 --- a/content/common/navigation_client.mojom +++ b/content/common/navigation_client.mojom
@@ -119,11 +119,6 @@ // removed, then this will no longer be needed. url.mojom.Url? initiator_base_url; - // Information about how `origin` was calculated, to help debug if it differs - // from the origin calculated on the browser side. - // TODO(crbug.com/40772732): Remove this. - string origin_calculation_debug_info; - // The 'Permissions-Policy' headers applied to the document. // https://w3c.github.io/webappsec-permissions-policy/#permissions-policy-http-header-field // Note: For backward compatibility, this field also contains
diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h index 0125c481..503ab27 100644 --- a/content/public/browser/web_contents_delegate.h +++ b/content/public/browser/web_contents_delegate.h
@@ -308,6 +308,8 @@ // false. virtual bool PreHandleMouseEvent(WebContents* source, const blink::WebMouseEvent& event); + virtual void PreHandleDragUpdate(const DropData& drop_data, + const gfx::PointF& client_pt) {} // Allows delegates to handle keyboard events before sending to the renderer. // See enum for description of return values.
diff --git a/content/public/test/navigation_simulator.h b/content/public/test/navigation_simulator.h index 3ab4b6777..441423c1 100644 --- a/content/public/test/navigation_simulator.h +++ b/content/public/test/navigation_simulator.h
@@ -30,6 +30,7 @@ class NavigationController; class NavigationHandle; +class NavigationThrottleRegistry; class RenderFrameHost; class WebContents; struct GlobalRequestID; @@ -346,6 +347,12 @@ // navigation has finished (successfully or not). virtual NavigationHandle* GetNavigationHandle() = 0; + // Returns the NavigationThrottleRegistry associated with the navigation + // being simulated. It is an error to call this before Start() or after the + // navigation has finished (successfully or not) as the runner does not + // outlive the NavigationHandle. + virtual NavigationThrottleRegistry& GetNavigationThrottleRegistry() = 0; + // Returns the GlobalRequestID for the simulated navigation request. Can be // invoked after the navigation has completed. It is an error to call this // before the simulated navigation has completed its WillProcessResponse
diff --git a/content/public/test/test_navigation_throttle_inserter.cc b/content/public/test/test_navigation_throttle_inserter.cc index f4cab537..465f04e 100644 --- a/content/public/test/test_navigation_throttle_inserter.cc +++ b/content/public/test/test_navigation_throttle_inserter.cc
@@ -6,6 +6,7 @@ #include <utility> +#include "content/browser/renderer_host/navigation_request.h" #include "content/public/browser/navigation_handle.h" namespace content { @@ -15,13 +16,24 @@ ThrottleInsertionCallback callback) : WebContentsObserver(web_contents), callback_(std::move(callback)) {} +TestNavigationThrottleInserter::TestNavigationThrottleInserter( + WebContents* web_contents, + NewThrottleInsertionCallback callback) + : WebContentsObserver(web_contents), new_callback_(std::move(callback)) {} + TestNavigationThrottleInserter::~TestNavigationThrottleInserter() = default; void TestNavigationThrottleInserter::DidStartNavigation( NavigationHandle* navigation_handle) { - if (std::unique_ptr<NavigationThrottle> throttle = - callback_.Run(navigation_handle)) { - navigation_handle->RegisterThrottleForTesting(std::move(throttle)); + if (callback_) { + if (std::unique_ptr<NavigationThrottle> throttle = + callback_.Run(navigation_handle)) { + navigation_handle->RegisterThrottleForTesting(std::move(throttle)); + } + } + if (new_callback_) { + new_callback_.Run(*NavigationRequest::From(navigation_handle) + ->GetNavigationThrottleRunnerForTesting()); } }
diff --git a/content/public/test/test_navigation_throttle_inserter.h b/content/public/test/test_navigation_throttle_inserter.h index 4dcb841..65bbee0 100644 --- a/content/public/test/test_navigation_throttle_inserter.h +++ b/content/public/test/test_navigation_throttle_inserter.h
@@ -13,20 +13,29 @@ namespace content { class NavigationThrottle; +class NavigationThrottleRegistry; class WebContents; +// TODO(https://crbug.com/412524375): Remove old callback type. using ThrottleInsertionCallback = base::RepeatingCallback<std::unique_ptr<NavigationThrottle>( NavigationHandle*)>; +using NewThrottleInsertionCallback = + base::RepeatingCallback<void(NavigationThrottleRegistry& registry)>; + // This class is instantiated with a NavigationThrottle factory callback, and // - Calls the callback in every DidStartNavigation. // - If the throttle is successfully created, registers it with the given // navigation. class TestNavigationThrottleInserter : public WebContentsObserver { public: + // TODO(https://crbug.com/412524375): Remove old constructor with a legacy + // callback type. TestNavigationThrottleInserter(WebContents* web_contents, ThrottleInsertionCallback callback); + TestNavigationThrottleInserter(WebContents* web_contents, + NewThrottleInsertionCallback callback); TestNavigationThrottleInserter(const TestNavigationThrottleInserter&) = delete; @@ -40,6 +49,7 @@ private: ThrottleInsertionCallback callback_; + NewThrottleInsertionCallback new_callback_; }; } // namespace content
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 4d40964a..2ec398b 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -5001,8 +5001,6 @@ params->method = "GET"; params->post_id = -1; params->embedding_token = embedding_token; - params->origin_calculation_debug_info = - document_loader->OriginCalculationDebugInfo().Utf8(); // Pass the navigation token back to the browser process, or generate a new // one if this navigation is committing without the browser process asking for
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index 9d41c83a..86e25ae8 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn
@@ -38,6 +38,12 @@ import("//content/shell/app/ios/extensions.gni") } +if (translate_genders) { + _gender_suffix = "_OTHER" +} else { + _gender_suffix = "" +} + # TODO(crbug.com/1336055, spang): Investigate using shell_views with cast builds as # true. shell_use_toolkit_views = toolkit_views && !is_castos @@ -533,14 +539,14 @@ "$root_gen_dir/third_party/blink/public/resources/blink_resources.pak", "$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_100_percent.pak", "$root_gen_dir/third_party/blink/public/resources/inspector_overlay_resources.pak", - "$root_gen_dir/third_party/blink/public/strings/blink_strings_en-US.pak", + "$root_gen_dir/third_party/blink/public/strings/blink_strings_en-US${_gender_suffix}.pak", "$root_gen_dir/third_party/blink/public/strings/permission_element_generated_strings.pak", - "$root_gen_dir/third_party/blink/public/strings/permission_element_strings_en-US.pak", + "$root_gen_dir/third_party/blink/public/strings/permission_element_strings_en-US${_gender_suffix}.pak", "$root_gen_dir/ui/resources/ui_resources_100_percent.pak", - "$root_gen_dir/ui/strings/app_locale_settings_en-US.pak", - "$root_gen_dir/ui/strings/auto_image_annotation_strings_en-US.pak", - "$root_gen_dir/ui/strings/ax_strings_en-US.pak", - "$root_gen_dir/ui/strings/ui_strings_en-US.pak", + "$root_gen_dir/ui/strings/app_locale_settings_en-US${_gender_suffix}.pak", + "$root_gen_dir/ui/strings/auto_image_annotation_strings_en-US${_gender_suffix}.pak", + "$root_gen_dir/ui/strings/ax_strings_en-US${_gender_suffix}.pak", + "$root_gen_dir/ui/strings/ui_strings_en-US${_gender_suffix}.pak", "$root_gen_dir/ui/webui/resources/webui_resources.pak", ]
diff --git a/content/test/navigation_simulator_impl.cc b/content/test/navigation_simulator_impl.cc index 68518db..0ffffbc 100644 --- a/content/test/navigation_simulator_impl.cc +++ b/content/test/navigation_simulator_impl.cc
@@ -1130,6 +1130,11 @@ return request_; } +NavigationThrottleRegistry& +NavigationSimulatorImpl::GetNavigationThrottleRegistry() { + return *GetNavigationHandle()->GetNavigationThrottleRunnerForTesting(); +} + content::GlobalRequestID NavigationSimulatorImpl::GetGlobalRequestID() { CHECK_GT(state_, STARTED) << "The GlobalRequestID is not available until " "after the navigation has completed " @@ -1593,9 +1598,7 @@ if (same_document) { params->origin = current_rfh->GetLastCommittedOrigin(); } else { - params->origin = origin_.value_or( - request_->browser_side_origin_to_commit_with_debug_info() - .first.value()); + params->origin = origin_.value_or(request_->GetOriginToCommit().value()); } if (same_document) {
diff --git a/content/test/navigation_simulator_impl.h b/content/test/navigation_simulator_impl.h index 30616905..2634ff1 100644 --- a/content/test/navigation_simulator_impl.h +++ b/content/test/navigation_simulator_impl.h
@@ -115,6 +115,7 @@ NavigationThrottle::ThrottleCheckResult GetLastThrottleCheckResult() override; NavigationRequest* GetNavigationHandle() override; + NavigationThrottleRegistry& GetNavigationThrottleRegistry() override; content::GlobalRequestID GetGlobalRequestID() override; void SetKeepLoading(bool keep_loading) override;
diff --git a/crypto/obsolete/md5.cc b/crypto/obsolete/md5.cc index 4a01856..2eac8cb 100644 --- a/crypto/obsolete/md5.cc +++ b/crypto/obsolete/md5.cc
@@ -22,8 +22,35 @@ CHECK(EVP_DigestInit(ctx_.get(), EVP_md5())); } +Md5::Md5(const Md5& other) { + *this = other; +} + +Md5::Md5(Md5&& other) { + *this = other; +} + +Md5& Md5::operator=(const Md5& other) { + CHECK(EVP_MD_CTX_copy_ex(ctx_.get(), other.ctx_.get())); + return *this; +} + +Md5& Md5::operator=(Md5&& other) { + ctx_ = std::move(other.ctx_); + return *this; +} + Md5::~Md5() = default; +Md5 Md5::MakeMd5HasherForTesting() { + return {}; +} + +std::array<uint8_t, Md5::kSize> Md5::HashForTesting( + base::span<const uint8_t> data) { + return Hash(data); +} + void Md5::Update(base::span<const uint8_t> data) { CHECK(EVP_DigestUpdate(ctx_.get(), data.data(), data.size())); }
diff --git a/crypto/obsolete/md5.h b/crypto/obsolete/md5.h index e9bb5cde1..c136797 100644 --- a/crypto/obsolete/md5.h +++ b/crypto/obsolete/md5.h
@@ -16,6 +16,10 @@ class Md5; } +namespace extensions::image_writer { +crypto::obsolete::Md5 MakeMd5HasherForImageWriter(); +} + namespace policy { crypto::obsolete::Md5 MakeMd5HasherForPolicyEventId(); } @@ -35,6 +39,10 @@ public: static constexpr size_t kSize = 16; + Md5(const Md5& other); + Md5(Md5&& other); + Md5& operator=(const Md5& other); + Md5& operator=(Md5&& other); ~Md5(); void Update(base::span<const uint8_t> data); @@ -42,12 +50,17 @@ void Finish(base::span<uint8_t, kSize> result); std::array<uint8_t, kSize> Finish(); + Md5 MakeMd5HasherForTesting(); + static std::array<uint8_t, kSize> HashForTesting( + base::span<const uint8_t> data); + private: FRIEND_TEST_ALL_PREFIXES(Md5Test, KnownAnswer); // The friends listed here are the areas required to continue using MD5 for // compatibility with existing specs, on-disk data, or similar. friend Md5 policy::MakeMd5HasherForPolicyEventId(); + friend Md5 extensions::image_writer::MakeMd5HasherForImageWriter(); // TODO(https://crbug.com/416304903): get rid of this. friend Md5 web_app::internals::MakeMd5HasherForWebAppShortcutIcon();
diff --git a/device/bluetooth/strings/BUILD.gn b/device/bluetooth/strings/BUILD.gn index e73c0b5..d8bdeb82 100644 --- a/device/bluetooth/strings/BUILD.gn +++ b/device/bluetooth/strings/BUILD.gn
@@ -6,17 +6,19 @@ import("//tools/grit/grit_rule.gni") import("//tools/grit/repack.gni") -grit("strings") { +grit_strings("strings") { source = "../bluetooth_strings.grd" - outputs = - [ "grit/bluetooth_strings.h" ] + - process_file_template(all_chrome_locales, - [ "bluetooth_strings_{{source_name_part}}.pak" ]) + outputs = [ "grit/bluetooth_strings.h" ] + output_prefix = "bluetooth_strings_" } repack("bluetooth_test_strings") { - sources = - [ "$root_gen_dir/device/bluetooth/strings/bluetooth_strings_en-US.pak" ] + if (translate_genders) { + sources = [ "$root_gen_dir/device/bluetooth/strings/bluetooth_strings_en-US_OTHER.pak" ] + } else { + sources = + [ "$root_gen_dir/device/bluetooth/strings/bluetooth_strings_en-US.pak" ] + } output = "$root_out_dir/bluetooth_test_strings.pak" deps = [ ":strings" ] }
diff --git a/device/fido/strings/BUILD.gn b/device/fido/strings/BUILD.gn index d033e97..e3437bf 100644 --- a/device/fido/strings/BUILD.gn +++ b/device/fido/strings/BUILD.gn
@@ -6,16 +6,19 @@ import("//tools/grit/grit_rule.gni") import("//tools/grit/repack.gni") -grit("strings") { +grit_strings("strings") { source = "../fido_strings.grd" outputs = [ "grit/fido_strings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "fido_strings_$locale.pak" ] - } + output_prefix = "fido_strings_" } repack("fido_test_strings") { - sources = [ "$root_gen_dir/device/fido/strings/fido_strings_en-US.pak" ] + if (translate_genders) { + sources = + [ "$root_gen_dir/device/fido/strings/fido_strings_en-US_OTHER.pak" ] + } else { + sources = [ "$root_gen_dir/device/fido/strings/fido_strings_en-US.pak" ] + } output = "$root_out_dir/fido_test_strings.pak" deps = [ ":strings" ] }
diff --git a/docs/adding_to_third_party.md b/docs/adding_to_third_party.md index 0b34789..6b40029 100644 --- a/docs/adding_to_third_party.md +++ b/docs/adding_to_third_party.md
@@ -4,11 +4,10 @@ Using third party code can save time and is consistent with our values - no need to reinvent the wheel! We put all code that isn't written by Chromium developers -into `//third_party` (even if you end up modifying just a few functions). We do -this to make it easy to track license compliance, security patches, and supply -the right credit and attributions. It also makes it a lot easier for other -projects that embed our code to track what is Chromium licensed and what is -covered by other licenses. +into `//third_party`. We do this to make it easy to track license compliance, +security patches, and supply the right credit and attributions. It also makes it +a lot easier for other projects that embed our code to track what is Chromium +licensed and what is covered by other licenses. ## Put the code in //third_party @@ -37,6 +36,9 @@ other directory with third_party in the name it's okay to put new things there. +Regardless of where you add a third party dependency, you should use the +[recommended directory structure](#standard-dep-structure). + ## Before you start To make sure the inclusion of a new third_party project makes sense for the @@ -171,12 +173,10 @@ to the deps entry so that developers on other platforms don't pull in things they don't need. -As for specifying the path where the library is fetched, a path like -`//third_party/<project_name>/src` is highly recommended so that you can put -the file like OWNERS or README.chromium at `//third_party/<project_name>`. If -you have a wrong path in DEPS and want to change the path of the existing -library in DEPS, please ask the infrastructure team before committing the -change. +Follow the [standard directory structure](#standard-dep-structure) when creating +a directory for your dependency. If you have a wrong path in +DEPS and want to change the path of the existing library in DEPS, please ask the +infrastructure team before committing the change. Lastly, add the new directory to Chromium's `//third_party/.gitignore`, so that it won't show up as untracked files when you run `git status` on the main @@ -184,14 +184,15 @@ ### Checking in the code directly -If you are checking in a snapshot, please describe the source in the -README.chromium file, described below. For security reasons, please retrieve -the code as securely as you can, using HTTPS and GPG signatures if available. +If you are checking in a snapshot, you should follow the [standard directory structure](#standard-dep-structure). +For security reasons, please retrieve the code as securely as you can, using +HTTPS and GPG signatures if available. If retrieving a tarball, please do not check the tarball itself into the tree, but do list the source and the SHA-512 hash (for verification) in the README.chromium and Change List. The SHA-512 hash can be computed via `sha512sum` or `openssl dgst -sha512`. If retrieving from a git -repository, please list the revision that the code was pulled from. +repository, please list the upstream URL and revision that the code was pulled +from. If you are checking the files in directly, you do not need an entry in DEPS and do not need to modify `//third_party/.gitignore`. @@ -203,6 +204,52 @@ See [Moving large files to Google Storage](https://goto.google.com/checking-in-large-files) +## Standard directory structure for dependencies {standard-dep-structure} + +Regardless of how you import a dependency, you should use the following +directory structure. This folder layout enforces separation between first and +third party code, making it easier to manage updates and dependency hygiene +long term. + +Any first party code or files you need for dependency management or +interoperability should be added to the top level dependency directory, and the +dependency source imported into the child src directory. + +**Recommended directory structure:** +``` +❯ //third_party/<dependency-name> +├── BUILD.gn +├── README.chromium +├── OWNERS +├── src <-- import third party code here +│ ├── LICENSE +│ ├── a.h +│ └── b.cc +``` + +**What constitutes a dependency:** + +* A dependency should be sourced from a single upstream location. Putting code + from multiple upstream sources in a single `//third_party` directory makes it + difficult to reason about the origin of files and perform automated updates. +* If your dependency has its own vendored dependencies, it's not necessary to + split these into additional directories. + +**Formatting:** + +Do not reformat or apply Chromium-style formatting to any code within the +dependency `src` directory. Maintaining the original formatting is essential +for generating clean diffs against upstream versions. This simplifies +reviewing upstream changes, applying security patches, and performing updates. + +If you experience issues with submitting a CL due to Chromium formatting +requirements which need to be disabled, or you need to format first party code +in your top level dependency folder, you can add a language appropriate +formatting config (e.g [.clang-format-ignore](https://clang.llvm.org/docs/ClangFormat.html#clang-format-ignore)) +to your top level dependency directory. Ensure it does not format the third +party code. + + ## Document the code's context ### Add OWNERS @@ -279,9 +326,18 @@ **Multiple packages** -Each package should have its own README.chromium. However, if this is not -possible and the information for multiple packages must be placed in a single -README.chromium, use the below line to separate the data for each package: +Adding multiple packages in a single third party directory is not recommended, +because it does not follow the best practices for [third party dependency structure](#standard-dep-structure) +and complicates vulnerability scanning. + +Each dependency should have its own third party directory with a few very +limited exceptions: +* A package manager is used to manage dependencies in the directory via a lockfile. +* Your third party dependency has its own vendored transitive dependencies + +If your dependency is covered by one of the above exceptions and the information +for multiple packages must be placed in a single README.chromium, use the below +line to separate the data for each package: ``` -------------------- DEPENDENCY DIVIDER -------------------- ```
diff --git a/docs/fuchsia/telemetry.md b/docs/fuchsia/telemetry.md index 74b7f42..7ab4d3a 100644 --- a/docs/fuchsia/telemetry.md +++ b/docs/fuchsia/telemetry.md
@@ -5,7 +5,7 @@ General instruction on running and debugging benchmarks can be found in the [`tools/perf/README.md`](../../tools/perf/README.md). -Fuchsia uses [web_engine_shell](../../fuchsia_web/webengine/test/README.md) to run +Fuchsia uses [web_engine_shell](../../fuchsia_web/shell/README.md) to run integration tests. Be sure to build any components you wish to deploy on your device, along with `web_engine_shell`.
diff --git a/extensions/strings/BUILD.gn b/extensions/strings/BUILD.gn index e456ee9..6bd619d 100644 --- a/extensions/strings/BUILD.gn +++ b/extensions/strings/BUILD.gn
@@ -8,10 +8,8 @@ assert(enable_extensions_core) -grit("strings") { +grit_strings("strings") { source = "extensions_strings.grd" - outputs = - [ "grit/extensions_strings.h" ] + - process_file_template(all_chrome_locales, - [ "extensions_strings_{{source_name_part}}.pak" ]) + outputs = [ "grit/extensions_strings.h" ] + output_prefix = "extensions_strings_" }
diff --git a/fuchsia_web/BUILD.gn b/fuchsia_web/BUILD.gn index cb8bca6..d0acd7d 100644 --- a/fuchsia_web/BUILD.gn +++ b/fuchsia_web/BUILD.gn
@@ -15,5 +15,6 @@ "runners:cast_runner", "shell", "webengine:web_engine", + "//build/fuchsia/test:component_storage_test", ] }
diff --git a/fuchsia_web/webengine/browser/web_engine_content_browser_client.cc b/fuchsia_web/webengine/browser/web_engine_content_browser_client.cc index 6f1812c..13cbc42 100644 --- a/fuchsia_web/webengine/browser/web_engine_content_browser_client.cc +++ b/fuchsia_web/webengine/browser/web_engine_content_browser_client.cc
@@ -326,7 +326,7 @@ if (explicit_sites_filter_error_page) { registry.AddThrottle(std::make_unique<SafeSitesNavigationThrottle>( - &navigation_handle, + registry, navigation_handle.GetWebContents()->GetBrowserContext(), *explicit_sites_filter_error_page)); }
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing.h b/gpu/command_buffer/service/shared_image/iosurface_image_backing.h index 3f939ce..0ad7beca 100644 --- a/gpu/command_buffer/service/shared_image/iosurface_image_backing.h +++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing.h
@@ -19,6 +19,8 @@ #include "ui/gl/gl_fence.h" #include "ui/gl/gl_surface.h" +@protocol MTLDevice; + namespace gl { class ScopedEGLSurfaceIOSurface; } // namespace gl @@ -141,15 +143,21 @@ void AddWGPUDeviceWithPendingCommands(wgpu::Device device) EXCLUSIVE_LOCKS_REQUIRED(lock_); - void WaitForDawnCommandsToBeScheduled(const wgpu::Device& device_to_exclude) - EXCLUSIVE_LOCKS_REQUIRED(lock_); void AddEGLDisplayWithPendingCommands(gl::GLDisplayEGL* display) EXCLUSIVE_LOCKS_REQUIRED(lock_); - void WaitForANGLECommandsToBeScheduled() EXCLUSIVE_LOCKS_REQUIRED(lock_); void ClearEGLDisplaysWithPendingCommands(gl::GLDisplayEGL* display_to_keep) EXCLUSIVE_LOCKS_REQUIRED(lock_); + // Wait for commands to be scheduled on every WGPUDevice or EGLDisplay that's + // pending a flush except those using the same MTLDevice as `waiting_device`. + // This is needed in two cases: 1) handing off the IOSurface to CoreAnimation + // since there's no other synchronization mechanism, and 2) accessing the + // IOSurface on different GPUs/MTLDevices since there could be shadow copies + // performed by the kernel. + void WaitForCommandsToBeScheduled(id<MTLDevice> waiting_device = nil) + EXCLUSIVE_LOCKS_REQUIRED(lock_); + private: class GLTextureIRepresentation; class DawnRepresentation;
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm b/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm index 577e739..62110a3 100644 --- a/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm +++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm
@@ -10,8 +10,10 @@ #include "gpu/command_buffer/service/shared_image/iosurface_image_backing.h" #include <EGL/egl.h> +#include <EGL/eglext.h> #import <Metal/Metal.h> #include <dawn/native/MetalBackend.h> +#include <dawn/webgpu_cpp.h> #include "base/apple/scoped_cftyperef.h" #include "base/apple/scoped_nsobject.h" @@ -32,6 +34,7 @@ #include "gpu/command_buffer/service/shared_image/skia_graphite_dawn_image_representation.h" #include "gpu/command_buffer/service/skia_utils.h" #include "gpu/config/gpu_finch_features.h" +#include "third_party/angle/include/EGL/eglext_angle.h" #include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/include/gpu/ganesh/GrContextThreadSafeProxy.h" #include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h" @@ -186,6 +189,24 @@ } #endif +id<MTLDevice> QueryMetalDeviceFromANGLE(gl::GLDisplayEGL* display) { + id<MTLDevice> metal_device = nil; + if (gl::GetANGLEImplementation() == gl::ANGLEImplementation::kMetal) { + EGLAttrib angle_device_attrib = 0; + if (eglQueryDisplayAttribEXT(display->GetDisplay(), EGL_DEVICE_EXT, + &angle_device_attrib)) { + EGLDeviceEXT angle_device = + reinterpret_cast<EGLDeviceEXT>(angle_device_attrib); + EGLAttrib metal_device_attrib = 0; + if (eglQueryDeviceAttribEXT(angle_device, EGL_METAL_DEVICE_ANGLE, + &metal_device_attrib)) { + metal_device = (__bridge id)(void*)metal_device_attrib; + } + } + } + return metal_device; +} + class BackpressureMetalSharedEventImpl final : public BackpressureMetalSharedEvent { public: @@ -697,13 +718,8 @@ return false; } - // This will transition the image to be accessed by CoreAnimation. So - // WaitForANGLECommandsToBeScheduled() call is required. - iosurface_backing->WaitForANGLECommandsToBeScheduled(); - - // Likewise do the same for Dawn's commands. - iosurface_backing->WaitForDawnCommandsToBeScheduled( - /*device_to_exclude=*/nullptr); + // This will transition the image to be accessed by CoreAnimation. + iosurface_backing->WaitForCommandsToBeScheduled(); gl::GLContext* context = gl::GLContext::GetCurrent(); if (context) { @@ -808,17 +824,6 @@ return {}; } - // IOSurface might be written on a different GPU. We need to wait for - // previous Dawn and ANGLE commands to be scheduled first. - // Note: we don't need to wait for the commands from the same wgpu::Device to - // be scheduled, but we do need it on different devices since they could wrap - // the same IOSurface in different MTLTextures and the kernel needs to be told - // about the pending update to the IOSurface before we use it on another Metal - // command queue and the way to do that is waitUntilScheduled. - iosurface_backing->WaitForANGLECommandsToBeScheduled(); - iosurface_backing->WaitForDawnCommandsToBeScheduled( - /*device_to_exclude=*/device_); - usage_ = wgpu_texture_usage; internal_usage_ = internal_usage; @@ -846,6 +851,11 @@ return texture_; } + // IOSurface might be written on a different GPU. We need to wait for previous + // Dawn and ANGLE commands to be scheduled first. + iosurface_backing->WaitForCommandsToBeScheduled( + dawn::native::metal::GetMTLDevice(device_.Get())); + bool is_cleared = iosurface_backing->IsClearedInternal(); wgpu::SharedTextureMemoryBeginAccessDescriptor begin_access_desc = {}; begin_access_desc.initialized = is_cleared; @@ -857,26 +867,20 @@ std::vector<wgpu::SharedFence> shared_fences; std::vector<uint64_t> signaled_values; - // Synchronize with all of the MTLSharedEvents that have been - // stored in the backing as a consequence of earlier BeginAccess/ - // EndAccess calls against other representations. - if (gl::GetANGLEImplementation() == gl::ANGLEImplementation::kMetal) { - // Not possible to reach this with any other type of backing. - DCHECK_EQ(backing()->GetType(), SharedImageBackingType::kIOSurface); + // Synchronize with all of the MTLSharedEvents that have been stored in the + // backing as a consequence of earlier BeginAccess/EndAccess calls against + // other representations. + iosurface_backing->ProcessSharedEventsForBeginAccess( + readonly, [&](id<MTLSharedEvent> shared_event, uint64_t signaled_value) { + wgpu::SharedFenceMTLSharedEventDescriptor shared_event_desc; + shared_event_desc.sharedEvent = shared_event; - iosurface_backing->ProcessSharedEventsForBeginAccess( - readonly, - [&](id<MTLSharedEvent> shared_event, uint64_t signaled_value) { - wgpu::SharedFenceMTLSharedEventDescriptor shared_event_desc; - shared_event_desc.sharedEvent = shared_event; + wgpu::SharedFenceDescriptor fence_desc; + fence_desc.nextInChain = &shared_event_desc; - wgpu::SharedFenceDescriptor fence_desc; - fence_desc.nextInChain = &shared_event_desc; - - shared_fences.push_back(device_.ImportSharedFence(&fence_desc)); - signaled_values.push_back(signaled_value); - }); - } + shared_fences.push_back(device_.ImportSharedFence(&fence_desc)); + signaled_values.push_back(signaled_value); + }); // Populate `begin_access_desc` with the fence data. CHECK(shared_fences.size() == signaled_values.size()); @@ -1116,8 +1120,7 @@ CHECK_LE(pixmaps.size(), 3u); // Make sure any pending ANGLE EGLDisplays and Dawn devices are flushed. - WaitForANGLECommandsToBeScheduled(); - WaitForDawnCommandsToBeScheduled(/*device_to_exclude=*/nullptr); + WaitForCommandsToBeScheduled(); ScopedIOSurfaceLock io_surface_lock(io_surface_.get(), /*options=*/0); @@ -1168,8 +1171,7 @@ CHECK_LE(pixmaps.size(), 3u); // Make sure any pending ANGLE EGLDisplays and Dawn devices are flushed. - WaitForANGLECommandsToBeScheduled(); - WaitForDawnCommandsToBeScheduled(/*device_to_exclude=*/nullptr); + WaitForCommandsToBeScheduled(); ScopedIOSurfaceLock io_surface_lock(io_surface_.get(), /*options=*/0); @@ -1386,23 +1388,38 @@ wgpu_devices_pending_flush_.insert(std::move(device)); } -void IOSurfaceImageBacking::WaitForDawnCommandsToBeScheduled( - const wgpu::Device& device_to_exclude) { +void IOSurfaceImageBacking::WaitForCommandsToBeScheduled( + id<MTLDevice> waiting_device) { AssertLockAcquired(); - TRACE_EVENT0("gpu", - "IOSurfaceImageBacking::WaitForDawnCommandsToBeScheduled"); - bool excluded_device_was_pending_flush = false; + TRACE_EVENT0("gpu", "IOSurfaceImageBacking::WaitForCommandsToBeScheduled"); + + std::vector<wgpu::Device> wgpu_devices_to_keep; for (const auto& device : std::move(wgpu_devices_pending_flush_)) { - if (device.Get() == device_to_exclude.Get()) { - excluded_device_was_pending_flush = true; + // Only Metal backed devices are added to `wgpu_devices_pending_flush_`. + id<MTLDevice> mtl_device = dawn::native::metal::GetMTLDevice(device.Get()); + if (mtl_device && mtl_device == waiting_device) { + wgpu_devices_to_keep.push_back(device); continue; } + TRACE_EVENT0("gpu", + "IOSurfaceImageBacking::WaitForCommandsToBeScheduled::Dawn"); dawn::native::metal::WaitForCommandsToBeScheduled(device.Get()); } - if (excluded_device_was_pending_flush) { - // This device wasn't flushed, so we need to add it to the list again. - wgpu_devices_pending_flush_.insert(device_to_exclude); + wgpu_devices_pending_flush_ = std::move(wgpu_devices_to_keep); + + std::vector<gl::GLDisplayEGL*> egl_displays_to_keep; + for (auto* display : std::move(egl_displays_pending_flush_)) { + // Always flush work for any ANGLE-OpenGL EGLDisplays. + if (gl::GetANGLEImplementation() == gl::ANGLEImplementation::kMetal && + QueryMetalDeviceFromANGLE(display) == waiting_device) { + egl_displays_to_keep.push_back(display); + continue; + } + TRACE_EVENT0("gpu", + "IOSurfaceImageBacking::WaitForCommandsToBeScheduled::ANGLE"); + eglWaitUntilWorkScheduledANGLE(display->GetDisplay()); } + egl_displays_pending_flush_ = std::move(egl_displays_to_keep); } void IOSurfaceImageBacking::AddEGLDisplayWithPendingCommands( @@ -1411,16 +1428,6 @@ egl_displays_pending_flush_.insert(display); } -void IOSurfaceImageBacking::WaitForANGLECommandsToBeScheduled() { - AssertLockAcquired(); - TRACE_EVENT0("gpu", - "IOSurfaceImageBacking::WaitForANGLECommandsToBeScheduled"); - - for (auto* display : std::move(egl_displays_pending_flush_)) { - eglWaitUntilWorkScheduledANGLE(display->GetDisplay()); - } -} - void IOSurfaceImageBacking::ClearEGLDisplaysWithPendingCommands( gl::GLDisplayEGL* display_to_keep) { AssertLockAcquired(); @@ -1742,16 +1749,16 @@ CHECK(display); CHECK_EQ(display->GetDisplay(), egl_state->egl_display_); - // IOSurface might be written on a different queue. So we have to wait for the - // previous Dawn and ANGLE commands to be scheduled first so that the kernel - // knows about the pending update to the IOSurface. - WaitForDawnCommandsToBeScheduled(/*device_to_exclude=*/nullptr); - - // Note that we don't need to call WaitForANGLECommandsToBeScheduled for other + // Note that we don't need to call WaitForCommandsToBeScheduled for other // EGLDisplays because it is already done when the previous GL context is made // uncurrent. We can simply remove the other EGLDisplays from the list. ClearEGLDisplaysWithPendingCommands(/*display_to_keep=*/display); + // IOSurface might be written on a different queue. So we have to wait for the + // previous Dawn and ANGLE commands to be scheduled first so that the kernel + // knows about the pending update to the IOSurface. + WaitForCommandsToBeScheduled(QueryMetalDeviceFromANGLE(display)); + if (gl::GetANGLEImplementation() == gl::ANGLEImplementation::kMetal) { // If this image could potentially be shared with another Metal device, // it's necessary to synchronize between the two devices. If any Metal @@ -1853,7 +1860,9 @@ CHECK(display); CHECK_EQ(display->GetDisplay(), egl_state->egl_display_); - if (gl::GetANGLEImplementation() == gl::ANGLEImplementation::kMetal) { + const bool is_angle_metal = + gl::GetANGLEImplementation() == gl::ANGLEImplementation::kMetal; + if (is_angle_metal) { id<MTLSharedEvent> shared_event = nil; uint64_t signal_value = 0; if (display->CreateMetalSharedEvent(&shared_event, &signal_value)) { @@ -1885,10 +1894,18 @@ // serialized with respect to reads (so that the end of a write always // triggers a release and copy). By design, IOSurfaceImageBackingFactory // enforces this property for this use case. + // + // For ANGLE Metal, we need to rebind the texture for two reasons: + // 1) ReleaseTexImage flushes the command buffer which contains the shared + // event signal above, otherwise the shared event might never be signaled + // since we skip calling eglWaitUntilWorkScheduledANGLE in single GPU case. + // 2) BindTexImage adds a synchronization dependency on the command buffer + // which contains the shared event wait before the next ANGLE access. + // Otherwise, ANGLE might skip waiting on the command buffer and hence the + // shared event and do a CPU readback from the IOSurface in some cases. const bool is_swangle = gl::GetANGLEImplementation() == gl::ANGLEImplementation::kSwiftShader; - - if (is_swangle && egl_state->num_ongoing_accesses_ == 0) { + if ((is_swangle || is_angle_metal) && egl_state->num_ongoing_accesses_ == 0) { CHECK_EQ(static_cast<int>(egl_state->gl_textures_.size()), format().NumberOfPlanes()); CHECK_EQ(static_cast<int>(egl_state->egl_surfaces_.size()),
diff --git a/headless/lib/browser/headless_content_browser_client.cc b/headless/lib/browser/headless_content_browser_client.cc index 0865a115..bf1cebd 100644 --- a/headless/lib/browser/headless_content_browser_client.cc +++ b/headless/lib/browser/headless_content_browser_client.cc
@@ -460,7 +460,7 @@ content::NavigationHandle& handle = registry.GetNavigationHandle(); if (browser_->GetPrefs()) { registry.AddThrottle(std::make_unique<PolicyBlocklistNavigationThrottle>( - &handle, handle.GetWebContents()->GetBrowserContext())); + registry, handle.GetWebContents()->GetBrowserContext())); } } #endif // defined(HEADLESS_USE_POLICY)
diff --git "a/infra/config/generated/builders/ci/Mac Builder \050dbg\051/targets/chromium.mac.json" "b/infra/config/generated/builders/ci/Mac Builder \050dbg\051/targets/chromium.mac.json" index cdccbe07..556b0765 100644 --- "a/infra/config/generated/builders/ci/Mac Builder \050dbg\051/targets/chromium.mac.json" +++ "b/infra/config/generated/builders/ci/Mac Builder \050dbg\051/targets/chromium.mac.json"
@@ -182,25 +182,6 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/mac.mac-rel.browser_tests.filter" - ], - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "browser_tests", - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Mac-15" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 20 - }, - "test": "browser_tests", - "test_id_prefix": "ninja://chrome/test:browser_tests/" - }, - { - "args": [ "--gtest_filter=-*UsingRealWebcam*" ], "merge": {
diff --git a/infra/config/generated/builders/ci/ToTFuchsia x64/targets/chromium.clang.json b/infra/config/generated/builders/ci/ToTFuchsia x64/targets/chromium.clang.json index 0fbeee8a..938bccd 100644 --- a/infra/config/generated/builders/ci/ToTFuchsia x64/targets/chromium.clang.json +++ b/infra/config/generated/builders/ci/ToTFuchsia x64/targets/chromium.clang.json
@@ -106,6 +106,21 @@ }, "test": "blink_wpt_tests", "test_id_prefix": "ninja://:blink_wpt_tests/" + }, + { + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "component_storage_test", + "swarming": { + "dimensions": { + "kvm": "1", + "os": "Ubuntu-22.04" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "component_storage_test", + "test_id_prefix": "ninja://build/fuchsia/test:component_storage_test/" } ] }
diff --git a/infra/config/generated/builders/ci/fuchsia-fyi-arm64-dbg/targets/chromium.fuchsia.fyi.json b/infra/config/generated/builders/ci/fuchsia-fyi-arm64-dbg/targets/chromium.fuchsia.fyi.json index 0d2e098e4..ab226f82 100644 --- a/infra/config/generated/builders/ci/fuchsia-fyi-arm64-dbg/targets/chromium.fuchsia.fyi.json +++ b/infra/config/generated/builders/ci/fuchsia-fyi-arm64-dbg/targets/chromium.fuchsia.fyi.json
@@ -1418,6 +1418,26 @@ }, "test": "angle_unittests", "test_id_prefix": "ninja://third_party/angle/src/tests:angle_unittests/" + }, + { + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "component_storage_test", + "resultdb": { + "enable": true, + "inv_extended_properties_dir": "${ISOLATED_OUTDIR}/invocations" + }, + "swarming": { + "dimensions": { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-22.04|Ubuntu-20.04" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "component_storage_test", + "test_id_prefix": "ninja://build/fuchsia/test:component_storage_test/" } ] }
diff --git a/infra/config/generated/builders/ci/fuchsia-fyi-x64-asan/targets/chromium.fuchsia.fyi.json b/infra/config/generated/builders/ci/fuchsia-fyi-x64-asan/targets/chromium.fuchsia.fyi.json index 77d7168..4787c7c 100644 --- a/infra/config/generated/builders/ci/fuchsia-fyi-x64-asan/targets/chromium.fuchsia.fyi.json +++ b/infra/config/generated/builders/ci/fuchsia-fyi-x64-asan/targets/chromium.fuchsia.fyi.json
@@ -1383,6 +1383,25 @@ "test_id_prefix": "ninja://:blink_wpt_tests/" }, { + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "component_storage_test", + "resultdb": { + "enable": true, + "inv_extended_properties_dir": "${ISOLATED_OUTDIR}/invocations" + }, + "swarming": { + "dimensions": { + "kvm": "1", + "os": "Ubuntu-22.04" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "component_storage_test", + "test_id_prefix": "ninja://build/fuchsia/test:component_storage_test/" + }, + { "args": [ "context_lost", "--show-stdout",
diff --git a/infra/config/generated/builders/ci/fuchsia-netstack2-x64-cast-receiver-rel/targets/chromium.fuchsia.fyi.json b/infra/config/generated/builders/ci/fuchsia-netstack2-x64-cast-receiver-rel/targets/chromium.fuchsia.fyi.json index 6a20bac..a940e69 100644 --- a/infra/config/generated/builders/ci/fuchsia-netstack2-x64-cast-receiver-rel/targets/chromium.fuchsia.fyi.json +++ b/infra/config/generated/builders/ci/fuchsia-netstack2-x64-cast-receiver-rel/targets/chromium.fuchsia.fyi.json
@@ -1721,6 +1721,30 @@ }, { "args": [ + "--device-spec=x64-emu-large", + "--product=terminal_with_netstack2.x64" + ], + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "component_storage_test", + "resultdb": { + "enable": true, + "inv_extended_properties_dir": "${ISOLATED_OUTDIR}/invocations" + }, + "swarming": { + "dimensions": { + "kvm": "1", + "os": "Ubuntu-22.04" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "component_storage_test", + "test_id_prefix": "ninja://build/fuchsia/test:component_storage_test/" + }, + { + "args": [ "context_lost", "--show-stdout", "--browser=web-engine-shell",
diff --git a/infra/config/generated/builders/ci/fuchsia-x64-cast-receiver-dbg/targets/chromium.fuchsia.json b/infra/config/generated/builders/ci/fuchsia-x64-cast-receiver-dbg/targets/chromium.fuchsia.json index 2ea880b..f001bb4c 100644 --- a/infra/config/generated/builders/ci/fuchsia-x64-cast-receiver-dbg/targets/chromium.fuchsia.json +++ b/infra/config/generated/builders/ci/fuchsia-x64-cast-receiver-dbg/targets/chromium.fuchsia.json
@@ -1465,6 +1465,26 @@ "test_id_prefix": "ninja://:blink_wpt_tests/" }, { + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "component_storage_test", + "resultdb": { + "enable": true, + "inv_extended_properties_dir": "${ISOLATED_OUTDIR}/invocations" + }, + "swarming": { + "dimensions": { + "kvm": "1", + "os": "Ubuntu-22.04" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "component_storage_test", + "test_id_prefix": "ninja://build/fuchsia/test:component_storage_test/" + }, + { "args": [ "context_lost", "--show-stdout",
diff --git a/infra/config/generated/builders/ci/fuchsia-x64-cast-receiver-rel/targets/chromium.fuchsia.json b/infra/config/generated/builders/ci/fuchsia-x64-cast-receiver-rel/targets/chromium.fuchsia.json index 65c8acf..b1722ed 100644 --- a/infra/config/generated/builders/ci/fuchsia-x64-cast-receiver-rel/targets/chromium.fuchsia.json +++ b/infra/config/generated/builders/ci/fuchsia-x64-cast-receiver-rel/targets/chromium.fuchsia.json
@@ -1655,6 +1655,29 @@ }, { "args": [ + "--device-spec=x64-emu-large" + ], + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "component_storage_test", + "resultdb": { + "enable": true, + "inv_extended_properties_dir": "${ISOLATED_OUTDIR}/invocations" + }, + "swarming": { + "dimensions": { + "kvm": "1", + "os": "Ubuntu-22.04" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "component_storage_test", + "test_id_prefix": "ninja://build/fuchsia/test:component_storage_test/" + }, + { + "args": [ "context_lost", "--show-stdout", "--browser=web-engine-shell",
diff --git a/infra/config/generated/builders/ci/fuchsia-x64-perf-cast-receiver-rel/targets/chromium.fuchsia.fyi.json b/infra/config/generated/builders/ci/fuchsia-x64-perf-cast-receiver-rel/targets/chromium.fuchsia.fyi.json index 8597731..a4810f5 100644 --- a/infra/config/generated/builders/ci/fuchsia-x64-perf-cast-receiver-rel/targets/chromium.fuchsia.fyi.json +++ b/infra/config/generated/builders/ci/fuchsia-x64-perf-cast-receiver-rel/targets/chromium.fuchsia.fyi.json
@@ -1652,6 +1652,29 @@ }, { "args": [ + "--device-spec=x64-emu-large" + ], + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "component_storage_test", + "resultdb": { + "enable": true, + "inv_extended_properties_dir": "${ISOLATED_OUTDIR}/invocations" + }, + "swarming": { + "dimensions": { + "kvm": "1", + "os": "Ubuntu-22.04" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "component_storage_test", + "test_id_prefix": "ninja://build/fuchsia/test:component_storage_test/" + }, + { + "args": [ "context_lost", "--show-stdout", "--browser=web-engine-shell",
diff --git a/infra/config/generated/builders/ci/mac15-tests-dbg/targets/chromium.mac.json b/infra/config/generated/builders/ci/mac15-tests-dbg/targets/chromium.mac.json index f5f6c1c..94cab17 100644 --- a/infra/config/generated/builders/ci/mac15-tests-dbg/targets/chromium.mac.json +++ b/infra/config/generated/builders/ci/mac15-tests-dbg/targets/chromium.mac.json
@@ -177,25 +177,6 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/mac.mac-rel.browser_tests.filter" - ], - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "browser_tests", - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Mac-15" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 20 - }, - "test": "browser_tests", - "test_id_prefix": "ninja://chrome/test:browser_tests/" - }, - { - "args": [ "--gtest_filter=-*UsingRealWebcam*" ], "merge": {
diff --git a/infra/config/generated/builders/try/fuchsia-fyi-arm64-dbg/targets/chromium.fuchsia.fyi.json b/infra/config/generated/builders/try/fuchsia-fyi-arm64-dbg/targets/chromium.fuchsia.fyi.json index 0d2e098e4..ab226f82 100644 --- a/infra/config/generated/builders/try/fuchsia-fyi-arm64-dbg/targets/chromium.fuchsia.fyi.json +++ b/infra/config/generated/builders/try/fuchsia-fyi-arm64-dbg/targets/chromium.fuchsia.fyi.json
@@ -1418,6 +1418,26 @@ }, "test": "angle_unittests", "test_id_prefix": "ninja://third_party/angle/src/tests:angle_unittests/" + }, + { + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "component_storage_test", + "resultdb": { + "enable": true, + "inv_extended_properties_dir": "${ISOLATED_OUTDIR}/invocations" + }, + "swarming": { + "dimensions": { + "cpu": "arm64", + "inside_docker": "1", + "os": "Ubuntu-22.04|Ubuntu-20.04" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "component_storage_test", + "test_id_prefix": "ninja://build/fuchsia/test:component_storage_test/" } ] }
diff --git a/infra/config/generated/builders/try/fuchsia-fyi-x64-asan/targets/chromium.fuchsia.fyi.json b/infra/config/generated/builders/try/fuchsia-fyi-x64-asan/targets/chromium.fuchsia.fyi.json index 77d7168..4787c7c 100644 --- a/infra/config/generated/builders/try/fuchsia-fyi-x64-asan/targets/chromium.fuchsia.fyi.json +++ b/infra/config/generated/builders/try/fuchsia-fyi-x64-asan/targets/chromium.fuchsia.fyi.json
@@ -1383,6 +1383,25 @@ "test_id_prefix": "ninja://:blink_wpt_tests/" }, { + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "component_storage_test", + "resultdb": { + "enable": true, + "inv_extended_properties_dir": "${ISOLATED_OUTDIR}/invocations" + }, + "swarming": { + "dimensions": { + "kvm": "1", + "os": "Ubuntu-22.04" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "component_storage_test", + "test_id_prefix": "ninja://build/fuchsia/test:component_storage_test/" + }, + { "args": [ "context_lost", "--show-stdout",
diff --git a/infra/config/generated/builders/try/fuchsia-netstack2-x64-cast-receiver-rel/targets/chromium.fuchsia.fyi.json b/infra/config/generated/builders/try/fuchsia-netstack2-x64-cast-receiver-rel/targets/chromium.fuchsia.fyi.json index 6a20bac..a940e69 100644 --- a/infra/config/generated/builders/try/fuchsia-netstack2-x64-cast-receiver-rel/targets/chromium.fuchsia.fyi.json +++ b/infra/config/generated/builders/try/fuchsia-netstack2-x64-cast-receiver-rel/targets/chromium.fuchsia.fyi.json
@@ -1721,6 +1721,30 @@ }, { "args": [ + "--device-spec=x64-emu-large", + "--product=terminal_with_netstack2.x64" + ], + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "component_storage_test", + "resultdb": { + "enable": true, + "inv_extended_properties_dir": "${ISOLATED_OUTDIR}/invocations" + }, + "swarming": { + "dimensions": { + "kvm": "1", + "os": "Ubuntu-22.04" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "component_storage_test", + "test_id_prefix": "ninja://build/fuchsia/test:component_storage_test/" + }, + { + "args": [ "context_lost", "--show-stdout", "--browser=web-engine-shell",
diff --git a/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-dbg-compile/targets/chromium.fuchsia.json b/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-dbg-compile/targets/chromium.fuchsia.json index 2ea880b..f001bb4c 100644 --- a/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-dbg-compile/targets/chromium.fuchsia.json +++ b/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-dbg-compile/targets/chromium.fuchsia.json
@@ -1465,6 +1465,26 @@ "test_id_prefix": "ninja://:blink_wpt_tests/" }, { + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "component_storage_test", + "resultdb": { + "enable": true, + "inv_extended_properties_dir": "${ISOLATED_OUTDIR}/invocations" + }, + "swarming": { + "dimensions": { + "kvm": "1", + "os": "Ubuntu-22.04" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "component_storage_test", + "test_id_prefix": "ninja://build/fuchsia/test:component_storage_test/" + }, + { "args": [ "context_lost", "--show-stdout",
diff --git a/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-dbg/targets/chromium.fuchsia.json b/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-dbg/targets/chromium.fuchsia.json index 2ea880b..f001bb4c 100644 --- a/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-dbg/targets/chromium.fuchsia.json +++ b/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-dbg/targets/chromium.fuchsia.json
@@ -1465,6 +1465,26 @@ "test_id_prefix": "ninja://:blink_wpt_tests/" }, { + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "component_storage_test", + "resultdb": { + "enable": true, + "inv_extended_properties_dir": "${ISOLATED_OUTDIR}/invocations" + }, + "swarming": { + "dimensions": { + "kvm": "1", + "os": "Ubuntu-22.04" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "component_storage_test", + "test_id_prefix": "ninja://build/fuchsia/test:component_storage_test/" + }, + { "args": [ "context_lost", "--show-stdout",
diff --git a/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-rel/targets/chromium.fuchsia.json b/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-rel/targets/chromium.fuchsia.json index 65c8acf..b1722ed 100644 --- a/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-rel/targets/chromium.fuchsia.json +++ b/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-rel/targets/chromium.fuchsia.json
@@ -1655,6 +1655,29 @@ }, { "args": [ + "--device-spec=x64-emu-large" + ], + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "component_storage_test", + "resultdb": { + "enable": true, + "inv_extended_properties_dir": "${ISOLATED_OUTDIR}/invocations" + }, + "swarming": { + "dimensions": { + "kvm": "1", + "os": "Ubuntu-22.04" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "component_storage_test", + "test_id_prefix": "ninja://build/fuchsia/test:component_storage_test/" + }, + { + "args": [ "context_lost", "--show-stdout", "--browser=web-engine-shell",
diff --git a/infra/config/generated/builders/try/fuchsia-x64-perf-cast-receiver-rel/targets/chromium.fuchsia.fyi.json b/infra/config/generated/builders/try/fuchsia-x64-perf-cast-receiver-rel/targets/chromium.fuchsia.fyi.json index 8597731..a4810f5 100644 --- a/infra/config/generated/builders/try/fuchsia-x64-perf-cast-receiver-rel/targets/chromium.fuchsia.fyi.json +++ b/infra/config/generated/builders/try/fuchsia-x64-perf-cast-receiver-rel/targets/chromium.fuchsia.fyi.json
@@ -1652,6 +1652,29 @@ }, { "args": [ + "--device-spec=x64-emu-large" + ], + "isolate_profile_data": true, + "merge": { + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "component_storage_test", + "resultdb": { + "enable": true, + "inv_extended_properties_dir": "${ISOLATED_OUTDIR}/invocations" + }, + "swarming": { + "dimensions": { + "kvm": "1", + "os": "Ubuntu-22.04" + }, + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "component_storage_test", + "test_id_prefix": "ninja://build/fuchsia/test:component_storage_test/" + }, + { + "args": [ "context_lost", "--show-stdout", "--browser=web-engine-shell",
diff --git a/infra/config/generated/builders/try/mac_chromium_compile_dbg_ng/targets/chromium.mac.json b/infra/config/generated/builders/try/mac_chromium_compile_dbg_ng/targets/chromium.mac.json index cdccbe07..556b0765 100644 --- a/infra/config/generated/builders/try/mac_chromium_compile_dbg_ng/targets/chromium.mac.json +++ b/infra/config/generated/builders/try/mac_chromium_compile_dbg_ng/targets/chromium.mac.json
@@ -182,25 +182,6 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/mac.mac-rel.browser_tests.filter" - ], - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "browser_tests", - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Mac-15" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 20 - }, - "test": "browser_tests", - "test_id_prefix": "ninja://chrome/test:browser_tests/" - }, - { - "args": [ "--gtest_filter=-*UsingRealWebcam*" ], "merge": {
diff --git a/infra/config/generated/builders/try/mac_chromium_dbg_ng/targets/chromium.mac.json b/infra/config/generated/builders/try/mac_chromium_dbg_ng/targets/chromium.mac.json index cdccbe07..556b0765 100644 --- a/infra/config/generated/builders/try/mac_chromium_dbg_ng/targets/chromium.mac.json +++ b/infra/config/generated/builders/try/mac_chromium_dbg_ng/targets/chromium.mac.json
@@ -182,25 +182,6 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/mac.mac-rel.browser_tests.filter" - ], - "merge": { - "script": "//testing/merge_scripts/standard_gtest_merge.py" - }, - "name": "browser_tests", - "swarming": { - "dimensions": { - "cpu": "x86-64", - "os": "Mac-15" - }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 20 - }, - "test": "browser_tests", - "test_id_prefix": "ninja://chrome/test:browser_tests/" - }, - { - "args": [ "--gtest_filter=-*UsingRealWebcam*" ], "merge": {
diff --git a/infra/config/generated/testing/gn_isolate_map.pyl b/infra/config/generated/testing/gn_isolate_map.pyl index 2d4ff3a..d6553f0 100644 --- a/infra/config/generated/testing/gn_isolate_map.pyl +++ b/infra/config/generated/testing/gn_isolate_map.pyl
@@ -628,6 +628,12 @@ "src/third_party/android_sdk/public/platform-tools/adb", ], }, + "component_storage_test": { + "label": "//build/fuchsia/test:component_storage_test", + "type": "script", + "script": "//build/fuchsia/test/component_storage_test.py", + "skip_usage_check": True, + }, "components/media_router/common/providers/cast/certificate": { "label": "//components/media_router/common/providers/cast/certificate", "type": "additional_compile_target",
diff --git a/infra/config/subprojects/chromium/ci/chromium.mac.star b/infra/config/subprojects/chromium/ci/chromium.mac.star index 6cb9c26..8b6dfd7 100644 --- a/infra/config/subprojects/chromium/ci/chromium.mac.star +++ b/infra/config/subprojects/chromium/ci/chromium.mac.star
@@ -959,13 +959,8 @@ shards = 8, ), ), - "browser_tests": targets.mixin( - args = [ - "--test-launcher-filter-file=../../testing/buildbot/filters/mac.mac-rel.browser_tests.filter", - ], - swarming = targets.swarming( - shards = 20, - ), + "browser_tests": targets.remove( + reason = "https://crbug.com/1406364", ), "content_browsertests": targets.mixin( # https://crbug.com/1279504
diff --git a/infra/config/targets/binaries.star b/infra/config/targets/binaries.star index 7cadf023..a9c18b92 100644 --- a/infra/config/targets/binaries.star +++ b/infra/config/targets/binaries.star
@@ -715,6 +715,13 @@ label = "//components:components_unittests", ) +targets.binaries.script( + name = "component_storage_test", + label = "//build/fuchsia/test:component_storage_test", + script = "//build/fuchsia/test/component_storage_test.py", + skip_usage_check = True, +) + targets.binaries.windowed_test_launcher( name = "compositor_unittests", label = "//ui/compositor:compositor_unittests",
diff --git a/infra/config/targets/bundles.star b/infra/config/targets/bundles.star index a9b4dc1c..0c5a62c1 100644 --- a/infra/config/targets/bundles.star +++ b/infra/config/targets/bundles.star
@@ -3018,6 +3018,7 @@ name = "fuchsia_isolated_scripts", targets = [ "chromium_webkit_isolated_scripts", + "component_storage_test", # TODO(crbug.com/40821367): Enable content_shell_crash_test "gpu_angle_fuchsia_unittests_isolated_scripts", ],
diff --git a/infra/config/targets/tests.star b/infra/config/targets/tests.star index 68e386cf..8793c1c 100644 --- a/infra/config/targets/tests.star +++ b/infra/config/targets/tests.star
@@ -715,6 +715,10 @@ name = "components_unittests", ) +targets.tests.isolated_script_test( + name = "component_storage_test", +) + targets.tests.gtest_test( name = "compositor_unittests", )
diff --git a/internal b/internal index 5de18f0..7a2d2c5a 160000 --- a/internal +++ b/internal
@@ -1 +1 @@ -Subproject commit 5de18f0aacc3865198ffcb45372a83f6b0b9b27b +Subproject commit 7a2d2c5a328e293e0a9849b8d1e17e59d56a3b14
diff --git a/ios/chrome/app/strings/BUILD.gn b/ios/chrome/app/strings/BUILD.gn index 7a9ed667..b4cacc8 100644 --- a/ios/chrome/app/strings/BUILD.gn +++ b/ios/chrome/app/strings/BUILD.gn
@@ -13,20 +13,15 @@ ] } -grit("ios_strings") { +grit_strings("ios_strings") { source = "ios_strings.grd" output_dir = "$root_gen_dir/ios/chrome" outputs = [ "grit/ios_strings.h" ] - foreach(locale, locales_with_pseudolocales) { - outputs += [ "ios_strings_$locale.pak" ] - } + locales = locales_with_pseudolocales } -grit("ios_branded_strings") { +grit_strings("ios_branded_strings") { source = "ios_${branding_path_product}_strings.grd" output_dir = "$root_gen_dir/ios/chrome" outputs = [ "grit/ios_branded_strings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "ios_branded_strings_$locale.pak" ] - } }
diff --git a/ios/chrome/browser/collaboration/model/ios_collaboration_controller_delegate.mm b/ios/chrome/browser/collaboration/model/ios_collaboration_controller_delegate.mm index 19c6c3a8f..a7d31ac 100644 --- a/ios/chrome/browser/collaboration/model/ios_collaboration_controller_delegate.mm +++ b/ios/chrome/browser/collaboration/model/ios_collaboration_controller_delegate.mm
@@ -178,6 +178,10 @@ operation = AuthenticationOperation::kSheetSigninAndHistorySync; break; + case SigninStatus::kSigninDisabled: + // TODO(crbug.com/390153810): Handle the sign in disabled case. + NOTREACHED(); + case SigninStatus::kSignedInPaused: // TODO(crbug.com/390153810): Handle the sign in paused. NOTREACHED();
diff --git a/ios/chrome/browser/home_customization/coordinator/BUILD.gn b/ios/chrome/browser/home_customization/coordinator/BUILD.gn index 6c69e630..fd8c565f 100644 --- a/ios/chrome/browser/home_customization/coordinator/BUILD.gn +++ b/ios/chrome/browser/home_customization/coordinator/BUILD.gn
@@ -4,6 +4,8 @@ source_set("coordinator") { sources = [ + "home_customization_background_color_picker_mediator.h", + "home_customization_background_color_picker_mediator.mm", "home_customization_background_picker_action_sheet_coordinator.h", "home_customization_background_picker_action_sheet_coordinator.mm", "home_customization_coordinator+Testing.h", @@ -32,9 +34,13 @@ "//ios/chrome/browser/shared/model/prefs:pref_names", "//ios/chrome/browser/shared/model/profile", "//ios/chrome/browser/shared/public/features", + "//ios/chrome/browser/shared/ui/util", "//ios/chrome/browser/url_loading/model", "//ios/public/provider/chrome/browser/ui_utils:ui_utils_api", + "//skia", + "//third_party/material_color_utilities", "//ui/base", + "//ui/color/dynamic_color", "//url", ] frameworks = [ "UIKit.framework" ]
diff --git a/ios/chrome/browser/home_customization/coordinator/DEPS b/ios/chrome/browser/home_customization/coordinator/DEPS index 06f22bd..a95c87a 100644 --- a/ios/chrome/browser/home_customization/coordinator/DEPS +++ b/ios/chrome/browser/home_customization/coordinator/DEPS
@@ -3,5 +3,6 @@ "+ios/chrome/browser/url_loading/model", "+ios/chrome/browser/parcel_tracking", "+ios/chrome/browser/content_suggestions/ui_bundled/set_up_list", - "+ios/chrome/browser/ntp/ui_bundled" + "+ios/chrome/browser/ntp/ui_bundled", + "+third_party/material_color_utilities/src/cpp" ]
diff --git a/ios/chrome/browser/home_customization/coordinator/home_customization_background_color_picker_mediator.h b/ios/chrome/browser/home_customization/coordinator/home_customization_background_color_picker_mediator.h new file mode 100644 index 0000000..479541c5 --- /dev/null +++ b/ios/chrome/browser/home_customization/coordinator/home_customization_background_color_picker_mediator.h
@@ -0,0 +1,28 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_HOME_CUSTOMIZATION_COORDINATOR_HOME_CUSTOMIZATION_BACKGROUND_COLOR_PICKER_MEDIATOR_H_ +#define IOS_CHROME_BROWSER_HOME_CUSTOMIZATION_COORDINATOR_HOME_CUSTOMIZATION_BACKGROUND_COLOR_PICKER_MEDIATOR_H_ + +#import <UIKit/UIKit.h> + +#import "ios/chrome/browser/home_customization/ui/home_customization_background_color_picker_mutator.h" +@protocol HomeCustomizationBackgroundColorPickerConsumer; + +// A mediator that generates and configures background color palettes +// for the Home customization screen, and communicates them to a consumer. +@interface HomeCustomizationBackgroundColorPickerMediator + : NSObject <HomeCustomizationBackgroundColorPickerMutator> + +// The consumer that receives the generated color palette configurations. +@property(nonatomic, weak) id<HomeCustomizationBackgroundColorPickerConsumer> + consumer; + +// Generates a predefined set of color palettes and provides them to the +// consumer. +- (void)configureColorPalettes; + +@end + +#endif // IOS_CHROME_BROWSER_HOME_CUSTOMIZATION_COORDINATOR_HOME_CUSTOMIZATION_BACKGROUND_COLOR_PICKER_MEDIATOR_H_
diff --git a/ios/chrome/browser/home_customization/coordinator/home_customization_background_color_picker_mediator.mm b/ios/chrome/browser/home_customization/coordinator/home_customization_background_color_picker_mediator.mm new file mode 100644 index 0000000..66302fe --- /dev/null +++ b/ios/chrome/browser/home_customization/coordinator/home_customization_background_color_picker_mediator.mm
@@ -0,0 +1,119 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/home_customization/coordinator/home_customization_background_color_picker_mediator.h" + +#import <Foundation/Foundation.h> + +#import "ios/chrome/browser/home_customization/ui/home_customization_background_color_picker_consumer.h" +#import "skia/ext/skia_utils_ios.h" +#import "third_party/material_color_utilities/src/cpp/cam/hct.h" +#import "third_party/material_color_utilities/src/cpp/palettes/core.h" +#import "third_party/material_color_utilities/src/cpp/utils/utils.h" +#import "ui/color/dynamic_color/palette_factory.h" + +// Define constants within the namespace +namespace { + +// A block type that provides a dynamic color based on the current trait +// collection. +typedef UIColor* (^DynamicColorProviderBlock)(UITraitCollection* traits); + +// Represents a pair of tone values for a given color tone, +// with separate values for light and dark UI modes. +struct ToneSet { + // The tone value to use in light mode. + int light_mode; + + // The tone value to use in dark mode. + int dark_mode; +}; + +// The tone value used for generating a light variant of the seed color. +const ToneSet kLightTone = { + /*light_mode=*/90, + /*dark_mode=*/30, +}; + +// The tone value used for generating a medium variant of the seed color. +const ToneSet kMediumTone = { + /*light_mode=*/80, + /*dark_mode=*/50, +}; + +// The tone value used for generating a dark variant of the seed color. +const ToneSet kDarkTone = { + /*light_mode=*/40, + /*dark_mode=*/80, +}; + +// Returns a dynamic `UIColor` that adapts to the system's light or dark +// appearance using tones derived from the given `TonalPalette`. +DynamicColorProviderBlock GetDynamicProviderForPrimary( + const ui::TonalPalette& primary, + const ToneSet& toneSet) { + uint32_t lightARGB = primary.get(toneSet.light_mode); + uint32_t darkARGB = primary.get(toneSet.dark_mode); + + return ^UIColor*(UITraitCollection* traits) { + BOOL isDark = (traits.userInterfaceStyle == UIUserInterfaceStyleDark); + return skia::UIColorFromSkColor(isDark ? darkARGB : lightARGB); + }; +} + +} // namespace + +@implementation HomeCustomizationBackgroundColorPickerMediator + +- (void)configureColorPalettes { + NSMutableArray* configs = [NSMutableArray array]; + + // TODO(crbug.com/408243803):Add the UIColor seeds that will be used by Monet + // to generate the color palettes. + [@[ + [UIColor redColor], [UIColor blueColor], [UIColor greenColor], + [UIColor orangeColor], [UIColor purpleColor] + ] enumerateObjectsUsingBlock:^(UIColor* seedColor, NSUInteger index, + BOOL* stop) { + [configs addObject:[self configurationForSeedColor:seedColor]]; + }]; + + [_consumer setColorPaletteConfigurations:configs]; +} + +#pragma mark - Private + +// Creates and returns a color palette configuration from a seed color. +- (HomeCustomizationColorPaletteConfiguration*)configurationForSeedColor: + (UIColor*)seedColor { + HomeCustomizationColorPaletteConfiguration* config = + [[HomeCustomizationColorPaletteConfiguration alloc] init]; + + CGFloat red = 0.0; + CGFloat green = 0.0; + CGFloat blue = 0.0; + CGFloat alpha = 0.0; + [seedColor getRed:&red green:&green blue:&blue alpha:&alpha]; + + SkColor skColor = + SkColorSetARGB(alpha * 255.0, red * 255.0, green * 255.0, blue * 255.0); + + std::unique_ptr<ui::Palette> palette = ui::GeneratePalette( + skColor, ui::ColorProviderKey::SchemeVariant::kTonalSpot); + ui::TonalPalette primary = palette->primary(); + + config.seedColor = seedColor; + config.lightColor = + [UIColor colorWithDynamicProvider:GetDynamicProviderForPrimary( + primary, kLightTone)]; + config.mediumColor = + [UIColor colorWithDynamicProvider:GetDynamicProviderForPrimary( + primary, kMediumTone)]; + config.darkColor = + [UIColor colorWithDynamicProvider:GetDynamicProviderForPrimary( + primary, kDarkTone)]; + return config; +} + +@end
diff --git a/ios/chrome/browser/home_customization/coordinator/home_customization_background_picker_action_sheet_coordinator.mm b/ios/chrome/browser/home_customization/coordinator/home_customization_background_picker_action_sheet_coordinator.mm index 3d6c48d..ac61d8c 100644 --- a/ios/chrome/browser/home_customization/coordinator/home_customization_background_picker_action_sheet_coordinator.mm +++ b/ios/chrome/browser/home_customization/coordinator/home_customization_background_picker_action_sheet_coordinator.mm
@@ -4,12 +4,21 @@ #import "ios/chrome/browser/home_customization/coordinator/home_customization_background_picker_action_sheet_coordinator.h" +#import "ios/chrome/browser/home_customization/coordinator/home_customization_background_color_picker_mediator.h" #import "ios/chrome/browser/home_customization/ui/home_customization_background_color_picker_view_controller.h" #import "ios/chrome/browser/home_customization/ui/home_customization_background_photo_library_picker_view_controller.h" #import "ios/chrome/browser/home_customization/ui/home_customization_background_preset_gallery_picker_view_controller.h" #import "ios/chrome/grit/ios_strings.h" #import "ui/base/l10n/l10n_util_mac.h" +@interface HomeCustomizationBackgroundPickerActionSheetCoordinator () { + // The mediator for the color picker. + HomeCustomizationBackgroundColorPickerMediator* + _backgroundColorPickerMediator; +} + +@end + @implementation HomeCustomizationBackgroundPickerActionSheetCoordinator - (instancetype)initWithBaseViewController:(UIViewController*)viewController @@ -24,6 +33,8 @@ - (void)start { __weak __typeof(self) weakSelf = self; + _backgroundColorPickerMediator = + [[HomeCustomizationBackgroundColorPickerMediator alloc] init]; [self addItemWithTitle: @@ -56,6 +67,7 @@ - (void)stop { [self.baseViewController dismissViewControllerAnimated:YES completion:nil]; + _backgroundColorPickerMediator.consumer = nil; [super stop]; } @@ -63,8 +75,13 @@ // Presents the view controller for picking a solid background color. - (void)presentBackgroundColorPicker { - UIViewController* mainViewController = + HomeCustomizationBackgroundColorPickerViewController* mainViewController = [[HomeCustomizationBackgroundColorPickerViewController alloc] init]; + + mainViewController.mutator = _backgroundColorPickerMediator; + _backgroundColorPickerMediator.consumer = mainViewController; + [_backgroundColorPickerMediator configureColorPalettes]; + mainViewController.modalPresentationStyle = UIModalPresentationFormSheet; UINavigationController* navigationController = [[UINavigationController alloc] initWithRootViewController:mainViewController];
diff --git a/ios/chrome/browser/home_customization/ui/BUILD.gn b/ios/chrome/browser/home_customization/ui/BUILD.gn index 08bf71d3e..9170ff6b 100644 --- a/ios/chrome/browser/home_customization/ui/BUILD.gn +++ b/ios/chrome/browser/home_customization/ui/BUILD.gn
@@ -7,6 +7,8 @@ "home_customization_background_cell+subclassing.h", "home_customization_background_cell.h", "home_customization_background_cell.mm", + "home_customization_background_color_picker_consumer.h", + "home_customization_background_color_picker_mutator.h", "home_customization_background_color_picker_view_controller.h", "home_customization_background_color_picker_view_controller.mm", "home_customization_background_photo_library_picker_view_controller.h", @@ -18,6 +20,8 @@ "home_customization_background_preset_gallery_picker_view_controller.mm", "home_customization_collection_configurator.h", "home_customization_collection_configurator.mm", + "home_customization_color_palette_configuration.h", + "home_customization_color_palette_configuration.mm", "home_customization_discover_consumer.h", "home_customization_discover_view_controller.h", "home_customization_discover_view_controller.mm", @@ -36,6 +40,8 @@ "home_customization_toggle_cell.h", "home_customization_toggle_cell.mm", "home_customization_view_controller_protocol.h", + "home_cutomization_color_palette_cell.h", + "home_cutomization_color_palette_cell.mm", ] deps = [ "//ios/chrome/app/strings:ios_strings",
diff --git a/ios/chrome/browser/home_customization/ui/home_customization_background_color_picker_consumer.h b/ios/chrome/browser/home_customization/ui/home_customization_background_color_picker_consumer.h new file mode 100644 index 0000000..783769b --- /dev/null +++ b/ios/chrome/browser/home_customization/ui/home_customization_background_color_picker_consumer.h
@@ -0,0 +1,22 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_HOME_CUSTOMIZATION_UI_HOME_CUSTOMIZATION_BACKGROUND_COLOR_PICKER_CONSUMER_H_ +#define IOS_CHROME_BROWSER_HOME_CUSTOMIZATION_UI_HOME_CUSTOMIZATION_BACKGROUND_COLOR_PICKER_CONSUMER_H_ + +#import <Foundation/Foundation.h> + +#import "ios/chrome/browser/home_customization/ui/home_customization_color_palette_configuration.h" + +// A consumer protocol that receives updates about background color palettes. +@protocol HomeCustomizationBackgroundColorPickerConsumer + +// Sets the available background color palette configurations, indexed by seed +// color index. +- (void)setColorPaletteConfigurations: + (NSArray<HomeCustomizationColorPaletteConfiguration*>*) + colorPaletteConfigurations; +@end + +#endif // IOS_CHROME_BROWSER_HOME_CUSTOMIZATION_UI_HOME_CUSTOMIZATION_BACKGROUND_COLOR_PICKER_CONSUMER_H_
diff --git a/ios/chrome/browser/home_customization/ui/home_customization_background_color_picker_mutator.h b/ios/chrome/browser/home_customization/ui/home_customization_background_color_picker_mutator.h new file mode 100644 index 0000000..3574a6d --- /dev/null +++ b/ios/chrome/browser/home_customization/ui/home_customization_background_color_picker_mutator.h
@@ -0,0 +1,15 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_HOME_CUSTOMIZATION_UI_HOME_CUSTOMIZATION_BACKGROUND_COLOR_PICKER_MUTATOR_H_ +#define IOS_CHROME_BROWSER_HOME_CUSTOMIZATION_UI_HOME_CUSTOMIZATION_BACKGROUND_COLOR_PICKER_MUTATOR_H_ + +// A mutator protocol used to communicate with the +// `HomeCustomizationBackgroundColorPickerMediator`. +@protocol HomeCustomizationBackgroundColorPickerMutator +// TODO(crbug.com/408243803): Add the mutator implementation when the cells are +// tapped. +@end + +#endif // IOS_CHROME_BROWSER_HOME_CUSTOMIZATION_UI_HOME_CUSTOMIZATION_BACKGROUND_COLOR_PICKER_MUTATOR_H_
diff --git a/ios/chrome/browser/home_customization/ui/home_customization_background_color_picker_view_controller.h b/ios/chrome/browser/home_customization/ui/home_customization_background_color_picker_view_controller.h index 9fba0329..e74a43e 100644 --- a/ios/chrome/browser/home_customization/ui/home_customization_background_color_picker_view_controller.h +++ b/ios/chrome/browser/home_customization/ui/home_customization_background_color_picker_view_controller.h
@@ -7,11 +7,21 @@ #import <UIKit/UIKit.h> +#import "ios/chrome/browser/home_customization/ui/home_customization_background_color_picker_consumer.h" + +@protocol HomeCustomizationBackgroundColorPickerMutator; + // View controller responsible for displaying and managing the background color // picker in the Home customization flow. Implements collection view delegate // and data source to handle color options. @interface HomeCustomizationBackgroundColorPickerViewController - : UIViewController <UICollectionViewDelegate, UICollectionViewDataSource> + : UIViewController <HomeCustomizationBackgroundColorPickerConsumer, + UICollectionViewDataSource> + +// Mutator for communicating with the +// `HomeCustomizationBackgroundColorPickerMediator`. +@property(nonatomic, weak) id<HomeCustomizationBackgroundColorPickerMutator> + mutator; @end
diff --git a/ios/chrome/browser/home_customization/ui/home_customization_background_color_picker_view_controller.mm b/ios/chrome/browser/home_customization/ui/home_customization_background_color_picker_view_controller.mm index c2f486b..8250613 100644 --- a/ios/chrome/browser/home_customization/ui/home_customization_background_color_picker_view_controller.mm +++ b/ios/chrome/browser/home_customization/ui/home_customization_background_color_picker_view_controller.mm
@@ -4,10 +4,45 @@ #import "ios/chrome/browser/home_customization/ui/home_customization_background_color_picker_view_controller.h" +#import "ios/chrome/browser/home_customization/ui/home_customization_color_palette_configuration.h" +#import "ios/chrome/browser/home_customization/ui/home_cutomization_color_palette_cell.h" #import "ios/chrome/browser/home_customization/utils/home_customization_constants.h" #import "ios/chrome/grit/ios_strings.h" #import "ui/base/l10n/l10n_util_mac.h" +// Define constants within the namespace +namespace { +// The width and height of each color palette cell in the collection view. +const CGFloat kColorCellSize = 48.0; + +// The vertical spacing between rows of cells. +const CGFloat kLineSpacing = 28.0; + +// The horizontal spacing between cells in the same row. +const CGFloat kItemSpacing = 20.0; + +// The top padding for the section in the collection view. +const CGFloat kSectionInsetTop = 20.0; + +// The left and right padding for the section in the collection view. +const CGFloat kSectionInsetSides = 27.0; + +// The bottom padding for the section in the collection view. +const CGFloat kSectionInsetBottom = 20.0; +} // namespace + +@interface HomeCustomizationBackgroundColorPickerViewController () { + // An array storing the available color palette configurations, + // ordered by their index in the palette. + NSArray<HomeCustomizationColorPaletteConfiguration*>* + _colorPaletteConfigurations; + + // The `UICollectionViewCellRegistration` for registering and configuring the + // `HomeCustomizationColorPaletteCell` in the collection view. + UICollectionViewCellRegistration* _colorCellRegistration; +} +@end + @implementation HomeCustomizationBackgroundColorPickerViewController - (void)viewDidLoad { @@ -15,6 +50,7 @@ self.title = l10n_util::GetNSStringWithFixup( IDS_IOS_HOME_CUSTOMIZATION_BACKGROUND_PICKER_COLOR_TITLE); + self.view.backgroundColor = [UIColor systemBackgroundColor]; UIBarButtonItem* dismissButton = [[UIBarButtonItem alloc] @@ -28,17 +64,73 @@ self.navigationItem.backBarButtonItem.accessibilityIdentifier = kNavigationBarBackButtonIdentifier; [self.navigationItem setHidesBackButton:YES]; + + UICollectionViewFlowLayout* layout = + [[UICollectionViewFlowLayout alloc] init]; + + layout.itemSize = CGSizeMake(kColorCellSize, kColorCellSize); + layout.minimumLineSpacing = kLineSpacing; + layout.minimumInteritemSpacing = kItemSpacing; + layout.sectionInset = + UIEdgeInsetsMake(kSectionInsetTop, kSectionInsetSides, + kSectionInsetBottom, kSectionInsetSides); + + _colorCellRegistration = [UICollectionViewCellRegistration + registrationWithCellClass:[HomeCustomizationColorPaletteCell class] + configurationHandler:^( + HomeCustomizationColorPaletteCell* cell, NSIndexPath* indexPath, + HomeCustomizationColorPaletteConfiguration* configuration) { + cell.configuration = configuration; + }]; + + UICollectionView* collectionView = + [[UICollectionView alloc] initWithFrame:CGRectZero + collectionViewLayout:layout]; + collectionView.dataSource = self; + + collectionView.translatesAutoresizingMaskIntoConstraints = NO; + [self.view addSubview:collectionView]; + + [NSLayoutConstraint activateConstraints:@[ + [collectionView.topAnchor constraintEqualToAnchor:self.view.topAnchor], + [collectionView.leadingAnchor + constraintEqualToAnchor:self.view.leadingAnchor], + [collectionView.trailingAnchor + constraintEqualToAnchor:self.view.trailingAnchor], + [collectionView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor] + ]]; +} + +#pragma mark - HomeCustomizationBackgroundColorPickerConsumer + +- (void)setColorPaletteConfigurations: + (NSArray<HomeCustomizationColorPaletteConfiguration*>*) + colorPaletteConfigurations { + _colorPaletteConfigurations = colorPaletteConfigurations; } #pragma mark - UICollectionViewDelegate - (NSInteger)collectionView:(UICollectionView*)collectionView numberOfItemsInSection:(NSInteger)section { - return 0; + return _colorPaletteConfigurations.count; } - (UICollectionViewCell*)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(NSIndexPath*)indexPath { + HomeCustomizationColorPaletteConfiguration* configuration = + _colorPaletteConfigurations[indexPath.item]; + + if (indexPath.item >= 0) { + std::size_t index = static_cast<std::size_t>(indexPath.item); + if (index < _colorPaletteConfigurations.count) { + return [collectionView + dequeueConfiguredReusableCellWithRegistration:_colorCellRegistration + forIndexPath:indexPath + item:configuration]; + } + } + return nil; }
diff --git a/ios/chrome/browser/home_customization/ui/home_customization_color_palette_configuration.h b/ios/chrome/browser/home_customization/ui/home_customization_color_palette_configuration.h new file mode 100644 index 0000000..2eeb26b --- /dev/null +++ b/ios/chrome/browser/home_customization/ui/home_customization_color_palette_configuration.h
@@ -0,0 +1,28 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_HOME_CUSTOMIZATION_UI_HOME_CUSTOMIZATION_COLOR_PALETTE_CONFIGURATION_H_ +#define IOS_CHROME_BROWSER_HOME_CUSTOMIZATION_UI_HOME_CUSTOMIZATION_COLOR_PALETTE_CONFIGURATION_H_ + +#import <UIKit/UIKit.h> + +// A model object that defines a background color palette, including +// light, medium, and dark variants derived from a seed color. +@interface HomeCustomizationColorPaletteConfiguration : NSObject + +// A lighter tone variant of the seed color. +@property(nonatomic, strong) UIColor* lightColor; + +// A medium tone variant of the seed color. +@property(nonatomic, strong) UIColor* mediumColor; + +// A darker tone variant of the seed color. +@property(nonatomic, strong) UIColor* darkColor; + +// The original seed color used to generate the palette. +@property(nonatomic, strong) UIColor* seedColor; + +@end + +#endif // IOS_CHROME_BROWSER_HOME_CUSTOMIZATION_UI_HOME_CUSTOMIZATION_COLOR_PALETTE_CONFIGURATION_H_
diff --git a/ios/chrome/browser/home_customization/ui/home_customization_color_palette_configuration.mm b/ios/chrome/browser/home_customization/ui/home_customization_color_palette_configuration.mm new file mode 100644 index 0000000..325e850 --- /dev/null +++ b/ios/chrome/browser/home_customization/ui/home_customization_color_palette_configuration.mm
@@ -0,0 +1,9 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/home_customization/ui/home_customization_color_palette_configuration.h" + +@implementation HomeCustomizationColorPaletteConfiguration + +@end
diff --git a/ios/chrome/browser/home_customization/ui/home_cutomization_color_palette_cell.h b/ios/chrome/browser/home_customization/ui/home_cutomization_color_palette_cell.h new file mode 100644 index 0000000..9e36ce3 --- /dev/null +++ b/ios/chrome/browser/home_customization/ui/home_cutomization_color_palette_cell.h
@@ -0,0 +1,23 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_HOME_CUSTOMIZATION_UI_HOME_CUTOMIZATION_COLOR_PALETTE_CELL_H_ +#define IOS_CHROME_BROWSER_HOME_CUSTOMIZATION_UI_HOME_CUTOMIZATION_COLOR_PALETTE_CELL_H_ + +#import <UIKit/UIKit.h> + +// Configuration used to populate the color palette cell. +@class HomeCustomizationColorPaletteConfiguration; + +// A collection view cell that displays a single background color palette option +// for the background customization. +@interface HomeCustomizationColorPaletteCell : UICollectionViewCell + +// The configuration model that specifies the colors shown in the cell. +@property(nonatomic, strong) + HomeCustomizationColorPaletteConfiguration* configuration; + +@end + +#endif // IOS_CHROME_BROWSER_HOME_CUSTOMIZATION_UI_HOME_CUTOMIZATION_COLOR_PALETTE_CELL_H_
diff --git a/ios/chrome/browser/home_customization/ui/home_cutomization_color_palette_cell.mm b/ios/chrome/browser/home_customization/ui/home_cutomization_color_palette_cell.mm new file mode 100644 index 0000000..883de23 --- /dev/null +++ b/ios/chrome/browser/home_customization/ui/home_cutomization_color_palette_cell.mm
@@ -0,0 +1,87 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/home_customization/ui/home_cutomization_color_palette_cell.h" + +#import <UIKit/UIKit.h> + +#import "base/check.h" +#import "ios/chrome/browser/home_customization/ui/home_customization_color_palette_configuration.h" + +@implementation HomeCustomizationColorPaletteCell { + // View representing the light tone color. + UIView* _lightColorView; + + // View representing the dark tone color. + UIView* _darkColorView; + + // View representing the medium tone color. + UIView* _mediumColorView; +} + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + self.backgroundColor = UIColor.clearColor; + + _lightColorView = [[UIView alloc] init]; + _darkColorView = [[UIView alloc] init]; + _mediumColorView = [[UIView alloc] init]; + + _lightColorView.translatesAutoresizingMaskIntoConstraints = NO; + _darkColorView.translatesAutoresizingMaskIntoConstraints = NO; + _mediumColorView.translatesAutoresizingMaskIntoConstraints = NO; + + [self addSubview:_lightColorView]; + [self addSubview:_darkColorView]; + [self addSubview:_mediumColorView]; + + [NSLayoutConstraint activateConstraints:@[ + // Top half (light color). + [_lightColorView.topAnchor constraintEqualToAnchor:self.topAnchor], + [_lightColorView.leadingAnchor + constraintEqualToAnchor:self.leadingAnchor], + [_lightColorView.trailingAnchor + constraintEqualToAnchor:self.trailingAnchor], + [_lightColorView.heightAnchor constraintEqualToAnchor:self.heightAnchor + multiplier:0.5], + + // Bottom left quarter (dark color). + [_darkColorView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor], + [_darkColorView.leadingAnchor constraintEqualToAnchor:self.leadingAnchor], + [_darkColorView.widthAnchor constraintEqualToAnchor:self.widthAnchor + multiplier:0.5], + [_darkColorView.heightAnchor constraintEqualToAnchor:self.heightAnchor + multiplier:0.5], + + // Bottom right quarter (medium color). + [_mediumColorView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor], + [_mediumColorView.trailingAnchor + constraintEqualToAnchor:self.trailingAnchor], + [_mediumColorView.widthAnchor constraintEqualToAnchor:self.widthAnchor + multiplier:0.5], + [_mediumColorView.heightAnchor constraintEqualToAnchor:self.heightAnchor + multiplier:0.5], + ]]; + } + return self; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + + // Circle shape by rounding the corners + self.layer.cornerRadius = self.bounds.size.width / 2.0; + self.clipsToBounds = YES; +} + +- (void)setConfiguration: + (HomeCustomizationColorPaletteConfiguration*)configuration { + _configuration = configuration; + _lightColorView.backgroundColor = configuration.lightColor; + _darkColorView.backgroundColor = configuration.darkColor; + _mediumColorView.backgroundColor = configuration.mediumColor; +} + +@end
diff --git a/ios/chrome/browser/web/model/chrome_web_client.h b/ios/chrome/browser/web/model/chrome_web_client.h index fc79652..032ad05 100644 --- a/ios/chrome/browser/web/model/chrome_web_client.h +++ b/ios/chrome/browser/web/model/chrome_web_client.h
@@ -33,6 +33,7 @@ std::string GetApplicationLocale() const override; bool IsAppSpecificURL(const GURL& url) const override; std::string GetUserAgent(web::UserAgentType type) const override; + std::string GetMainThreadName() const override; std::u16string GetLocalizedString(int message_id) const override; std::string_view GetDataResource( int resource_id,
diff --git a/ios/chrome/browser/web/model/chrome_web_client.mm b/ios/chrome/browser/web/model/chrome_web_client.mm index cc2c8f2..2da89db 100644 --- a/ios/chrome/browser/web/model/chrome_web_client.mm +++ b/ios/chrome/browser/web/model/chrome_web_client.mm
@@ -363,6 +363,10 @@ return web::BuildMobileUserAgent(GetMobileProduct()); } +std::string ChromeWebClient::GetMainThreadName() const { + return "CrWebMain"; +} + std::u16string ChromeWebClient::GetLocalizedString(int message_id) const { return l10n_util::GetStringUTF16(message_id); }
diff --git a/ios/chrome/browser/whats_new/ui/strings/BUILD.gn b/ios/chrome/browser/whats_new/ui/strings/BUILD.gn index 040aa86..9fab4a96 100644 --- a/ios/chrome/browser/whats_new/ui/strings/BUILD.gn +++ b/ios/chrome/browser/whats_new/ui/strings/BUILD.gn
@@ -5,11 +5,9 @@ import("//build/config/locales.gni") import("//tools/grit/grit_rule.gni") -grit("strings") { +grit_strings("strings") { source = "ios_whats_new_strings.grd" output_dir = "$root_gen_dir/ios/chrome" outputs = [ "grit/ios_whats_new_strings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "ios_whats_new_strings_$locale.pak" ] - } + output_prefix = "ios_whats_new_strings_" }
diff --git a/ios/chrome/content_widget_extension/strings/BUILD.gn b/ios/chrome/content_widget_extension/strings/BUILD.gn index 8dff629..3c79ab3a 100644 --- a/ios/chrome/content_widget_extension/strings/BUILD.gn +++ b/ios/chrome/content_widget_extension/strings/BUILD.gn
@@ -6,11 +6,9 @@ import("//build/config/locales.gni") import("//tools/grit/grit_rule.gni") -grit("strings") { +grit_strings("strings") { source = "ios_content_widget_extension_${branding_path_product}_strings.grd" output_dir = "$root_gen_dir/ios/content_widget_extension" outputs = [ "grit/ios_content_widget_extension_branded_strings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "ios_content_widget_extension_branded_strings_$locale.pak" ] - } + output_prefix = "ios_content_widget_extension_branded_strings_" }
diff --git a/ios/chrome/credential_provider_extension/strings/BUILD.gn b/ios/chrome/credential_provider_extension/strings/BUILD.gn index b118fd37..f5e5b959 100644 --- a/ios/chrome/credential_provider_extension/strings/BUILD.gn +++ b/ios/chrome/credential_provider_extension/strings/BUILD.gn
@@ -5,11 +5,9 @@ import("//build/config/locales.gni") import("//tools/grit/grit_rule.gni") -grit("strings") { +grit_strings("strings") { source = "ios_credential_provider_extension_strings.grd" output_dir = "$root_gen_dir/ios/credential_provider_extension" outputs = [ "grit/ios_credential_provider_extension_strings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "ios_credential_provider_extension_strings_$locale.pak" ] - } + output_prefix = "ios_credential_provider_extension_strings_" }
diff --git a/ios/chrome/open_extension/strings/BUILD.gn b/ios/chrome/open_extension/strings/BUILD.gn index 5df449b..dbea06db 100644 --- a/ios/chrome/open_extension/strings/BUILD.gn +++ b/ios/chrome/open_extension/strings/BUILD.gn
@@ -5,11 +5,9 @@ import("//build/config/locales.gni") import("//tools/grit/grit_rule.gni") -grit("strings") { +grit_strings("strings") { source = "ios_open_extension_${branding_path_product}_strings.grd" output_dir = "$root_gen_dir/ios/open_extension" outputs = [ "grit/ios_open_extension_branded_strings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "ios_open_extension_branded_strings_$locale.pak" ] - } + output_prefix = "ios_open_extension_branded_strings_" }
diff --git a/ios/chrome/search_widget_extension/strings/BUILD.gn b/ios/chrome/search_widget_extension/strings/BUILD.gn index 00df3f3..d214bf5f 100644 --- a/ios/chrome/search_widget_extension/strings/BUILD.gn +++ b/ios/chrome/search_widget_extension/strings/BUILD.gn
@@ -6,11 +6,9 @@ import("//build/config/locales.gni") import("//tools/grit/grit_rule.gni") -grit("strings") { +grit_strings("strings") { source = "ios_search_widget_extension_${branding_path_product}_strings.grd" output_dir = "$root_gen_dir/ios/search_widget_extension" outputs = [ "grit/ios_search_widget_extension_branded_strings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "ios_search_widget_extension_branded_strings_$locale.pak" ] - } + output_prefix = "ios_search_widget_extension_branded_strings_" }
diff --git a/ios/chrome/share_extension/strings/BUILD.gn b/ios/chrome/share_extension/strings/BUILD.gn index fc08eb2b..eabdec1 100644 --- a/ios/chrome/share_extension/strings/BUILD.gn +++ b/ios/chrome/share_extension/strings/BUILD.gn
@@ -5,11 +5,9 @@ import("//build/config/locales.gni") import("//tools/grit/grit_rule.gni") -grit("strings") { +grit_strings("strings") { source = "ios_share_extension_strings.grd" output_dir = "$root_gen_dir/ios/share_extension" outputs = [ "grit/ios_share_extension_strings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "ios_share_extension_strings_$locale.pak" ] - } + output_prefix = "ios_share_extension_strings_" }
diff --git a/ios/chrome/widget_kit_extension/strings/BUILD.gn b/ios/chrome/widget_kit_extension/strings/BUILD.gn index c780b02..eae97db 100644 --- a/ios/chrome/widget_kit_extension/strings/BUILD.gn +++ b/ios/chrome/widget_kit_extension/strings/BUILD.gn
@@ -5,11 +5,9 @@ import("//build/config/locales.gni") import("//tools/grit/grit_rule.gni") -grit("strings") { +grit_strings("strings") { source = "ios_widget_kit_extension_strings.grd" output_dir = "$root_gen_dir/ios/widget_kit_extension" outputs = [ "grit/ios_widget_kit_extension_strings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "ios_widget_kit_extension_strings_$locale.pak" ] - } + output_prefix = "ios_widget_kit_extension_strings_" }
diff --git a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1 index 6b612ac0..6fd93bd7 100644 --- a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -e3edaf782e8f7149c4c2492e3e7a55533b5638ad \ No newline at end of file +e83b6b238ea10cb67a1cad02fef0ddf20bd701cd \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1 b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1 index d3b92eb3..03e91d6f 100644 --- a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1
@@ -1 +1 @@ -5a24acfa661c59bd8eb53e20d89ba10a23de757e \ No newline at end of file +1c7a5d05d7bc15a38ec5d5dc957f9a6ab279760e \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 index 0cead64..f63a419 100644 --- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -4e7143699ba681818cab8c98ec0d39998d43cc87 \ No newline at end of file +3e545bdb1a460666466b7e75f1ea1530ac1ab4d6 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1 index a626e5df..367f0fa 100644 --- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1
@@ -1 +1 @@ -e13e0ffcbdd1b91cfb251441cf1e3eff6f255322 \ No newline at end of file +7edca93a5f3da84d9b3bec5c61a12dd2751fb93e \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 index e176586..8f0b7d53 100644 --- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -54f71374da89594dfdbc25e1f90e897ed3fbbeaa \ No newline at end of file +2fa4ad0f4b2baeae4f167a5585de05d0c5da5b98 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1 index 7f66ac3..bb3e8464 100644 --- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1
@@ -1 +1 @@ -a2caf961234900394a8039c7b2c1e74ed7562b1b \ No newline at end of file +6c3293d383cb2b3b75ba7f6f1140df3a6c7cab87 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1 index 803649ae..125e24b 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -4036b5db59d8c153da0c24ad91a780e6061dcaf0 \ No newline at end of file +d3596ab6811c6440dc812ab45c033e5cf46c955d \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1 index 0660c05..ad51185 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -76bc5701495778b9db3f446869591ec9f45734e6 \ No newline at end of file +aa827e01c365ddc93ed796459b370fccc6995ca3 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1 index 4ab2859..51bc465 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -cfe872b9fc93298b235d7d423d68ca900e38ead5 \ No newline at end of file +b86d0c3678c1b54f388833057c5200e25972db4d \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1 index 047e6e9c..374ef34 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -9f334152f35499b5f00f36a8906b28dda901da44 \ No newline at end of file +43de3ae7ad6b09bc744a1955399c9a066bec1f3d \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 index ad9288ae..23afe6c 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -b6a85dbe1fd2d7d17ee714acd1e9303c682b1c02 \ No newline at end of file +da94702d642d621dbf91498157ed258562872bd9 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1 index 4ffa20c..e0c95fba 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -f625ed4638257c969b975d98f137717dc71a76af \ No newline at end of file +0233896bc1ad8255f5f9109a08f57d55404e2dc9 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 index 9152f79f..3ec7e1c 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -94db3fa3a60e48af158c566cba149af100116b88 \ No newline at end of file +bc66a15eb8325005648820cdc2f10f62593afa77 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1 index eda7b36..8806ab94 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -0e3aff95dd9f2f827ab1ae47dbd4dcd51cf3086c \ No newline at end of file +0163bdeaab93259b50af8b1c8277f7a08c5cac68 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 index 91dc2a6..9e2baa2 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -e0332d07cfc93647eb21f7af0553d8a4449d72ab \ No newline at end of file +77598fd63598aebae733780e9d96fd9239e77712 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1 index 5c4ec80c..bf9a9e87 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -cd52aeb6ddf2ea57d809fc7a2ebdd46095b4b7b8 \ No newline at end of file +5e51373abe3f2278a86540f6bb4ad979a25d103b \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 index 9c7f715..27eeb3f3 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -52deadc27942090c40f04674ec314aa856569a02 \ No newline at end of file +78045c87916304e5f0b76783f054096693d783fe \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1 index 3ef9efe..784ccec 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -362f24d16d131448bf0f2ec87ee5e9d3d0df694c \ No newline at end of file +e6c2d37215b80f879647274eb8dfceb1fc224275 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 index d714b0b..b93e2db 100644 --- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -8e61156591295d7e7216a3bb15d6d3ef31b1858b \ No newline at end of file +05daaf5aa23786597cdb7628504b4bbf81503f29 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 index 6fb827c..7a74712 100644 --- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -5f397699b0b9d48a8dccfafa637991051a737b7b \ No newline at end of file +32ecf69c38f73d6800ded374daee594368cfbc3a \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 index 3c10a54..d29b3231 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -30cfdb6241dfe222a5796a2608824ccd9c238f54 \ No newline at end of file +341108f8c614b31666f30f246216eb4c47e888db \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1 index 8c916e3..64c9e67 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -8dbc98f17be818d6f35848a9f3d63f7039f2f20f \ No newline at end of file +48ba6deb3edc7f8666f71cd129eab53797c20be5 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 index 9adb7d4..d569c3a 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -9ff82179f542204d5776257bceeaa0d16d42ad3f \ No newline at end of file +dcf5e7830335049925329161209933bdadb4a543 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1 index 5977791..2616ad8 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -76dc804eaaedb9bd7d6051cf98c2cf9aef1b826b \ No newline at end of file +aad36b4d3e972fd3b8aeb3465f18afcac8862a6b \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 index d0208d6..265caeec 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -0accc764651e6aa91a7f91e10b5176cacbc7bba8 \ No newline at end of file +aa79f83ae88173dddd2d8bc32208d267bdb0e06e \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1 index 2265367..98bbc8b 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -fa2a6fc90c741236ee1c3e1d239d3a4a4fb6aa8c \ No newline at end of file +2971b968bd37726d7a7b47d196ad672e87b4254c \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 index 751f790d..ba6cff35 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -e7b6e5963970afbf8266e6490ce6e9df4d4e718b \ No newline at end of file +a4214754898c718d6128b859c07895d0af2f6e24 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1 index 5809b26..e3790816 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -8c2470ab343dd081ee28eb7196da7b85a6b2996e \ No newline at end of file +d2e78755f2f8f398c56ebd2749adbb71f69d6b9a \ No newline at end of file
diff --git a/ios/web/init/web_main_loop.mm b/ios/web/init/web_main_loop.mm index 68139e4..bcb8687 100644 --- a/ios/web/init/web_main_loop.mm +++ b/ios/web/init/web_main_loop.mm
@@ -212,7 +212,10 @@ } void WebMainLoop::InitializeMainThread() { - base::PlatformThread::SetName("CrWebMain"); + const std::string name = web::GetWebClient()->GetMainThreadName(); + if (!name.empty()) { + base::PlatformThread::SetName(name); + } // Register the main thread by instantiating it, but don't call any methods. DCHECK(base::SingleThreadTaskRunner::HasCurrentDefault());
diff --git a/ios/web/public/web_client.h b/ios/web/public/web_client.h index 4b82c7bf..27bb22e 100644 --- a/ios/web/public/web_client.h +++ b/ios/web/public/web_client.h
@@ -94,6 +94,11 @@ // Returns the user agent string for the specified type. virtual std::string GetUserAgent(UserAgentType type) const; + // Returns the name of the main thread. If the returned string is empty, + // the main thread name will not be set. The default implementation returns + // an empty string and does not rename the main thread. + virtual std::string GetMainThreadName() const; + // Returns a string resource given its id. virtual std::u16string GetLocalizedString(int message_id) const;
diff --git a/ios/web/web_client.mm b/ios/web/web_client.mm index 3dfb34e..fb2a8e7 100644 --- a/ios/web/web_client.mm +++ b/ios/web/web_client.mm
@@ -47,6 +47,10 @@ return std::string(); } +std::string WebClient::GetMainThreadName() const { + return std::string(); +} + std::u16string WebClient::GetLocalizedString(int message_id) const { return std::u16string(); }
diff --git a/media/base/demuxer.h b/media/base/demuxer.h index 0c3f0b03..6d45124 100644 --- a/media/base/demuxer.h +++ b/media/base/demuxer.h
@@ -173,15 +173,17 @@ // all tracks should be disabled. |change_completed_cb| is fired after the // demuxer streams are disabled, however this callback should then notify // the appropriate renderer in order for tracks to be switched fully. - virtual void OnEnabledAudioTracksChanged( - const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - TrackChangeCB change_completed_cb) = 0; - virtual void OnSelectedVideoTrackChanged( - const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - TrackChangeCB change_completed_cb) = 0; + // TODO(crbug.com/41393620): No more than one video track may be enabled at + // once, per the VideoTrack w3c spec. Due to our renderer implementation, only + // one audio track is supported, but this restriction isn't necessarily a + // permanent one. We should either decide to always stick with one audio + // track and switch `track_ids` to an std::optional container, or to support + // multiple audio tracks. + virtual void OnTracksChanged(DemuxerStream::Type track_type, + const std::vector<MediaTrack::Id>& track_ids, + base::TimeDelta curr_time, + TrackChangeCB change_completed_cb) = 0; // Allows a demuxer to change behavior based on the playback rate, including // but not limited to changing the amount of buffer space.
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 358bd89..52e5c568 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -1691,12 +1691,6 @@ "RenderMutedAudio", base::FEATURE_ENABLED_BY_DEFAULT); -// Serves as killswitch for rolling out Mappable SharedImage mojom support. -// TODO(crbug.com/40263579): Eliminate post safe rollout. -BASE_FEATURE(kSupportMappableSharedImageOverMojo, - "SupportMappableSharedImageOverMojo", - base::FEATURE_ENABLED_BY_DEFAULT); - // Controls headless Live Caption experiment, which is likely unstable. BASE_FEATURE(kHeadlessLiveCaption, "HeadlessLiveCaption",
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index 628fd50..ce8e748 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -533,10 +533,6 @@ MEDIA_EXPORT BASE_DECLARE_FEATURE(kRenderMutedAudio); -// Serves as killswitch for rolling out Mappable SharedImage mojom support. -// TODO(crbug.com/40263579): Eliminate post safe rollout. -MEDIA_EXPORT BASE_DECLARE_FEATURE(kSupportMappableSharedImageOverMojo); - // Enable experimental headless captions. MEDIA_EXPORT BASE_DECLARE_FEATURE(kHeadlessLiveCaption);
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h index 50636b4..dd99ed3 100644 --- a/media/base/mock_filters.h +++ b/media/base/mock_filters.h
@@ -193,14 +193,9 @@ (), (const, override)); MOCK_METHOD(void, - OnEnabledAudioTracksChanged, - (const std::vector<MediaTrack::Id>&, - base::TimeDelta, - TrackChangeCB), - (override)); - MOCK_METHOD(void, - OnSelectedVideoTrackChanged, - (const std::vector<MediaTrack::Id>&, + OnTracksChanged, + (DemuxerStream::Type, + const std::vector<MediaTrack::Id>&, base::TimeDelta, TrackChangeCB), (override));
diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc index 12590103..00c415f 100644 --- a/media/base/pipeline_impl.cc +++ b/media/base/pipeline_impl.cc
@@ -101,16 +101,10 @@ PipelineStatistics GetStatistics() const; void SetCdm(CdmContext* cdm_context, CdmAttachedCB cdm_attached_cb); - // |enabled_track_ids| contains track ids of enabled audio tracks. - void OnEnabledAudioTracksChanged( - const std::vector<MediaTrack::Id>& enabled_track_ids, - base::OnceClosure change_completed_cb); - - // |selected_track_id| is either empty, which means no video track is - // selected, or contains the selected video track id. - void OnSelectedVideoTrackChanged( - std::optional<MediaTrack::Id> selected_track_id, - base::OnceClosure change_completed_cb); + // Handles asynchronous track changing for the demuxer and renderer. + void OnTracksChanged(DemuxerStream::Type track_type, + std::vector<MediaTrack::Id> enabled_track_ids, + base::OnceClosure change_completed_cb); void OnExternalVideoFrameRequest(); @@ -770,13 +764,32 @@ media_task_runner_->PostTask( FROM_HERE, base::BindOnce( - &RendererWrapper::OnEnabledAudioTracksChanged, - base::Unretained(renderer_wrapper_.get()), enabled_track_ids, + &RendererWrapper::OnTracksChanged, + base::Unretained(renderer_wrapper_.get()), DemuxerStream::AUDIO, + std::move(enabled_track_ids), base::BindPostTaskToCurrentDefault(std::move(change_completed_cb)))); } -void PipelineImpl::RendererWrapper::OnEnabledAudioTracksChanged( - const std::vector<MediaTrack::Id>& enabled_track_ids, +void PipelineImpl::OnSelectedVideoTrackChanged( + std::optional<MediaTrack::Id> selected_track_id, + base::OnceClosure change_completed_cb) { + DCHECK(thread_checker_.CalledOnValidThread()); + std::vector<MediaTrack::Id> tracks; + if (selected_track_id) { + tracks.push_back(*selected_track_id); + } + + media_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&RendererWrapper::OnTracksChanged, + base::Unretained(renderer_wrapper_.get()), + DemuxerStream::VIDEO, std::move(tracks), + base::BindPostTaskToCurrentDefault( + std::move(change_completed_cb)))); +} + +void PipelineImpl::RendererWrapper::OnTracksChanged( + DemuxerStream::Type track_type, + std::vector<MediaTrack::Id> enabled_track_ids, base::OnceClosure change_completed_cb) { DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); @@ -797,74 +810,14 @@ std::move(change_completed_cb).Run(); return; } - demuxer_->OnEnabledAudioTracksChanged( - enabled_track_ids, GetCurrentTimestamp(), + + demuxer_->OnTracksChanged( + track_type, std::move(enabled_track_ids), GetCurrentTimestamp(), base::BindOnce(&RendererWrapper::OnDemuxerCompletedTrackChange, - weak_factory_.GetWeakPtr(), DemuxerStream::AUDIO, + weak_factory_.GetWeakPtr(), track_type, std::move(change_completed_cb))); } -void PipelineImpl::OnSelectedVideoTrackChanged( - std::optional<MediaTrack::Id> selected_track_id, - base::OnceClosure change_completed_cb) { - DCHECK(thread_checker_.CalledOnValidThread()); - media_task_runner_->PostTask( - FROM_HERE, - base::BindOnce( - &RendererWrapper::OnSelectedVideoTrackChanged, - base::Unretained(renderer_wrapper_.get()), selected_track_id, - base::BindPostTaskToCurrentDefault(std::move(change_completed_cb)))); -} - -void PipelineImpl::RendererWrapper::OnSelectedVideoTrackChanged( - std::optional<MediaTrack::Id> selected_track_id, - base::OnceClosure change_completed_cb) { - DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); - - // See RenderWrapper::OnEnabledAudioTracksChanged. - if (state_ == State::kCreated) { - DCHECK(!demuxer_); - std::move(change_completed_cb).Run(); - return; - } - - if (state_ == State::kStopping || state_ == State::kStopped) { - std::move(change_completed_cb).Run(); - return; - } - - std::vector<MediaTrack::Id> tracks; - if (selected_track_id) - tracks.push_back(*selected_track_id); - - demuxer_->OnSelectedVideoTrackChanged( - tracks, GetCurrentTimestamp(), - base::BindOnce(&RendererWrapper::OnDemuxerCompletedTrackChange, - weak_factory_.GetWeakPtr(), DemuxerStream::VIDEO, - std::move(change_completed_cb))); -} - -void PipelineImpl::OnExternalVideoFrameRequest() { - // This function is currently a no-op unless we're on a Windows build with - // Media Foundation for Clear running. - DCHECK(thread_checker_.CalledOnValidThread()); - if (!external_video_frame_request_signaled_) { - external_video_frame_request_signaled_ = true; - media_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&RendererWrapper::OnExternalVideoFrameRequest, - base::Unretained(renderer_wrapper_.get()))); - } -} - -void PipelineImpl::RendererWrapper::OnExternalVideoFrameRequest() { - DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); - if (!shared_state_.renderer) { - return; - } - - shared_state_.renderer->OnExternalVideoFrameRequest(); -} - void PipelineImpl::RendererWrapper::OnDemuxerCompletedTrackChange( DemuxerStream::Type stream_type, base::OnceClosure change_completed_cb, @@ -890,6 +843,27 @@ } } +void PipelineImpl::OnExternalVideoFrameRequest() { + // This function is currently a no-op unless we're on a Windows build with + // Media Foundation for Clear running. + DCHECK(thread_checker_.CalledOnValidThread()); + if (!external_video_frame_request_signaled_) { + external_video_frame_request_signaled_ = true; + media_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&RendererWrapper::OnExternalVideoFrameRequest, + base::Unretained(renderer_wrapper_.get()))); + } +} + +void PipelineImpl::RendererWrapper::OnExternalVideoFrameRequest() { + DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); + if (!shared_state_.renderer) { + return; + } + + shared_state_.renderer->OnExternalVideoFrameRequest(); +} + void PipelineImpl::RendererWrapper::OnStatisticsUpdate( const PipelineStatistics& stats) { DVLOG(3) << __func__;
diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc index c63d1b7..d9fcbe78 100644 --- a/media/filters/chunk_demuxer.cc +++ b/media/filters/chunk_demuxer.cc
@@ -875,11 +875,10 @@ return itr->second->GetHighestPresentationTimestamp(); } -void ChunkDemuxer::FindAndEnableProperTracks( - const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - DemuxerStream::Type track_type, - TrackChangeCB change_completed_cb) { +void ChunkDemuxer::OnTracksChanged(DemuxerStream::Type track_type, + const std::vector<MediaTrack::Id>& track_ids, + base::TimeDelta curr_time, + TrackChangeCB change_completed_cb) { base::AutoLock auto_lock(lock_); std::set<ChunkDemuxerStream*> enabled_streams; @@ -914,22 +913,6 @@ std::move(change_completed_cb).Run(streams); } -void ChunkDemuxer::OnEnabledAudioTracksChanged( - const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - TrackChangeCB change_completed_cb) { - FindAndEnableProperTracks(track_ids, curr_time, DemuxerStream::AUDIO, - std::move(change_completed_cb)); -} - -void ChunkDemuxer::OnSelectedVideoTrackChanged( - const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - TrackChangeCB change_completed_cb) { - FindAndEnableProperTracks(track_ids, curr_time, DemuxerStream::VIDEO, - std::move(change_completed_cb)); -} - void ChunkDemuxer::DisableCanChangeType() { supports_change_type_ = false; }
diff --git a/media/filters/chunk_demuxer.h b/media/filters/chunk_demuxer.h index 1c78069..1143a31 100644 --- a/media/filters/chunk_demuxer.h +++ b/media/filters/chunk_demuxer.h
@@ -306,13 +306,10 @@ // buffered, returns base::TimeDelta(). base::TimeDelta GetHighestPresentationTimestamp(const std::string& id) const; - void OnEnabledAudioTracksChanged(const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - TrackChangeCB change_completed_cb) override; - - void OnSelectedVideoTrackChanged(const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - TrackChangeCB change_completed_cb) override; + void OnTracksChanged(DemuxerStream::Type track_type, + const std::vector<MediaTrack::Id>& track_ids, + base::TimeDelta curr_time, + TrackChangeCB change_completed_cb) override; void SetPlaybackRate(double rate) override {} @@ -478,14 +475,6 @@ std::unique_ptr<media::StreamParser> stream_parser, std::optional<std::string_view> expected_codecs); - // Helper for video and audio track changing. For the `track_type`, enables - // tracks associated with `track_ids` and disables the rest. Fires - // `change_completed_cb` when the operation is completed. - void FindAndEnableProperTracks(const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - DemuxerStream::Type track_type, - TrackChangeCB change_completed_cb); - void ChangeState_Locked(State new_state); // Reports an error and puts the demuxer in a state where it won't accept more
diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc index bfde410..58676b6 100644 --- a/media/filters/chunk_demuxer_unittest.cc +++ b/media/filters/chunk_demuxer_unittest.cc
@@ -4613,28 +4613,28 @@ std::vector<MediaTrack::Id> video_tracks; base::RunLoop disable_video; - demuxer->OnSelectedVideoTrackChanged( - video_tracks, base::TimeDelta(), + demuxer->OnTracksChanged( + DemuxerStream::VIDEO, video_tracks, base::TimeDelta(), base::BindOnce(QuitLoop, disable_video.QuitClosure())); disable_video.Run(); base::RunLoop disable_audio; - demuxer->OnEnabledAudioTracksChanged( - audio_tracks, base::TimeDelta(), + demuxer->OnTracksChanged( + DemuxerStream::AUDIO, audio_tracks, base::TimeDelta(), base::BindOnce(QuitLoop, disable_audio.QuitClosure())); disable_audio.Run(); base::RunLoop enable_video; video_tracks.push_back(MediaTrack::Id("1")); - demuxer->OnSelectedVideoTrackChanged( - video_tracks, base::TimeDelta(), + demuxer->OnTracksChanged( + DemuxerStream::VIDEO, video_tracks, base::TimeDelta(), base::BindOnce(QuitLoop, enable_video.QuitClosure())); enable_video.Run(); base::RunLoop enable_audio; audio_tracks.push_back(MediaTrack::Id("2")); - demuxer->OnEnabledAudioTracksChanged( - audio_tracks, base::TimeDelta(), + demuxer->OnTracksChanged( + DemuxerStream::AUDIO, audio_tracks, base::TimeDelta(), base::BindOnce(QuitLoop, enable_audio.QuitClosure())); enable_audio.Run();
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc index ff199ef..8cb1707 100644 --- a/media/filters/ffmpeg_demuxer.cc +++ b/media/filters/ffmpeg_demuxer.cc
@@ -1782,10 +1782,22 @@ RunPendingSeekCB(PIPELINE_OK); } -void FFmpegDemuxer::FindAndEnableProperTracks( +void FFmpegDemuxer::OnTrackChangeSeekComplete( + base::OnceClosure cb, + std::vector<FFmpegDemuxerStream*> needs_flush, + int seek_status) { + for (const auto& stream : needs_flush) { + CHECK(stream->IsEnabled()); + stream->FlushBuffers(true); + } + // TODO(crbug.com/41393620): Report seek failures for track changes too. + std::move(cb).Run(); +} + +void FFmpegDemuxer::OnTracksChanged( + DemuxerStream::Type track_type, const std::vector<MediaTrack::Id>& track_ids, base::TimeDelta curr_time, - DemuxerStream::Type track_type, TrackChangeCB change_completed_cb) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); @@ -1841,34 +1853,6 @@ } } -void FFmpegDemuxer::OnTrackChangeSeekComplete( - base::OnceClosure cb, - std::vector<FFmpegDemuxerStream*> needs_flush, - int seek_status) { - for (const auto& stream : needs_flush) { - CHECK(stream->IsEnabled()); - stream->FlushBuffers(true); - } - // TODO(crbug.com/40898124): Report seek failures for track changes too. - std::move(cb).Run(); -} - -void FFmpegDemuxer::OnEnabledAudioTracksChanged( - const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - TrackChangeCB change_completed_cb) { - FindAndEnableProperTracks(track_ids, curr_time, DemuxerStream::AUDIO, - std::move(change_completed_cb)); -} - -void FFmpegDemuxer::OnSelectedVideoTrackChanged( - const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - TrackChangeCB change_completed_cb) { - FindAndEnableProperTracks(track_ids, curr_time, DemuxerStream::VIDEO, - std::move(change_completed_cb)); -} - void FFmpegDemuxer::ReadFrameIfNeeded() { DCHECK(task_runner_->RunsTasksInCurrentSequence());
diff --git a/media/filters/ffmpeg_demuxer.h b/media/filters/ffmpeg_demuxer.h index a7aa7028..e096166c 100644 --- a/media/filters/ffmpeg_demuxer.h +++ b/media/filters/ffmpeg_demuxer.h
@@ -250,13 +250,10 @@ // Allow FFmpegDemxuerStream to notify us about an error. void NotifyDemuxerError(PipelineStatus error); - void OnEnabledAudioTracksChanged(const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - TrackChangeCB change_completed_cb) override; - - void OnSelectedVideoTrackChanged(const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - TrackChangeCB change_completed_cb) override; + void OnTracksChanged(DemuxerStream::Type track_type, + const std::vector<MediaTrack::Id>& track_ids, + base::TimeDelta curr_time, + TrackChangeCB change_completed_cb) override; void SetPlaybackRate(double rate) override {} // The lowest demuxed timestamp. If negative, DemuxerStreams must use this to @@ -278,14 +275,6 @@ // To allow tests access to privates. friend class FFmpegDemuxerTest; - // Helper for video and audio track changing. For the `track_type`, enables - // tracks associated with `track_ids` and disables the rest. Fires - // `change_completed_cb` when the operation is completed. - void FindAndEnableProperTracks(const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - DemuxerStream::Type track_type, - TrackChangeCB change_completed_cb); - // FFmpeg callbacks during initialization. void OnOpenContextDone(bool result); void OnFindStreamInfoDone(int result);
diff --git a/media/filters/ffmpeg_demuxer_unittest.cc b/media/filters/ffmpeg_demuxer_unittest.cc index fba6aead..a122d68 100644 --- a/media/filters/ffmpeg_demuxer_unittest.cc +++ b/media/filters/ffmpeg_demuxer_unittest.cc
@@ -1769,28 +1769,28 @@ std::vector<MediaTrack::Id> video_tracks; base::RunLoop disable_video; - demuxer->OnSelectedVideoTrackChanged( - video_tracks, base::TimeDelta(), + demuxer->OnTracksChanged( + DemuxerStream::VIDEO, video_tracks, base::TimeDelta(), base::BindOnce(QuitLoop, disable_video.QuitClosure())); disable_video.Run(); base::RunLoop disable_audio; - demuxer->OnEnabledAudioTracksChanged( - audio_tracks, base::TimeDelta(), + demuxer->OnTracksChanged( + DemuxerStream::AUDIO, audio_tracks, base::TimeDelta(), base::BindOnce(QuitLoop, disable_audio.QuitClosure())); disable_audio.Run(); base::RunLoop enable_video; video_tracks.push_back(MediaTrack::Id("1")); - demuxer->OnSelectedVideoTrackChanged( - video_tracks, base::TimeDelta(), + demuxer->OnTracksChanged( + DemuxerStream::VIDEO, video_tracks, base::TimeDelta(), base::BindOnce(QuitLoop, enable_video.QuitClosure())); enable_video.Run(); base::RunLoop enable_audio; audio_tracks.push_back(MediaTrack::Id("2")); - demuxer->OnEnabledAudioTracksChanged( - audio_tracks, base::TimeDelta(), + demuxer->OnTracksChanged( + DemuxerStream::AUDIO, audio_tracks, base::TimeDelta(), base::BindOnce(QuitLoop, enable_audio.QuitClosure())); enable_audio.Run();
diff --git a/media/filters/manifest_demuxer.cc b/media/filters/manifest_demuxer.cc index 6535467..ef7f191 100644 --- a/media/filters/manifest_demuxer.cc +++ b/media/filters/manifest_demuxer.cc
@@ -294,44 +294,27 @@ std::move(change_completed_cb).Run(mapped_streams); } -void ManifestDemuxer::OnEnabledAudioTracksChanged( +void ManifestDemuxer::OnTracksChanged( + DemuxerStream::Type track_type, const std::vector<MediaTrack::Id>& track_ids, base::TimeDelta curr_time, TrackChangeCB change_completed_cb) { DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); - std::optional<MediaTrack::Id> selected_track = std::nullopt; std::vector<MediaTrack::Id> chunk_demuxer_tracks = track_ids; if (!track_ids.empty()) { selected_track = track_ids[0]; - chunk_demuxer_tracks = {*internal_audio_track_id_}; + if (track_type == DemuxerStream::AUDIO) { + chunk_demuxer_tracks = {*internal_audio_track_id_}; + } else if (track_type == DemuxerStream::VIDEO) { + chunk_demuxer_tracks = {*internal_video_track_id_}; + } } - chunk_demuxer_->OnEnabledAudioTracksChanged( - std::move(chunk_demuxer_tracks), curr_time, + chunk_demuxer_->OnTracksChanged( + track_type, std::move(chunk_demuxer_tracks), curr_time, base::BindOnce(&ManifestDemuxer::OnChunkDemuxerTracksChangeComplete, - weak_factory_.GetWeakPtr(), DemuxerStream::AUDIO, - std::move(selected_track), - std::move(change_completed_cb))); -} - -void ManifestDemuxer::OnSelectedVideoTrackChanged( - const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - TrackChangeCB change_completed_cb) { - DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); - - std::optional<MediaTrack::Id> selected_track = std::nullopt; - std::vector<MediaTrack::Id> chunk_demuxer_tracks = track_ids; - if (!track_ids.empty()) { - selected_track = track_ids[0]; - chunk_demuxer_tracks = {*internal_video_track_id_}; - } - - chunk_demuxer_->OnSelectedVideoTrackChanged( - std::move(chunk_demuxer_tracks), curr_time, - base::BindOnce(&ManifestDemuxer::OnChunkDemuxerTracksChangeComplete, - weak_factory_.GetWeakPtr(), DemuxerStream::VIDEO, + weak_factory_.GetWeakPtr(), track_type, std::move(selected_track), std::move(change_completed_cb))); }
diff --git a/media/filters/manifest_demuxer.h b/media/filters/manifest_demuxer.h index 532aa4e..61028f8 100644 --- a/media/filters/manifest_demuxer.h +++ b/media/filters/manifest_demuxer.h
@@ -201,12 +201,10 @@ std::optional<container_names::MediaContainerName> GetContainerForMetrics() const override; - void OnEnabledAudioTracksChanged(const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - TrackChangeCB change_completed_cb) override; - void OnSelectedVideoTrackChanged(const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - TrackChangeCB change_completed_cb) override; + void OnTracksChanged(DemuxerStream::Type track_type, + const std::vector<MediaTrack::Id>& track_ids, + base::TimeDelta curr_time, + TrackChangeCB change_completed_cb) override; // `ManifestDemuxerEngineHost` implementation bool AddRole(std::string_view role, RelaxedParserSupportedType mime) override;
diff --git a/media/filters/manifest_demuxer_unittest.cc b/media/filters/manifest_demuxer_unittest.cc index fd7c174..7bcec42 100644 --- a/media/filters/manifest_demuxer_unittest.cc +++ b/media/filters/manifest_demuxer_unittest.cc
@@ -377,8 +377,8 @@ // Disable video track: bool was_called = false; - manifest_demuxer_->OnSelectedVideoTrackChanged( - {}, base::Seconds(0), + manifest_demuxer_->OnTracksChanged( + DemuxerStream::VIDEO, {}, base::Seconds(0), base::BindOnce( [](bool* was_called, const std::vector<DemuxerStream*>& streams) { ASSERT_TRUE(streams.empty()); @@ -390,8 +390,8 @@ // Enable video track: was_called = false; - manifest_demuxer_->OnSelectedVideoTrackChanged( - {MediaTrack::Id("video")}, base::Seconds(0), + manifest_demuxer_->OnTracksChanged( + DemuxerStream::VIDEO, {MediaTrack::Id("video")}, base::Seconds(0), base::BindOnce( [](bool* was_called, const std::vector<DemuxerStream*>& streams) { ASSERT_EQ(streams.size(), 1u); @@ -403,8 +403,8 @@ // Disable audio track: was_called = false; - manifest_demuxer_->OnEnabledAudioTracksChanged( - {}, base::Seconds(0), + manifest_demuxer_->OnTracksChanged( + DemuxerStream::AUDIO, {}, base::Seconds(0), base::BindOnce( [](bool* was_called, const std::vector<DemuxerStream*>& streams) { ASSERT_TRUE(streams.empty()); @@ -416,8 +416,8 @@ // Enable audio track: was_called = false; - manifest_demuxer_->OnEnabledAudioTracksChanged( - {MediaTrack::Id("audio")}, base::Seconds(0), + manifest_demuxer_->OnTracksChanged( + DemuxerStream::AUDIO, {MediaTrack::Id("audio")}, base::Seconds(0), base::BindOnce( [](bool* was_called, const std::vector<DemuxerStream*>& streams) { ASSERT_EQ(streams.size(), 1u);
diff --git a/media/gpu/windows/supported_profile_helpers.cc b/media/gpu/windows/supported_profile_helpers.cc index 498b7cf..1814b07 100644 --- a/media/gpu/windows/supported_profile_helpers.cc +++ b/media/gpu/windows/supported_profile_helpers.cc
@@ -332,8 +332,12 @@ continue; } if (profile_id == DXVA_ModeAV1_VLD_Profile1) { - supported_resolutions[AV1PROFILE_PROFILE_HIGH] = GetResolutionsForGUID( - video_device_wrapper, profile_id, kModernResolutions); + // DXVA spec for high profile (section 7.2) does not include NV12 as + // mandatory format, here we only test 8b-444 (AYUV) and skip check of + // Y410. + supported_resolutions[AV1PROFILE_PROFILE_HIGH] = + GetResolutionsForGUID(video_device_wrapper, profile_id, + kModernResolutions, DXGI_FORMAT_AYUV); continue; } if (profile_id == DXVA_ModeAV1_VLD_Profile2) {
diff --git a/media/mojo/mojom/video_frame_mojom_traits.cc b/media/mojo/mojom/video_frame_mojom_traits.cc index 2f978f8..ab90df6 100644 --- a/media/mojo/mojom/video_frame_mojom_traits.cc +++ b/media/mojo/mojom/video_frame_mojom_traits.cc
@@ -7,7 +7,6 @@ #include <utility> #include <vector> -#include "base/feature_list.h" #include "base/functional/callback_helpers.h" #include "base/logging.h" #include "base/memory/unsafe_shared_memory_region.h" @@ -16,7 +15,6 @@ #include "gpu/ipc/common/gpu_memory_buffer_support.h" #include "media/base/color_plane_layout.h" #include "media/base/format_utils.h" -#include "media/base/media_switches.h" #include "media/mojo/mojom/video_frame_metadata_mojom_traits.h" #include "mojo/public/cpp/base/time_mojom_traits.h" #include "mojo/public/cpp/system/handle.h" @@ -33,12 +31,6 @@ namespace { -// Determines whether Mappable SharedImage over mojo is supported. -bool SupportMappableSI() { - return base::FeatureList::IsEnabled( - media::kSupportMappableSharedImageOverMojo); -} - base::ReadOnlySharedMemoryRegion CreateRegion(const media::VideoFrame& frame, std::vector<uint32_t>& offsets, std::vector<int32_t>& strides) { @@ -132,15 +124,16 @@ std::optional<gpu::ExportedSharedImage> shared_image; gpu::SyncToken sync_token; if (input->HasSharedImage()) { - bool with_buffer_handle = is_mappable_si_enabled && SupportMappableSI(); - shared_image = input->shared_image()->Export(with_buffer_handle); + shared_image = input->shared_image()->Export( + /*with_buffer_handle=*/is_mappable_si_enabled); sync_token = input->acquire_sync_token(); - if (with_buffer_handle) { + if (is_mappable_si_enabled) { return media::mojom::VideoFrameData::NewSharedImageData( media::mojom::SharedImageVideoFrameData::New( std::move(shared_image.value()), std::move(sync_token), - is_mappable_si_enabled, std::move(input->ycbcr_info()))); + /*is_mappable_si_enabled=*/true, + std::move(input->ycbcr_info()))); } } @@ -411,7 +404,7 @@ } bool is_mappable_si_enabled = shared_image_data.is_mappable_si_enabled(); - if (is_mappable_si_enabled && SupportMappableSI()) { + if (is_mappable_si_enabled) { // VideoFrame should have buffer usage if Mappable SharedImage is enabled. // NOTE: This isn't exactly correct for software SharedImages can be // mappable but do not have buffer usage. But since, such software
diff --git a/media/remoting/stream_provider.cc b/media/remoting/stream_provider.cc index 3f8cb023..22cade65 100644 --- a/media/remoting/stream_provider.cc +++ b/media/remoting/stream_provider.cc
@@ -504,7 +504,8 @@ return std::optional<container_names::MediaContainerName>(); } -void StreamProvider::OnEnabledAudioTracksChanged( +void StreamProvider::OnTracksChanged( + DemuxerStream::Type track_type, const std::vector<MediaTrack::Id>& track_ids, base::TimeDelta curr_time, TrackChangeCB change_completed_cb) { @@ -513,15 +514,6 @@ DVLOG(1) << "Track changes are not supported."; } -void StreamProvider::OnSelectedVideoTrackChanged( - const std::vector<media::MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - TrackChangeCB change_completed_cb) { - std::vector<DemuxerStream*> streams; - std::move(change_completed_cb).Run(streams); - DVLOG(1) << "Track changes are not supported."; -} - void StreamProvider::Destroy() { DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
diff --git a/media/remoting/stream_provider.h b/media/remoting/stream_provider.h index 6bf9c8c..21ee763 100644 --- a/media/remoting/stream_provider.h +++ b/media/remoting/stream_provider.h
@@ -63,12 +63,10 @@ int64_t GetMemoryUsage() const override; std::optional<container_names::MediaContainerName> GetContainerForMetrics() const override; - void OnEnabledAudioTracksChanged(const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - TrackChangeCB change_completed_cb) override; - void OnSelectedVideoTrackChanged(const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta curr_time, - TrackChangeCB change_completed_cb) override; + void OnTracksChanged(DemuxerStream::Type track_type, + const std::vector<MediaTrack::Id>& track_ids, + base::TimeDelta curr_time, + TrackChangeCB change_completed_cb) override; void SetPlaybackRate(double rate) override {} protected:
diff --git a/net/dns/host_resolver_internal_result.cc b/net/dns/host_resolver_internal_result.cc index b8fbaee..afaf662 100644 --- a/net/dns/host_resolver_internal_result.cc +++ b/net/dns/host_resolver_internal_result.cc
@@ -423,7 +423,7 @@ base::Value::List endpoints_list; endpoints_list.reserve(endpoints_.size()); - for (IPEndPoint endpoint : endpoints_) { + for (const IPEndPoint& endpoint : endpoints_) { endpoints_list.Append(endpoint.ToValue()); } dict.Set(kValueEndpointsKey, std::move(endpoints_list));
diff --git a/net/network_error_logging/network_error_logging_service.cc b/net/network_error_logging/network_error_logging_service.cc index 6fb48e56..8f483af 100644 --- a/net/network_error_logging/network_error_logging_service.cc +++ b/net/network_error_logging/network_error_logging_service.cc
@@ -574,7 +574,7 @@ DCHECK(initialized_); if (PoliciesArePersisted()) { // TODO(chlily): Add a DeleteAllNelPolicies command to PersistentNelStore. - for (auto origin_and_policy : policies_) { + for (const auto& origin_and_policy : policies_) { store_->DeleteNelPolicy(origin_and_policy.second); } store_->Flush();
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index b1a654a..b2450ed 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc
@@ -49,7 +49,7 @@ #include "base/values.h" #include "build/build_config.h" #include "build/buildflag.h" -#include "crypto/sha2.h" +#include "crypto/hash.h" #include "net/base/chunked_upload_data_stream.h" #include "net/base/cronet_buildflags.h" #include "net/base/directory_listing.h" @@ -628,19 +628,15 @@ #if !BUILDFLAG(IS_IOS) // Compute the root cert's SPKI hash on the fly, to avoid hardcoding it within // tests. -bool GetTestRootCertSPKIHash(SHA256HashValue* root_hash) { +std::array<uint8_t, crypto::hash::kSha256Size> GetTestRootCertSPKIHash() { scoped_refptr<X509Certificate> root_cert = ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem"); - if (!root_cert) - return false; + CHECK(root_cert); std::string_view root_spki; - if (!asn1::ExtractSPKIFromDERCert( - x509_util::CryptoBufferAsStringPiece(root_cert->cert_buffer()), - &root_spki)) { - return false; - } - crypto::SHA256HashString(root_spki, root_hash, sizeof(SHA256HashValue)); - return true; + CHECK(asn1::ExtractSPKIFromDERCert( + x509_util::CryptoBufferAsStringPiece(root_cert->cert_buffer()), + &root_spki)); + return crypto::hash::Sha256(root_spki); } #endif @@ -11511,8 +11507,7 @@ ASSERT_TRUE(test_server.Start()); CertVerifier::Config cert_verifier_config = GetCertVerifierConfig(); - SHA256HashValue root_cert_spki_hash; - ASSERT_TRUE(GetTestRootCertSPKIHash(&root_cert_spki_hash)); + auto root_cert_spki_hash = GetTestRootCertSPKIHash(); auto crl_set = CRLSet::ForTesting(false, &root_cert_spki_hash, test_server.GetCertificate()->serial_number(), "", {}); @@ -11731,8 +11726,7 @@ // Configure for kHSTSSubdomainWithKnownInterception CertVerifyResult sts_sub_result = fake_result; - SHA256HashValue root_hash; - ASSERT_TRUE(GetTestRootCertSPKIHash(&root_hash)); + auto root_hash = GetTestRootCertSPKIHash(); sts_sub_result.public_key_hashes.push_back(HashValue(root_hash)); sts_sub_result.cert_status |= CERT_STATUS_REVOKED | CERT_STATUS_KNOWN_INTERCEPTION_BLOCKED;
diff --git a/pdf/pdf_ink_metrics_handler.cc b/pdf/pdf_ink_metrics_handler.cc index a597fc0..75f9b71 100644 --- a/pdf/pdf_ink_metrics_handler.cc +++ b/pdf/pdf_ink_metrics_handler.cc
@@ -62,7 +62,7 @@ {SkColorSetRGB(0x19, 0x67, 0xD2), StrokeMetricPenColor::kBlue3}, {SkColorSetRGB(0x88, 0x59, 0x45), StrokeMetricPenColor::kTan3}, }); -// LINT.ThenChange(//chrome/browser/resources/pdf/elements/ink_color_selector.ts:PenColors) +// LINT.ThenChange(//chrome/browser/resources/pdf/elements//ink_annotation_brush_mixin.ts:PenColors) // LINT.IfChange(HighlighterColors) constexpr auto kHighlighterColors = @@ -85,7 +85,7 @@ {SkColorSetRGB(0xFF, 0x63, 0x0C), StrokeMetricHighlighterColor::kOrange}, }); -// LINT.ThenChange(//chrome/browser/resources/pdf/elements/ink_color_selector.ts:HighlighterColors) +// LINT.ThenChange(//chrome/browser/resources/pdf/elements//ink_annotation_brush_mixin.ts:HighlighterColors) void ReportStrokeTypeAndMaybeSize(StrokeMetricBrushType type, std::optional<StrokeMetricBrushSize> size) {
diff --git a/pdf/pdf_ink_module.cc b/pdf/pdf_ink_module.cc index 0ad1fb74..0b80ebcf 100644 --- a/pdf/pdf_ink_module.cc +++ b/pdf/pdf_ink_module.cc
@@ -165,7 +165,7 @@ PdfInkModule::~PdfInkModule() = default; bool PdfInkModule::ShouldBlockTextSelectionChanged() { - return is_text_highlighting(); + return features::kPdfInk2TextHighlighting.Get() && is_text_highlighting(); } bool PdfInkModule::HasInputsToDraw() const { @@ -553,12 +553,16 @@ return false; } - // TODO(crbug.com/342445982): Handle text selection for touch. - gfx::PointF position = event.touches[0].PositionInWidget(); - return is_drawing_stroke() - ? StartStroke(position, event.TimeStamp(), tool_type) - : StartEraseStroke(position, tool_type); + if (is_drawing_stroke()) { + if (IsHighlightingTextAtPosition(drawing_stroke_state(), position)) { + // Multi-click text selection for touch is not supported. + return StartTextHighlight(position, /*click_count=*/1, event.TimeStamp()); + } + return StartStroke(position, event.TimeStamp(), tool_type); + } + + return StartEraseStroke(position, tool_type); } bool PdfInkModule::OnTouchEnd(const blink::WebTouchEvent& event) { @@ -575,6 +579,10 @@ } gfx::PointF position = event.touches[0].PositionInWidget(); + if (features::kPdfInk2TextHighlighting.Get() && is_text_highlighting()) { + return FinishTextHighlight(position); + } + return is_drawing_stroke() ? FinishStroke(position, event.TimeStamp(), tool_type) : FinishEraseStroke(position, tool_type); @@ -594,6 +602,10 @@ } gfx::PointF position = event.touches[0].PositionInWidget(); + if (features::kPdfInk2TextHighlighting.Get() && is_text_highlighting()) { + return ContinueTextHighlight(position); + } + return is_drawing_stroke() ? ContinueStroke(position, event.TimeStamp(), tool_type) : ContinueEraseStroke(position, tool_type);
diff --git a/pdf/pdf_ink_module_unittest.cc b/pdf/pdf_ink_module_unittest.cc index 434cdba..418125a 100644 --- a/pdf/pdf_ink_module_unittest.cc +++ b/pdf/pdf_ink_module_unittest.cc
@@ -146,6 +146,12 @@ {kTwoPageVerticalLayoutHorzLinePoint1Canonical, base::Seconds(0)}, }); +// Commonly used test brush message params. The color corresponds to "Red1" for +// pen brushes and "Light Red" for highlighter brushes. +constexpr TestAnnotationBrushMessageParams kRedBrushParams{ + /*color_r=*/0xF2, /*color_g=*/0x8B, + /*color_b=*/0x82, /*size=*/6.0f}; + // Matcher for ink::Stroke objects against their expected brush and inputs. MATCHER_P(InkStrokeEq, expected_brush, "") { const auto& [actual_stroke, expected_inputs] = arg; @@ -587,9 +593,10 @@ TEST_P(PdfInkModuleTest, HandleSetAnnotationBrushMessagePen) { EnableAnnotationMode(); - TestAnnotationBrushMessageParams message_params{/*color_r=*/10, - /*color_g=*/255, - /*color_b=*/50, /*size=*/8.0}; + TestAnnotationBrushMessageParams message_params{/*color_r=*/0x0A, + /*color_g=*/0xFF, + /*color_b=*/0x32, + /*size=*/8.0f}; base::Value::Dict message = CreateSetAnnotationBrushMessageForTesting("pen", &message_params); EXPECT_TRUE(ink_module().OnMessage(message)); @@ -598,7 +605,7 @@ ASSERT_TRUE(brush); const ink::Brush& ink_brush = brush->ink_brush(); - EXPECT_EQ(SkColorSetRGB(10, 255, 50), GetSkColorFromInkBrush(ink_brush)); + EXPECT_EQ(SkColorSetRGB(0x0A, 0xFF, 0x32), GetSkColorFromInkBrush(ink_brush)); EXPECT_EQ(8.0f, ink_brush.GetSize()); ASSERT_EQ(1u, ink_brush.CoatCount()); const ink::BrushCoat& coat = ink_brush.GetCoats()[0]; @@ -611,9 +618,10 @@ TEST_P(PdfInkModuleTest, HandleSetAnnotationBrushMessageHighlighter) { EnableAnnotationMode(); - TestAnnotationBrushMessageParams message_params{/*color_r=*/240, - /*color_g=*/133, - /*color_b=*/0, /*size=*/4.5}; + TestAnnotationBrushMessageParams message_params{/*color_r=*/0xF0, + /*color_g=*/0x85, + /*color_b=*/0x00, + /*size=*/4.5f}; base::Value::Dict message = CreateSetAnnotationBrushMessageForTesting("highlighter", &message_params); EXPECT_TRUE(ink_module().OnMessage(message)); @@ -622,7 +630,7 @@ ASSERT_TRUE(brush); const ink::Brush& ink_brush = brush->ink_brush(); - EXPECT_EQ(SkColorSetRGB(240, 133, 0), GetSkColorFromInkBrush(ink_brush)); + EXPECT_EQ(SkColorSetRGB(0xF0, 0x85, 0x00), GetSkColorFromInkBrush(ink_brush)); EXPECT_EQ(4.5f, ink_brush.GetSize()); ASSERT_EQ(1u, ink_brush.CoatCount()); const ink::BrushCoat& coat = ink_brush.GetCoats()[0]; @@ -635,8 +643,9 @@ TEST_P(PdfInkModuleTest, HandleSetAnnotationBrushMessageColorZero) { EnableAnnotationMode(); - TestAnnotationBrushMessageParams message_params{/*color_r=*/0, /*color_g=*/0, - /*color_b=*/0, /*size=*/4.5}; + TestAnnotationBrushMessageParams message_params{ + /*color_r=*/0x00, /*color_g=*/0x00, + /*color_b=*/0x00, /*size=*/4.5f}; base::Value::Dict message = CreateSetAnnotationBrushMessageForTesting("pen", &message_params); EXPECT_TRUE(ink_module().OnMessage(message)); @@ -738,9 +747,10 @@ EnableAnnotationMode(); - TestAnnotationBrushMessageParams message_params{/*color_r=*/0, - /*color_g=*/255, - /*color_b=*/0, /*size=*/16.0}; + TestAnnotationBrushMessageParams message_params{/*color_r=*/0x00, + /*color_g=*/0xFF, + /*color_b=*/0x00, + /*size=*/16.0f}; base::Value::Dict message = CreateSetAnnotationBrushMessageForTesting("pen", &message_params); EXPECT_TRUE(ink_module().OnMessage(message)); @@ -777,10 +787,10 @@ EnableAnnotationMode(); - TestAnnotationBrushMessageParams message_params{/*color_r=*/0, - /*color_g=*/255, - /*color_b=*/0, - /*size=*/16.0}; + TestAnnotationBrushMessageParams message_params{/*color_r=*/0x00, + /*color_g=*/0xFF, + /*color_b=*/0x00, + /*size=*/16.0f}; base::Value::Dict message = CreateSetAnnotationBrushMessageForTesting("pen", &message_params); EXPECT_TRUE(ink_module().OnMessage(message)); @@ -1941,10 +1951,10 @@ // Start drawing a stroke with a black pen. The stroke will not finish // until the mouse-up event. EXPECT_CALL(client(), StrokeAdded(_, _, _)).Times(0); - TestAnnotationBrushMessageParams black_pen_message_params{/*color_r=*/0, - /*color_g=*/0, - /*color_b=*/0, - /*size=*/3.0}; + TestAnnotationBrushMessageParams black_pen_message_params{/*color_r=*/0x00, + /*color_g=*/0x00, + /*color_b=*/0x00, + /*size=*/3.0f}; SelectBrushTool(PdfInkBrush::Type::kPen, black_pen_message_params); blink::WebMouseEvent mouse_down_event = @@ -1955,10 +1965,10 @@ // While the stroke is still in progress, change the pen color. This has no // immediate effect on the in-progress stroke. - TestAnnotationBrushMessageParams red_pen_message_params{/*color_r=*/242, - /*color_g=*/139, - /*color_b=*/130, - /*size=*/3.0}; + TestAnnotationBrushMessageParams red_pen_message_params{/*color_r=*/0xF2, + /*color_g=*/0x8B, + /*color_b=*/0x82, + /*size=*/3.0f}; SelectBrushTool(PdfInkBrush::Type::kPen, red_pen_message_params); VerifyAndClearExpectations(); @@ -1979,9 +1989,10 @@ // Do another stroke. Notice that the changed pen color is in effect for // the new stroke that is added. - EXPECT_CALL(client(), - StrokeAdded(kPageIndex, InkStrokeId(1), - InkStrokeBrushColorEq(SkColorSetRGB(242, 139, 130)))); + EXPECT_CALL( + client(), + StrokeAdded(kPageIndex, InkStrokeId(1), + InkStrokeBrushColorEq(SkColorSetRGB(0xF2, 0x8B, 0x82)))); EXPECT_TRUE(ink_module().HandleInputEvent(mouse_down_event)); EXPECT_TRUE(ink_module().HandleInputEvent(mouse_up_event)); } @@ -1996,9 +2007,10 @@ EXPECT_CALL(client(), StrokeAdded(_, _, _)).Times(0); EXPECT_CALL(client(), UpdateInkCursor(CursorBitmapImageSizeEq(SkISize(6, 6)))); - TestAnnotationBrushMessageParams message_params{/*color_r=*/0, - /*color_g=*/0, - /*color_b=*/0, /*size=*/2.0}; + TestAnnotationBrushMessageParams message_params{/*color_r=*/0x00, + /*color_g=*/0x00, + /*color_b=*/0x00, + /*size=*/2.0f}; SelectBrushTool(PdfInkBrush::Type::kPen, message_params); blink::WebMouseEvent mouse_down_event = @@ -2009,7 +2021,7 @@ // While the stroke is still in progress, change the pen size. This has no // immediate effect on the in-progress stroke. - message_params.size = 6.0; + message_params.size = 6.0f; SelectBrushTool(PdfInkBrush::Type::kPen, message_params); VerifyAndClearExpectations(); @@ -2122,9 +2134,10 @@ // While the stroke is still in progress, change the input tool type to a // pen. Note that this causes the in-progress erase stroke to finish even // before the mouse-up event. - TestAnnotationBrushMessageParams message_params{/*color_r=*/0, - /*color_g=*/0, - /*color_b=*/0, /*size=*/8.0}; + TestAnnotationBrushMessageParams message_params{/*color_r=*/0x00, + /*color_g=*/0x00, + /*color_b=*/0x00, + /*size=*/8.0f}; SelectBrushTool(PdfInkBrush::Type::kPen, message_params); VerifyAndClearExpectations(); @@ -2161,10 +2174,10 @@ EXPECT_CALL(client(), StrokeAdded(_, _, _)).Times(0); EXPECT_CALL(client(), UpdateInkCursor(CursorBitmapImageSizeEq(SkISize(6, 6)))); - TestAnnotationBrushMessageParams pen_message_params{/*color_r=*/0, - /*color_g=*/0, - /*color_b=*/0, - /*size=*/2.0}; + TestAnnotationBrushMessageParams pen_message_params{/*color_r=*/0x00, + /*color_g=*/0x00, + /*color_b=*/0x00, + /*size=*/2.0f}; SelectBrushTool(PdfInkBrush::Type::kPen, pen_message_params); blink::WebMouseEvent mouse_down_event = @@ -2175,10 +2188,10 @@ // While the stroke is still in progress, change the input tool type to a // highlighter. The entire stroke changes to this new type. - TestAnnotationBrushMessageParams highlighter_message_params{/*color_r=*/221, - /*color_g=*/243, - /*color_b=*/0, - /*size=*/8.0}; + TestAnnotationBrushMessageParams highlighter_message_params{/*color_r=*/0xDD, + /*color_g=*/0xF3, + /*color_b=*/0x00, + /*size=*/8.0f}; SelectBrushTool(PdfInkBrush::Type::kHighlighter, highlighter_message_params); VerifyAndClearExpectations(); @@ -2827,8 +2840,7 @@ 1); // Draw a stroke with "Red 1" color. - TestAnnotationBrushMessageParams params = {/*color_r=*/0xF2, /*color_g=*/0x8B, - /*color_b=*/0x82, /*size=*/3.0}; + TestAnnotationBrushMessageParams params = kRedBrushParams; SelectBrushTool(PdfInkBrush::Type::kPen, params); ApplyStrokeWithMouseAtMouseDownPoint(); @@ -2853,8 +2865,7 @@ base::HistogramTester histograms; // Draw a stroke with "Light Red" color. - TestAnnotationBrushMessageParams params = {/*color_r=*/0xF2, /*color_g=*/0x8B, - /*color_b=*/0x82, /*size=*/6.0}; + TestAnnotationBrushMessageParams params = kRedBrushParams; SelectBrushTool(PdfInkBrush::Type::kHighlighter, params); ApplyStrokeWithMouseAtMouseDownPoint(); @@ -2885,8 +2896,8 @@ histograms.ExpectUniqueSample(kPenSizeMetric, StrokeMetricBrushSize::kMedium, 1); - TestAnnotationBrushMessageParams params = {/*color_r=*/242, /*color_g=*/139, - /*color_b=*/130, /*size=*/1.0}; + TestAnnotationBrushMessageParams params = {/*color_r=*/0xF2, /*color_g=*/0x8B, + /*color_b=*/0x82, /*size=*/1.0f}; SelectBrushTool(PdfInkBrush::Type::kPen, params); ApplyStrokeWithMouseAtMouseDownPoint(); @@ -2894,7 +2905,7 @@ StrokeMetricBrushSize::kExtraThin, 1); histograms.ExpectTotalCount(kPenSizeMetric, 2); - params.size = 8.0; + params.size = 8.0f; SelectBrushTool(PdfInkBrush::Type::kPen, params); ApplyStrokeWithMouseAtMouseDownPoint(); @@ -2910,8 +2921,8 @@ base::HistogramTester histograms; // Draw a stroke with medium size. - TestAnnotationBrushMessageParams params = {/*color_r=*/242, /*color_g=*/139, - /*color_b=*/130, /*size=*/8.0}; + TestAnnotationBrushMessageParams params = {/*color_r=*/0xF2, /*color_g=*/0x8B, + /*color_b=*/0x82, /*size=*/8.0f}; SelectBrushTool(PdfInkBrush::Type::kHighlighter, params); ApplyStrokeWithMouseAtMouseDownPoint(); @@ -2919,7 +2930,7 @@ StrokeMetricBrushSize::kMedium, 1); // Draw a stroke with extra thin size. - params.size = 4.0; + params.size = 4.0f; SelectBrushTool(PdfInkBrush::Type::kHighlighter, params); ApplyStrokeWithMouseAtMouseDownPoint(); @@ -2928,7 +2939,7 @@ histograms.ExpectTotalCount(kHighlighterSizeMetric, 2); // Draw a stroke with extra thick size. - params.size = 16.0; + params.size = 16.0f; SelectBrushTool(PdfInkBrush::Type::kHighlighter, params); ApplyStrokeWithMouseAtMouseDownPoint(); @@ -2952,8 +2963,7 @@ histograms.ExpectUniqueSample(kTypeMetric, StrokeMetricBrushType::kPen, 1); // Draw a highlighter stroke. - TestAnnotationBrushMessageParams params = {/*color_r=*/242, /*color_g=*/139, - /*color_b=*/130, /*size=*/6.0}; + TestAnnotationBrushMessageParams params = kRedBrushParams; SelectBrushTool(PdfInkBrush::Type::kHighlighter, params); ApplyStrokeWithMouseAtMouseDownPoint(); @@ -2977,7 +2987,7 @@ histograms.ExpectTotalCount(kTypeMetric, 3); // Draw another pen stroke. - params.size = 3.0; + params.size = 3.0f; SelectBrushTool(PdfInkBrush::Type::kPen, params); ApplyStrokeWithMouseAtMouseDownPoint(); @@ -3081,6 +3091,10 @@ class PdfInkModuleTextHighlightTest : public PdfInkModuleStrokeTest { public: + static constexpr TestAnnotationBrushMessageParams kOrangeBrushParams{ + /*color_r=*/0xFF, + /*color_g=*/0x63, + /*color_b=*/0x0C, /*size=*/6.0f}; static constexpr gfx::Rect kHorizontalSelection{10, 15, 30, 10}; static constexpr gfx::Rect kVerticalSelection{10, 15, 6, 10}; static constexpr gfx::PointF kStartPointInsidePage0{10.0, 10.0}; @@ -3088,19 +3102,28 @@ static constexpr SkColor kOrangeColor = SkColorSetRGB(0xFF, 0x63, 0x0C); protected: - // Helper method for running a simple text selection highlight test with a - // single selection rect on page zero. - void RunSingleSelectionTest(const gfx::Rect& selection_rect, - base::span<const PdfInkInputData> expected_inputs, - float expected_size) { + // Helper method for running a simple text highlighting test using text + // selected by mouse with a single selection rect on page zero. + void RunSingleSelectionWithMouseTest( + const gfx::Rect& selection_rect, + base::span<const PdfInkInputData> expected_inputs, + float expected_size) { + SetUpSingleSelectionTest(selection_rect); + + // Apply a text highlight stroke at the given points. + ApplyStrokeWithMouseAtPoints(kStartPointInsidePage0, {kEndPointInsidePage0}, + kEndPointInsidePage0); + + VerifySingleSelectionTest(expected_inputs, expected_size); + } + + // Set up single selection test expectations before text selection strokes + // have been applied. + void SetUpSingleSelectionTest(const gfx::Rect& selection_rect) { EnableAnnotationMode(); InitializeSimpleSinglePageBasicLayout(); - // Select the highlighter tool with an "Orange" color. - TestAnnotationBrushMessageParams params = {/*color_r=*/0xFF, - /*color_g=*/0x63, - /*color_b=*/0x0C, /*size=*/6.0f}; - SelectBrushTool(PdfInkBrush::Type::kHighlighter, params); + SelectBrushTool(PdfInkBrush::Type::kHighlighter, kOrangeBrushParams); std::vector<gfx::Rect> selection_rects{selection_rect}; EXPECT_CALL(client(), GetSelectionRects()) @@ -3113,11 +3136,12 @@ EXPECT_CALL(client(), OnTextOrLinkAreaClick(kStartPointInsidePage0, /*click_count=*/1)); EXPECT_CALL(client(), ExtendSelectionByPoint(kEndPointInsidePage0)); + } - // Apply a text highlight stroke at the given points. - ApplyStrokeWithMouseAtPoints(kStartPointInsidePage0, {kEndPointInsidePage0}, - kEndPointInsidePage0); - + // Verify single selection test results after applying text selection strokes. + void VerifySingleSelectionTest( + base::span<const PdfInkInputData> expected_inputs, + float expected_size) { EXPECT_EQ(1, client().stroke_finished_count()); EXPECT_THAT(updated_ink_thumbnail_page_indices(), ElementsAre(0)); @@ -3170,9 +3194,7 @@ InitializeSimpleSinglePageBasicLayout(); // Select the pen tool with a "Light Red" color. - TestAnnotationBrushMessageParams params = {/*color_r=*/0xF2, /*color_g=*/0x8B, - /*color_b=*/0x82, /*size=*/6.0f}; - SelectBrushTool(PdfInkBrush::Type::kPen, params); + SelectBrushTool(PdfInkBrush::Type::kPen, kRedBrushParams); EXPECT_CALL(client(), GetSelectionRects()).Times(0); EXPECT_CALL(client(), IsSelectableTextOrLinkArea(kStartPointInsidePage0)) @@ -3207,7 +3229,7 @@ } TEST_P(PdfInkModuleTextHighlightTest, SingleHorizontalSelection) { - RunSingleSelectionTest( + RunSingleSelectionWithMouseTest( /*selection_rect=*/kHorizontalSelection, /*expected_inputs=*/ {PdfInkInputData(gfx::PointF(15.0, 20.0)), @@ -3216,7 +3238,7 @@ } TEST_P(PdfInkModuleTextHighlightTest, SingleVerticalSelection) { - RunSingleSelectionTest( + RunSingleSelectionWithMouseTest( /*selection_rect=*/kVerticalSelection, /*expected_inputs=*/ {PdfInkInputData(gfx::PointF(13.0, 18.0)), @@ -3225,7 +3247,7 @@ } TEST_P(PdfInkModuleTextHighlightTest, SingleSquareSelection) { - RunSingleSelectionTest( + RunSingleSelectionWithMouseTest( /*selection_rect=*/gfx::Rect(10, 15, 12, 12), /*expected_inputs=*/ {PdfInkInputData(gfx::PointF(16.0, 21.0))}, @@ -3235,7 +3257,7 @@ TEST_P(PdfInkModuleTextHighlightTest, SingleHorizontalSelectionRotatedClockwise90) { client().set_orientation(PageOrientation::kClockwise90); - RunSingleSelectionTest( + RunSingleSelectionWithMouseTest( /*selection_rect=*/kHorizontalSelection, /*expected_inputs=*/ {PdfInkInputData(gfx::PointF(20.0, 14.0)), @@ -3246,7 +3268,7 @@ TEST_P(PdfInkModuleTextHighlightTest, SingleVerticalSelectionRotatedClockwise90) { client().set_orientation(PageOrientation::kClockwise90); - RunSingleSelectionTest( + RunSingleSelectionWithMouseTest( /*selection_rect=*/kVerticalSelection, /*expected_inputs=*/ {PdfInkInputData(gfx::PointF(18.0, 36.0)), @@ -3257,7 +3279,7 @@ TEST_P(PdfInkModuleTextHighlightTest, SingleHorizontalSelectionRotatedClockwise180) { client().set_orientation(PageOrientation::kClockwise180); - RunSingleSelectionTest( + RunSingleSelectionWithMouseTest( /*selection_rect=*/kHorizontalSelection, /*expected_inputs=*/ {PdfInkInputData(gfx::PointF(14.0, 39.0)), @@ -3268,7 +3290,7 @@ TEST_P(PdfInkModuleTextHighlightTest, SingleVerticalSelectionRotatedClockwise180) { client().set_orientation(PageOrientation::kClockwise180); - RunSingleSelectionTest( + RunSingleSelectionWithMouseTest( /*selection_rect=*/kVerticalSelection, /*expected_inputs=*/ {PdfInkInputData(gfx::PointF(36.0, 37.0)), @@ -3279,7 +3301,7 @@ TEST_P(PdfInkModuleTextHighlightTest, SingleHorizontalSelectionRotatedClockwise270) { client().set_orientation(PageOrientation::kClockwise270); - RunSingleSelectionTest( + RunSingleSelectionWithMouseTest( /*selection_rect=*/kHorizontalSelection, /*expected_inputs=*/ {PdfInkInputData(gfx::PointF(39.0, 15.0)), @@ -3290,7 +3312,7 @@ TEST_P(PdfInkModuleTextHighlightTest, SingleVerticalSelectionRotatedClockwise270) { client().set_orientation(PageOrientation::kClockwise270); - RunSingleSelectionTest( + RunSingleSelectionWithMouseTest( /*selection_rect=*/kVerticalSelection, /*expected_inputs=*/ {PdfInkInputData(gfx::PointF(37.0, 13.0)), @@ -3303,7 +3325,7 @@ InitializeSimpleSinglePageBasicLayout(); client().set_zoom(2.0f); - RunSingleSelectionTest( + RunSingleSelectionWithMouseTest( /*selection_rect=*/kHorizontalSelection, /*expected_inputs=*/ {PdfInkInputData(gfx::PointF(7.5, 10.0)), @@ -3316,7 +3338,7 @@ InitializeSimpleSinglePageBasicLayout(); client().set_zoom(0.5f); - RunSingleSelectionTest( + RunSingleSelectionWithMouseTest( /*selection_rect=*/kHorizontalSelection, /*expected_inputs=*/ {PdfInkInputData(gfx::PointF(30.0, 40.0)), @@ -3328,11 +3350,7 @@ EnableAnnotationMode(); InitializeSimpleSinglePageBasicLayout(); - // Select the highlighter tool with an "Orange" color. - TestAnnotationBrushMessageParams params = {/*color_r=*/0xFF, - /*color_g=*/0x63, - /*color_b=*/0x0C, /*size=*/6.0f}; - SelectBrushTool(PdfInkBrush::Type::kHighlighter, params); + SelectBrushTool(PdfInkBrush::Type::kHighlighter, kOrangeBrushParams); constexpr gfx::Rect kHorizontalSelection2{15, 25, 10, 5}; std::vector<gfx::Rect> selection_rects{kHorizontalSelection, @@ -3396,14 +3414,10 @@ EnableAnnotationMode(); InitializeSimpleSinglePageBasicLayout(); - // Select the highlighter tool with an "Orange" color. - TestAnnotationBrushMessageParams params = {/*color_r=*/0xFF, - /*color_g=*/0x63, - /*color_b=*/0x0C, /*size=*/6.0}; - SelectBrushTool(PdfInkBrush::Type::kHighlighter, params); + SelectBrushTool(PdfInkBrush::Type::kHighlighter, kOrangeBrushParams); // There will be no text selection rects. - std::vector<gfx::Rect> selection_rects{}; + std::vector<gfx::Rect> selection_rects; EXPECT_CALL(client(), GetSelectionRects()).WillOnce(Return(selection_rects)); EXPECT_CALL(client(), IsSelectableTextOrLinkArea(kStartPointInsidePage0)) .WillRepeatedly(Return(true)); @@ -3426,11 +3440,7 @@ EnableAnnotationMode(); InitializeSimpleSinglePageBasicLayout(); - // Select the highlighter tool with an "Orange" color. - TestAnnotationBrushMessageParams params = {/*color_r=*/0xFF, - /*color_g=*/0x63, - /*color_b=*/0x0C, /*size=*/6.0}; - SelectBrushTool(PdfInkBrush::Type::kHighlighter, params); + SelectBrushTool(PdfInkBrush::Type::kHighlighter, kOrangeBrushParams); ClickTextAtPoint(kStartPointInsidePage0, /*click_count=*/1); @@ -3469,11 +3479,7 @@ EnableAnnotationMode(); InitializeSimpleSinglePageBasicLayout(); - // Select the highlighter tool with an "Orange" color. - TestAnnotationBrushMessageParams params = {/*color_r=*/0xFF, - /*color_g=*/0x63, - /*color_b=*/0x0C, /*size=*/6.0}; - SelectBrushTool(PdfInkBrush::Type::kHighlighter, params); + SelectBrushTool(PdfInkBrush::Type::kHighlighter, kOrangeBrushParams); ClickTextAtPoint(kStartPointInsidePage0, /*click_count=*/1); @@ -3523,11 +3529,7 @@ EnableAnnotationMode(); InitializeSimpleSinglePageBasicLayout(); - // Select the highlighter tool with an "Orange" color. - TestAnnotationBrushMessageParams params = {/*color_r=*/0xFF, - /*color_g=*/0x63, - /*color_b=*/0x0C, /*size=*/6.0f}; - SelectBrushTool(PdfInkBrush::Type::kHighlighter, params); + SelectBrushTool(PdfInkBrush::Type::kHighlighter, kOrangeBrushParams); // Start in a text area. EXPECT_CALL(client(), IsSelectableTextOrLinkArea(_)).WillOnce(Return(true)); @@ -3587,11 +3589,7 @@ EnableAnnotationMode(); InitializeVerticalTwoPageLayout(); - // Select the highlighter tool with an "Orange" color. - TestAnnotationBrushMessageParams params = {/*color_r=*/0xFF, - /*color_g=*/0x63, - /*color_b=*/0x0C, /*size=*/6.0f}; - SelectBrushTool(PdfInkBrush::Type::kHighlighter, params); + SelectBrushTool(PdfInkBrush::Type::kHighlighter, kOrangeBrushParams); // Start on page 0. EXPECT_CALL(client(), IsSelectableTextOrLinkArea(_)) @@ -3667,11 +3665,7 @@ EnableAnnotationMode(); InitializeSimpleSinglePageBasicLayout(); - // Select the highlighter tool with an "Orange" color. - TestAnnotationBrushMessageParams params = {/*color_r=*/0xFF, - /*color_g=*/0x63, - /*color_b=*/0x0C, /*size=*/6.0f}; - SelectBrushTool(PdfInkBrush::Type::kHighlighter, params); + SelectBrushTool(PdfInkBrush::Type::kHighlighter, kOrangeBrushParams); std::vector<gfx::Rect> selection_rects{gfx::Rect(9, 14, 5, 10)}; EXPECT_CALL(client(), GetSelectionRects()) @@ -3686,6 +3680,114 @@ RunStrokeMissedEndEventThenMouseMoveTest(); } +TEST_P(PdfInkModuleTextHighlightTest, TouchSingleHorizontalSelection) { + SetUpSingleSelectionTest(kHorizontalSelection); + + // Apply a text highlight stroke at the given points. + ApplyStrokeWithTouchAtPoints(base::span_from_ref(kStartPointInsidePage0), + {base::span_from_ref(kEndPointInsidePage0)}, + base::span_from_ref(kEndPointInsidePage0)); + + constexpr auto kExpectedInputs = std::to_array<PdfInkInputData>( + {PdfInkInputData(gfx::PointF(15.0, 20.0)), + PdfInkInputData(gfx::PointF(35.0, 20.0))}); + VerifySingleSelectionTest(kExpectedInputs, /*expected_size=*/10.0f); +} + +TEST_P(PdfInkModuleTextHighlightTest, TouchOneClickCount) { + EnableAnnotationMode(); + InitializeSimpleSinglePageBasicLayout(); + + SelectBrushTool(PdfInkBrush::Type::kHighlighter, kOrangeBrushParams); + + // There will be no text selection rects. + std::vector<gfx::Rect> selection_rects; + EXPECT_CALL(client(), GetSelectionRects()).WillOnce(Return(selection_rects)); + EXPECT_CALL(client(), IsSelectableTextOrLinkArea(kStartPointInsidePage0)) + .WillRepeatedly(Return(true)); + + EXPECT_CALL(client(), OnTextOrLinkAreaClick(kStartPointInsidePage0, + /*click_count=*/1)); + EXPECT_CALL(client(), ExtendSelectionByPoint(_)).Times(0); + + blink::WebTouchEvent touch_event = + CreateTouchEvent(blink::WebInputEvent::Type::kTouchStart, + base::span_from_ref(kStartPointInsidePage0)); + EXPECT_TRUE(ink_module().HandleInputEvent(touch_event)); + + touch_event = CreateTouchEvent(blink::WebInputEvent::Type::kTouchEnd, + base::span_from_ref(kStartPointInsidePage0)); + EXPECT_TRUE(ink_module().HandleInputEvent(touch_event)); + + EXPECT_EQ(0, client().stroke_finished_count()); + EXPECT_TRUE(updated_ink_thumbnail_page_indices().empty()); + + std::map<int, std::vector<raw_ref<const ink::Stroke>>> collected_strokes = + CollectVisibleStrokes(ink_module().GetVisibleStrokesIterator()); + EXPECT_TRUE(collected_strokes.empty()); +} + +TEST_P(PdfInkModuleTextHighlightTest, MultiTouchDoesNotSelectText) { + EnableAnnotationMode(); + InitializeSimpleSinglePageBasicLayout(); + + SelectBrushTool(PdfInkBrush::Type::kHighlighter, kOrangeBrushParams); + + EXPECT_CALL(client(), IsSelectableTextOrLinkArea(_)).Times(0); + + ApplyStrokeWithTouchAtPointsNotHandled( + {kStartPointInsidePage0, kStartPointInsidePage0}, + {{kEndPointInsidePage0, kEndPointInsidePage0}}, + {kEndPointInsidePage0, kEndPointInsidePage0}); +} + +TEST_P(PdfInkModuleTextHighlightTest, PenSingleHorizontalSelection) { + const std::vector<PdfInkInputData> expected_inputs{ + PdfInkInputData(gfx::PointF(15.0, 20.0)), + PdfInkInputData(gfx::PointF(35.0, 20.0))}; + SetUpSingleSelectionTest(kHorizontalSelection); + + // Apply a text highlight stroke at the given points. + ApplyStrokeWithPenAtPoints(base::span_from_ref(kStartPointInsidePage0), + {base::span_from_ref(kEndPointInsidePage0)}, + base::span_from_ref(kEndPointInsidePage0)); + + VerifySingleSelectionTest(expected_inputs, /*expected_size=*/10.0f); +} + +TEST_P(PdfInkModuleTextHighlightTest, PenOneClickCount) { + EnableAnnotationMode(); + InitializeSimpleSinglePageBasicLayout(); + + SelectBrushTool(PdfInkBrush::Type::kHighlighter, kOrangeBrushParams); + + // There will be no text selection rects. + std::vector<gfx::Rect> selection_rects; + EXPECT_CALL(client(), GetSelectionRects()).WillOnce(Return(selection_rects)); + EXPECT_CALL(client(), IsSelectableTextOrLinkArea(kStartPointInsidePage0)) + .WillRepeatedly(Return(true)); + + EXPECT_CALL(client(), OnTextOrLinkAreaClick(kStartPointInsidePage0, + /*click_count=*/1)); + EXPECT_CALL(client(), ExtendSelectionByPoint(_)).Times(0); + + blink::WebTouchEvent pen_event = + CreatePenEvent(blink::WebInputEvent::Type::kTouchStart, + base::span_from_ref(kStartPointInsidePage0)); + EXPECT_TRUE(ink_module().HandleInputEvent(pen_event)); + + pen_event = CreatePenEvent(blink::WebInputEvent::Type::kTouchEnd, + base::span_from_ref(kStartPointInsidePage0)); + EXPECT_TRUE(ink_module().HandleInputEvent(pen_event)); + + EXPECT_EQ(0, client().stroke_finished_count()); + EXPECT_TRUE(updated_ink_thumbnail_page_indices().empty()); + + std::map<int, std::vector<raw_ref<const ink::Stroke>>> collected_strokes = + CollectVisibleStrokes(ink_module().GetVisibleStrokesIterator()); + EXPECT_TRUE(collected_strokes.empty()); +} + TEST_P(PdfInkModuleTextHighlightTest, CursorOnMouseMove) { EnableAnnotationMode(); InitializeSimpleSinglePageBasicLayout(); @@ -3695,8 +3797,7 @@ EXPECT_CALL(client(), UpdateInkCursor(CursorBitmapImageSizeEq(SkISize(8, 8)))); - TestAnnotationBrushMessageParams params = {/*color_r=*/0xF2, /*color_g=*/0x8B, - /*color_b=*/0x82, /*size=*/6.0f}; + TestAnnotationBrushMessageParams params = kRedBrushParams; SelectBrushTool(PdfInkBrush::Type::kPen, params); // `kStartPointInsidePage0` will be the selectable text area position, while @@ -3751,10 +3852,8 @@ // Select the highlighter tool. The cursor should be the custom highlighter // cursor. EXPECT_CALL(client(), - UpdateInkCursor(CursorBitmapImageSizeEq(SkISize(10, 10)))); - TestAnnotationBrushMessageParams params = {/*color_r=*/0xF2, /*color_g=*/0x8B, - /*color_b=*/0x82, /*size=*/8.0f}; - SelectBrushTool(PdfInkBrush::Type::kHighlighter, params); + UpdateInkCursor(CursorBitmapImageSizeEq(SkISize(8, 8)))); + SelectBrushTool(PdfInkBrush::Type::kHighlighter, kRedBrushParams); VerifyAndClearExpectations(); @@ -3791,7 +3890,7 @@ // End text highlighting. The cursor should restore to the custom highlighter // cursor. EXPECT_CALL(client(), - UpdateInkCursor(CursorBitmapImageSizeEq(SkISize(10, 10)))); + UpdateInkCursor(CursorBitmapImageSizeEq(SkISize(8, 8)))); blink::WebMouseEvent mouse_up_event = MouseEventBuilder() .CreateLeftMouseUpAtPosition(kEndPointInsidePage0) @@ -3806,10 +3905,8 @@ // Select the highlighter tool. The cursor should be the custom highlighter // cursor. EXPECT_CALL(client(), - UpdateInkCursor(CursorBitmapImageSizeEq(SkISize(10, 10)))); - TestAnnotationBrushMessageParams params = {/*color_r=*/0xF2, /*color_g=*/0x8B, - /*color_b=*/0x82, /*size=*/8.0f}; - SelectBrushTool(PdfInkBrush::Type::kHighlighter, params); + UpdateInkCursor(CursorBitmapImageSizeEq(SkISize(8, 8)))); + SelectBrushTool(PdfInkBrush::Type::kHighlighter, kRedBrushParams); VerifyAndClearExpectations();
diff --git a/pdf/pdf_view_web_plugin.cc b/pdf/pdf_view_web_plugin.cc index bcb7097..a51357c 100644 --- a/pdf/pdf_view_web_plugin.cc +++ b/pdf/pdf_view_web_plugin.cc
@@ -1481,6 +1481,15 @@ void PdfViewWebPlugin::SelectionChanged(const gfx::Rect& left, const gfx::Rect& right) { +#if BUILDFLAG(ENABLE_PDF_INK2) + // Ignore the selected text if `ink_module_` is currently text highlighting. + // This prevents `pdf_host_` from showing touch handles for touch text + // highlighting. + if (ink_module_ && ink_module_->ShouldBlockTextSelectionChanged()) { + return; + } +#endif // BUILDFLAG(ENABLE_PDF_INK2) + gfx::PointF left_point(left.x() + available_area_.x(), left.y()); gfx::PointF right_point(right.x() + available_area_.x(), right.y()); @@ -1514,8 +1523,7 @@ void PdfViewWebPlugin::SetSelectedText(const std::string& selected_text) { #if BUILDFLAG(ENABLE_PDF_INK2) // Ignore the selected text if `ink_module_` is currently text highlighting. - if (features::kPdfInk2TextHighlighting.Get() && - ink_module_->ShouldBlockTextSelectionChanged()) { + if (ink_module_ && ink_module_->ShouldBlockTextSelectionChanged()) { return; } #endif // BUILDFLAG(ENABLE_PDF_INK2)
diff --git a/pdf/pdf_view_web_plugin_unittest.cc b/pdf/pdf_view_web_plugin_unittest.cc index 87ade8d6..d4331a5 100644 --- a/pdf/pdf_view_web_plugin_unittest.cc +++ b/pdf/pdf_view_web_plugin_unittest.cc
@@ -3333,9 +3333,10 @@ // Enter annotation mode and select the highlighter. plugin_->OnMessage(CreateSetAnnotationModeMessageForTesting(/*enable=*/true)); - TestAnnotationBrushMessageParams message_params{/*color_r=*/240, - /*color_g=*/133, - /*color_b=*/0, /*size=*/4.5}; + TestAnnotationBrushMessageParams message_params{/*color_r=*/0xF0, + /*color_g=*/0x85, + /*color_b=*/0x00, + /*size=*/4.5f}; plugin_->OnMessage(CreateSetAnnotationBrushMessageForTesting( "highlighter", &message_params)); @@ -3353,14 +3354,20 @@ EXPECT_CALL(*client_ptr_, TextSelectionChanged(_, _, _)).Times(0); plugin_->SetSelectedText("text"); + + EXPECT_CALL(pdf_host_, SelectionChanged(_, _, _, _)).Times(0); + + plugin_->SelectionChanged({-10, -20, 30, 40}, {50, 60, 70, 80}); + pdf_receiver_.FlushForTesting(); } TEST_P(PdfViewWebPluginInkTextHighlightTest, DrawInProgressTextHighlight) { // Enter annotation mode and select the highlighter. plugin_->OnMessage(CreateSetAnnotationModeMessageForTesting(/*enable=*/true)); - TestAnnotationBrushMessageParams message_params{/*color_r=*/240, - /*color_g=*/133, - /*color_b=*/0, /*size=*/4.5}; + TestAnnotationBrushMessageParams message_params{/*color_r=*/0xF0, + /*color_g=*/0x85, + /*color_b=*/0x00, + /*size=*/4.5f}; plugin_->OnMessage(CreateSetAnnotationBrushMessageForTesting( "highlighter", &message_params));
diff --git a/remoting/resources/BUILD.gn b/remoting/resources/BUILD.gn index aeed8ca..9b3231f 100644 --- a/remoting/resources/BUILD.gn +++ b/remoting/resources/BUILD.gn
@@ -38,7 +38,7 @@ ] + rebase_path(sources_to_verify, root_build_dir) } -grit("strings") { +grit_strings("strings") { source = "remoting_strings.grd" output_name = "remoting_strings" @@ -46,15 +46,13 @@ # generated file root. output_dir = root_gen_dir - outputs = [ "remoting/base/string_resources.h" ] + outputs = + [ "remoting/base/string_resources.h" ] + remoting_resources_locale_files # The grd produces a *.pak file and a messages.json file (this one uses # underscores instead of hyphens) for each locale. - outputs += - process_file_template(remoting_locales_with_pseudolocales, - [ "remoting/resources/{{source_name_part}}.pak" ]) - - outputs += remoting_resources_locale_files + locales = remoting_locales_with_pseudolocales + output_prefix = "remoting/resources/" if (is_official_build) { defines = [ "_official_build" ] @@ -68,21 +66,42 @@ # replacement over the locales. Here, we can do this in GN script by # pretending the locale list is a list of files. The {{source_name_part}} # will just expand to the locale name. - inputs = process_file_template( - remoting_locales, - [ "$root_gen_dir/remoting/resources/{{source_name_part}}.pak" ]) + inputs = [] + foreach(locale, remoting_locales) { + if (translate_genders) { + inputs += process_file_template( + all_chrome_genders, + "$root_gen_dir/remoting/resources/${locale}_{{source_name_part}}.pak") + } else { + inputs += [ "$root_gen_dir/remoting/resources/${locale}.pak" ] + } + } # Likewise, process the outputs in the same way as the inputs. + outputs = [] if (is_apple) { # On mac, use underscores instead of hyphens and put the files in a # different place. - outputs = process_file_template( - remoting_locales_with_underscores, - [ "$root_out_dir/remoting/resources/{{source_name_part}}.lproj/locale.pak" ]) + foreach(locale, remoting_locales_with_underscores) { + if (translate_genders) { + outputs += process_file_template( + all_chrome_genders, + "$root_out_dir/remoting/resources/${locale}_{{source_name_part}}.lproj/locale.pak") + } else { + outputs += + [ "$root_out_dir/remoting/resources/${locale}.lproj/locale.pak" ] + } + } } else { - outputs = process_file_template( - remoting_locales, - [ "$root_out_dir/remoting_locales/{{source_name_part}}.pak" ]) + foreach(locale, remoting_locales) { + if (translate_genders) { + outputs += process_file_template( + all_chrome_genders, + "$root_out_dir/remoting_locales/${locale}_{{source_name_part}}.pak") + } else { + outputs += [ "$root_out_dir/remoting_locales/${locale}.pak" ] + } + } } args = [
diff --git a/services/data_decoder/BUILD.gn b/services/data_decoder/BUILD.gn index e9edd2cf..cfb9adda 100644 --- a/services/data_decoder/BUILD.gn +++ b/services/data_decoder/BUILD.gn
@@ -23,8 +23,6 @@ "data_decoder_service.h", "gzipper.cc", "gzipper.h", - "json_parser_impl.cc", - "json_parser_impl.h", "structured_headers_parser_impl.cc", "structured_headers_parser_impl.h", "xml_parser.cc",
diff --git a/services/data_decoder/data_decoder_service.cc b/services/data_decoder/data_decoder_service.cc index c62d95a0..8e03776c 100644 --- a/services/data_decoder/data_decoder_service.cc +++ b/services/data_decoder/data_decoder_service.cc
@@ -15,7 +15,6 @@ #include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "services/data_decoder/cbor_parser_impl.h" #include "services/data_decoder/gzipper.h" -#include "services/data_decoder/json_parser_impl.h" #include "services/data_decoder/public/mojom/image_decoder.mojom.h" #include "services/data_decoder/structured_headers_parser_impl.h" #include "services/data_decoder/xml_parser.h" @@ -54,12 +53,6 @@ #endif } -void DataDecoderService::BindJsonParser( - mojo::PendingReceiver<mojom::JsonParser> receiver) { - mojo::MakeSelfOwnedReceiver(std::make_unique<JsonParserImpl>(), - std::move(receiver)); -} - void DataDecoderService::BindStructuredHeadersParser( mojo::PendingReceiver<mojom::StructuredHeadersParser> receiver) { mojo::MakeSelfOwnedReceiver(std::make_unique<StructuredHeadersParserImpl>(),
diff --git a/services/data_decoder/data_decoder_service.h b/services/data_decoder/data_decoder_service.h index aa07370..8ed7492 100644 --- a/services/data_decoder/data_decoder_service.h +++ b/services/data_decoder/data_decoder_service.h
@@ -13,7 +13,6 @@ #include "services/data_decoder/public/mojom/data_decoder_service.mojom.h" #include "services/data_decoder/public/mojom/gzipper.mojom.h" #include "services/data_decoder/public/mojom/image_decoder.mojom.h" -#include "services/data_decoder/public/mojom/json_parser.mojom.h" #include "services/data_decoder/public/mojom/structured_headers_parser.mojom.h" #include "services/data_decoder/public/mojom/xml_parser.mojom.h" @@ -43,8 +42,6 @@ // mojom::DataDecoderService implementation: void BindImageDecoder( mojo::PendingReceiver<mojom::ImageDecoder> receiver) override; - void BindJsonParser( - mojo::PendingReceiver<mojom::JsonParser> receiver) override; void BindStructuredHeadersParser( mojo::PendingReceiver<mojom::StructuredHeadersParser> receiver) override; void BindXmlParser(mojo::PendingReceiver<mojom::XmlParser> receiver) override;
diff --git a/services/data_decoder/json_parser_impl.cc b/services/data_decoder/json_parser_impl.cc deleted file mode 100644 index b9bdb32..0000000 --- a/services/data_decoder/json_parser_impl.cc +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2016 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "services/data_decoder/json_parser_impl.h" - -#include <memory> -#include <utility> - -#include "base/json/json_reader.h" -#include "base/values.h" - -namespace data_decoder { - -JsonParserImpl::JsonParserImpl() = default; - -JsonParserImpl::~JsonParserImpl() = default; - -void JsonParserImpl::Parse(const std::string& json, - uint32_t options, - ParseCallback callback) { - auto ret = base::JSONReader::ReadAndReturnValueWithError(json, options); - if (ret.has_value()) { - std::move(callback).Run(std::move(*ret), std::nullopt); - } else { - std::move(callback).Run(std::nullopt, - std::make_optional(std::move(ret.error().message))); - } -} - -} // namespace data_decoder
diff --git a/services/data_decoder/json_parser_impl.h b/services/data_decoder/json_parser_impl.h deleted file mode 100644 index c37a028..0000000 --- a/services/data_decoder/json_parser_impl.h +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2013 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SERVICES_DATA_DECODER_JSON_PARSER_IMPL_H_ -#define SERVICES_DATA_DECODER_JSON_PARSER_IMPL_H_ - -#include <string> - -#include "services/data_decoder/public/mojom/json_parser.mojom.h" - -namespace data_decoder { - -class JsonParserImpl : public mojom::JsonParser { - public: - JsonParserImpl(); - - JsonParserImpl(const JsonParserImpl&) = delete; - JsonParserImpl& operator=(const JsonParserImpl&) = delete; - - ~JsonParserImpl() override; - - private: - // mojom::JsonParser implementation. - void Parse(const std::string& json, - uint32_t options, - ParseCallback callback) override; -}; - -} // namespace data_decoder - -#endif // SERVICES_DATA_DECODER_JSON_PARSER_IMPL_H_
diff --git a/services/data_decoder/public/cpp/data_decoder.cc b/services/data_decoder/public/cpp/data_decoder.cc index 512b48a..da86c8f 100644 --- a/services/data_decoder/public/cpp/data_decoder.cc +++ b/services/data_decoder/public/cpp/data_decoder.cc
@@ -23,7 +23,6 @@ #include "net/http/structured_headers.h" #include "services/data_decoder/public/mojom/cbor_parser.mojom.h" #include "services/data_decoder/public/mojom/gzipper.mojom.h" -#include "services/data_decoder/public/mojom/json_parser.mojom.h" #include "services/data_decoder/public/mojom/structured_headers_parser.mojom.h" #include "services/data_decoder/public/mojom/xml_parser.mojom.h"
diff --git a/services/data_decoder/public/cpp/data_decoder_unittest.cc b/services/data_decoder/public/cpp/data_decoder_unittest.cc index 0e8cf67..313659e 100644 --- a/services/data_decoder/public/cpp/data_decoder_unittest.cc +++ b/services/data_decoder/public/cpp/data_decoder_unittest.cc
@@ -17,7 +17,6 @@ #include "build/build_config.h" #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h" #include "services/data_decoder/public/mojom/cbor_parser.mojom.h" -#include "services/data_decoder/public/mojom/json_parser.mojom.h" #include "testing/gtest/include/gtest/gtest.h" namespace data_decoder { @@ -31,44 +30,6 @@ test::InProcessDataDecoder in_process_data_decoder_; }; -TEST_F(DataDecoderTest, ReuseJson) { - // Verify that a single DataDecoder with concurrent interface connections will - // only use one service instance. - - DataDecoder decoder; - mojo::Remote<mojom::JsonParser> parser1; - decoder.GetService()->BindJsonParser(parser1.BindNewPipeAndPassReceiver()); - parser1.FlushForTesting(); - EXPECT_TRUE(parser1.is_connected()); - EXPECT_EQ(1u, service().receivers().size()); - - mojo::Remote<mojom::JsonParser> parser2; - decoder.GetService()->BindJsonParser(parser2.BindNewPipeAndPassReceiver()); - parser2.FlushForTesting(); - EXPECT_TRUE(parser2.is_connected()); - EXPECT_TRUE(parser1.is_connected()); - EXPECT_EQ(1u, service().receivers().size()); -} - -TEST_F(DataDecoderTest, IsolationJson) { - // Verify that separate DataDecoder instances make separate connections to the - // service. - - DataDecoder decoder1; - mojo::Remote<mojom::JsonParser> parser1; - decoder1.GetService()->BindJsonParser(parser1.BindNewPipeAndPassReceiver()); - parser1.FlushForTesting(); - EXPECT_TRUE(parser1.is_connected()); - EXPECT_EQ(1u, service().receivers().size()); - - DataDecoder decoder2; - mojo::Remote<mojom::JsonParser> parser2; - decoder2.GetService()->BindJsonParser(parser2.BindNewPipeAndPassReceiver()); - parser2.FlushForTesting(); - EXPECT_TRUE(parser2.is_connected()); - EXPECT_EQ(2u, service().receivers().size()); -} - TEST_F(DataDecoderTest, ReuseCbor) { // Verify that a single DataDecoder with concurrent interface connections will // only use one service instance.
diff --git a/services/data_decoder/public/cpp/test_support/fake_data_decoder_service.cc b/services/data_decoder/public/cpp/test_support/fake_data_decoder_service.cc index d518580..4d288aa 100644 --- a/services/data_decoder/public/cpp/test_support/fake_data_decoder_service.cc +++ b/services/data_decoder/public/cpp/test_support/fake_data_decoder_service.cc
@@ -17,11 +17,6 @@ FAIL(); } -void FakeDataDecoderService::BindJsonParser( - mojo::PendingReceiver<data_decoder::mojom::JsonParser> receiver) { - FAIL(); -} - void FakeDataDecoderService::BindStructuredHeadersParser( mojo::PendingReceiver<data_decoder::mojom::StructuredHeadersParser> receiver) {
diff --git a/services/data_decoder/public/cpp/test_support/fake_data_decoder_service.h b/services/data_decoder/public/cpp/test_support/fake_data_decoder_service.h index 1027e9a1..f00fc286 100644 --- a/services/data_decoder/public/cpp/test_support/fake_data_decoder_service.h +++ b/services/data_decoder/public/cpp/test_support/fake_data_decoder_service.h
@@ -12,7 +12,6 @@ #include "services/data_decoder/public/mojom/data_decoder_service.mojom.h" #include "services/data_decoder/public/mojom/gzipper.mojom.h" #include "services/data_decoder/public/mojom/image_decoder.mojom.h" -#include "services/data_decoder/public/mojom/json_parser.mojom.h" #include "services/data_decoder/public/mojom/structured_headers_parser.mojom.h" #include "services/data_decoder/public/mojom/xml_parser.mojom.h" @@ -34,8 +33,6 @@ // data_decoder::mojom::DataDecoderService: void BindImageDecoder(mojo::PendingReceiver<data_decoder::mojom::ImageDecoder> receiver) override; - void BindJsonParser(mojo::PendingReceiver<data_decoder::mojom::JsonParser> - receiver) override; void BindStructuredHeadersParser( mojo::PendingReceiver<data_decoder::mojom::StructuredHeadersParser> receiver) override;
diff --git a/services/data_decoder/public/cpp/test_support/in_process_data_decoder.cc b/services/data_decoder/public/cpp/test_support/in_process_data_decoder.cc index 9ddde27..239041c 100644 --- a/services/data_decoder/public/cpp/test_support/in_process_data_decoder.cc +++ b/services/data_decoder/public/cpp/test_support/in_process_data_decoder.cc
@@ -59,11 +59,6 @@ GetForwardingInterface()->BindImageDecoder(std::move(receiver)); } -void InProcessDataDecoder::BindJsonParser( - mojo::PendingReceiver<mojom::JsonParser> receiver) { - GetForwardingInterface()->BindJsonParser(std::move(receiver)); -} - void InProcessDataDecoder::BindWebBundleParserFactory( mojo::PendingReceiver<web_package::mojom::WebBundleParserFactory> receiver) {
diff --git a/services/data_decoder/public/cpp/test_support/in_process_data_decoder.h b/services/data_decoder/public/cpp/test_support/in_process_data_decoder.h index 7169bad..1deb349 100644 --- a/services/data_decoder/public/cpp/test_support/in_process_data_decoder.h +++ b/services/data_decoder/public/cpp/test_support/in_process_data_decoder.h
@@ -63,8 +63,6 @@ mojom::DataDecoderService* GetForwardingInterface() override; void BindImageDecoder( mojo::PendingReceiver<mojom::ImageDecoder> receiver) override; - void BindJsonParser( - mojo::PendingReceiver<mojom::JsonParser> receiver) override; void BindWebBundleParserFactory( mojo::PendingReceiver<web_package::mojom::WebBundleParserFactory> receiver) override;
diff --git a/services/data_decoder/public/mojom/BUILD.gn b/services/data_decoder/public/mojom/BUILD.gn index 89edc148..7f8fb52 100644 --- a/services/data_decoder/public/mojom/BUILD.gn +++ b/services/data_decoder/public/mojom/BUILD.gn
@@ -10,7 +10,6 @@ "data_decoder_service.mojom", "gzipper.mojom", "image_decoder.mojom", - "json_parser.mojom", "structured_headers_parser.mojom", ]
diff --git a/services/data_decoder/public/mojom/data_decoder_service.mojom b/services/data_decoder/public/mojom/data_decoder_service.mojom index 8779e65..d3ac389 100644 --- a/services/data_decoder/public/mojom/data_decoder_service.mojom +++ b/services/data_decoder/public/mojom/data_decoder_service.mojom
@@ -10,7 +10,6 @@ import "services/data_decoder/public/mojom/cbor_parser.mojom"; import "services/data_decoder/public/mojom/gzipper.mojom"; import "services/data_decoder/public/mojom/image_decoder.mojom"; -import "services/data_decoder/public/mojom/json_parser.mojom"; import "services/data_decoder/public/mojom/structured_headers_parser.mojom"; import "services/data_decoder/public/mojom/xml_parser.mojom"; @@ -23,9 +22,6 @@ // Binds an interface which can be used to decode compressed image data. BindImageDecoder(pending_receiver<ImageDecoder> receiver); - // Binds an interface which can be used to parse JSON data. - BindJsonParser(pending_receiver<JsonParser> receiver); - // Binds an interface which can be used to parse XML data. BindXmlParser(pending_receiver<XmlParser> reciever);
diff --git a/services/data_decoder/public/mojom/json_parser.mojom b/services/data_decoder/public/mojom/json_parser.mojom deleted file mode 100644 index cb761fcb..0000000 --- a/services/data_decoder/public/mojom/json_parser.mojom +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2016 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -module data_decoder.mojom; - -import "mojo/public/mojom/base/values.mojom"; - -// Interface to parse JSON documents into a base::Value structure. -interface JsonParser { - // Parses the input |json| according to the base::JSONReader |options| - // bitmask. Returns the parsed |result| on success or a string - // |error| message on failure. - Parse(string json, uint32 options) => - (mojo_base.mojom.Value? result, string? error); -};
diff --git a/services/network/cookie_manager_unittest.cc b/services/network/cookie_manager_unittest.cc index 6498e754..96a2d06 100644 --- a/services/network/cookie_manager_unittest.cc +++ b/services/network/cookie_manager_unittest.cc
@@ -2412,24 +2412,26 @@ TEST_F(CookieManagerTest, BlockThirdPartyCookies) { const GURL kThisURL = GURL("http://www.this.com"); + const net::CookiePartitionKey cookie_partition_key = + net::CookiePartitionKey::FromURLForTesting(kThisURL); const url::Origin kThisOrigin = url::Origin::Create(kThisURL); const net::SiteForCookies kThisSiteForCookies = net::SiteForCookies::FromOrigin(kThisOrigin); const net::SiteForCookies kNullSiteForCookies; EXPECT_TRUE(service()->cookie_settings().IsFullCookieAccessAllowed( - kThisURL, kNullSiteForCookies, kThisOrigin, - net::CookieSettingOverrides())); + kThisURL, kNullSiteForCookies, kThisOrigin, net::CookieSettingOverrides(), + cookie_partition_key)); // Set block third party cookies to true, cookie should now be blocked. cookie_service_client()->BlockThirdPartyCookies(true); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(service()->cookie_settings().IsFullCookieAccessAllowed( - kThisURL, kNullSiteForCookies, kThisOrigin, - net::CookieSettingOverrides())); + kThisURL, kNullSiteForCookies, kThisOrigin, net::CookieSettingOverrides(), + cookie_partition_key)); EXPECT_TRUE(service()->cookie_settings().IsFullCookieAccessAllowed( - kThisURL, kThisSiteForCookies, kThisOrigin, - net::CookieSettingOverrides())); + kThisURL, kThisSiteForCookies, kThisOrigin, net::CookieSettingOverrides(), + cookie_partition_key)); // Set block third party cookies back to false, cookie should no longer be // blocked. @@ -2437,8 +2439,8 @@ base::RunLoop().RunUntilIdle(); EXPECT_TRUE(service()->cookie_settings().IsFullCookieAccessAllowed( - kThisURL, kNullSiteForCookies, kThisOrigin, - net::CookieSettingOverrides())); + kThisURL, kNullSiteForCookies, kThisOrigin, net::CookieSettingOverrides(), + cookie_partition_key)); } // A test class having cookie store with a persistent backing store.
diff --git a/services/network/network_service_network_delegate.cc b/services/network/network_service_network_delegate.cc index 6052048..8f991bc 100644 --- a/services/network/network_service_network_delegate.cc +++ b/services/network/network_service_network_delegate.cc
@@ -345,9 +345,9 @@ const url::Origin& origin) const { return network_context_->cookie_manager() ->cookie_settings() - .IsFullCookieAccessAllowed(origin.GetURL(), - net::SiteForCookies::FromOrigin(origin), - origin, net::CookieSettingOverrides()); + .IsFullCookieAccessAllowed( + origin.GetURL(), net::SiteForCookies::FromOrigin(origin), origin, + net::CookieSettingOverrides(), /*cookie_partition_key=*/std::nullopt); } void NetworkServiceNetworkDelegate::OnCanSendReportingReports( @@ -379,9 +379,9 @@ const GURL& endpoint) const { return network_context_->cookie_manager() ->cookie_settings() - .IsFullCookieAccessAllowed(origin.GetURL(), - net::SiteForCookies::FromOrigin(origin), - origin, net::CookieSettingOverrides()); + .IsFullCookieAccessAllowed( + origin.GetURL(), net::SiteForCookies::FromOrigin(origin), origin, + net::CookieSettingOverrides(), /*cookie_partition_key=*/std::nullopt); } bool NetworkServiceNetworkDelegate::OnCanUseReportingClient( @@ -389,9 +389,9 @@ const GURL& endpoint) const { return network_context_->cookie_manager() ->cookie_settings() - .IsFullCookieAccessAllowed(origin.GetURL(), - net::SiteForCookies::FromOrigin(origin), - origin, net::CookieSettingOverrides()); + .IsFullCookieAccessAllowed( + origin.GetURL(), net::SiteForCookies::FromOrigin(origin), origin, + net::CookieSettingOverrides(), /*cookie_partition_key=*/std::nullopt); } int NetworkServiceNetworkDelegate::HandleClearSiteDataHeader(
diff --git a/services/network/restricted_cookie_manager.cc b/services/network/restricted_cookie_manager.cc index 35593610..6096cd52 100644 --- a/services/network/restricted_cookie_manager.cc +++ b/services/network/restricted_cookie_manager.cc
@@ -1112,7 +1112,8 @@ storage_access_api_status, /*is_ad_tagged=*/false, /*apply_devtools_overrides=*/apply_devtools_overrides, - /*force_disable_third_party_cookies=*/false))); + /*force_disable_third_party_cookies=*/false), + cookie_partition_key_)); } void RestrictedCookieManager::InstallReceiver(
diff --git a/services/strings/BUILD.gn b/services/strings/BUILD.gn index 6bf8d877..d020be2 100644 --- a/services/strings/BUILD.gn +++ b/services/strings/BUILD.gn
@@ -7,17 +7,20 @@ import("//tools/grit/grit_rule.gni") import("//tools/grit/repack.gni") -grit("strings") { +grit_strings("strings") { source = "../services_strings.grd" defines = [ "enable_screen_ai_service=$enable_screen_ai_service" ] - outputs = - [ "grit/services_strings.h" ] + - process_file_template(all_chrome_locales, - [ "services_strings_{{source_name_part}}.pak" ]) + outputs = [ "grit/services_strings.h" ] + output_prefix = "services_strings_" } repack("services_test_strings") { - sources = [ "$root_gen_dir/services/strings/services_strings_en-US.pak" ] + if (translate_genders) { + sources = + [ "$root_gen_dir/services/strings/services_strings_en-US_OTHER.pak" ] + } else { + sources = [ "$root_gen_dir/services/strings/services_strings_en-US.pak" ] + } output = "$root_out_dir/services_test_strings.pak" deps = [ ":strings" ] }
diff --git a/services/webnn/tflite/graph_builder_tflite.cc b/services/webnn/tflite/graph_builder_tflite.cc index d4ef9f4..8643822 100644 --- a/services/webnn/tflite/graph_builder_tflite.cc +++ b/services/webnn/tflite/graph_builder_tflite.cc
@@ -1679,6 +1679,58 @@ } std::optional<GraphBuilderTflite::TensorInfo> +GraphBuilderTflite::CanFuseQuantizeAndGetOutput(const mojom::Pool2d& pool2d) { + // L2Pool doesn't support quantized implementation. + CHECK_NE(pool2d.kind, mojom::Pool2d::Kind::kL2Pool2d); + + if (!IsDequantizeOutput(pool2d.input_operand_id)) { + return std::nullopt; + } + + const mojom::DequantizeLinear& input_dequantize = + GetDequantizeOp(pool2d.input_operand_id); + if (!IsInts8AndScalarScale(input_dequantize)) { + return std::nullopt; + } + + // TODO(crbug.com/413083273): Consider the restriction in GPU delegate. + // For the kernel of pooling, the `|input scale - output scale|` must be less + // than 1.0e-6, and zero point of output tensor must be the same as input. + // https://source.chromium.org/chromium/chromium/src/+/main:third_party/tflite/src/tensorflow/lite/kernels/pooling.cc;drc=edd09bcc365dcc696d0f23ca7c3dc18f5e1dcdab;l=101 + std::optional<size_t> next_op = IsNextOpQuantize( + pool2d.output_operand_id, + {GetOperand(input_dequantize.input_operand_id).descriptor.data_type()}); + if (!next_op) { + return std::nullopt; + } + const mojom::QuantizeLinear& output_quantize = GetQuantizeOp(*next_op); + if (!IsInts8AndScalarScale(output_quantize)) { + return std::nullopt; + } + base::span<const float> input_scale_values = + GetConstantValue<float>(input_dequantize.scale_operand_id); + base::span<const float> output_scale_values = + GetConstantValue<float>(output_quantize.scale_operand_id); + base::CheckedNumeric<float> checked_sub_scale = + base::MakeCheckedNum<float>(input_scale_values[0]) - + output_scale_values[0]; + if (!checked_sub_scale.IsValid() || + checked_sub_scale.Abs().ValueOrDie() > 1.0e-6) { + return std::nullopt; + } + + base::FixedArray<int64_t> input_zero_point_values = + GetConstantInt64Value(input_dequantize.zero_point_operand_id); + base::FixedArray<int64_t> output_zero_point_values = + GetConstantInt64Value(output_quantize.zero_point_operand_id); + if (input_zero_point_values[0] != output_zero_point_values[0]) { + return std::nullopt; + } + + return TrySerializeQuantizedOutput(*next_op); +} + +std::optional<GraphBuilderTflite::TensorInfo> GraphBuilderTflite::CanFuseQuantizeAndGetOutput( const mojom::Transpose& transpose) { if (!IsDequantizeOutput(transpose.input_operand_id)) { @@ -1802,13 +1854,9 @@ } const mojom::QuantizeLinear& output_quantize = GetQuantizeOp(*next_op); - if (GetOperand(output_quantize.scale_operand_id) - .descriptor.NumberOfElements() != 1) { + if (!IsInts8AndScalarScale(output_quantize)) { return std::nullopt; } - CHECK_EQ(GetOperand(output_quantize.zero_point_operand_id) - .descriptor.NumberOfElements(), - 1u); return next_op; } @@ -1972,23 +2020,24 @@ return quantize_op_idx; } -bool GraphBuilderTflite::IsInts8AndScalarScale( - const mojom::DequantizeLinear& dequantize_linear) { - if (!DataTypeConstraint::kInts8.Has( - GetOperand(dequantize_linear.input_operand_id) - .descriptor.data_type())) { - return false; +template <typename OpType> + requires(std::is_same_v<OpType, mojom::DequantizeLinear> || + std::is_same_v<OpType, mojom::QuantizeLinear>) +bool GraphBuilderTflite::IsInts8AndScalarScale(const OpType& op) { + if constexpr (std::is_same_v<OpType, mojom::DequantizeLinear>) { + if (!DataTypeConstraint::kInts8.Has( + GetOperand(op.input_operand_id).descriptor.data_type())) { + return false; + } } - if (GetOperand(dequantize_linear.scale_operand_id) - .descriptor.NumberOfElements() != 1) { + if (GetOperand(op.scale_operand_id).descriptor.NumberOfElements() != 1) { return false; } // The shape of scale and zero point is the same that has been verified in // the function ValidateScaleZeroPointOperandShapeIsCompatibleWithInput. - CHECK_EQ(GetOperand(dequantize_linear.zero_point_operand_id) - .descriptor.NumberOfElements(), + CHECK_EQ(GetOperand(op.zero_point_operand_id).descriptor.NumberOfElements(), 1u); return true; } @@ -5510,7 +5559,27 @@ return base::unexpected("Pool2d in tflite doesn't support dilations."); } + ::tflite::BuiltinOperator operator_code; + std::optional<TensorInfo> quantized_output; const mojom::Operand& input_operand = GetOperand(pool2d.input_operand_id); + switch (pool2d.kind) { + case mojom::Pool2d::Kind::kAveragePool2d: + CHECK(context_properties_.data_type_limits.average_pool2d_input.Supports( + input_operand.descriptor)); + operator_code = ::tflite::BuiltinOperator_AVERAGE_POOL_2D; + quantized_output = CanFuseQuantizeAndGetOutput(pool2d); + break; + case mojom::Pool2d::Kind::kMaxPool2d: + CHECK(context_properties_.data_type_limits.max_pool2d_input.Supports( + input_operand.descriptor)); + operator_code = ::tflite::BuiltinOperator_MAX_POOL_2D; + quantized_output = CanFuseQuantizeAndGetOutput(pool2d); + break; + case mojom::Pool2d::Kind::kL2Pool2d: + // TODO(crbug.com/361717758): Support L2Pool2d. + return base::unexpected("L2Pool2d is not supported in tflite."); + } + const auto& input_shape = input_operand.descriptor.shape(); CHECK_EQ(input_shape.size(), 4u); const webnn::Size2d<uint32_t> input_size2d = {.height = input_shape[1], @@ -5523,8 +5592,13 @@ GetTfLitePaddingMode(*pool2d.padding, input_size2d, filter_size2d, *pool2d.strides, *pool2d.dilations, /*is_transposed_conv2d=*/false)); - ASSIGN_OR_RETURN(const TensorInfo& input_tensor_info, - SerializeInputTensorInfo(pool2d.input_operand_id)); + ASSIGN_OR_RETURN( + const TensorInfo& input_tensor_info, + SerializeInputTensorInfo( + pool2d.input_operand_id, + /*quantize_params=*/0, + /*operation_supports_float16=*/false, + /*fuse_dequantize_quantize=*/quantized_output.has_value())); // Insert a Pad operator before TfLite Pool2d if needed for explicit padding. std::optional<TensorIndex> explicit_pad_index; if (padding_mode.paddings) { @@ -5533,22 +5607,6 @@ InsertPadOperation(input_tensor_info, padding_mode.paddings.value())); } - ::tflite::BuiltinOperator operator_code; - switch (pool2d.kind) { - case mojom::Pool2d::Kind::kAveragePool2d: - CHECK(context_properties_.data_type_limits.average_pool2d_input.Supports( - input_operand.descriptor)); - operator_code = ::tflite::BuiltinOperator_AVERAGE_POOL_2D; - break; - case mojom::Pool2d::Kind::kMaxPool2d: - CHECK(context_properties_.data_type_limits.max_pool2d_input.Supports( - input_operand.descriptor)); - operator_code = ::tflite::BuiltinOperator_MAX_POOL_2D; - break; - case mojom::Pool2d::Kind::kL2Pool2d: - return base::unexpected("L2Pool2d is not supported in tflite."); - } - const auto pool_2d_options = ::tflite::CreatePool2DOptions( builder_, padding_mode.mode, pool2d.strides->width, pool2d.strides->height, filter_size2d.width, filter_size2d.height, @@ -5557,14 +5615,20 @@ // Create `tflite::Operator` with the tensor index of inputs and outputs // operand. The type of operation is determined by the index of the operator // code. - ASSIGN_OR_RETURN(const TensorInfo& output_tensor_info, - SerializeOutputTensorInfo(pool2d.output_operand_id)); + int32_t output_tensor_index; + if (quantized_output) { + output_tensor_index = quantized_output->index; + } else { + ASSIGN_OR_RETURN(const TensorInfo& output_tensor_info, + SerializeOutputTensorInfo(pool2d.output_operand_id)); + output_tensor_index = output_tensor_info.index; + } const OperatorCodeIndex operator_code_index = GetOperatorCodeIndex(operator_code); const std::array<TensorIndex, 1> op_inputs = {explicit_pad_index ? explicit_pad_index.value() : input_tensor_info.index}; - const std::array<TensorIndex, 1> op_outputs = {output_tensor_info.index}; + const std::array<TensorIndex, 1> op_outputs = {output_tensor_index}; return ::tflite::CreateOperator( builder_, operator_code_index, builder_.CreateVector<TensorIndex>(op_inputs),
diff --git a/services/webnn/tflite/graph_builder_tflite.h b/services/webnn/tflite/graph_builder_tflite.h index f986301..12e3d69 100644 --- a/services/webnn/tflite/graph_builder_tflite.h +++ b/services/webnn/tflite/graph_builder_tflite.h
@@ -724,6 +724,8 @@ const mojom::ElementWiseBinary& binary); std::optional<TensorInfo> CanFuseQuantizeAndGetOutput(const mojom::Elu& elu); std::optional<TensorInfo> CanFuseQuantizeAndGetOutput( + const mojom::Pool2d& pool2d); + std::optional<TensorInfo> CanFuseQuantizeAndGetOutput( const mojom::Transpose& transpose); std::optional<TensorInfo> CanFuseQuantizeAndGetOutput( const mojom::Tanh& tanh); @@ -763,12 +765,16 @@ std::optional<OperationId> IsNextOpQuantize( OperandId output_operand_id, SupportedDataTypes supported_quantized_types); - // Check if the input is dequantized from (u)int8, and its scale and zero - // point are scalar values. + // Check if the input of DequantizeLinear is (u)int8, the output of + // QuantizeLinear has been validated (u)int8 in `IsNextOpQuantize`, and its + // scale and zero point are scalar values. // // Used by DQ->op->Q fusion to satisfy XNNPACK delegate's validation in // `CheckTensorFloat32OrQUInt8Type`. - bool IsInts8AndScalarScale(const mojom::DequantizeLinear& dequantize_linear); + template <typename OpType> + requires(std::is_same_v<OpType, mojom::DequantizeLinear> || + std::is_same_v<OpType, mojom::QuantizeLinear>) + bool IsInts8AndScalarScale(const OpType& op); bool IsSerializedWithMismatchQuantizeParameters( OperandId operand_id,
diff --git a/testing/buildbot/README.md b/testing/buildbot/README.md index 1876694..85f6f45 100644 --- a/testing/buildbot/README.md +++ b/testing/buildbot/README.md
@@ -426,7 +426,7 @@ isolate, invoke a wrapper script from src/testing/scripts as their top-level entry point, and are used to adapt to multiple kinds of test harnesses. These must implement the - [Test Executable API](//docs/testing/test_executable_api.md) and + [Test Executable API](/docs/testing/test_executable_api.md) and can also be run either locally or under Swarming. * `junit_tests`: (Android-specific) JUnit tests. These are not run under Swarming.
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json index 9f68936..01a4ad9 100644 --- a/testing/buildbot/chromium.perf.fyi.json +++ b/testing/buildbot/chromium.perf.fyi.json
@@ -91,7 +91,6 @@ "--ignore-benchmark-exit-code", "--output-format=histograms", "--experimental-tbmv3-metrics", - "--extra-path=/b/s/w/ir/bin/", "-d", "--os-check=ignore" ], @@ -104,13 +103,6 @@ }, "swarming": { "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "fuchsia/third_party/openssh-portable/${platform}", - "location": ".", - "revision": "build_id:8787350426829126785" - } - ], "dimensions": { "cpu": null, "device_type": "Nelson", @@ -147,7 +139,6 @@ "--ignore-benchmark-exit-code", "--output-format=histograms", "--experimental-tbmv3-metrics", - "--extra-path=/b/s/w/ir/bin/", "-d", "--os-check=ignore" ], @@ -160,13 +151,6 @@ }, "swarming": { "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "fuchsia/third_party/openssh-portable/${platform}", - "location": ".", - "revision": "build_id:8787350426829126785" - } - ], "dimensions": { "cpu": null, "device_type": "Sherlock",
diff --git a/testing/scripts/run_performance_tests.py b/testing/scripts/run_performance_tests.py index 91a8ec6c..28a73aeb 100755 --- a/testing/scripts/run_performance_tests.py +++ b/testing/scripts/run_performance_tests.py
@@ -31,7 +31,7 @@ TESTING: To test changes to this script, please run unit tests: $ cd testing/scripts -$ vpython3 -m unittest run_performance_tests_unittest.py +$ vpython3 run_performance_tests_unittest.py Run end-to-end tests: $ cd tools/perf @@ -739,6 +739,7 @@ def __init__(self, options, isolated_out_dir): self.options = options + self._parse_arguments() self.isolated_out_dir = isolated_out_dir self.network = self._get_network_arg(options.passthrough_args) if self.options.luci_chromium: @@ -751,7 +752,15 @@ browser_arg = _get_browser_arg(options.passthrough_args) self.is_android = _is_android(browser_arg) self._find_browser(browser_arg) - self.driver_path_arg = self._find_chromedriver() + + def _parse_arguments(self): + parser = argparse.ArgumentParser() + parser.add_argument('--official-browser', + type=str, + required=False, + help='Use official build of the browser') + self.cb_options, self.options.passthrough_args = parser.parse_known_args( + self.options.passthrough_args) def _get_network_arg(self, args): if _arg := _get_arg(args, '--network='): @@ -818,6 +827,14 @@ arg for arg in self.options.passthrough_args if not arg.startswith('--browser=') ] + if self.cb_options.official_browser: + if self.is_android: + raise RuntimeError( + 'Running official build not yet supported on Android') + self.browser = self.CHROME_BROWSER % self.cb_options.official_browser + self.driver_path_arg = [] + return + self.driver_path_arg = self._find_chromedriver() if '/' in browser_arg or '\\' in browser_arg: # The --browser arg looks like a path. Use it as-is. self.browser = self.CHROME_BROWSER % browser_arg
diff --git a/testing/scripts/run_performance_tests_unittest.py b/testing/scripts/run_performance_tests_unittest.py index 195178e2..cbede1a 100644 --- a/testing/scripts/run_performance_tests_unittest.py +++ b/testing/scripts/run_performance_tests_unittest.py
@@ -148,7 +148,8 @@ del mock_exists run_performance_tests.copy_map_file_to_out_dir('file', 'dir') - mock_copyfile.assert_called_with('file', 'dir/benchmarks_shard_map.json') + mock_copyfile.assert_called_with( + 'file', str(pathlib.Path('dir/benchmarks_shard_map.json'))) # pylint: enable=no-self-use @mock.patch.object(run_performance_tests.CrossbenchTest, @@ -399,7 +400,8 @@ network_dict = json.loads(crosebench_test.network[0].split('=', 1)[1]) self.assertDictEqual(network_dict, expected_dict) - def testCrossbenchFindBrowserFromEmbedder(self): + @mock.patch.object(run_performance_tests.browser_finder, 'FindBrowser') + def testCrossbenchFindBrowserFromEmbedder(self, _): fake_args = ( _create_crossbench_args('android-webview-trichrome-google-bundle') + ['--embedder=org.foo.bar']) @@ -410,7 +412,24 @@ expected_hjson = crossbench_test.ANDROID_HJSON % ( 'org.foo.bar', run_performance_tests.ADB_TOOL) expected_browser = crossbench_test.CHROME_BROWSER % expected_hjson - self.assertEqual(crossbench_test.network, expected_browser) + self.assertEqual(crossbench_test.browser, expected_browser) + + def testCrossbenchOfficialBrowser(self): + fake_args = _create_crossbench_args() + fake_args.append('--official-browser=chrome-stable-1.2.3.4') + options = run_performance_tests.parse_arguments(fake_args) + + cb_test = run_performance_tests.CrossbenchTest(options, 'dir') + command_list = cb_test._generate_command_list( + cb_test.options.benchmarks, cb_test.options.passthrough_args, 'dir') + + self.assertIn('--browser=chrome-stable-1.2.3.4', command_list) + # The --official-browser arg should have been removed from command_list. + self.assertFalse( + [x for x in command_list if x.startswith('--official-browser')]) + # Crossbench should find the official build of WebDriver, instead of using + # a path from us. + self.assertFalse([x for x in command_list if x.startswith('--driver-path')]) def _create_crossbench_args(browser='./chrome'): @@ -421,3 +440,7 @@ '--benchmark-display-name=speedometer3.crossbench', f'--browser={browser}', ] + + +if __name__ == '__main__': + unittest.main()
diff --git a/third_party/androidx/build.gradle b/third_party/androidx/build.gradle index 0c94aca..9183abf 100644 --- a/third_party/androidx/build.gradle +++ b/third_party/androidx/build.gradle
@@ -304,7 +304,7 @@ google() maven { // This URL is generated by the fetch_all_androidx.py script. - url 'https://androidx.dev/snapshots/builds/13465832/artifacts/repository' + url 'https://androidx.dev/snapshots/builds/13468622/artifacts/repository' } mavenCentral() }
diff --git a/third_party/angle b/third_party/angle index 00845fd..b729fb7 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit 00845fd649a450a00e61215f44bb4fc95d515c97 +Subproject commit b729fb74e68bb2b3db6c95067f4ffc1e0c25bc07
diff --git a/third_party/blink/public/strings/BUILD.gn b/third_party/blink/public/strings/BUILD.gn index 0a7fda7..f853223 100644 --- a/third_party/blink/public/strings/BUILD.gn +++ b/third_party/blink/public/strings/BUILD.gn
@@ -5,20 +5,16 @@ import("//build/config/locales.gni") import("//tools/grit/grit_rule.gni") -grit("strings") { +grit_strings("strings") { source = "blink_strings.grd" - outputs = [ "grit/blink_strings.h" ] + - process_file_template(all_chrome_locales, - [ "blink_strings_{{source_name_part}}.pak" ]) + outputs = [ "grit/blink_strings.h" ] + output_prefix = "blink_strings_" } # The base strings for the permission element. -grit("permission_element_strings") { +grit_strings("permission_element_strings") { source = "permission_element_strings.grd" outputs = [ "grit/permission_element_strings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "permission_element_strings_$locale.pak" ] - } } action("generate_permission_element_strings_mono_grd") {
diff --git a/third_party/blink/public/web/web_document_loader.h b/third_party/blink/public/web/web_document_loader.h index 0527831..33e2368 100644 --- a/third_party/blink/public/web/web_document_loader.h +++ b/third_party/blink/public/web/web_document_loader.h
@@ -141,8 +141,6 @@ CrossVariantMojoRemote<mojom::CodeCacheHostInterfaceBase> code_cache_host_for_background) = 0; - virtual WebString OriginCalculationDebugInfo() const = 0; - // Whether the frame holding this document has loaded a document that is not // an initial empty document. virtual bool HasLoadedNonInitialEmptyDocument() const = 0;
diff --git a/third_party/blink/renderer/core/css/document_style_environment_variables.cc b/third_party/blink/renderer/core/css/document_style_environment_variables.cc index 441c942..d26030c 100644 --- a/third_party/blink/renderer/core/css/document_style_environment_variables.cc +++ b/third_party/blink/renderer/core/css/document_style_environment_variables.cc
@@ -56,10 +56,8 @@ Document& document) : StyleEnvironmentVariables(parent), document_(&document) { if (RuntimeEnabledFeatures::CSSPreferredTextScaleEnabled()) { - SetVariable( - UADefinedVariable::kPreferredTextScale, - String::Number( - document_->GetSettings()->GetAccessibilityFontScaleFactor())); + SetPreferredTextScale( + document_->GetSettings()->GetAccessibilityFontScaleFactor()); } } @@ -97,5 +95,42 @@ // Do nothing if this is an unknown variable. } } +namespace { + +double SnapToClosestFontScaleBucket(double raw_font_scale) { + static const std::array<double, 7> font_scale_buckets = {0.85, 1, 1.15, 1.3, + 1.5, 1.8, 2}; + + // Handle cases where the input value is outside the range of literals. + if (raw_font_scale <= font_scale_buckets.front()) { + return font_scale_buckets.front(); + } + if (raw_font_scale >= font_scale_buckets.back()) { + return font_scale_buckets.back(); + } + + // std::lower_bound finds the first element >= raw_font_scale. + const auto it = std::lower_bound(font_scale_buckets.begin(), + font_scale_buckets.end(), raw_font_scale); + + const double higher_candidate = *it; + // The element before 'it' is the other candidate. + // Safe because we handled edge cases above. + const double lower_candidate = *(it - 1); + + const double diff_to_lower = std::abs(raw_font_scale - lower_candidate); + const double diff_to_higher = std::abs(raw_font_scale - higher_candidate); + + return (diff_to_lower <= diff_to_higher) ? lower_candidate : higher_candidate; +} + +} // namespace + +void DocumentStyleEnvironmentVariables::SetPreferredTextScale( + double raw_font_scale_from_os) { + SetVariable( + UADefinedVariable::kPreferredTextScale, + String::Number(SnapToClosestFontScaleBucket(raw_font_scale_from_os))); +} } // namespace blink
diff --git a/third_party/blink/renderer/core/css/document_style_environment_variables.h b/third_party/blink/renderer/core/css/document_style_environment_variables.h index 52b3cb0..b04af42 100644 --- a/third_party/blink/renderer/core/css/document_style_environment_variables.h +++ b/third_party/blink/renderer/core/css/document_style_environment_variables.h
@@ -39,6 +39,8 @@ WTF::Vector<unsigned> indices, bool record_metrics); + void SetPreferredTextScale(double); + // Resolve the variable |name| and return the data. This will also cause // future changes to this variable to invalidate the associated document's // style. UseCounter metrics will be recorded when this function is used.
diff --git a/third_party/blink/renderer/core/html/forms/option_list.cc b/third_party/blink/renderer/core/html/forms/option_list.cc index 76fdd36f..49807dc0 100644 --- a/third_party/blink/renderer/core/html/forms/option_list.cc +++ b/third_party/blink/renderer/core/html/forms/option_list.cc
@@ -176,8 +176,7 @@ return nullptr; } for (OptionListIterator it = begin(); it; ++it) { - if (it->IsKeyboardFocusableSlow( - Element::UpdateBehavior::kAssertNoLayoutUpdates)) { + if (it->IsKeyboardFocusableSlow(Element::UpdateBehavior::kStyleAndLayout)) { return &*it; } }
diff --git a/third_party/blink/renderer/core/html/forms/text_field_input_type.cc b/third_party/blink/renderer/core/html/forms/text_field_input_type.cc index d63317b..8a70f8c6 100644 --- a/third_party/blink/renderer/core/html/forms/text_field_input_type.cc +++ b/third_party/blink/renderer/core/html/forms/text_field_input_type.cc
@@ -219,7 +219,8 @@ if (!GetElement().IsFocused()) return; - if (RuntimeEnabledFeatures::SelectAccessibilityReparentInputEnabled()) { + if (RuntimeEnabledFeatures::SelectAccessibilityReparentInputEnabled() || + RuntimeEnabledFeatures::SelectAccessibilityNestedInputEnabled()) { if (auto* select = GetElement().FirstAncestorSelectElement()) { if (AtomicString(event.key()) == keywords::kArrowDown) { if (auto* option =
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index abcc4436..4eab174 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -373,7 +373,6 @@ HeapMojoRemote<mojom::blink::ContentSecurityNotifier> content_security_notifier_; scoped_refptr<SecurityOrigin> origin_to_commit; - AtomicString origin_calculation_debug_info; BlinkStorageKey storage_key; WebNavigationType navigation_type; DocumentLoadTiming document_load_timing; @@ -2333,19 +2332,16 @@ scoped_refptr<SecurityOrigin> DocumentLoader::CalculateOrigin( Document* owner_document) { scoped_refptr<SecurityOrigin> origin; - StringBuilder debug_info_builder; // Whether the origin is newly created within this call, instead of copied // from an existing document's origin or from `origin_to_commit_`. If this is // true, we won't try to compare the nonce of this origin (if it's opaque) to // the browser-calculated origin later on. - bool origin_is_newly_created = false; if (IsPagePopupRunningInWebTest(frame_)) { // If we are a page popup in LayoutTests ensure we use the popup // owner's security origin so the tests can possibly access the // document via internals API. auto* owner_context = frame_->PagePopupOwner()->GetExecutionContext(); origin = owner_context->GetSecurityOrigin()->IsolatedCopy(); - debug_info_builder.Append("use_popup_owner_origin"); } else if (owner_document && owner_document->domWindow()) { // Prefer taking `origin` from `owner_document` if one is available - this // will correctly inherit/alias `SecurityOrigin::domain_` from the @@ -2364,19 +2360,6 @@ // But origin_to_commit_ is currently cloned with IsolatedCopy() which // breaks aliasing... origin = owner_document->domWindow()->GetMutableSecurityOrigin(); - debug_info_builder.Append("use_owner_document_origin("); - // Add debug information about the owner document too. - if (owner_document->GetFrame() == frame_->Tree().Parent()) { - debug_info_builder.Append("parent"); - } else { - debug_info_builder.Append("opener"); - } - debug_info_builder.Append(":"); - debug_info_builder.Append( - owner_document->Loader()->origin_calculation_debug_info_); - debug_info_builder.Append(", url="); - debug_info_builder.Append(owner_document->Url().BaseAsString()); - debug_info_builder.Append(")"); } else if (origin_to_commit_) { // Origin to commit is specified by the browser process, it must be taken // and used directly. An exception is when the owner origin should be @@ -2385,30 +2368,23 @@ // non-renderer only origin bits will be the same, which will be asserted at // the end of this function. origin = origin_to_commit_; - debug_info_builder.Append("use_origin_to_commit"); } else { - debug_info_builder.Append("use_url_with_precursor"); // Otherwise, create an origin that propagates precursor information // as needed. For non-opaque origins, this creates a standard tuple // origin, but for opaque origins, it creates an origin with the // initiator origin as the precursor. origin = SecurityOrigin::CreateWithReferenceOrigin(url_, requestor_origin_.get()); - origin_is_newly_created = true; } if ((policy_container_->GetPolicies().sandbox_flags & network::mojom::blink::WebSandboxFlags::kOrigin) != network::mojom::blink::WebSandboxFlags::kNone) { - debug_info_builder.Append(", add_sandbox[new_origin_precursor="); // If `origin_to_commit_` is set, don't create a new opaque origin, but just // use `origin_to_commit_`, which is already opaque. auto sandbox_origin = origin_to_commit_ ? origin_to_commit_ : origin->DeriveNewOpaqueOrigin(); CHECK(sandbox_origin->IsOpaque()); - debug_info_builder.Append( - sandbox_origin->GetOriginOrPrecursorOriginIfOpaque()->ToString()); - debug_info_builder.Append("]"); // If we're supposed to inherit our security origin from our // owner, but we're also sandboxed, the only things we inherit are @@ -2433,20 +2409,16 @@ ->IsPotentiallyTrustworthy(); if (is_potentially_trustworthy) { sandbox_origin->SetOpaqueOriginIsPotentiallyTrustworthy(true); - debug_info_builder.Append(", _potentially_trustworthy"); } } else if (owner_document) { if (origin->IsPotentiallyTrustworthy()) { sandbox_origin->SetOpaqueOriginIsPotentiallyTrustworthy(true); - debug_info_builder.Append(", _potentially_trustworthy"); } if (origin->CanLoadLocalResources()) { sandbox_origin->GrantLoadLocalResources(); - debug_info_builder.Append(", _load_local"); } } origin = sandbox_origin; - origin_is_newly_created = !origin_to_commit_; } if (commit_reason_ == CommitReason::kInitialization && @@ -2458,19 +2430,16 @@ // navigated. CHECK(origin->IsOpaque()); origin->GrantUniversalAccess(); - debug_info_builder.Append(", universal_access_webview"); } else if (!frame_->GetSettings()->GetWebSecurityEnabled()) { // Web security is turned off. We should let this document access // every other document. This is used primary by testing harnesses for // web sites. origin->GrantUniversalAccess(); - debug_info_builder.Append(", universal_access_no_web_security"); } else if (origin->IsLocal()) { if (frame_->GetSettings()->GetAllowUniversalAccessFromFileURLs()) { // Some clients want local URLs to have universal access, but that // setting is dangerous for other clients. origin->GrantUniversalAccess(); - debug_info_builder.Append(", universal_access_allow_file"); } else if (!frame_->GetSettings()->GetAllowFileAccessFromFileURLs()) { // Some clients do not want local URLs to have access to other local // URLs. @@ -2482,34 +2451,20 @@ // `origin_to_commit_`. origin_to_commit_->BlockLocalAccessFromLocalOrigin(); } - debug_info_builder.Append(", universal_access_block_file"); } } if (grant_load_local_resources_) { origin->GrantLoadLocalResources(); - debug_info_builder.Append(", grant_load_local_resources"); } if (origin->IsOpaque()) { KURL url = url_.IsEmpty() ? BlankURL() : url_; if (SecurityOrigin::Create(url)->IsPotentiallyTrustworthy()) { origin->SetOpaqueOriginIsPotentiallyTrustworthy(true); - debug_info_builder.Append(", is_potentially_trustworthy"); } } - if (origin_is_newly_created) { - // This information will be used by the browser side to figure out if it can - // do browser vs renderer calculated origin equality check. Note that this - // information must be the last part of the debug info string. - // TODO(https://crbug.com/888079): Consider adding a separate boolean that - // tracks this instead of piggybacking `origin_calculation_debug_info_`. - debug_info_builder.Append(", is_newly_created"); - } - origin_calculation_debug_info_ = debug_info_builder.ToAtomicString(); if (origin_to_commit_) { - SCOPED_CRASH_KEY_STRING256("OriginCalc", "debug_info", - origin_calculation_debug_info_.Ascii()); SCOPED_CRASH_KEY_STRING256("OriginCalc", "url_stripped", url_.StrippedForUseAsReferrer().Ascii()); SCOPED_CRASH_KEY_BOOL("OriginCalc", "same_ptr",
diff --git a/third_party/blink/renderer/core/loader/document_loader.h b/third_party/blink/renderer/core/loader/document_loader.h index 10682e12..01b97e56 100644 --- a/third_party/blink/renderer/core/loader/document_loader.h +++ b/third_party/blink/renderer/core/loader/document_loader.h
@@ -214,9 +214,6 @@ code_cache_host, CrossVariantMojoRemote<mojom::blink::CodeCacheHostInterfaceBase> code_cache_host_for_background) override; - WebString OriginCalculationDebugInfo() const override { - return origin_calculation_debug_info_; - } bool HasLoadedNonInitialEmptyDocument() const override; bool IsForDiscard() const override; @@ -701,11 +698,6 @@ const scoped_refptr<SecurityOrigin> origin_to_commit_; - // Information about how `origin_to_commit_` was calculated, to help debug if - // it differs from the origin calculated on the browser side. - // TODO(https://crbug.com/1220238): Remove this. - AtomicString origin_calculation_debug_info_; - blink::BlinkStorageKey storage_key_; WebNavigationType navigation_type_;
diff --git a/third_party/blink/renderer/core/loader/image_loader.cc b/third_party/blink/renderer/core/loader/image_loader.cc index a27611fb..74dc54f 100644 --- a/third_party/blink/renderer/core/loader/image_loader.cc +++ b/third_party/blink/renderer/core/loader/image_loader.cc
@@ -414,6 +414,7 @@ void ImageLoader::DoUpdateFromElement(const DOMWrapperWorld* world, UpdateFromElementBehavior update_behavior, + const KURL* source_url, UpdateType update_type, bool force_blocking) { // FIXME: According to @@ -440,8 +441,13 @@ return; } + KURL url; AtomicString image_source_url = element_->ImageSourceURL(); - const KURL url = ImageSourceToKURL(image_source_url); + if (RuntimeEnabledFeatures::OptimizeHTMLElementUrlsEnabled() && source_url) { + url = *source_url; + } else { + url = ImageSourceToKURL(image_source_url); + } ImageResourceContent* new_image_content = nullptr; if (!url.IsNull() && !url.IsEmpty()) { // Unlike raw <img>, we block mixed content inside of <picture> or @@ -659,10 +665,12 @@ delay_until_do_update_from_element_ = nullptr; } - if (ShouldLoadImmediately(ImageSourceToKURL(image_source_url)) && + const KURL image_source_kurl = ImageSourceToKURL(image_source_url); + if (ShouldLoadImmediately(image_source_kurl) && update_behavior != kUpdateFromMicrotask) { DoUpdateFromElement(element_->GetExecutionContext()->GetCurrentWorld(), - update_behavior, UpdateType::kSync, force_blocking); + update_behavior, &image_source_kurl, UpdateType::kSync, + force_blocking); return; } // Allow the idiom "img.src=''; img.src='.." to clear down the image before an
diff --git a/third_party/blink/renderer/core/loader/image_loader.h b/third_party/blink/renderer/core/loader/image_loader.h index eb6b8fd..d643e57 100644 --- a/third_party/blink/renderer/core/loader/image_loader.h +++ b/third_party/blink/renderer/core/loader/image_loader.h
@@ -173,6 +173,7 @@ // force_blocking ensures that the image will block the load event. void DoUpdateFromElement(const DOMWrapperWorld* world, UpdateFromElementBehavior, + const KURL* source_url = nullptr, UpdateType = UpdateType::kAsync, bool force_blocking = false);
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc index cfa264b..67637ba 100644 --- a/third_party/blink/renderer/core/page/page.cc +++ b/third_party/blink/renderer/core/page/page.cc
@@ -1093,10 +1093,10 @@ if (!document || !document->IsActive()) { continue; } - document->GetStyleEngine().EnsureEnvironmentVariables().SetVariable( - UADefinedVariable::kPreferredTextScale, - String::Number( - document->GetSettings()->GetAccessibilityFontScaleFactor())); + document->GetStyleEngine() + .EnsureEnvironmentVariables() + .SetPreferredTextScale( + document->GetSettings()->GetAccessibilityFontScaleFactor()); } break; case ChangeType::kTextAutosizing:
diff --git a/third_party/blink/renderer/modules/ai/BUILD.gn b/third_party/blink/renderer/modules/ai/BUILD.gn index 3fee2a63..c917b75 100644 --- a/third_party/blink/renderer/modules/ai/BUILD.gn +++ b/third_party/blink/renderer/modules/ai/BUILD.gn
@@ -31,6 +31,8 @@ "language_model_factory.h", "language_model_params.cc", "language_model_params.h", + "language_model_prompt_builder.cc", + "language_model_prompt_builder.h", "model_execution_responder.cc", "model_execution_responder.h", "on_device_translation/create_translator_client.cc",
diff --git a/third_party/blink/renderer/modules/ai/language_model.cc b/third_party/blink/renderer/modules/ai/language_model.cc index edae9ec..66f10d1b 100644 --- a/third_party/blink/renderer/modules/ai/language_model.cc +++ b/third_party/blink/renderer/modules/ai/language_model.cc
@@ -32,6 +32,7 @@ #include "third_party/blink/renderer/modules/ai/dom_ai.h" #include "third_party/blink/renderer/modules/ai/exception_helpers.h" #include "third_party/blink/renderer/modules/ai/language_model_factory.h" +#include "third_party/blink/renderer/modules/ai/language_model_prompt_builder.h" #include "third_party/blink/renderer/modules/ai/model_execution_responder.h" #include "third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_source_util.h" #include "third_party/blink/renderer/modules/event_target_modules_names.h" @@ -171,238 +172,6 @@ receiver_; }; -mojom::blink::AILanguageModelPromptContentPtr ToMojo(String prompt) { - return mojom::blink::AILanguageModelPromptContent::NewText(prompt); -} - -mojom::blink::AILanguageModelPromptContentPtr ToMojo( - AudioBuffer* audio_buffer, - ExceptionState& exception_state) { - if (audio_buffer->numberOfChannels() > 2) { - // TODO(crbug.com/382180351): Support more than 2 channels. - exception_state.ThrowDOMException( - DOMExceptionCode::kSyntaxError, - "Audio with more than 2 channels is not supported."); - return nullptr; - } - on_device_model::mojom::blink::AudioDataPtr audio_data = - on_device_model::mojom::blink::AudioData::New(); - audio_data->sample_rate = audio_buffer->sampleRate(); - audio_data->frame_count = audio_buffer->length(); - // TODO(crbug.com/382180351): Use other mono mixing utils like - // AudioBus::CreateByMixingToMono. - audio_data->channel_count = 1; - base::span<const float> channel0 = audio_buffer->getChannelData(0)->AsSpan(); - audio_data->data = WTF::Vector<float>(channel0.size()); - for (size_t i = 0; i < channel0.size(); ++i) { - audio_data->data[i] = channel0[i]; - // If second channel exists, average the two channels to produce mono. - if (audio_buffer->numberOfChannels() > 1) { - audio_data->data[i] = - (audio_data->data[i] + audio_buffer->getChannelData(1)->AsSpan()[i]) / - 2.0f; - } - } - return mojom::blink::AILanguageModelPromptContent::NewAudio( - std::move(audio_data)); -} - -mojom::blink::AILanguageModelPromptContentPtr ToMojo( - base::span<uint8_t> audio_bytes, - ExecutionContext* execution_context, - ExceptionState& exception_state) { - // TODO(crbug.com/401010825): Use the file sample rate. - scoped_refptr<AudioBus> bus = AudioBus::CreateBusFromInMemoryAudioFile( - audio_bytes, /*mix_to_mono=*/true, /*sample_rate=*/48000); - if (!bus) { - // TODO(crbug.com/409615288): This should throw a TypeError according to the - // spec. - exception_state.ThrowDOMException(DOMExceptionCode::kDataError, - "Missing or invalid audio data."); - return nullptr; - } - - on_device_model::mojom::blink::AudioDataPtr audio_data = - on_device_model::mojom::blink::AudioData::New(); - audio_data->sample_rate = bus->SampleRate(); - audio_data->frame_count = bus->length(); - audio_data->channel_count = bus->NumberOfChannels(); - CHECK_EQ(audio_data->channel_count, 1); - // TODO(crbug.com/382180351): Avoid a copy. - audio_data->data = WTF::Vector<float>(bus->length()); - std::copy_n(bus->Channel(0)->Data(), bus->Channel(0)->length(), - audio_data->data.begin()); - return mojom::blink::AILanguageModelPromptContent::NewAudio( - std::move(audio_data)); -} - -mojom::blink::AILanguageModelPromptContentPtr ToMojo( - Blob* blob, - ExecutionContext* execution_context, - ExceptionState& exception_state) { - // TODO(crbug.com/382180351): Make blob reading async or alternatively - // use FileReaderSync instead (fix linker and exception issues). - SyncedFileReaderAccumulator* blobReader = - MakeGarbageCollected<SyncedFileReaderAccumulator>(); - - auto [error_code, reader_data] = blobReader->Load( - blob->GetBlobDataHandle(), - execution_context->GetTaskRunner(TaskType::kFileReading)); - if (error_code != FileErrorCode::kOK) { - exception_state.ThrowDOMException(DOMExceptionCode::kDataError, - "Failed to read blob."); - return nullptr; - } - ArrayBufferContents audio_contents = - std::move(reader_data).AsArrayBufferContents(); - if (!audio_contents.IsValid()) { - exception_state.ThrowDOMException(DOMExceptionCode::kDataError, - "Failed to read blob."); - return nullptr; - } - return ToMojo(audio_contents.ByteSpan(), execution_context, exception_state); -} - -mojom::blink::AILanguageModelPromptContentPtr ToMojo( - V8ImageBitmapSource* bitmap, - ScriptState* script_state, - ExceptionState& exception_state) { - std::optional<SkBitmap> skia_bitmap = - GetBitmapFromV8ImageBitmapSource(script_state, bitmap, exception_state); - if (exception_state.HadException()) { - return nullptr; - } - return mojom::blink::AILanguageModelPromptContent::NewBitmap( - skia_bitmap.value()); -} - -mojom::blink::AILanguageModelPromptContentPtr ConvertPromptToMojoContent( - V8LanguageModelPromptType content_type, - const V8LanguageModelPromptContent* content, - ScriptState* script_state, - ExceptionState& exception_state, - ExecutionContext* execution_context, - WTF::HashSet<mojom::blink::AILanguageModelPromptType>& allowed_types) { - switch (content_type.AsEnum()) { - case V8LanguageModelPromptType::Enum::kText: - return ToMojo(content->GetAsString()); - case V8LanguageModelPromptType::Enum::kImage: - if (!allowed_types.Contains( - mojom::blink::AILanguageModelPromptType::kImage)) { - exception_state.ThrowDOMException( - DOMExceptionCode::kNotSupportedError, - "Image not supported. Session is not initialized with image " - "support."); - return nullptr; - } - UseCounter::Count(execution_context, - WebFeature::kLanguageModel_Prompt_Input_Image); - if (content->IsV8ImageBitmapSource()) { - return ToMojo(content->GetAsV8ImageBitmapSource(), script_state, - exception_state); - } - exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError, - "Unsupported image content type"); - return nullptr; - case V8LanguageModelPromptType::Enum::kAudio: - if (!allowed_types.Contains( - mojom::blink::AILanguageModelPromptType::kAudio)) { - exception_state.ThrowDOMException( - DOMExceptionCode::kNotSupportedError, - "Audio not supported. Session is not initialized with audio " - "support."); - return nullptr; - } - UseCounter::Count(execution_context, - WebFeature::kLanguageModel_Prompt_Input_Audio); - switch (content->GetContentType()) { - case V8LanguageModelPromptContent::ContentType::kAudioBuffer: - return ToMojo(content->GetAsAudioBuffer(), exception_state); - case V8LanguageModelPromptContent::ContentType::kBlob: - return ToMojo(content->GetAsBlob(), execution_context, - exception_state); - case V8LanguageModelPromptContent::ContentType::kArrayBuffer: - return ToMojo(content->GetAsArrayBuffer()->Content()->ByteSpan(), - execution_context, exception_state); - case V8LanguageModelPromptContent::ContentType::kArrayBufferView: - return ToMojo(content->GetAsArrayBufferView()->ByteSpan(), - execution_context, exception_state); - default: - exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError, - "Unsupported audio content type"); - return nullptr; - } - } -} - -// Return `prompt`'s content as a mojo struct or nullptr if there was an error. -mojom::blink::AILanguageModelPromptPtr ConvertPromptToMojo( - const V8LanguageModelPrompt* prompt, - ScriptState* script_state, - ExceptionState& exception_state, - ExecutionContext* execution_context, - WTF::HashSet<mojom::blink::AILanguageModelPromptType>& allowed_types) { - switch (prompt->GetContentType()) { - // Handle basic string prompt. - case V8LanguageModelPrompt::ContentType::kString: { - auto result = mojom::blink::AILanguageModelPrompt::New(); - result->content = ToMojo(prompt->GetAsString()); - if (result->content.is_null()) { - return nullptr; - } - result->role = mojom::blink::AILanguageModelPromptRole::kUser; - return result; - } - // Handle dictionary for multimodal input. - case V8LanguageModelPrompt::ContentType::kLanguageModelPromptDict: - LanguageModelPromptDict* dict = prompt->GetAsLanguageModelPromptDict(); - auto result = mojom::blink::AILanguageModelPrompt::New(); - result->content = ConvertPromptToMojoContent( - dict->type(), dict->content(), script_state, exception_state, - execution_context, allowed_types); - if (result->content.is_null()) { - return nullptr; - } - result->role = LanguageModel::ConvertRoleToMojo(dict->role()); - return result; - } -} - -// Populates the `prompts` mojo struct vector from `input`. Returns an exception -// if some input was specified incorrectly or inaccessible, nullptr otherwise. -std::optional<WTF::Vector<mojom::blink::AILanguageModelPromptPtr>> BuildPrompts( - const V8LanguageModelPromptInput* input, - ScriptState* script_state, - ExceptionState& exception_state, - ExecutionContext* execution_context, - WTF::HashSet<mojom::blink::AILanguageModelPromptType>& allowed_types) { - WTF::Vector<mojom::blink::AILanguageModelPromptPtr> prompts; - if (input->IsLanguageModelPromptDictOrStringSequence()) { - const auto& sequence = - input->GetAsLanguageModelPromptDictOrStringSequence(); - for (const auto& entry : sequence) { - mojom::blink::AILanguageModelPromptPtr prompt = - ConvertPromptToMojo(entry, script_state, exception_state, - execution_context, allowed_types); - if (prompt.is_null()) { - return std::nullopt; - } - prompts.push_back(std::move(prompt)); - } - } else { - CHECK(input->IsV8LanguageModelPrompt()); - auto* entry = input->GetAsV8LanguageModelPrompt(); - mojom::blink::AILanguageModelPromptPtr prompt = ConvertPromptToMojo( - entry, script_state, exception_state, execution_context, allowed_types); - if (prompt.is_null()) { - return std::nullopt; - } - prompts.push_back(std::move(prompt)); - } - - return prompts; -} - // Parses `constraint` from `options` if available. On success or if no // constraint is present returns true, returns false and throws an exception on // failure.
diff --git a/third_party/blink/renderer/modules/ai/language_model_prompt_builder.cc b/third_party/blink/renderer/modules/ai/language_model_prompt_builder.cc new file mode 100644 index 0000000..fb81ee8 --- /dev/null +++ b/third_party/blink/renderer/modules/ai/language_model_prompt_builder.cc
@@ -0,0 +1,269 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/ai/language_model_prompt_builder.h" + +#include "third_party/blink/public/mojom/ai/ai_language_model.mojom-blink-forward.h" +#include "third_party/blink/renderer/bindings/core/v8/idl_types.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_language_model_create_options.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_language_model_prompt_dict.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_union_language_model_prompt_content.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_union_language_model_prompt_input.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_union_languagemodelpromptdict_string.h" +#include "third_party/blink/renderer/core/dom/abort_signal.h" +#include "third_party/blink/renderer/core/dom/events/event_target.h" +#include "third_party/blink/renderer/core/event_type_names.h" +#include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" +#include "third_party/blink/renderer/core/fileapi/blob.h" +#include "third_party/blink/renderer/core/fileapi/file_reader_client.h" +#include "third_party/blink/renderer/core/frame/web_feature.h" +#include "third_party/blink/renderer/core/streams/readable_stream.h" +#include "third_party/blink/renderer/modules/ai/language_model.h" +#include "third_party/blink/renderer/modules/ai/language_model_factory.h" +#include "third_party/blink/renderer/modules/ai/language_model_prompt_builder.h" +#include "third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_source_util.h" +#include "third_party/blink/renderer/modules/webaudio/audio_buffer.h" +#include "third_party/blink/renderer/platform/audio/audio_bus.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_remote.h" + +namespace blink { +namespace { + +mojom::blink::AILanguageModelPromptContentPtr ToMojo(String prompt) { + return mojom::blink::AILanguageModelPromptContent::NewText(prompt); +} + +mojom::blink::AILanguageModelPromptContentPtr ToMojo( + AudioBuffer* audio_buffer, + ExceptionState& exception_state) { + if (audio_buffer->numberOfChannels() > 2) { + // TODO(crbug.com/382180351): Support more than 2 channels. + exception_state.ThrowDOMException( + DOMExceptionCode::kSyntaxError, + "Audio with more than 2 channels is not supported."); + return nullptr; + } + on_device_model::mojom::blink::AudioDataPtr audio_data = + on_device_model::mojom::blink::AudioData::New(); + audio_data->sample_rate = audio_buffer->sampleRate(); + audio_data->frame_count = audio_buffer->length(); + // TODO(crbug.com/382180351): Use other mono mixing utils like + // AudioBus::CreateByMixingToMono. + audio_data->channel_count = 1; + base::span<const float> channel0 = audio_buffer->getChannelData(0)->AsSpan(); + audio_data->data = WTF::Vector<float>(channel0.size()); + for (size_t i = 0; i < channel0.size(); ++i) { + audio_data->data[i] = channel0[i]; + // If second channel exists, average the two channels to produce mono. + if (audio_buffer->numberOfChannels() > 1) { + audio_data->data[i] = + (audio_data->data[i] + audio_buffer->getChannelData(1)->AsSpan()[i]) / + 2.0f; + } + } + return mojom::blink::AILanguageModelPromptContent::NewAudio( + std::move(audio_data)); +} + +mojom::blink::AILanguageModelPromptContentPtr ToMojo( + base::span<uint8_t> audio_bytes, + ExecutionContext* execution_context, + ExceptionState& exception_state) { + // TODO(crbug.com/401010825): Use the file sample rate. + scoped_refptr<AudioBus> bus = AudioBus::CreateBusFromInMemoryAudioFile( + audio_bytes, /*mix_to_mono=*/true, /*sample_rate=*/48000); + if (!bus) { + // TODO(crbug.com/409615288): This should throw a TypeError according to the + // spec. + exception_state.ThrowDOMException(DOMExceptionCode::kDataError, + "Missing or invalid audio data."); + return nullptr; + } + + on_device_model::mojom::blink::AudioDataPtr audio_data = + on_device_model::mojom::blink::AudioData::New(); + audio_data->sample_rate = bus->SampleRate(); + audio_data->frame_count = bus->length(); + audio_data->channel_count = bus->NumberOfChannels(); + CHECK_EQ(audio_data->channel_count, 1); + // TODO(crbug.com/382180351): Avoid a copy. + audio_data->data = WTF::Vector<float>(bus->length()); + std::copy_n(bus->Channel(0)->Data(), bus->Channel(0)->length(), + audio_data->data.begin()); + return mojom::blink::AILanguageModelPromptContent::NewAudio( + std::move(audio_data)); +} + +mojom::blink::AILanguageModelPromptContentPtr ToMojo( + Blob* blob, + ExecutionContext* execution_context, + ExceptionState& exception_state) { + // TODO(crbug.com/382180351): Make blob reading async or alternatively + // use FileReaderSync instead (fix linker and exception issues). + SyncedFileReaderAccumulator* blobReader = + MakeGarbageCollected<SyncedFileReaderAccumulator>(); + + auto [error_code, reader_data] = blobReader->Load( + blob->GetBlobDataHandle(), + execution_context->GetTaskRunner(TaskType::kFileReading)); + if (error_code != FileErrorCode::kOK) { + exception_state.ThrowDOMException(DOMExceptionCode::kDataError, + "Failed to read blob."); + return nullptr; + } + ArrayBufferContents audio_contents = + std::move(reader_data).AsArrayBufferContents(); + if (!audio_contents.IsValid()) { + exception_state.ThrowDOMException(DOMExceptionCode::kDataError, + "Failed to read blob."); + return nullptr; + } + return ToMojo(audio_contents.ByteSpan(), execution_context, exception_state); +} + +mojom::blink::AILanguageModelPromptContentPtr ToMojo( + V8ImageBitmapSource* bitmap, + ScriptState* script_state, + ExceptionState& exception_state) { + std::optional<SkBitmap> skia_bitmap = + GetBitmapFromV8ImageBitmapSource(script_state, bitmap, exception_state); + if (exception_state.HadException()) { + return nullptr; + } + return mojom::blink::AILanguageModelPromptContent::NewBitmap( + skia_bitmap.value()); +} + +mojom::blink::AILanguageModelPromptContentPtr ConvertPromptToMojoContent( + V8LanguageModelPromptType content_type, + const V8LanguageModelPromptContent* content, + ScriptState* script_state, + ExceptionState& exception_state, + ExecutionContext* execution_context, + WTF::HashSet<mojom::blink::AILanguageModelPromptType>& allowed_types) { + switch (content_type.AsEnum()) { + case V8LanguageModelPromptType::Enum::kText: + return ToMojo(content->GetAsString()); + case V8LanguageModelPromptType::Enum::kImage: + if (!allowed_types.Contains( + mojom::blink::AILanguageModelPromptType::kImage)) { + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "Image not supported. Session is not initialized with image " + "support."); + return nullptr; + } + UseCounter::Count(execution_context, + WebFeature::kLanguageModel_Prompt_Input_Image); + if (content->IsV8ImageBitmapSource()) { + return ToMojo(content->GetAsV8ImageBitmapSource(), script_state, + exception_state); + } + exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError, + "Unsupported image content type"); + return nullptr; + case V8LanguageModelPromptType::Enum::kAudio: + if (!allowed_types.Contains( + mojom::blink::AILanguageModelPromptType::kAudio)) { + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "Audio not supported. Session is not initialized with audio " + "support."); + return nullptr; + } + UseCounter::Count(execution_context, + WebFeature::kLanguageModel_Prompt_Input_Audio); + switch (content->GetContentType()) { + case V8LanguageModelPromptContent::ContentType::kAudioBuffer: + return ToMojo(content->GetAsAudioBuffer(), exception_state); + case V8LanguageModelPromptContent::ContentType::kBlob: + return ToMojo(content->GetAsBlob(), execution_context, + exception_state); + case V8LanguageModelPromptContent::ContentType::kArrayBuffer: + return ToMojo(content->GetAsArrayBuffer()->Content()->ByteSpan(), + execution_context, exception_state); + case V8LanguageModelPromptContent::ContentType::kArrayBufferView: + return ToMojo(content->GetAsArrayBufferView()->ByteSpan(), + execution_context, exception_state); + default: + exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError, + "Unsupported audio content type"); + return nullptr; + } + } +} + +// Return `prompt`'s content as a mojo struct or nullptr if there was an error. +mojom::blink::AILanguageModelPromptPtr ConvertPromptToMojo( + const V8LanguageModelPrompt* prompt, + ScriptState* script_state, + ExceptionState& exception_state, + ExecutionContext* execution_context, + WTF::HashSet<mojom::blink::AILanguageModelPromptType>& allowed_types) { + switch (prompt->GetContentType()) { + // Handle basic string prompt. + case V8LanguageModelPrompt::ContentType::kString: { + auto result = mojom::blink::AILanguageModelPrompt::New(); + result->content = ToMojo(prompt->GetAsString()); + if (result->content.is_null()) { + return nullptr; + } + result->role = mojom::blink::AILanguageModelPromptRole::kUser; + return result; + } + // Handle dictionary for multimodal input. + case V8LanguageModelPrompt::ContentType::kLanguageModelPromptDict: + LanguageModelPromptDict* dict = prompt->GetAsLanguageModelPromptDict(); + auto result = mojom::blink::AILanguageModelPrompt::New(); + result->content = ConvertPromptToMojoContent( + dict->type(), dict->content(), script_state, exception_state, + execution_context, allowed_types); + if (result->content.is_null()) { + return nullptr; + } + result->role = LanguageModel::ConvertRoleToMojo(dict->role()); + return result; + } +} + +} // namespace + +// Populates the `prompts` mojo struct vector from `input`. Returns an exception +// if some input was specified incorrectly or inaccessible, nullptr otherwise. +std::optional<WTF::Vector<mojom::blink::AILanguageModelPromptPtr>> BuildPrompts( + const V8LanguageModelPromptInput* input, + ScriptState* script_state, + ExceptionState& exception_state, + ExecutionContext* execution_context, + WTF::HashSet<mojom::blink::AILanguageModelPromptType>& allowed_types) { + WTF::Vector<mojom::blink::AILanguageModelPromptPtr> prompts; + if (input->IsLanguageModelPromptDictOrStringSequence()) { + const auto& sequence = + input->GetAsLanguageModelPromptDictOrStringSequence(); + for (const auto& entry : sequence) { + mojom::blink::AILanguageModelPromptPtr prompt = + ConvertPromptToMojo(entry, script_state, exception_state, + execution_context, allowed_types); + if (prompt.is_null()) { + return std::nullopt; + } + prompts.push_back(std::move(prompt)); + } + } else { + CHECK(input->IsV8LanguageModelPrompt()); + auto* entry = input->GetAsV8LanguageModelPrompt(); + mojom::blink::AILanguageModelPromptPtr prompt = ConvertPromptToMojo( + entry, script_state, exception_state, execution_context, allowed_types); + if (prompt.is_null()) { + return std::nullopt; + } + prompts.push_back(std::move(prompt)); + } + + return prompts; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/ai/language_model_prompt_builder.h b/third_party/blink/renderer/modules/ai/language_model_prompt_builder.h new file mode 100644 index 0000000..f0dae024 --- /dev/null +++ b/third_party/blink/renderer/modules/ai/language_model_prompt_builder.h
@@ -0,0 +1,29 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_AI_LANGUAGE_MODEL_PROMPT_BUILDER_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_AI_LANGUAGE_MODEL_PROMPT_BUILDER_H_ + +#include "third_party/blink/public/mojom/ai/ai_language_model.mojom-blink-forward.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" +#include "third_party/blink/renderer/platform/wtf/hash_set.h" + +namespace blink { + +class ScriptState; +class AbortSignal; +class V8LanguageModelPromptInput; +class ExceptionState; + +std::optional<WTF::Vector<mojom::blink::AILanguageModelPromptPtr>> BuildPrompts( + const V8LanguageModelPromptInput* input, + ScriptState* script_state, + ExceptionState& exception_state, + ExecutionContext* execution_context, + WTF::HashSet<mojom::blink::AILanguageModelPromptType>& allowed_types); + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_AI_LANGUAGE_MODEL_PROMPT_BUILDER_H_
diff --git a/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source_test.cc b/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source_test.cc index 76261e9..16c9f57 100644 --- a/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source_test.cc +++ b/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source_test.cc
@@ -30,6 +30,28 @@ using testing::Sequence; namespace blink { +namespace { +scoped_refptr<media::VideoFrame> CreateTestFrameWithGMB( + const gfx::Size& coded_size, + const gfx::Rect& visible_rect, + const gfx::Size& natural_size, + media::VideoFrame::StorageType storage_type, + media::VideoPixelFormat pixel_format, + base::TimeDelta timestamp, + std::unique_ptr<gfx::GpuMemoryBuffer> gmb) { + CHECK_EQ(storage_type, + media::VideoFrame::StorageType::STORAGE_GPU_MEMORY_BUFFER); + CHECK(gmb); + std::optional<gfx::BufferFormat> buffer_format = + media::VideoPixelFormatToGfxBufferFormat(pixel_format); + CHECK(buffer_format) << "Pixel format " + << media::VideoPixelFormatToString(pixel_format) + << " has no corresponding gfx::BufferFormat"; + + return media::VideoFrame::WrapExternalGpuMemoryBuffer( + visible_rect, natural_size, std::move(gmb), timestamp); +} +} // namespace void ExpectUpdateRectEquals(const gfx::Rect& expected, const webrtc::VideoFrame::UpdateRect actual) {
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 8afb9e2..1c541dc 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -3206,6 +3206,10 @@ status: "experimental", }, { + name: "OptimizeHTMLElementUrls", + status: "experimental", + }, + { // This flag makes the <option> element's label attribute render the // contents of the label attribute even if it is only whitespace in order // to match the spec and firefox. It also stops stripping/simplifying @@ -3846,7 +3850,7 @@ // composited pixel alignment issues. See // https://crbug.com/40084005 name: "RenderSurfaceFor2DScaleTransform", - status: "experimental", + status: "stable", }, { name: "ReportEventTimingAtVisibilityChange",
diff --git a/third_party/blink/renderer/platform/testing/video_frame_utils.cc b/third_party/blink/renderer/platform/testing/video_frame_utils.cc index 8665466..5775b14 100644 --- a/third_party/blink/renderer/platform/testing/video_frame_utils.cc +++ b/third_party/blink/renderer/platform/testing/video_frame_utils.cc
@@ -84,25 +84,4 @@ } } -scoped_refptr<media::VideoFrame> CreateTestFrameWithGMB( - const gfx::Size& coded_size, - const gfx::Rect& visible_rect, - const gfx::Size& natural_size, - media::VideoFrame::StorageType storage_type, - media::VideoPixelFormat pixel_format, - base::TimeDelta timestamp, - std::unique_ptr<gfx::GpuMemoryBuffer> gmb) { - CHECK_EQ(storage_type, - media::VideoFrame::StorageType::STORAGE_GPU_MEMORY_BUFFER); - CHECK(gmb); - std::optional<gfx::BufferFormat> buffer_format = - media::VideoPixelFormatToGfxBufferFormat(pixel_format); - CHECK(buffer_format) << "Pixel format " - << media::VideoPixelFormatToString(pixel_format) - << " has no corresponding gfx::BufferFormat"; - - return media::VideoFrame::WrapExternalGpuMemoryBuffer( - visible_rect, natural_size, std::move(gmb), timestamp); -} - } // namespace blink
diff --git a/third_party/blink/renderer/platform/testing/video_frame_utils.h b/third_party/blink/renderer/platform/testing/video_frame_utils.h index ed4079b..2039807 100644 --- a/third_party/blink/renderer/platform/testing/video_frame_utils.h +++ b/third_party/blink/renderer/platform/testing/video_frame_utils.h
@@ -29,15 +29,6 @@ base::TimeDelta timestamp, gpu::TestSharedImageInterface* test_sii); -scoped_refptr<media::VideoFrame> CreateTestFrameWithGMB( - const gfx::Size& coded_size, - const gfx::Rect& visible_rect, - const gfx::Size& natural_size, - media::VideoFrame::StorageType storage_type, - media::VideoPixelFormat pixel_format, - base::TimeDelta timestamp, - std::unique_ptr<gfx::GpuMemoryBuffer> gmb); - } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_VIDEO_FRAME_UTILS_H_
diff --git a/third_party/blink/tools/blinkpy/wpt_tests/product.py b/third_party/blink/tools/blinkpy/wpt_tests/product.py index 24cbdf2..0a5b2bd 100644 --- a/third_party/blink/tools/blinkpy/wpt_tests/product.py +++ b/third_party/blink/tools/blinkpy/wpt_tests/product.py
@@ -16,6 +16,8 @@ _log = logging.getLogger(__name__) IOS_VERSION = '17.0' IOS_DEVICE = 'iPhone 14 Pro' +# Use a hard coded version, we might need to update this occasionally +CHROME_ANDROID_STABLE_VERSION = '138.0.7158.0' def do_delay_imports(): @@ -81,7 +83,7 @@ # pylint: disable=assignment-from-none options.browser_version = self.get_version() if self._options.stable: - options.browser_channel = 'stable' + options.channel = 'stable' options.webdriver_binary = self._options.webdriver_binary or self.webdriver_binary options.webdriver_args.extend(self.additional_webdriver_args()) @@ -238,8 +240,12 @@ def _install_chrome_stable(self, device): install_script = self._port._path_finder.path_from_chromium_base( 'clank', 'bin', 'install_chrome.py') - self._host.executive.run_command( - [install_script, '--serial', device.serial, '--channel', 'stable']) + self._host.executive.run_command([ + install_script, '--serial', device.serial, '--channel', 'stable', + '--adb', self.adb_binary, '--chrome-version', + CHROME_ANDROID_STABLE_VERSION, '--package', + 'TrichromeChromeGoogle6432' + ]) try: yield finally: @@ -304,6 +310,8 @@ options.package_name = self.get_browser_package_name() def get_version(self): + if self._options.stable: + return CHROME_ANDROID_STABLE_VERSION version_provider = self.get_version_provider_package_name() if self.devices and version_provider: # Assume devices are identically provisioned, so select any. @@ -338,6 +346,8 @@ See Also: https://github.com/web-platform-tests/wpt/blob/merge_pr_33203/tools/wpt/browser.py#L867-L924 """ + if self._options.stable: + return 'com.android.chrome' if self.browser_apk: # pylint: disable=undefined-variable; with contextlib.suppress(apk_helper.ApkHelperError):
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 14b6409..4df48eab 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -9358,11 +9358,3 @@ # Gardener 2025-05-07 crbug.com/416123241 [ Linux ] fast/forms/select/customizable-select/disallowed-select-descendants-console-message.html [ Failure Pass ] - -# Temporarily skipped to land https://crrev.com/c/6502712, after which expectations will be updated -crbug.com/414525205 http/tests/devtools/console/console-functions.js [ Failure Pass ] -crbug.com/414525205 http/tests/devtools/sources/debugger-ui/watch-expressions-preserve-expansion.js [ Failure Pass ] -crbug.com/414525205 http/tests/devtools/sources/debugger/properties-special.js [ Failure Pass ] -crbug.com/414525205 external/wpt/webidl/ecmascript-binding/builtin-function-properties.any.html [ Failure Pass ] -crbug.com/414525205 external/wpt/webidl/ecmascript-binding/builtin-function-properties.any.worker.html [ Failure Pass ] -crbug.com/414525205 external/wpt/webidl/ecmascript-binding/legacy-factory-function-builtin-properties.window.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/idbcursor-request-source.any.js b/third_party/blink/web_tests/external/wpt/IndexedDB/idbcursor-request-source.any.js index 2fe8c66..8e1b34e 100644 --- a/third_party/blink/web_tests/external/wpt/IndexedDB/idbcursor-request-source.any.js +++ b/third_party/blink/web_tests/external/wpt/IndexedDB/idbcursor-request-source.any.js
@@ -6,21 +6,111 @@ 'use strict'; -[cursor => cursor.update(0), cursor => cursor.delete()].forEach( - func => indexeddb_test( - (t, db) => { - db.createObjectStore('store', {autoIncrement: true}); - }, - (t, db) => { - const tx = db.transaction('store', 'readwrite'); - const store = tx.objectStore('store'); - store.put('value'); - store.openCursor().onsuccess = t.step_func(e => { - const cursor = e.target.result; - assert_equals( - func(cursor).source, cursor, - `${func}.source should be the cursor itself`); +// Setup each test by populating an object store with an index for the cursor to +// iterate and manipulate. +function initializeDatabase(db) { + const store = db.createObjectStore('store', {autoIncrement: true}); + store.createIndex('index', /*keypath=*/ 'value'); + store.put({value: 'z'}); + store.put({value: 'y'}); + store.put({value: 'x'}); + store.put({value: 'w'}); +} + +function isIndex(cursorSourceType) { + return cursorSourceType === 'IDBIndex'; +} + +// Return the object store or index, depending on the test's `cursorSourceType`. +function getCursorSource(transaction, cursorSourceType) { + let cursorSource = transaction.objectStore('store'); + if (isIndex(cursorSourceType)) { + cursorSource = cursorSource.index('index'); + } + return cursorSource; +} + +// Verify the request source after calling delete() or update() on the cursor. +function cursor_request_source_test( + cursorSourceType, createRequestFunctionName, createRequestFunctionArgs) { + indexeddb_test( + (t, db) => initializeDatabase(db), + (t, db) => { + const tx = db.transaction('store', 'readwrite'); + const cursorSource = getCursorSource(tx, cursorSourceType); + + // Open the cursor. + const openCursorRequest = cursorSource.openCursor(); + openCursorRequest.onerror = + t.unreached_func('The cursor must not fail to open.'); + + openCursorRequest.onsuccess = t.step_func(e => { + // Use the cursor to create a new request. + const cursor = e.target.result; + const request = + cursor[createRequestFunctionName](...createRequestFunctionArgs); + assert_equals( + request.source, cursor, + `The request's source must be the cursor itself.`); + t.done(); + }); + }, + `The source of the request from ${cursorSourceType}::${ + createRequestFunctionName}() is the cursor itself`); +} + +// Verify the request source after calling openCursor() or openKeyCursor() and +// then using the cursor to iterate. +function open_cursor_request_source_test( + cursorSourceType, openCursorFunctionName) { + indexeddb_test( + (t, db) => initializeDatabase(db), + (t, db) => { + const tx = db.transaction('store', 'readonly'); + const cursorSource = getCursorSource(tx, cursorSourceType); + + // Open the cursor. + const openCursorRequest = cursorSource[openCursorFunctionName](); + openCursorRequest.onerror = + t.unreached_func('The cursor must not fail to open or iterate.'); + + assert_equals( + openCursorRequest.source, cursorSource, + 'The request source must be the opener of the cursor.'); + + // Verify the cursor's `request.source` after iterating with + // `advance()`, `continue()`, and `continuePrimaryKey()`. + let iterationCount = 0; + openCursorRequest.onsuccess = t.step_func(e => { + assert_equals( + openCursorRequest.source, cursorSource, + 'The request source must be the opener of the cursor after iterating.'); + + const cursor = e.target.result; + ++iterationCount; + + if (iterationCount == 1) { + cursor.advance(1); + } else if (iterationCount == 2) { + cursor.continue(); + } else if (iterationCount == 3 && isIndex(cursorSourceType)) { + cursor.continuePrimaryKey('z', 0); + } else { t.done(); - }); - }, - `The source of the request from ${func} is the cursor itself`)); + } + }); + }, + `${cursorSourceType}::${ + openCursorFunctionName}'s request source must be the ${ + cursorSourceType} instance that opened the cursor`); +} + +open_cursor_request_source_test('IDBObjectStore', 'openCursor'); +open_cursor_request_source_test('IDBObjectStore', 'openKeyCursor'); +open_cursor_request_source_test('IDBIndex', 'openCursor'); +open_cursor_request_source_test('IDBIndex', 'openKeyCursor'); + +cursor_request_source_test('IDBObjectStore', 'update', /*args=*/[0]); +cursor_request_source_test('IDBObjectStore', 'delete', /*args=*/[]); +cursor_request_source_test('IDBIndex', 'update', /*args=*/[0]); +cursor_request_source_test('IDBIndex', 'delete', /*args=*/[]);
diff --git a/third_party/blink/web_tests/external/wpt/webidl/ecmascript-binding/builtin-function-properties.any-expected.txt b/third_party/blink/web_tests/external/wpt/webidl/ecmascript-binding/builtin-function-properties.any-expected.txt deleted file mode 100644 index 4dfe1fa..0000000 --- a/third_party/blink/web_tests/external/wpt/webidl/ecmascript-binding/builtin-function-properties.any-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -This is a testharness.js-based test. -[FAIL] Constructor property enumeration order of "length", "name", and "prototype" - assert_array_equals: expected property 2 to be "prototype" but got "arguments" (expected array ["length", "name", "prototype"] got ["length", "name", "arguments"]) -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/webidl/ecmascript-binding/builtin-function-properties.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/webidl/ecmascript-binding/builtin-function-properties.any.worker-expected.txt deleted file mode 100644 index 4dfe1fa..0000000 --- a/third_party/blink/web_tests/external/wpt/webidl/ecmascript-binding/builtin-function-properties.any.worker-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -This is a testharness.js-based test. -[FAIL] Constructor property enumeration order of "length", "name", and "prototype" - assert_array_equals: expected property 2 to be "prototype" but got "arguments" (expected array ["length", "name", "prototype"] got ["length", "name", "arguments"]) -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/webidl/ecmascript-binding/legacy-factory-function-builtin-properties.window-expected.txt b/third_party/blink/web_tests/external/wpt/webidl/ecmascript-binding/legacy-factory-function-builtin-properties.window-expected.txt deleted file mode 100644 index 7dc3162d..0000000 --- a/third_party/blink/web_tests/external/wpt/webidl/ecmascript-binding/legacy-factory-function-builtin-properties.window-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -This is a testharness.js-based test. -[FAIL] Legacy factory function property enumeration order of "length", "name", and "prototype" - assert_array_equals: expected property 2 to be "prototype" but got "arguments" (expected array ["length", "name", "prototype"] got ["length", "name", "arguments"]) -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/pooling.https.any.js b/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/pooling.https.any.js index f385aab..8f81ff56 100644 --- a/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/pooling.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/pooling.https.any.js
@@ -34,46 +34,6 @@ // MLOperand maxPool2d( // MLOperand input, optional MLPool2dOptions options = {}); - -const getPoolingOperatorsPrecisionTolerance = (graphResources) => { - const args = graphResources.operators[0].arguments; - const inputShape = - graphResources.inputs[args[0][Object.keys(args[0])[0]]].descriptor.shape; - const options = - args.length === 2 ? {...args[1][Object.keys(args[1])[0]]} : {}; - let height; - let width; - - if (options.windowDimensions) { - height = options.windowDimensions[0]; - width = options.windowDimensions[1]; - } else { - // If not present, the window dimensions are assumed to be the height and - // width dimensions of the input shape - if (options.layout && options.layout === 'nhwc') { - height = inputShape[1]; - width = inputShape[2]; - } else { - // nhwc layout of input - height = inputShape[2]; - width = inputShape[3]; - } - } - - const tolerance = height * width + 2; - const toleranceDict = { - averagePool2d: {float32: tolerance, float16: tolerance}, - l2Pool2d: {float32: tolerance, float16: tolerance}, - maxPool2d: {float32: 0, float16: 0}, - }; - const expectedDataType = - getExpectedDataTypeOfSingleOutput(graphResources.expectedOutputs); - return { - metricType: 'ULP', - value: toleranceDict[graphResources.operators[0].name][expectedDataType] - }; -}; - const poolingOperatorsTests = [ // averagePool2d tests { @@ -2345,8 +2305,7 @@ if (navigator.ml) { poolingOperatorsTests.forEach((test) => { - webnn_conformance_test( - buildAndExecuteGraph, getPoolingOperatorsPrecisionTolerance, test); + webnn_conformance_test(buildAndExecuteGraph, getPrecisionTolerance, test); }); } else { test(() => assert_implements(navigator.ml, 'missing navigator.ml'));
diff --git a/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/qdq_subgraph.https.any.js b/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/qdq_subgraph.https.any.js index 64f3776..5ec9ff8 100644 --- a/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/qdq_subgraph.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/qdq_subgraph.https.any.js
@@ -1007,6 +1007,170 @@ } } }, + { + 'name': 'quantized averagePool2d', + 'graph': { + 'inputs': { + 'input': { + 'data': [ + -2.549168109893799, -4.794857501983643, + 8.413617134094238, 6.108623504638672 + ], + 'descriptor': {shape: [1, 2, 2, 1], dataType: 'float32'}, + 'constant': false + }, + 'inputScale': { + 'data': [0.343092918395996], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'inputZeroPoint': { + 'data': [-128], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + 'outputScale': { + 'data': [0.343092918395996], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'outputZeroPoint': { + 'data': [-128], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + }, + 'operators': [ + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'input'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'quantizedInput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedInput'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'dequantizedInput' + }, + { + 'name': 'averagePool2d', + 'arguments': [{'input': 'dequantizedInput'}, {'options': {'layout': 'nhwc'}}], + 'outputs': 'averagePool2dOutput' + }, + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'averagePool2dOutput'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'quantizedAveragePool2dOutput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedAveragePool2dOutput'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'output' + } + ], + 'expectedOutputs': { + 'output': { + 'data': [ + 3.774022102355957, + ], + 'descriptor': {shape: [1, 1, 1, 1], dataType: 'float32'} + } + } + } + }, + { + 'name': 'quantized maxPool2d', + 'graph': { + 'inputs': { + 'input': { + 'data': [ + -2.549168109893799, -4.794857501983643, + 8.413617134094238, 6.108623504638672 + ], + 'descriptor': {shape: [1, 2, 2, 1], dataType: 'float32'}, + 'constant': false + }, + 'inputScale': { + 'data': [0.343092918395996], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'inputZeroPoint': { + 'data': [-128], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + 'outputScale': { + 'data': [0.343092918395996], + 'descriptor': {shape: [1], dataType: 'float32'}, + 'constant': true + }, + 'outputZeroPoint': { + 'data': [-128], + 'descriptor': {shape: [1], dataType: 'int8'}, + 'constant': true + }, + }, + 'operators': [ + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'input'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'quantizedInput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedInput'}, + {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'} + ], + 'outputs': 'dequantizedInput' + }, + { + 'name': 'maxPool2d', + 'arguments': [{'input': 'dequantizedInput'}, {'options': {'layout': 'nhwc'}}], + 'outputs': 'maxPool2dOutput' + }, + { + 'name': 'quantizeLinear', + 'arguments': [ + {'input': 'maxPool2dOutput'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'quantizedMaxPool2dOutput' + }, + { + 'name': 'dequantizeLinear', + 'arguments': [ + {'input': 'quantizedMaxPool2dOutput'}, + {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'} + ], + 'outputs': 'output' + } + ], + 'expectedOutputs': { + 'output': { + 'data': [ + 8.577322959899902, + ], + 'descriptor': {shape: [1, 1, 1, 1], dataType: 'float32'} + } + } + } + }, ]; if (navigator.ml) {
diff --git a/third_party/blink/web_tests/external/wpt/webnn/resources/utils.js b/third_party/blink/web_tests/external/wpt/webnn/resources/utils.js index 50d7911..9d5cfc7 100644 --- a/third_party/blink/web_tests/external/wpt/webnn/resources/utils.js +++ b/third_party/blink/web_tests/external/wpt/webnn/resources/utils.js
@@ -59,6 +59,13 @@ op, graphResources, intermediateOperands) .value; break; + case 'averagePool2d': + case 'maxPool2d': + case 'l2Pool2d': + toleranceValue += getPoolingOperatorsPrecisionTolerance( + op, graphResources, intermediateOperands) + .value; + break; default: const operatorTolerance = operatorToleranceDict[op.name]?.[expectedDataType]; @@ -1006,6 +1013,53 @@ return {metricType: 'ULP', value: toleranceValueDict[expectedDataType]}; }; +const getPoolingOperatorsPrecisionTolerance = + (op, graphResources, intermediateOperands) => { + const args = op.arguments; + const operatorName = op.name; + const {inputs} = graphResources; + let inputShape; + const inputIndex = args[0][Object.keys(args[0])[0]]; + if (inputs[inputIndex]) { + inputShape = inputs[inputIndex].descriptor.shape; + } else { + inputShape = intermediateOperands[inputIndex].shape; + } + const options = + args.length === 2 ? {...args[1][Object.keys(args[1])[0]]} : {}; + let height; + let width; + + if (options.windowDimensions) { + height = options.windowDimensions[0]; + width = options.windowDimensions[1]; + } else { + // If not present, the window dimensions are assumed to be the height + // and width dimensions of the input shape + if (options.layout && options.layout === 'nhwc') { + height = inputShape[1]; + width = inputShape[2]; + } else { + // nhwc layout of input + height = inputShape[2]; + width = inputShape[3]; + } + } + + const tolerance = height * width + 2; + const toleranceDict = { + averagePool2d: {float32: tolerance, float16: tolerance}, + l2Pool2d: {float32: tolerance, float16: tolerance}, + maxPool2d: {float32: 0, float16: 0}, + }; + const expectedDataType = + getExpectedDataTypeOfSingleOutput(graphResources.expectedOutputs); + return { + metricType: 'ULP', + value: toleranceDict[operatorName][expectedDataType] + }; +}; + const getInstanceNormPrecisionTolerance = (graphResources) => { // according to // https://github.com/web-platform-tests/wpt/pull/43891#discussion_r1457026316
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-functions-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-functions-expected.txt index aac7dbe..41f1fd9 100644 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-functions-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/console/console-functions-expected.txt
@@ -4,11 +4,11 @@ console-functions.js:30 ƒ simple() - arguments: null - caller: null length: 0 name: "simple" prototype: {} + arguments: null + caller: null [[FunctionLocation]]: console-functions.js:15 [[Prototype]]: ƒ () [[Scopes]]: Scopes[1] @@ -46,11 +46,11 @@ console-functions.js:30 ƒ anonymous() - arguments: null - caller: null length: 0 name: "" prototype: {} + arguments: null + caller: null [[FunctionLocation]]: console-functions.js:18 [[Prototype]]: ƒ () [[Scopes]]: Scopes[1] @@ -60,11 +60,11 @@ console-functions.js:30 ƒ anonymous(x, y) - arguments: null - caller: null length: 2 name: "" prototype: {} + arguments: null + caller: null [[FunctionLocation]]: console-functions.js:19 [[Prototype]]: ƒ () [[Scopes]]: Scopes[1] @@ -74,11 +74,11 @@ console-functions.js:30 ƒ namedArgs(x) - arguments: null - caller: null length: 1 name: "namedArgs" prototype: {} + arguments: null + caller: null [[FunctionLocation]]: console-functions.js:20 [[Prototype]]: ƒ () [[Scopes]]: Scopes[1] @@ -88,11 +88,11 @@ console-functions.js:30 ƒ namedArgs2(x, y) - arguments: null - caller: null length: 2 name: "namedArgs2" prototype: {} + arguments: null + caller: null [[FunctionLocation]]: console-functions.js:21 [[Prototype]]: ƒ () [[Scopes]]: Scopes[1] @@ -102,11 +102,11 @@ console-functions.js:30 ƒ anonymous({}) - arguments: null - caller: null length: 1 name: "" prototype: {} + arguments: null + caller: null [[FunctionLocation]]: console-functions.js:22 [[Prototype]]: ƒ () [[Scopes]]: Scopes[1]
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/watch-expressions-preserve-expansion-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/watch-expressions-preserve-expansion-expected.txt index 6c5de86..101d5e4 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/watch-expressions-preserve-expansion-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-ui/watch-expressions-preserve-expansion-expected.txt
@@ -120,11 +120,11 @@ length: 300 [[Prototype]]: Array(0) func: function() {return a + b;} - arguments: null - caller: null length: 0 name: prototype: Object + arguments: null + caller: null [[FunctionLocation]]: Object [[Prototype]]: function () { [native code] } Page reloaded. @@ -242,11 +242,11 @@ length: 300 [[Prototype]]: Array(0) func: function() {return a + b;} - arguments: null - caller: null length: 0 name: prototype: Object + arguments: null + caller: null [[FunctionLocation]]: Object [[Prototype]]: function () { [native code] }
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger/properties-special-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger/properties-special-expected.txt index 850720e..b3648e9f 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger/properties-special-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger/properties-special-expected.txt
@@ -5,11 +5,11 @@ properties-special.js:14 ƒ anonymous(a,b) - arguments: null - caller: null length: 2 name: "" prototype: {} + arguments: null + caller: null [[FunctionLocation]]: properties-special.js:14 [[Prototype]]: ƒ () [[Scopes]]: Scopes[1]
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-env/env-preferred-text-scale-002.html b/third_party/blink/web_tests/wpt_internal/css/css-env/env-preferred-text-scale-002.html new file mode 100644 index 0000000..fbe2960 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/css/css-env/env-preferred-text-scale-002.html
@@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html lang="en" class="reftest-wait"> +<meta content="width=device-width,initial-scale=1.0,minimum-scale=1.0" + name="viewport"> +<meta name="assert" + content="env(preferred-text-scale) exposes the user's preferred text scale from the OS, clamped to a hardcoded set of values"> +<link rel="help" href="https://drafts.csswg.org/css-env-1/#text-zoom"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<script src="/common/reftest-wait.js"></script> +<style> + div { + background-color: green; + width: calc(50px * env(preferred-text-scale)); + height: calc(50px * env(preferred-text-scale)); + } +</style> + +<p>Test passes if there is a filled green square and <strong>no red</strong>. +</p> +<div></div> +<script> + if (window.internals) { + internals.settings.setAccessibilityFontScaleFactor(1.91); + } else { + document.body.appendChild(document.createTextNode("No window.internals? This test will fail.")); + } + requestAnimationFrame(() => requestAnimationFrame(() => { + takeScreenshot(); + })); +</script>
diff --git a/third_party/boringssl/src b/third_party/boringssl/src index 154bb58..f371c85 160000 --- a/third_party/boringssl/src +++ b/third_party/boringssl/src
@@ -1 +1 @@ -Subproject commit 154bb5860a47c160c3be09003908c64c1de11bff +Subproject commit f371c85a8d58bf911cba6073bcca6d497af81dc9
diff --git a/third_party/catapult b/third_party/catapult index 64c31ff..74f545d 160000 --- a/third_party/catapult +++ b/third_party/catapult
@@ -1 +1 @@ -Subproject commit 64c31ffa4d735add4a7e7520a52e0e3160216132 +Subproject commit 74f545d009ceef464f840938ae079ffbc112a102
diff --git a/third_party/depot_tools b/third_party/depot_tools index fab0a42..a7571b1 160000 --- a/third_party/depot_tools +++ b/third_party/depot_tools
@@ -1 +1 @@ -Subproject commit fab0a4296b8830c569a4dc82285bfb58a5c2fca8 +Subproject commit a7571b1596305d6a6fe26c788f24e40c579fcda8
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src index 6e4e34a..6d3155a 160000 --- a/third_party/devtools-frontend/src +++ b/third_party/devtools-frontend/src
@@ -1 +1 @@ -Subproject commit 6e4e34acb617713aa7b51311d6ea87c58c609b32 +Subproject commit 6d3155a3c0b50687e4f417e19d4491e66d56ef3c
diff --git a/third_party/libaddressinput/BUILD.gn b/third_party/libaddressinput/BUILD.gn index ab7e3ed..92fd2ff 100644 --- a/third_party/libaddressinput/BUILD.gn +++ b/third_party/libaddressinput/BUILD.gn
@@ -22,16 +22,14 @@ include_dirs = [ target_gen_dir ] } -grit("strings") { +grit_strings("strings") { source = "chromium/address_input_strings.grd" outputs = [ "messages.h", "en_messages.cc", ] - foreach(locale, all_chrome_locales) { - outputs += [ "address_input_strings_$locale.pak" ] - } + output_prefix = "address_input_strings_" configs = [ ":internal_config" ] }
diff --git a/third_party/libxslt/chromium/change-atype-extra.patch b/third_party/libxslt/chromium/change-atype-extra.patch deleted file mode 100644 index 9e2f666..0000000 --- a/third_party/libxslt/chromium/change-atype-extra.patch +++ /dev/null
@@ -1,110 +0,0 @@ -diff --git a/third_party/libxslt/src/libxslt/transform.c b/third_party/libxslt/src/libxslt/transform.c -index 54ef821b5016f..1ac2471d6441b 100644 ---- a/third_party/libxslt/src/libxslt/transform.c -+++ b/third_party/libxslt/src/libxslt/transform.c -@@ -5772,7 +5772,8 @@ xsltCleanupSourceDoc(xmlDocPtr doc) { - xmlAttrPtr prop = cur->properties; - - while (prop) { -- prop->atype &= ~(XSLT_SOURCE_NODE_MASK << 27); -+ prop->extra &= -+ ~(XSLT_SOURCE_NODE_MASK << XSLT_SOURCE_NODE_SHIFT_32); - prop->psvi = NULL; - prop = prop->next; - } -diff --git a/third_party/libxslt/src/libxslt/xsltutils.c b/third_party/libxslt/src/libxslt/xsltutils.c -index a20da96182289..0155e7fc5a89f 100644 ---- a/third_party/libxslt/src/libxslt/xsltutils.c -+++ b/third_party/libxslt/src/libxslt/xsltutils.c -@@ -1920,26 +1920,26 @@ xsltSaveResultToString(xmlChar **doc_txt_ptr, int * doc_txt_len, - int - xsltGetSourceNodeFlags(xmlNodePtr node) { - /* -- * Squeeze the bit flags into the upper bits of -+ * Squeeze the bit flags into the upper 4 bits of - * -- * - 'int properties' member in struct _xmlDoc -- * - 'xmlAttributeType atype' member in struct _xmlAttr -+ * - 'unsigned int extra' member in struct _xmlDoc -+ * - 'unsigned int extra' member in struct _xmlAttr - * - 'unsigned short extra' member in struct _xmlNode - */ - switch (node->type) { - case XML_DOCUMENT_NODE: - case XML_HTML_DOCUMENT_NODE: -- return ((xmlDocPtr) node)->properties >> 27; -+ return ((xmlDocPtr) node)->extra >> XSLT_SOURCE_NODE_SHIFT_32; - - case XML_ATTRIBUTE_NODE: -- return ((xmlAttrPtr) node)->atype >> 27; -+ return ((xmlAttrPtr) node)->extra >> XSLT_SOURCE_NODE_SHIFT_32; - - case XML_ELEMENT_NODE: - case XML_TEXT_NODE: - case XML_CDATA_SECTION_NODE: - case XML_PI_NODE: - case XML_COMMENT_NODE: -- return node->extra >> 12; -+ return node->extra >> XSLT_SOURCE_NODE_SHIFT_32; - - default: - return 0; -@@ -1964,11 +1964,11 @@ xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node, - switch (node->type) { - case XML_DOCUMENT_NODE: - case XML_HTML_DOCUMENT_NODE: -- ((xmlDocPtr) node)->properties |= flags << 27; -+ ((xmlDocPtr) node)->extra |= (flags << XSLT_SOURCE_NODE_SHIFT_32); - return 0; - - case XML_ATTRIBUTE_NODE: -- ((xmlAttrPtr) node)->atype |= flags << 27; -+ ((xmlAttrPtr) node)->extra |= (flags << XSLT_SOURCE_NODE_SHIFT_32); - return 0; - - case XML_ELEMENT_NODE: -@@ -1976,7 +1976,7 @@ xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node, - case XML_CDATA_SECTION_NODE: - case XML_PI_NODE: - case XML_COMMENT_NODE: -- node->extra |= flags << 12; -+ node->extra |= (flags << XSLT_SOURCE_NODE_SHIFT_16); - return 0; - - default: -@@ -1998,11 +1998,11 @@ xsltClearSourceNodeFlags(xmlNodePtr node, int flags) { - switch (node->type) { - case XML_DOCUMENT_NODE: - case XML_HTML_DOCUMENT_NODE: -- ((xmlDocPtr) node)->properties &= ~(flags << 27); -+ ((xmlDocPtr) node)->extra &= ~(flags << XSLT_SOURCE_NODE_SHIFT_32); - return 0; - - case XML_ATTRIBUTE_NODE: -- ((xmlAttrPtr) node)->atype &= ~(flags << 27); -+ ((xmlAttrPtr) node)->extra &= ~(flags << XSLT_SOURCE_NODE_SHIFT_32); - return 0; - - case XML_ELEMENT_NODE: -@@ -2010,7 +2010,7 @@ xsltClearSourceNodeFlags(xmlNodePtr node, int flags) { - case XML_CDATA_SECTION_NODE: - case XML_PI_NODE: - case XML_COMMENT_NODE: -- node->extra &= ~(flags << 12); -+ node->extra &= ~(flags << XSLT_SOURCE_NODE_SHIFT_16); - return 0; - - default: -diff --git a/third_party/libxslt/src/libxslt/xsltutils.h b/third_party/libxslt/src/libxslt/xsltutils.h -index 2514774b3f11a..d15d22726afaa 100644 ---- a/third_party/libxslt/src/libxslt/xsltutils.h -+++ b/third_party/libxslt/src/libxslt/xsltutils.h -@@ -261,6 +261,8 @@ XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL - #define XSLT_SOURCE_NODE_MASK 15u - #define XSLT_SOURCE_NODE_HAS_KEY 1u - #define XSLT_SOURCE_NODE_HAS_ID 2u -+#define XSLT_SOURCE_NODE_SHIFT_16 12u -+#define XSLT_SOURCE_NODE_SHIFT_32 28u - int - xsltGetSourceNodeFlags(xmlNodePtr node); - int
diff --git a/third_party/libxslt/chromium/change-id.patch b/third_party/libxslt/chromium/change-id.patch deleted file mode 100644 index b151abb..0000000 --- a/third_party/libxslt/chromium/change-id.patch +++ /dev/null
@@ -1,114 +0,0 @@ -diff --git a/third_party/libxslt/src/libxslt/functions.c b/third_party/libxslt/src/libxslt/functions.c -index 72a58dc4d6592..309af458c22f7 100644 ---- a/third_party/libxslt/src/libxslt/functions.c -+++ b/third_party/libxslt/src/libxslt/functions.c -@@ -760,7 +760,7 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ - } - - if (xsltGetSourceNodeFlags(cur) & XSLT_SOURCE_NODE_HAS_ID) { -- id = (unsigned long) (size_t) *psviPtr; -+ id = (unsigned long) xsltGetSourceNodeValue(cur); - } else { - if (cur->type == XML_TEXT_NODE && cur->line == USHRT_MAX) { - /* Text nodes store big line numbers in psvi. */ -@@ -772,7 +772,7 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ - goto out; - } - -- if (tctxt->currentId == ULONG_MAX) { -+ if (tctxt->currentId == XSLT_SOURCE_NODE_VALUE_MAX) { - xsltTransformError(tctxt, NULL, NULL, - "generate-id(): id overflow\n"); - ctxt->error = XPATH_MEMORY_ERROR; -@@ -780,7 +780,7 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ - } - - id = ++tctxt->currentId; -- *psviPtr = (void *) (size_t) id; -+ xsltSetSourceNodeValue(cur, id); - xsltSetSourceNodeFlags(tctxt, cur, XSLT_SOURCE_NODE_HAS_ID); - } - -diff --git a/third_party/libxslt/src/libxslt/xsltutils.c b/third_party/libxslt/src/libxslt/xsltutils.c -index 0155e7fc5a89f..aec8be4ad077c 100644 ---- a/third_party/libxslt/src/libxslt/xsltutils.c -+++ b/third_party/libxslt/src/libxslt/xsltutils.c -@@ -2018,6 +2018,54 @@ xsltClearSourceNodeFlags(xmlNodePtr node, int flags) { - } - } - -+/** -+ * xsltGetSourceNodeValue: -+ * @node: Node from source document -+ * -+ * Returns the associated 28 bit unsigned value for a source node, -+ * or 0 if node does not have an associated value. -+ */ -+int -+xsltGetSourceNodeValue(xmlNodePtr node) { -+ switch (node->type) { -+ case XML_DOCUMENT_NODE: -+ case XML_HTML_DOCUMENT_NODE: -+ return (((xmlDocPtr) node)->extra & XSLT_SOURCE_NODE_VALUE_MASK); -+ -+ case XML_ATTRIBUTE_NODE: -+ return (((xmlAttrPtr) node)->extra & XSLT_SOURCE_NODE_VALUE_MASK); -+ -+ default: -+ return 0; -+ } -+} -+ -+/** -+ * xsltSetSourceNodeValue: -+ * @node: Node from source document -+ * @value: 28 bit unsigned value to associate with the node. -+ * -+ * Returns 0 on success, -1 on error. -+ */ -+int -+xsltSetSourceNodeValue(xmlNodePtr node, int value) { -+ switch (node->type) { -+ case XML_DOCUMENT_NODE: -+ case XML_HTML_DOCUMENT_NODE: -+ ((xmlDocPtr) node)->extra &= ~XSLT_SOURCE_NODE_VALUE_MASK; -+ ((xmlDocPtr) node)->extra |= (value & XSLT_SOURCE_NODE_VALUE_MASK); -+ return 0; -+ -+ case XML_ATTRIBUTE_NODE: -+ ((xmlAttrPtr) node)->extra &= ~XSLT_SOURCE_NODE_VALUE_MASK; -+ ((xmlAttrPtr) node)->extra |= (value & XSLT_SOURCE_NODE_VALUE_MASK); -+ return 0; -+ -+ default: -+ return -1; -+ } -+} -+ - /** - * xsltGetPSVIPtr: - * @cur: Node -diff --git a/third_party/libxslt/src/libxslt/xsltutils.h b/third_party/libxslt/src/libxslt/xsltutils.h -index d15d22726afaa..1e753eebadd98 100644 ---- a/third_party/libxslt/src/libxslt/xsltutils.h -+++ b/third_party/libxslt/src/libxslt/xsltutils.h -@@ -263,6 +263,8 @@ XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL - #define XSLT_SOURCE_NODE_HAS_ID 2u - #define XSLT_SOURCE_NODE_SHIFT_16 12u - #define XSLT_SOURCE_NODE_SHIFT_32 28u -+#define XSLT_SOURCE_NODE_VALUE_MASK ((1 << XSLT_SOURCE_NODE_SHIFT_32) - 1) -+#define XSLT_SOURCE_NODE_VALUE_MAX XSLT_SOURCE_NODE_VALUE_MASK - int - xsltGetSourceNodeFlags(xmlNodePtr node); - int -@@ -270,6 +272,10 @@ xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node, - int flags); - int - xsltClearSourceNodeFlags(xmlNodePtr node, int flags); -+int -+xsltSetSourceNodeValue(xmlNodePtr node, int value); -+int -+xsltGetSourceNodeValue(xmlNodePtr node); - void ** - xsltGetPSVIPtr(xmlNodePtr cur); - /** DOC_ENABLE */
diff --git a/third_party/libxslt/chromium/new-unified-atype-extra.patch b/third_party/libxslt/chromium/new-unified-atype-extra.patch new file mode 100644 index 0000000..9af5109 --- /dev/null +++ b/third_party/libxslt/chromium/new-unified-atype-extra.patch
@@ -0,0 +1,206 @@ +diff --git a/third_party/libxslt/src/libxslt/functions.c b/third_party/libxslt/src/libxslt/functions.c +index 72a58dc4d6592..309af458c22f7 100644 +--- a/third_party/libxslt/src/libxslt/functions.c ++++ b/third_party/libxslt/src/libxslt/functions.c +@@ -760,7 +760,7 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ + } + + if (xsltGetSourceNodeFlags(cur) & XSLT_SOURCE_NODE_HAS_ID) { +- id = (unsigned long) (size_t) *psviPtr; ++ id = (unsigned long) xsltGetSourceNodeValue(cur); + } else { + if (cur->type == XML_TEXT_NODE && cur->line == USHRT_MAX) { + /* Text nodes store big line numbers in psvi. */ +@@ -772,7 +772,7 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ + goto out; + } + +- if (tctxt->currentId == ULONG_MAX) { ++ if (tctxt->currentId == XSLT_SOURCE_NODE_VALUE_MAX) { + xsltTransformError(tctxt, NULL, NULL, + "generate-id(): id overflow\n"); + ctxt->error = XPATH_MEMORY_ERROR; +@@ -780,7 +780,7 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ + } + + id = ++tctxt->currentId; +- *psviPtr = (void *) (size_t) id; ++ xsltSetSourceNodeValue(cur, id); + xsltSetSourceNodeFlags(tctxt, cur, XSLT_SOURCE_NODE_HAS_ID); + } + +diff --git a/third_party/libxslt/src/libxslt/transform.c b/third_party/libxslt/src/libxslt/transform.c +index 54ef821b5016f..1ac2471d6441b 100644 +--- a/third_party/libxslt/src/libxslt/transform.c ++++ b/third_party/libxslt/src/libxslt/transform.c +@@ -5772,7 +5772,8 @@ xsltCleanupSourceDoc(xmlDocPtr doc) { + xmlAttrPtr prop = cur->properties; + + while (prop) { +- prop->atype &= ~(XSLT_SOURCE_NODE_MASK << 27); ++ prop->extra &= ++ ~(XSLT_SOURCE_NODE_MASK << XSLT_SOURCE_NODE_SHIFT_32); + prop->psvi = NULL; + prop = prop->next; + } +diff --git a/third_party/libxslt/src/libxslt/xsltutils.c b/third_party/libxslt/src/libxslt/xsltutils.c +index a20da96182289..b431fafbbb441 100644 +--- a/third_party/libxslt/src/libxslt/xsltutils.c ++++ b/third_party/libxslt/src/libxslt/xsltutils.c +@@ -1920,26 +1920,26 @@ xsltSaveResultToString(xmlChar **doc_txt_ptr, int * doc_txt_len, + int + xsltGetSourceNodeFlags(xmlNodePtr node) { + /* +- * Squeeze the bit flags into the upper bits of ++ * Squeeze the bit flags into the upper 4 bits of + * +- * - 'int properties' member in struct _xmlDoc +- * - 'xmlAttributeType atype' member in struct _xmlAttr ++ * - 'unsigned int extra' member in struct _xmlDoc ++ * - 'unsigned int extra' member in struct _xmlAttr + * - 'unsigned short extra' member in struct _xmlNode + */ + switch (node->type) { + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: +- return ((xmlDocPtr) node)->properties >> 27; ++ return ((xmlDocPtr) node)->extra >> XSLT_SOURCE_NODE_SHIFT_32; + + case XML_ATTRIBUTE_NODE: +- return ((xmlAttrPtr) node)->atype >> 27; ++ return ((xmlAttrPtr) node)->extra >> XSLT_SOURCE_NODE_SHIFT_32; + + case XML_ELEMENT_NODE: + case XML_TEXT_NODE: + case XML_CDATA_SECTION_NODE: + case XML_PI_NODE: + case XML_COMMENT_NODE: +- return node->extra >> 12; ++ return node->extra >> XSLT_SOURCE_NODE_SHIFT_32; + + default: + return 0; +@@ -1964,11 +1964,13 @@ xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node, + switch (node->type) { + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: +- ((xmlDocPtr) node)->properties |= flags << 27; ++ ((xmlDocPtr) node)->extra |= ++ ((unsigned) flags << XSLT_SOURCE_NODE_SHIFT_32); + return 0; + + case XML_ATTRIBUTE_NODE: +- ((xmlAttrPtr) node)->atype |= flags << 27; ++ ((xmlAttrPtr) node)->extra |= ++ ((unsigned) flags << XSLT_SOURCE_NODE_SHIFT_32); + return 0; + + case XML_ELEMENT_NODE: +@@ -1976,7 +1978,7 @@ xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node, + case XML_CDATA_SECTION_NODE: + case XML_PI_NODE: + case XML_COMMENT_NODE: +- node->extra |= flags << 12; ++ node->extra |= ((unsigned) flags << XSLT_SOURCE_NODE_SHIFT_16); + return 0; + + default: +@@ -1998,11 +2000,13 @@ xsltClearSourceNodeFlags(xmlNodePtr node, int flags) { + switch (node->type) { + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: +- ((xmlDocPtr) node)->properties &= ~(flags << 27); ++ ((xmlDocPtr) node)->extra &= ++ ~((unsigned) flags << XSLT_SOURCE_NODE_SHIFT_32); + return 0; + + case XML_ATTRIBUTE_NODE: +- ((xmlAttrPtr) node)->atype &= ~(flags << 27); ++ ((xmlAttrPtr) node)->extra &= ++ ~((unsigned) flags << XSLT_SOURCE_NODE_SHIFT_32); + return 0; + + case XML_ELEMENT_NODE: +@@ -2010,7 +2014,55 @@ xsltClearSourceNodeFlags(xmlNodePtr node, int flags) { + case XML_CDATA_SECTION_NODE: + case XML_PI_NODE: + case XML_COMMENT_NODE: +- node->extra &= ~(flags << 12); ++ node->extra &= ~((unsigned) flags << XSLT_SOURCE_NODE_SHIFT_16); ++ return 0; ++ ++ default: ++ return -1; ++ } ++} ++ ++/** ++ * xsltGetSourceNodeValue: ++ * @node: Node from source document ++ * ++ * Returns the associated 28 bit unsigned value for a source node, ++ * or 0 if node does not have an associated value. ++ */ ++int ++xsltGetSourceNodeValue(xmlNodePtr node) { ++ switch (node->type) { ++ case XML_DOCUMENT_NODE: ++ case XML_HTML_DOCUMENT_NODE: ++ return (((xmlDocPtr) node)->extra & XSLT_SOURCE_NODE_VALUE_MASK); ++ ++ case XML_ATTRIBUTE_NODE: ++ return (((xmlAttrPtr) node)->extra & XSLT_SOURCE_NODE_VALUE_MASK); ++ ++ default: ++ return 0; ++ } ++} ++ ++/** ++ * xsltSetSourceNodeValue: ++ * @node: Node from source document ++ * @value: 28 bit unsigned value to associate with the node. ++ * ++ * Returns 0 on success, -1 on error. ++ */ ++int ++xsltSetSourceNodeValue(xmlNodePtr node, int value) { ++ switch (node->type) { ++ case XML_DOCUMENT_NODE: ++ case XML_HTML_DOCUMENT_NODE: ++ ((xmlDocPtr) node)->extra &= ~XSLT_SOURCE_NODE_VALUE_MASK; ++ ((xmlDocPtr) node)->extra |= (value & XSLT_SOURCE_NODE_VALUE_MASK); ++ return 0; ++ ++ case XML_ATTRIBUTE_NODE: ++ ((xmlAttrPtr) node)->extra &= ~XSLT_SOURCE_NODE_VALUE_MASK; ++ ((xmlAttrPtr) node)->extra |= (value & XSLT_SOURCE_NODE_VALUE_MASK); + return 0; + + default: +diff --git a/third_party/libxslt/src/libxslt/xsltutils.h b/third_party/libxslt/src/libxslt/xsltutils.h +index 2514774b3f11a..1e753eebadd98 100644 +--- a/third_party/libxslt/src/libxslt/xsltutils.h ++++ b/third_party/libxslt/src/libxslt/xsltutils.h +@@ -261,6 +261,10 @@ XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL + #define XSLT_SOURCE_NODE_MASK 15u + #define XSLT_SOURCE_NODE_HAS_KEY 1u + #define XSLT_SOURCE_NODE_HAS_ID 2u ++#define XSLT_SOURCE_NODE_SHIFT_16 12u ++#define XSLT_SOURCE_NODE_SHIFT_32 28u ++#define XSLT_SOURCE_NODE_VALUE_MASK ((1 << XSLT_SOURCE_NODE_SHIFT_32) - 1) ++#define XSLT_SOURCE_NODE_VALUE_MAX XSLT_SOURCE_NODE_VALUE_MASK + int + xsltGetSourceNodeFlags(xmlNodePtr node); + int +@@ -268,6 +272,10 @@ xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node, + int flags); + int + xsltClearSourceNodeFlags(xmlNodePtr node, int flags); ++int ++xsltSetSourceNodeValue(xmlNodePtr node, int value); ++int ++xsltGetSourceNodeValue(xmlNodePtr node); + void ** + xsltGetPSVIPtr(xmlNodePtr cur); + /** DOC_ENABLE */
diff --git a/third_party/libxslt/src/libxslt/xsltutils.c b/third_party/libxslt/src/libxslt/xsltutils.c index aec8be4a..b431faf 100644 --- a/third_party/libxslt/src/libxslt/xsltutils.c +++ b/third_party/libxslt/src/libxslt/xsltutils.c
@@ -1964,11 +1964,13 @@ switch (node->type) { case XML_DOCUMENT_NODE: case XML_HTML_DOCUMENT_NODE: - ((xmlDocPtr) node)->extra |= (flags << XSLT_SOURCE_NODE_SHIFT_32); + ((xmlDocPtr) node)->extra |= + ((unsigned) flags << XSLT_SOURCE_NODE_SHIFT_32); return 0; case XML_ATTRIBUTE_NODE: - ((xmlAttrPtr) node)->extra |= (flags << XSLT_SOURCE_NODE_SHIFT_32); + ((xmlAttrPtr) node)->extra |= + ((unsigned) flags << XSLT_SOURCE_NODE_SHIFT_32); return 0; case XML_ELEMENT_NODE: @@ -1976,7 +1978,7 @@ case XML_CDATA_SECTION_NODE: case XML_PI_NODE: case XML_COMMENT_NODE: - node->extra |= (flags << XSLT_SOURCE_NODE_SHIFT_16); + node->extra |= ((unsigned) flags << XSLT_SOURCE_NODE_SHIFT_16); return 0; default: @@ -1998,11 +2000,13 @@ switch (node->type) { case XML_DOCUMENT_NODE: case XML_HTML_DOCUMENT_NODE: - ((xmlDocPtr) node)->extra &= ~(flags << XSLT_SOURCE_NODE_SHIFT_32); + ((xmlDocPtr) node)->extra &= + ~((unsigned) flags << XSLT_SOURCE_NODE_SHIFT_32); return 0; case XML_ATTRIBUTE_NODE: - ((xmlAttrPtr) node)->extra &= ~(flags << XSLT_SOURCE_NODE_SHIFT_32); + ((xmlAttrPtr) node)->extra &= + ~((unsigned) flags << XSLT_SOURCE_NODE_SHIFT_32); return 0; case XML_ELEMENT_NODE: @@ -2010,7 +2014,7 @@ case XML_CDATA_SECTION_NODE: case XML_PI_NODE: case XML_COMMENT_NODE: - node->extra &= ~(flags << XSLT_SOURCE_NODE_SHIFT_16); + node->extra &= ~((unsigned) flags << XSLT_SOURCE_NODE_SHIFT_16); return 0; default:
diff --git a/third_party/perfetto b/third_party/perfetto index e2d7750..993d41d 160000 --- a/third_party/perfetto +++ b/third_party/perfetto
@@ -1 +1 @@ -Subproject commit e2d7750acd15d57c6c88e3c8fb8c5a45f424ba96 +Subproject commit 993d41d0c39335e35fe577808e8f704e58d9dbfb
diff --git a/third_party/skia b/third_party/skia index ac2d5cee..0d16b74 160000 --- a/third_party/skia +++ b/third_party/skia
@@ -1 +1 @@ -Subproject commit ac2d5ceecb588e3be2a798896b92d27c91ad6461 +Subproject commit 0d16b74f74a5018c20fdaa753b41103bb08d08fd
diff --git a/tools/grit/grit_rule.gni b/tools/grit/grit_rule.gni index 597f4f4..dbfefc59 100644 --- a/tools/grit/grit_rule.gni +++ b/tools/grit/grit_rule.gni
@@ -2,6 +2,13 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +declare_args() { + # pass the "--translate-genders" flag into GRIT to generate 4 translation + # files per locale ("_OTHER", "_FEMININE", "_MASCULINE", "_NEUTER") instead of + # one. + translate_genders = false +} + # Instantiate grit. This will produce a script target to run grit (named # ${target_name}_grit), and a static library that compiles the .cc files. # @@ -90,6 +97,7 @@ # } import("//build/config/compiler/compiler.gni") import("//build/config/compute_inputs_for_analyze.gni") +import("//build/config/locales.gni") import("//build/config/sanitizers/sanitizers.gni") import("//build/toolchain/gcc_toolchain.gni") import("//tools/grit/grit_args.gni") @@ -358,6 +366,114 @@ } } +# This wraps grit(), generating outputs from locales, prefix, and translate_genders. +# +# The "grit_flags" optional parameter will be passed into "grit" after appending +# "--translate-genders" (if applicable), and the "outputs" optional parameter +# will be passed into "grit" after appending the locale- and gender-expanded pak +# file outputs. +# +# Parameters +# +# grit_flags (optional) +# List of strings containing extra command-line flags to pass to Grit. If +# translate_genders=true, "--translate-genders" will be appended to the +# list of flags before passing it through to grit(). +# +# outputs (optional) +# List of outputs from grit, relative to the target_gen_dir. Grit will +# verify at build time that this list is correct and will fail if there +# is a mismatch between the outputs specified by the .grd file and the +# outputs list here. Extra outputs will be added before passing it through +# to grit(), according to |output_prefix|, |locales|, and whether the +# |translate_genders| gn arg is set. +# +# locales (optional - defaults to all_chrome_locales) +# List of locales for translations. +# +# output_prefix (optional - defaults to "${target_name}_") +# String designating the prefix of the output filenames. The locales and +# (if enabled) genders, followed by ".pak", will be appended to this to +# make the full filenames. +# +# +# Example +# +# grit_strings("my_resources") { +# # Source and outputs are required. +# source = "myfile.grd" +# outputs = [ +# "foo_strings.h", +# ] +# +# # This will expand into many language-and-gender (where applicable) files +# # and be added to |outputs|. For example, the final |outputs| parameter +# # passed into "grit" would look something like: +# # outputs = [ "foo_strings.h", "foo_strings_af_OTHER.pak", +# # "foo_strings_af_FEMININE.pak", "foo_strings_af_MASCULINE.pak", +# # "foo_strings_af_NEUTER.pak", "foo_strings_am_OTHER.pak", ... ] +# locales = locales_with_pseudolocales +# output_prefix = "foo_strings_" +# +# # grit_flags will automatically be expanded to include +# # "--translate-genders", if applicable. +# grit_flags = [ "-E", "foo=bar" ] # Optional extra flags. +# # You can also put deps here if the grit source depends on generated +# # files. +# } +template("grit_strings") { + if (defined(invoker.grit_flags)) { + _grit_flags = invoker.grit_flags + } else { + _grit_flags = [] + } + if (translate_genders) { + _grit_flags += [ "--translate-genders" ] + } + + if (defined(invoker.locales)) { + _locales = invoker.locales + } else { + _locales = all_chrome_locales + } + + if (defined(invoker.output_prefix)) { + _output_prefix = invoker.output_prefix + } else { + _output_prefix = "${target_name}_" + } + + if (defined(invoker.outputs)) { + _outputs = invoker.outputs + } else { + _outputs = [] + } + foreach(locale, _locales) { + if (translate_genders) { + _outputs += process_file_template( + all_chrome_genders, + "${_output_prefix}${locale}_{{source_name_part}}.pak") + } else { + _outputs += [ "${_output_prefix}${locale}.pak" ] + } + } + + grit(target_name) { + forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) + forward_variables_from(invoker, + "*", + TESTONLY_AND_VISIBILITY + [ + "grit_flags", + "locales", + "output_prefix", + "outputs", + ]) + + outputs = _outputs + grit_flags = _grit_flags + } +} + if (is_android) { import("//build/config/android/rules.gni") @@ -394,7 +510,10 @@ "ANDROID_JAVA_TAGGED_ONLY=false", ] - # Ignore pak file IDs since they are not relevant. + if (translate_genders) { + grit_flags += [ "--translate-genders" ] + } + resource_ids = "" source = invoker.grd_file }
diff --git a/tools/grit/repack.gni b/tools/grit/repack.gni index ebba5ee..473ff8f 100644 --- a/tools/grit/repack.gni +++ b/tools/grit/repack.gni
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/locales.gni") import("//tools/grit/grit_rule.gni") # This file defines a template to invoke grit repack in a consistent manner. @@ -147,6 +148,12 @@ # Collects all targets the loop generates. _locale_targets = [] + if (translate_genders) { + _genders = all_chrome_genders + } else { + _genders = [ "" ] + } + # This loop iterates over the input locales and also keeps a counter so it # can simultaneously iterate over the output locales (using GN's very # limited looping capabilities). @@ -154,34 +161,42 @@ foreach(_input_locale, invoker.input_locales) { _output_locale = _output_locales[_current_index] - # Compute the name of the target for the current file. Save it for the deps. - _current_name = "${target_name}_${_input_locale}" - _locale_targets += [ ":$_current_name" ] - - repack(_current_name) { - forward_variables_from(invoker, - [ - "bundle_output", - "compress", - "copy_data_to_bundle", - "deps", - "mark_as_data", - "repack_allowlist", - "testonly", - ]) - visibility = [ ":${invoker.target_name}" ] - if (is_ios) { - output = "$_output_dir/${_output_locale}.lproj/locale.pak" + foreach(_gender, _genders) { + if (_gender == "") { + _gender_suffix = "" } else { - output = "$_output_dir/${_output_locale}.pak" + _gender_suffix = "_${_gender}" } - if (defined(copy_data_to_bundle) && copy_data_to_bundle) { - bundle_output = - "{{bundle_resources_dir}}/${_output_locale}.lproj/locale.pak" - } - sources = [] - foreach(_pattern, invoker.source_patterns) { - sources += [ "${_pattern}${_input_locale}.pak" ] + + # Compute the name of the target for the current file. Save it for the deps. + _current_name = "${target_name}_${_input_locale}${_gender_suffix}" + _locale_targets += [ ":$_current_name" ] + + repack(_current_name) { + forward_variables_from(invoker, + [ + "bundle_output", + "compress", + "copy_data_to_bundle", + "deps", + "mark_as_data", + "repack_allowlist", + "testonly", + ]) + visibility = [ ":${invoker.target_name}" ] + if (is_ios) { + output = + "$_output_dir/${_output_locale}${_gender_suffix}.lproj/locale.pak" + } else { + output = "$_output_dir/${_output_locale}${_gender_suffix}.pak" + } + if (defined(copy_data_to_bundle) && copy_data_to_bundle) { + bundle_output = "{{bundle_resources_dir}}/${_output_locale}${_gender_suffix}.lproj/locale.pak" + } + sources = [] + foreach(_pattern, invoker.source_patterns) { + sources += [ "${_pattern}${_input_locale}${_gender_suffix}.pak" ] + } } }
diff --git a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS index f32a8a6..0857f255 100644 --- a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS +++ b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS
@@ -231,6 +231,7 @@ # login jorgelo@chromium.org # mac +avi@chromium.org mek@chromium.org # magic_stack ckitagawa@chromium.org
diff --git a/tools/metrics/histograms/metadata/mac/OWNERS b/tools/metrics/histograms/metadata/mac/OWNERS index 515e408a..4b7e97b2 100644 --- a/tools/metrics/histograms/metadata/mac/OWNERS +++ b/tools/metrics/histograms/metadata/mac/OWNERS
@@ -2,4 +2,5 @@ # Prefer sending CLs to the owners listed below. # Use chromium-metrics-reviews@google.com as a backup. +avi@chromium.org mek@chromium.org
diff --git a/tools/metrics/histograms/metadata/page/histograms.xml b/tools/metrics/histograms/metadata/page/histograms.xml index 370725e4..d91d2da 100644 --- a/tools/metrics/histograms/metadata/page/histograms.xml +++ b/tools/metrics/histograms/metadata/page/histograms.xml
@@ -1013,7 +1013,7 @@ <histogram name="PageLoad.Clients.GoogleHomepage.DomainLookupTiming.NavigationToDomainLookupStart.{NavigationCountType}{BrowserInitializationStatus}" - units="ms" expires_after="2025-06-08"> + units="ms" expires_after="2025-10-05"> <owner>suzukikeita@chromium.org</owner> <owner>chrome-loading@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml index ac19fd0..e1ef3d2 100644 --- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml +++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -128,10 +128,21 @@ <owner>meacer@chromium.org</owner> <owner>trusty-transport@chromium.org</owner> <summary> - Records whether the user has Advanced Protection enabled. Logged on startup - when the enabled status changes. Can be logged multiple times for a user. In - practice, this counts the number of Chrome startups with Advanced Protection - enabled/disabled, rather than the actual user count. + Records whether the user has Advanced Protection enabled on desktop. Logged + on startup when the enabled status changes. Can be logged multiple times for + a user. In practice, this counts the number of Chrome startups with Advanced + Protection enabled/disabled, rather than the actual user count. + </summary> +</histogram> + +<histogram name="SafeBrowsing.Android.AdvancedProtection.Enabled" + enum="BooleanEnabled" expires_after="2025-12-01"> + <owner>pkotwicz@google.com</owner> + <owner>chrome-counter-abuse-alerts@google.com</owner> + <summary> + Records whether the user has Advanced Protection enabled. Logged on startup. + In practice, this counts the number of Chrome startups with Advanced + Protection enabled/disabled, rather than the actual user count. </summary> </histogram>
diff --git a/tools/metrics/histograms/metadata/ui/enums.xml b/tools/metrics/histograms/metadata/ui/enums.xml index af30f14..2d639a87 100644 --- a/tools/metrics/histograms/metadata/ui/enums.xml +++ b/tools/metrics/histograms/metadata/ui/enums.xml
@@ -75,6 +75,7 @@ <int value="28" label="Translate text in image with Google Lens"/> <int value="29" label="Search web for... in new tab"/> <int value="30" label="Open link in preview"/> + <int value="31" label="Open link in split view"/> </enum> <enum name="DefaultBrowserInfoBarUserInteraction"> @@ -285,6 +286,7 @@ <int value="153" label="IDC_CONTENT_CONTEXT_USE_PASSKEY_FROM_ANOTHER_DEVICE"/> <int value="154" label="IDC_CONTENT_CONTEXT_RELOAD_GLIC"/> <int value="155" label="IDC_CONTENT_CONTEXT_CLOSE_GLIC"/> + <int value="156" label="IDC_CONTENT_CONTEXT_OPENLINKSPLITVIEW"/> </enum> <enum name="ShapeRunFallback">
diff --git a/tools/metrics/histograms/metadata/user_education/histograms.xml b/tools/metrics/histograms/metadata/user_education/histograms.xml index c25ff2a..81c81827 100644 --- a/tools/metrics/histograms/metadata/user_education/histograms.xml +++ b/tools/metrics/histograms/metadata/user_education/histograms.xml
@@ -50,6 +50,9 @@ summary="Plus address manual fallback entry point in the context menu."/> <variant name="SideBySide" summary="Promotion for Split View in the tab context menu"/> + <variant name="SideBySideLinkMenuNewBadge" + summary="Promotion for Split View in the render view context menu when + right clicking a link."/> <variant name="TabOrganization" summary="Promotion for Organize Tabs in the app menu."/> <variant name="TabstripDeclutter"
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index c3b8b797..36e95e2 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -220,22 +220,14 @@ 'tests': [{ 'isolate': 'performance_web_engine_test_suite', - 'extra_args': [ - '--output-format=histograms', '--experimental-tbmv3-metrics', - '--extra-path=/b/s/w/ir/bin/' - ] + bot_platforms.FUCHSIA_EXEC_ARGS['nelson'], + 'extra_args': + ['--output-format=histograms', '--experimental-tbmv3-metrics'] + + bot_platforms.FUCHSIA_EXEC_ARGS['nelson'], 'type': TEST_TYPES.TELEMETRY, }], 'platform': 'fuchsia-wes', - # TODO(crbug.com/40272046): Replace with long-term solution for ssh in Fuchsia img, - # or codify as long-term solution. - 'cipd': { - "cipd_package": "fuchsia/third_party/openssh-portable/${platform}", - "location": ".", - "revision": "build_id:8787350426829126785" - }, 'dimension': { 'cpu': None, 'device_type': 'Nelson', @@ -247,22 +239,14 @@ 'tests': [{ 'isolate': 'performance_web_engine_test_suite', - 'extra_args': [ - '--output-format=histograms', '--experimental-tbmv3-metrics', - '--extra-path=/b/s/w/ir/bin/' - ] + bot_platforms.FUCHSIA_EXEC_ARGS['sherlock'], + 'extra_args': + ['--output-format=histograms', '--experimental-tbmv3-metrics'] + + bot_platforms.FUCHSIA_EXEC_ARGS['sherlock'], 'type': TEST_TYPES.TELEMETRY, }], 'platform': 'fuchsia-wes', - # TODO(crbug.com/40272046): Replace with long-term solution for ssh in Fuchsia img, - # or codify as long-term solution. - 'cipd': { - "cipd_package": "fuchsia/third_party/openssh-portable/${platform}", - "location": ".", - "revision": "build_id:8787350426829126785" - }, 'dimension': { 'cpu': None, 'device_type': 'Sherlock', @@ -317,7 +301,8 @@ 'dimension': { 'pool': 'chrome.tests.perf', 'os': 'Windows-11', - 'cpu': 'arm64-64-Snapdragon(R)_X_Plus_-_X1P64100_-_Qualcomm(R)_Oryon(TM)_CPU', + 'cpu': + 'arm64-64-Snapdragon(R)_X_Plus_-_X1P64100_-_Qualcomm(R)_Oryon(TM)_CPU', 'synthetic_product_name': 'Inspiron 14 Plus 7441 (Dell Inc.)' }, }, @@ -337,7 +322,8 @@ 'dimension': { 'pool': 'chrome.tests.perf', 'os': 'Windows-11', - 'cpu': 'arm64-64-Snapdragon(R)_X_Elite_-_X1E80100_-_Qualcomm(R)_Oryon(TM)_CPU', + 'cpu': + 'arm64-64-Snapdragon(R)_X_Elite_-_X1E80100_-_Qualcomm(R)_Oryon(TM)_CPU', 'synthetic_product_name': 'Latitude 7455 (Dell Inc.)' }, },
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 59327112..24d21ab 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,8 +5,8 @@ "full_remote_path": "perfetto-luci-artifacts/v50.1/linux-arm64/trace_processor_shell" }, "win": { - "hash": "b3b39240afb506e27ef5939231c01b089d208e2d", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/e2d7750acd15d57c6c88e3c8fb8c5a45f424ba96/trace_processor_shell.exe" + "hash": "412ece7bc88321398f735f622adea4d26c7810f2", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/993d41d0c39335e35fe577808e8f704e58d9dbfb/trace_processor_shell.exe" }, "linux_arm": { "hash": "99f971ca131f6d11c73f4b918099d434bdd8093c", @@ -21,8 +21,8 @@ "full_remote_path": "perfetto-luci-artifacts/v50.1/mac-arm64/trace_processor_shell" }, "linux": { - "hash": "3ae76c314990496879978c1b23d25238dd150509", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/e2d7750acd15d57c6c88e3c8fb8c5a45f424ba96/trace_processor_shell" + "hash": "4026dea19671293170bc7f302463b54f0e32b393", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/993d41d0c39335e35fe577808e8f704e58d9dbfb/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/ui/base/cocoa/appkit_utils.h b/ui/base/cocoa/appkit_utils.h index 903343a..1d83e88 100644 --- a/ui/base/cocoa/appkit_utils.h +++ b/ui/base/cocoa/appkit_utils.h
@@ -5,8 +5,10 @@ #ifndef UI_BASE_COCOA_APPKIT_UTILS_H_ #define UI_BASE_COCOA_APPKIT_UTILS_H_ +#ifdef __OBJC__ #import <Cocoa/Cocoa.h> #import <UniformTypeIdentifiers/UniformTypeIdentifiers.h> +#endif // __OBJC__ #include "base/component_export.h" @@ -18,6 +20,9 @@ // Returns true if both CGFloat values are equal. COMPONENT_EXPORT(UI_BASE) bool IsCGFloatEqual(CGFloat a, CGFloat b); +// Returns true if the current application owns the menu bar. +COMPONENT_EXPORT(UI_BASE) bool IsActiveApplication(); + // The NSServicesMenuRequestor protocol does not pass modern NSPasteboardType // constants in the `types` array, but only obsolete "Pboard" constants. This is // verified through macOS 15 (FB11838671). These are utility functions to @@ -26,6 +31,7 @@ // TODO(https://crbug.com/395661472): When this FB is fixed at the minimum // requirement for Chromium, remove these utility functions. +#ifdef __OBJC__ // Converts a single string value of either a modern pasteboard type or an // obsolete PBoard type to the corresponding UTType. Returns nil if nil is // specified as the type, or if the type cannot be found. @@ -36,6 +42,7 @@ // values are dropped, as NSArrays/NSSets cannot contain nils. COMPONENT_EXPORT(UI_BASE) NSSet<UTType*>* UTTypesForServicesTypeArray(NSArray* types); +#endif // __OBJC__ } // namespace ui
diff --git a/ui/base/cocoa/appkit_utils.mm b/ui/base/cocoa/appkit_utils.mm index aaeb09e..b7a0ace 100644 --- a/ui/base/cocoa/appkit_utils.mm +++ b/ui/base/cocoa/appkit_utils.mm
@@ -35,6 +35,10 @@ return std::fabs(a - b) <= std::numeric_limits<CGFloat>::epsilon(); } +bool IsActiveApplication() { + return NSRunningApplication.currentApplication.active; +} + UTType* UTTypeForServicesType(NSString* type) { if (!type) { return nil;
diff --git a/ui/chromeos/strings/BUILD.gn b/ui/chromeos/strings/BUILD.gn index 79bec05..07e8066 100644 --- a/ui/chromeos/strings/BUILD.gn +++ b/ui/chromeos/strings/BUILD.gn
@@ -7,12 +7,10 @@ assert(is_chromeos) -grit("strings") { +grit_strings("strings") { source = "../ui_chromeos_strings.grd" - outputs = - [ "grit/ui_chromeos_strings.h" ] + - process_file_template(all_chrome_locales, - [ "ui_chromeos_strings_{{source_name_part}}.pak" ]) + outputs = [ "grit/ui_chromeos_strings.h" ] + output_prefix = "ui_chromeos_strings_" } static_library("strings_provider") {
diff --git a/ui/resources/BUILD.gn b/ui/resources/BUILD.gn index 5430e071..ddffcb3 100644 --- a/ui/resources/BUILD.gn +++ b/ui/resources/BUILD.gn
@@ -5,6 +5,12 @@ import("//tools/grit/grit_rule.gni") import("//tools/grit/repack.gni") +if (translate_genders) { + _gender_suffix = "_OTHER" +} else { + _gender_suffix = "" +} + group("resources") { public_deps = [ ":ui_resources_grd", @@ -88,7 +94,7 @@ } else { copy("ui_test_pak") { sources = [ "$root_out_dir/ui_test.pak" ] - outputs = [ "$root_out_dir/ui/en-US.pak" ] + outputs = [ "$root_out_dir/ui/en-US${_gender_suffix}.pak" ] public_deps = [ ":repack_ui_test_pak_100_percent" ] } } @@ -114,9 +120,9 @@ sources = [ "$root_gen_dir/mojo/public/js/mojo_bindings_resources.pak", "$root_gen_dir/ui/resources/ui_resources_100_percent.pak", - "$root_gen_dir/ui/strings/app_locale_settings_en-US.pak", - "$root_gen_dir/ui/strings/ax_strings_en-US.pak", - "$root_gen_dir/ui/strings/ui_strings_en-US.pak", + "$root_gen_dir/ui/strings/app_locale_settings_en-US${_gender_suffix}.pak", + "$root_gen_dir/ui/strings/ax_strings_en-US${_gender_suffix}.pak", + "$root_gen_dir/ui/strings/ui_strings_en-US${_gender_suffix}.pak", "$root_gen_dir/ui/webui/resources/webui_resources.pak", ] @@ -140,7 +146,7 @@ if (is_chromeos) { sources += [ "$root_gen_dir/ui/chromeos/resources/ui_chromeos_resources_100_percent.pak", - "$root_gen_dir/ui/chromeos/strings/ui_chromeos_strings_en-US.pak", + "$root_gen_dir/ui/chromeos/strings/ui_chromeos_strings_en-US${_gender_suffix}.pak", ] deps += [ "//ui/chromeos/resources", @@ -181,9 +187,9 @@ visibility = [ ":ui_test_pak" ] sources = [ - "$root_gen_dir/ui/strings/app_locale_settings_en-US.pak", - "$root_gen_dir/ui/strings/ax_strings_en-US.pak", - "$root_gen_dir/ui/strings/ui_strings_en-US.pak", + "$root_gen_dir/ui/strings/app_locale_settings_en-US${_gender_suffix}.pak", + "$root_gen_dir/ui/strings/ax_strings_en-US${_gender_suffix}.pak", + "$root_gen_dir/ui/strings/ui_strings_en-US${_gender_suffix}.pak", ] output = "$root_out_dir/ui/en.lproj/locale.pak"
diff --git a/ui/strings/BUILD.gn b/ui/strings/BUILD.gn index 7406ace5..39cbe3c 100644 --- a/ui/strings/BUILD.gn +++ b/ui/strings/BUILD.gn
@@ -16,34 +16,22 @@ ] } -grit("ax_strings") { +grit_strings("ax_strings") { source = "ax_strings.grd" outputs = [ "grit/ax_strings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "ax_strings_$locale.pak" ] - } } -grit("auto_image_annotation_strings") { +grit_strings("auto_image_annotation_strings") { source = "auto_image_annotation_strings.grd" outputs = [ "grit/auto_image_annotation_strings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "auto_image_annotation_strings_$locale.pak" ] - } } -grit("ui_strings") { +grit_strings("ui_strings") { source = "ui_strings.grd" outputs = [ "grit/ui_strings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "ui_strings_$locale.pak" ] - } } -grit("app_locale_settings") { +grit_strings("app_locale_settings") { source = "app_locale_settings.grd" outputs = [ "grit/app_locale_settings.h" ] - foreach(locale, all_chrome_locales) { - outputs += [ "app_locale_settings_$locale.pak" ] - } }
diff --git a/v8 b/v8 index a1ba74a..a469663 160000 --- a/v8 +++ b/v8
@@ -1 +1 @@ -Subproject commit a1ba74a85fdfad2d8eac3857059676bc6e0fb686 +Subproject commit a46966388bbd892ee59d5d2688287704d1844302