diff --git a/DEPS b/DEPS index 51db2be..b34b928b 100644 --- a/DEPS +++ b/DEPS
@@ -275,11 +275,11 @@ # 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': '9f85e0e12d708c453c7abd6c9bd9768444c7640f', + 'skia_revision': 'd881def3e544be7db5524a80e5dce7ca0a970f09', # 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': 'fb15e275ae4d8cac652df87550c50cd151cef2c1', + 'v8_revision': 'dca05c50dc29a73c4396bb79318dd6b387974c25', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. @@ -287,7 +287,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': 'ee0d0b41a62640e0c37d1611f84e7533072c7256', + 'swiftshader_revision': 'd3b44fe1edef36ce3169daf9ea178c99784abe2f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -326,7 +326,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. - 'freetype_revision': 'd6857981239ea5f6e95cb4eb4402307f3527760a', + 'freetype_revision': 'c26872ed59cba3af2f407b5eefc92fcec92aa52b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -354,7 +354,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': '5e91454d1bdee651a57057728c9584a47b0186a0', + 'devtools_frontend_revision': 'ae1192b6309e632d35ff71b4e8ab28daa1b057e0', # 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. @@ -841,7 +841,7 @@ 'packages': [ { 'package': 'chromium/rts/model/linux-amd64', - 'version': '8zqTXxzVGxAv_4yJH62SDu338NH2a9Sj8E-Ue8Od1cQC', + 'version': 'mwQUySZTAjUh63HUF4elgaSEXQmxEgTrzt0aEQlqE7oC', }, ], 'dep_type': 'cipd', @@ -852,7 +852,7 @@ 'packages': [ { 'package': 'chromium/rts/model/mac-amd64', - 'version': 'SI7tqcfHGyKVRq_68Hdai7SqtG-ddU5RFVc313lMD_UC', + 'version': 'VyKiTzbwRVHNrfBYHduT0eAthyj9joVN-umACpbgqS4C', }, ], 'dep_type': 'cipd', @@ -863,7 +863,7 @@ 'packages': [ { 'package': 'chromium/rts/model/windows-amd64', - 'version': 'CHdWfS54WS0s0BeEADqbqHQ5mQqzzmMwGA7qUcJ5lQ0C', + 'version': '_Na4ODRyZ59BKH95r5cxBPSTd3F2mFFiO3kLcmj0LncC', }, ], 'dep_type': 'cipd', @@ -1113,7 +1113,7 @@ # Tools used when building Chrome for Chrome OS. This affects both the Simple # Chrome workflow, as well as the chromeos-chrome ebuild. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '97c3857f4712c249543d99f627312a5b8bc3cf70', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'c0a200192d7742fd7f5cb4ebd9dd158061c57645', 'condition': 'checkout_chromeos', }, @@ -1136,7 +1136,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '8f1fea025d78c26046d3135e026f097dc2022698', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '2a229719c26bbf2cbc65c91b372ea03c6bef3b9c', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1781,7 +1781,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@a9269965b79bd8a657080f295bfc677383ecb122', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@f51a1dbc4cf0ffbd7b12a3296c39538a5ec0b2ce', 'condition': 'checkout_src_internal', }, @@ -1811,7 +1811,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'aJEXXGyUnjQdOYV24rRrtQV8x3UK-KMkW9nExv9j4rcC', + 'version': 'L3ofmGEfbGxTWEs5VF9UqJT56YKWYcVA_R_rxOzwW80C', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -3703,6 +3703,7 @@ 'src/third_party/blink/renderer/build/scripts', 'src/third_party/blink/tools', # See http://crbug.com/625877. 'src/third_party/catapult', + 'src/third_party/mako', # Some failures triggered by crrev.com/c/3686969 'src/tools', ], },
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index 2358721..b378757 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -2356,7 +2356,7 @@ r"^extensions[\\/]renderer[\\/]logging_native_handler\.cc$", r"^fuchsia[\\/]base[\\/]init_logging.cc$", r"^fuchsia[\\/]engine[\\/]browser[\\/]frame_impl.cc$", - r"^fuchsia[\\/]runners[\\/]common[\\/]web_component.cc$", + r"^fuchsia_web[\\/]runners[\\/]common[\\/]web_component.cc$", r"^headless[\\/]app[\\/]headless_shell\.cc$", r"^ipc[\\/]ipc_logging\.cc$", r"^native_client_sdk[\\/]",
diff --git a/android_webview/browser/BUILD.gn b/android_webview/browser/BUILD.gn index 6e4daf2..aaf26bd 100644 --- a/android_webview/browser/BUILD.gn +++ b/android_webview/browser/BUILD.gn
@@ -183,8 +183,6 @@ "safe_browsing/aw_safe_browsing_ui_manager.h", "safe_browsing/aw_url_checker_delegate_impl.cc", "safe_browsing/aw_url_checker_delegate_impl.h", - "scoped_add_feature_flags.cc", - "scoped_add_feature_flags.h", "state_serializer.cc", "state_serializer.h", "tracing/aw_background_tracing_metrics_provider.cc",
diff --git a/android_webview/browser/cookie_manager.cc b/android_webview/browser/cookie_manager.cc index e9c2286..3b8f56e 100644 --- a/android_webview/browser/cookie_manager.cc +++ b/android_webview/browser/cookie_manager.cc
@@ -469,7 +469,7 @@ std::unique_ptr<net::CanonicalCookie> cc(net::CanonicalCookie::Create( new_host, value, base::Time::Now(), absl::nullopt /* server_time */, - net::CookiePartitionKey::Todo())); + absl::nullopt /* cookie_partition_key */)); if (!cc || !should_allow_cookie) { MaybeRunCookieCallback(std::move(callback), false);
diff --git a/android_webview/browser/scoped_add_feature_flags.cc b/android_webview/browser/scoped_add_feature_flags.cc deleted file mode 100644 index 84c3477..0000000 --- a/android_webview/browser/scoped_add_feature_flags.cc +++ /dev/null
@@ -1,82 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "android_webview/browser/scoped_add_feature_flags.h" - -#include "base/base_switches.h" -#include "base/command_line.h" -#include "base/containers/contains.h" -#include "base/strings/string_util.h" - -namespace android_webview { - -ScopedAddFeatureFlags::ScopedAddFeatureFlags(base::CommandLine* cl) : cl_(cl) { - std::string enabled_features = - cl->GetSwitchValueASCII(switches::kEnableFeatures); - std::string disabled_features = - cl->GetSwitchValueASCII(switches::kDisableFeatures); - for (auto& sp : base::FeatureList::SplitFeatureListString(enabled_features)) - enabled_features_.emplace_back(sp); - for (auto& sp : base::FeatureList::SplitFeatureListString(disabled_features)) - disabled_features_.emplace_back(sp); -} - -ScopedAddFeatureFlags::~ScopedAddFeatureFlags() { - cl_->AppendSwitchASCII(switches::kEnableFeatures, - base::JoinString(enabled_features_, ",")); - cl_->AppendSwitchASCII(switches::kDisableFeatures, - base::JoinString(disabled_features_, ",")); -} - -void ScopedAddFeatureFlags::EnableIfNotSet(const base::Feature& feature) { - AddFeatureIfNotSet(feature, /*suffix=*/"", /*enable=*/true); -} - -void ScopedAddFeatureFlags::EnableIfNotSetWithParameter( - const base::Feature& feature, - std::string name, - std::string value) { - std::string suffix = ":" + name + "/" + value; - AddFeatureIfNotSet(feature, suffix, true /* enable */); -} - -void ScopedAddFeatureFlags::DisableIfNotSet(const base::Feature& feature) { - AddFeatureIfNotSet(feature, /*suffix=*/"", /*enable=*/false); -} - -bool ScopedAddFeatureFlags::IsEnabled(const base::Feature& feature) { - return IsEnabledWithParameter(feature, /*name=*/"", /*value=*/""); -} - -bool ScopedAddFeatureFlags::IsEnabledWithParameter(const base::Feature& feature, - const std::string& name, - const std::string& value) { - std::string feature_name = feature.name; - if (!name.empty()) { - feature_name += ":" + name + "/" + value; - } - if (base::Contains(disabled_features_, feature_name)) - return false; - if (base::Contains(enabled_features_, feature_name)) - return true; - return feature.default_state == base::FEATURE_ENABLED_BY_DEFAULT; -} - -void ScopedAddFeatureFlags::AddFeatureIfNotSet(const base::Feature& feature, - const std::string& suffix, - bool enable) { - std::string feature_name = feature.name; - feature_name += suffix; - if (base::Contains(enabled_features_, feature_name) || - base::Contains(disabled_features_, feature_name)) { - return; - } - if (enable) { - enabled_features_.emplace_back(feature_name); - } else { - disabled_features_.emplace_back(feature_name); - } -} - -} // namespace android_webview
diff --git a/android_webview/browser/scoped_add_feature_flags.h b/android_webview/browser/scoped_add_feature_flags.h deleted file mode 100644 index 9cff556b1..0000000 --- a/android_webview/browser/scoped_add_feature_flags.h +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ANDROID_WEBVIEW_BROWSER_SCOPED_ADD_FEATURE_FLAGS_H_ -#define ANDROID_WEBVIEW_BROWSER_SCOPED_ADD_FEATURE_FLAGS_H_ - -#include <string> -#include <vector> - -#include "base/feature_list.h" -#include "base/memory/raw_ptr.h" - -namespace base { -class CommandLine; -} - -namespace android_webview { - -class ScopedAddFeatureFlags { - public: - explicit ScopedAddFeatureFlags(base::CommandLine* cl); - - ScopedAddFeatureFlags(const ScopedAddFeatureFlags&) = delete; - ScopedAddFeatureFlags& operator=(const ScopedAddFeatureFlags&) = delete; - - ~ScopedAddFeatureFlags(); - - // Any existing (user set) enable/disable takes precedence. - void EnableIfNotSet(const base::Feature& feature); - void DisableIfNotSet(const base::Feature& feature); - void EnableIfNotSetWithParameter(const base::Feature& feature, - std::string name, - std::string value); - // Check if the feature is enabled from command line or functions above - bool IsEnabled(const base::Feature& feature); - bool IsEnabledWithParameter(const base::Feature& feature, - const std::string& name, - const std::string& value); - - private: - void AddFeatureIfNotSet(const base::Feature& feature, - const std::string& suffix, - bool enable); - - const raw_ptr<base::CommandLine> cl_; - std::vector<std::string> enabled_features_; - std::vector<std::string> disabled_features_; -}; - -} // namespace android_webview - -#endif // ANDROID_WEBVIEW_BROWSER_SCOPED_ADD_FEATURE_FLAGS_H_
diff --git a/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java b/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java index da81a84e..6bec03b 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java +++ b/android_webview/java/src/org/chromium/android_webview/AwWebContentsObserver.java
@@ -167,7 +167,7 @@ }); } - if (client != null && navigation.isFragmentNavigation()) { + if (client != null && navigation.isPrimaryMainFrameFragmentNavigation()) { // Note fragment navigations do not have a matching onPageStarted. client.getCallbackHelper().postOnPageFinished(url); }
diff --git a/android_webview/lib/aw_main_delegate.cc b/android_webview/lib/aw_main_delegate.cc index c4520c5..4aec4d7 100644 --- a/android_webview/lib/aw_main_delegate.cc +++ b/android_webview/lib/aw_main_delegate.cc
@@ -12,7 +12,6 @@ #include "android_webview/browser/gfx/browser_view_renderer.h" #include "android_webview/browser/gfx/gpu_service_webview.h" #include "android_webview/browser/gfx/viz_compositor_thread_runner_webview.h" -#include "android_webview/browser/scoped_add_feature_flags.h" #include "android_webview/browser/tracing/aw_trace_event_args_allowlist.h" #include "android_webview/common/aw_descriptors.h" #include "android_webview/common/aw_features.h" @@ -32,6 +31,7 @@ #include "base/i18n/icu_util.h" #include "base/i18n/rtl.h" #include "base/posix/global_descriptors.h" +#include "base/scoped_add_feature_flags.h" #include "base/strings/string_number_conversions.h" #include "base/threading/thread_restrictions.h" #include "build/build_config.h" @@ -185,7 +185,7 @@ } { - ScopedAddFeatureFlags features(cl); + base::ScopedAddFeatureFlags features(cl); if (base::android::BuildInfo::GetInstance()->sdk_int() >= base::android::SDK_VERSION_OREO) { @@ -298,6 +298,11 @@ // Have the network service in the browser process even if we have separate // renderer processes. See also: switches::kInProcessGPU above. features.EnableIfNotSet(::features::kNetworkServiceInProcess); + + // Disable Event.path on Canary and Dev to help the deprecation and removal. + // See crbug.com/1277431 for more details. + if (version_info::android::GetChannel() < version_info::Channel::BETA) + features.DisableIfNotSet(blink::features::kEventPath); } android_webview::RegisterPathProvider();
diff --git a/android_webview/test/BUILD.gn b/android_webview/test/BUILD.gn index 540fc16..d9bc885d 100644 --- a/android_webview/test/BUILD.gn +++ b/android_webview/test/BUILD.gn
@@ -617,7 +617,6 @@ "../browser/renderer_host/auto_login_parser_unittest.cc", "../browser/safe_browsing/aw_ping_manager_unittest.cc", "../browser/safe_browsing/aw_safe_browsing_allowlist_manager_unittest.cc", - "../browser/scoped_add_feature_flags_unittests.cc", "../browser/state_serializer_unittest.cc", "../browser/tracing/aw_background_tracing_metrics_provider_unittest.cc", "../browser/tracing/aw_tracing_delegate_unittest.cc",
diff --git a/android_webview/tools/PRESUBMIT.py b/android_webview/tools/PRESUBMIT.py index 61cd833..84d2e4e 100644 --- a/android_webview/tools/PRESUBMIT.py +++ b/android_webview/tools/PRESUBMIT.py
@@ -13,7 +13,8 @@ output_api, input_api.PresubmitLocalPath(), files_to_check=['.*_test\\.py$'], - files_to_skip=[]) + files_to_skip=[], + run_on_python2=False) def CommonChecks(input_api, output_api):
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 958abc1..cd938ad 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -1633,6 +1633,9 @@ <message name="IDS_ASH_STYLUS_TOOLS_METALAYER_TOAST_LOADING" desc="Message content on the toast that appears when the user presses the stylus button to activate the Assistant but it is still loading."> Assistant is loading... </message> + <message name="IDS_ASH_STYLUS_TOOLS_METALAYER_TOAST_DEPRECATE" desc="Message content on the toast that appears when the user presses the stylus button to activate the Assistant but the feature is deprecated."> + Searching what's on my screen with Google Assistant is no longer supported. + </message> <message name="IDS_ASH_STYLUS_TOOLS_TITLE" desc="The title of the stylus tools dialog in the ash shelf."> Stylus tools </message>
diff --git a/ash/ash_strings_grd/IDS_ASH_STYLUS_TOOLS_METALAYER_TOAST_DEPRECATE.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STYLUS_TOOLS_METALAYER_TOAST_DEPRECATE.png.sha1 new file mode 100644 index 0000000..0f7638b --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_STYLUS_TOOLS_METALAYER_TOAST_DEPRECATE.png.sha1
@@ -0,0 +1 @@ +b866b07b84bb155bf2ffafb2871e773c0ec33f56 \ No newline at end of file
diff --git a/ash/components/arc/session/arc_container_client_adapter.cc b/ash/components/arc/session/arc_container_client_adapter.cc index 1a038b74..bfaacce 100644 --- a/ash/components/arc/session/arc_container_client_adapter.cc +++ b/ash/components/arc/session/arc_container_client_adapter.cc
@@ -167,6 +167,7 @@ request.set_packages_cache_mode( ToLoginManagerPackageCacheMode(params.packages_cache_mode)); request.set_skip_gms_core_cache(params.skip_gms_core_cache); + request.set_skip_tts_cache(params.skip_tts_cache); request.set_is_demo_session(params.is_demo_session); request.set_demo_session_apps_path(params.demo_session_apps_path.value()); request.set_locale(params.locale);
diff --git a/ash/components/arc/session/arc_container_client_adapter_unittest.cc b/ash/components/arc/session/arc_container_client_adapter_unittest.cc index d7c4a5c..7f6ff379 100644 --- a/ash/components/arc/session/arc_container_client_adapter_unittest.cc +++ b/ash/components/arc/session/arc_container_client_adapter_unittest.cc
@@ -196,6 +196,26 @@ EXPECT_TRUE(request.enable_tts_caching()); } +TEST_F(ArcContainerClientAdapterTest, ConvertUpgradeParams_SkipTtsCacheSetup) { + UpgradeParams upgrade_params; + upgrade_params.skip_tts_cache = true; + client_adapter()->UpgradeArc(std::move(upgrade_params), + base::BindOnce(&OnMiniInstanceStarted)); + const auto& upgrade_request = + chromeos::FakeSessionManagerClient::Get()->last_upgrade_arc_request(); + EXPECT_TRUE(upgrade_request.skip_tts_cache()); +} + +TEST_F(ArcContainerClientAdapterTest, + ConvertUpgradeParams_EnableTtsCacheSetup) { + UpgradeParams upgrade_params; + client_adapter()->UpgradeArc(std::move(upgrade_params), + base::BindOnce(&OnMiniInstanceStarted)); + const auto& upgrade_request = + chromeos::FakeSessionManagerClient::Get()->last_upgrade_arc_request(); + EXPECT_FALSE(upgrade_request.skip_tts_cache()); +} + struct DalvikMemoryProfileTestParam { // Requested profile. StartParams::DalvikMemoryProfile profile;
diff --git a/ash/components/arc/session/arc_upgrade_params.cc b/ash/components/arc/session/arc_upgrade_params.cc index db9b3be..980dba98 100644 --- a/ash/components/arc/session/arc_upgrade_params.cc +++ b/ash/components/arc/session/arc_upgrade_params.cc
@@ -36,6 +36,8 @@ packages_cache_mode(GetPackagesCacheMode()), skip_gms_core_cache(base::CommandLine::ForCurrentProcess()->HasSwitch( ash::switches::kArcDisableGmsCoreCache)), + skip_tts_cache(base::CommandLine::ForCurrentProcess()->HasSwitch( + ash::switches::kArcDisableTtsCache)), enable_arc_nearby_share( base::FeatureList::IsEnabled(arc::kEnableArcNearbyShare)) {}
diff --git a/ash/components/arc/session/arc_upgrade_params.h b/ash/components/arc/session/arc_upgrade_params.h index 4dc07d9..191b4c6 100644 --- a/ash/components/arc/session/arc_upgrade_params.h +++ b/ash/components/arc/session/arc_upgrade_params.h
@@ -67,6 +67,10 @@ // The constructor automatically populates this from command-line. bool skip_gms_core_cache; + // Option to disable TTS cache. + // The constructor automatically populates this from command-line. + bool skip_tts_cache; + // The supervision transition state for this account. Indicates whether // child account should become regular, regular account should become child // or neither.
diff --git a/ash/components/arc/session/arc_vm_client_adapter.cc b/ash/components/arc/session/arc_vm_client_adapter.cc index 00c3413..f09f575c 100644 --- a/ash/components/arc/session/arc_vm_client_adapter.cc +++ b/ash/components/arc/session/arc_vm_client_adapter.cc
@@ -160,6 +160,8 @@ static_cast<int>(upgrade_params.management_transition)), base::StringPrintf("%s.serialno=%s", prefix.c_str(), serial_number.c_str()), + base::StringPrintf("%s.skip_tts_cache=%d", prefix.c_str(), + upgrade_params.skip_tts_cache), }; // Conditionally sets more properties based on |upgrade_params|. if (!upgrade_params.locale.empty()) {
diff --git a/ash/components/arc/session/arc_vm_client_adapter_unittest.cc b/ash/components/arc/session/arc_vm_client_adapter_unittest.cc index a8d6a6e2..29d3b82 100644 --- a/ash/components/arc/session/arc_vm_client_adapter_unittest.cc +++ b/ash/components/arc/session/arc_vm_client_adapter_unittest.cc
@@ -2544,5 +2544,22 @@ base::Contains(request.params(), "androidboot.arc.tts.caching=1")); } +TEST_F(ArcVmClientAdapterTest, ConvertUpgradeParams_SkipTtsCacheSetup) { + StartMiniArc(); + UpgradeParams upgrade_params = GetPopulatedUpgradeParams(); + upgrade_params.skip_tts_cache = true; + UpgradeArcWithParams(true, std::move(upgrade_params)); + EXPECT_TRUE(base::Contains(boot_notification_server()->received_data(), + "ro.boot.skip_tts_cache=1")); +} + +TEST_F(ArcVmClientAdapterTest, ConvertUpgradeParams_EnableTtsCacheSetup) { + StartMiniArc(); + UpgradeParams upgrade_params = GetPopulatedUpgradeParams(); + UpgradeArcWithParams(true, std::move(upgrade_params)); + EXPECT_TRUE(base::Contains(boot_notification_server()->received_data(), + "ro.boot.skip_tts_cache=0")); +} + } // namespace } // namespace arc
diff --git a/ash/constants/ash_switches.cc b/ash/constants/ash_switches.cc index 9389f09..8137354 100644 --- a/ash/constants/ash_switches.cc +++ b/ash/constants/ash_switches.cc
@@ -101,6 +101,9 @@ // apps silently. Used in autotests to resolve racy conditions. const char kArcDisablePlayAutoInstall[] = "arc-disable-play-auto-install"; +// Used in autotest to disable TTS cache which is on by default. +const char kArcDisableTtsCache[] = "arc-disable-tts-cache"; + // Flag that disables ureadahead completely, including host and guest parts. // See also |kArcVmUreadaheadMode|. const char kArcDisableUreadahead[] = "arc-disable-ureadahead";
diff --git a/ash/constants/ash_switches.h b/ash/constants/ash_switches.h index 8604d5a9..dad1b84 100644 --- a/ash/constants/ash_switches.h +++ b/ash/constants/ash_switches.h
@@ -40,6 +40,7 @@ COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kArcDisableMediaStoreMaintenance[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kArcDisablePlayAutoInstall[]; +COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kArcDisableTtsCache[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kArcDisableUreadahead[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kArcForceShowOptInUi[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kArcGeneratePlayAutoInstall[];
diff --git a/ash/public/cpp/system/toast_catalog.h b/ash/public/cpp/system/toast_catalog.h index 0401fcf1f..c4a3277 100644 --- a/ash/public/cpp/system/toast_catalog.h +++ b/ash/public/cpp/system/toast_catalog.h
@@ -47,7 +47,8 @@ kDeskTemplateTooLarge = 33, kUndoCloseAll = 34, kEcheAppToast = 35, - kMaxValue = kEcheAppToast, + kDeprecateAssistantStylus = 36, + kMaxValue = kDeprecateAssistantStylus, }; } // namespace ash
diff --git a/ash/system/ime_menu/ime_menu_tray.cc b/ash/system/ime_menu/ime_menu_tray.cc index 1a85192d..d15778f 100644 --- a/ash/system/ime_menu/ime_menu_tray.cc +++ b/ash/system/ime_menu/ime_menu_tray.cc
@@ -398,12 +398,12 @@ // 2) login/lock screen. // 3) password input client. - bool should_show_buttom_buttoms = + const bool should_show_bottom_buttons = ime_controller_->is_extra_input_options_enabled() && !ime_controller_->current_ime().third_party && !IsInLoginOrLockScreen() && !IsInPasswordInputContext(); - if (!should_show_buttom_buttoms) { + if (!should_show_bottom_buttons) { is_emoji_enabled_ = is_handwriting_enabled_ = is_voice_enabled_ = false; return false; }
diff --git a/ash/system/network/fake_network_detailed_network_view.cc b/ash/system/network/fake_network_detailed_network_view.cc index 5f2e981..327c92c6 100644 --- a/ash/system/network/fake_network_detailed_network_view.cc +++ b/ash/system/network/fake_network_detailed_network_view.cc
@@ -8,7 +8,9 @@ #include "ash/system/network/fake_network_list_wifi_header_view.h" #include "ash/system/network/network_detailed_network_view.h" #include "ash/system/network/network_list_item_view.h" +#include "ash/system/network/network_list_mobile_header_view_impl.h" #include "ash/system/network/network_list_network_item_view.h" +#include "ash/system/network/network_list_wifi_header_view_impl.h" namespace ash { @@ -41,16 +43,16 @@ new NetworkListNetworkItemView(/*listener=*/nullptr)); }; -NetworkListNetworkHeaderView* +NetworkListWifiHeaderView* FakeNetworkDetailedNetworkView::AddWifiSectionHeader() { return network_list_->AddChildView( new FakeNetworkListWifiHeaderView(/*delegate=*/nullptr)); }; -NetworkListNetworkHeaderView* +NetworkListMobileHeaderView* FakeNetworkDetailedNetworkView::AddMobileSectionHeader() { return network_list_->AddChildView( new FakeNetworkListMobileHeaderView(/*delegate=*/nullptr)); -}; +} } // namespace ash \ No newline at end of file
diff --git a/ash/system/network/fake_network_detailed_network_view.h b/ash/system/network/fake_network_detailed_network_view.h index 324ef2e..26ba724 100644 --- a/ash/system/network/fake_network_detailed_network_view.h +++ b/ash/system/network/fake_network_detailed_network_view.h
@@ -8,7 +8,9 @@ #include "ash/ash_export.h" #include "ash/system/network/network_detailed_network_view.h" #include "ash/system/network/network_list_item_view.h" +#include "ash/system/network/network_list_mobile_header_view_impl.h" #include "ash/system/network/network_list_network_item_view.h" +#include "ash/system/network/network_list_wifi_header_view_impl.h" #include "ui/views/view.h" namespace ash { @@ -41,14 +43,14 @@ void NotifyNetworkListChanged() override; views::View* GetAsView() override; NetworkListNetworkItemView* AddNetworkListItem() override; - NetworkListNetworkHeaderView* AddWifiSectionHeader() override; - NetworkListNetworkHeaderView* AddMobileSectionHeader() override; + NetworkListWifiHeaderView* AddWifiSectionHeader() override; + NetworkListMobileHeaderView* AddMobileSectionHeader() override; // ViewClickListener: void OnViewClicked(views::View* view) override; std::unique_ptr<views::View> network_list_; - size_t notify_network_list_changed_call_count_; + size_t notify_network_list_changed_call_count_ = 0; NetworkListItemView* last_clicked_network_list_item_ = nullptr; };
diff --git a/ash/system/network/fake_network_list_mobile_header_view.cc b/ash/system/network/fake_network_list_mobile_header_view.cc index 4111c96..39833c6 100644 --- a/ash/system/network/fake_network_list_mobile_header_view.cc +++ b/ash/system/network/fake_network_list_mobile_header_view.cc
@@ -15,10 +15,9 @@ FakeNetworkListMobileHeaderView::~FakeNetworkListMobileHeaderView() = default; -void FakeNetworkListMobileHeaderView::SetToggleState(bool enabled, - bool visible) { +void FakeNetworkListMobileHeaderView::SetToggleState(bool enabled, bool is_on) { is_toggle_enabled_ = enabled; - is_toggle_visible_ = visible; + is_toggle_on_ = is_on; set_toggle_state_count_++; };
diff --git a/ash/system/network/fake_network_list_mobile_header_view.h b/ash/system/network/fake_network_list_mobile_header_view.h index d8dcbde..b8de2e73 100644 --- a/ash/system/network/fake_network_list_mobile_header_view.h +++ b/ash/system/network/fake_network_list_mobile_header_view.h
@@ -27,7 +27,7 @@ bool is_toggle_enabled() { return is_toggle_enabled_; } - bool is_toggle_visible() { return is_toggle_visible_; } + bool is_toggle_on() { return is_toggle_on_; } size_t set_toggle_state_count() { return set_toggle_state_count_; } @@ -41,13 +41,13 @@ private: // NetworkListNetworkHeaderView: - void SetToggleState(bool enabled, bool visible) override; + void SetToggleState(bool enabled, bool is_on) override; // NetworkListMobileHeaderView: void SetAddESimButtonState(bool enabled, bool visible) override; bool is_toggle_enabled_; - bool is_toggle_visible_; + bool is_toggle_on_; size_t set_toggle_state_count_; bool is_add_esim_enabled_;
diff --git a/ash/system/network/fake_network_list_wifi_header_view.cc b/ash/system/network/fake_network_list_wifi_header_view.cc index a0a91d8..5e79e89d 100644 --- a/ash/system/network/fake_network_list_wifi_header_view.cc +++ b/ash/system/network/fake_network_list_wifi_header_view.cc
@@ -15,9 +15,9 @@ FakeNetworkListWifiHeaderView::~FakeNetworkListWifiHeaderView() = default; -void FakeNetworkListWifiHeaderView::SetToggleState(bool enabled, bool visible) { +void FakeNetworkListWifiHeaderView::SetToggleState(bool enabled, bool is_on) { is_toggle_enabled_ = enabled; - is_toggle_visible_ = visible; + is_toggle_on_ = is_on; set_toggle_state_count_++; };
diff --git a/ash/system/network/fake_network_list_wifi_header_view.h b/ash/system/network/fake_network_list_wifi_header_view.h index 7fc1c9a8e..276a9f6 100644 --- a/ash/system/network/fake_network_list_wifi_header_view.h +++ b/ash/system/network/fake_network_list_wifi_header_view.h
@@ -26,7 +26,7 @@ bool is_toggle_enabled() { return is_toggle_enabled_; } - bool is_toggle_visible() { return is_toggle_visible_; } + bool is_toggle_is_on() { return is_toggle_on_; } size_t set_toggle_state_count() { return set_toggle_state_count_; } @@ -46,7 +46,7 @@ void SetJoinWifiButtonState(bool enabled, bool visible) override; bool is_toggle_enabled_; - bool is_toggle_visible_; + bool is_toggle_on_; size_t set_toggle_state_count_; bool is_join_wifi_enabled_;
diff --git a/ash/system/network/network_detailed_network_view.h b/ash/system/network/network_detailed_network_view.h index eb460bb..cbfa170 100644 --- a/ash/system/network/network_detailed_network_view.h +++ b/ash/system/network/network_detailed_network_view.h
@@ -7,8 +7,10 @@ #include "ash/ash_export.h" #include "ash/system/network/network_detailed_view.h" +#include "ash/system/network/network_list_mobile_header_view_impl.h" #include "ash/system/network/network_list_network_header_view.h" #include "ash/system/network/network_list_network_item_view.h" +#include "ash/system/network/network_list_wifi_header_view_impl.h" #include "ui/views/view.h" namespace ash { @@ -70,12 +72,12 @@ // Creates, adds and returns a Wifi sticky sub-header to the end of the // network list. The client is expected to use the returned pointer for // removing and rearranging the sub-header. - virtual NetworkListNetworkHeaderView* AddWifiSectionHeader() = 0; + virtual NetworkListWifiHeaderView* AddWifiSectionHeader() = 0; // Creates, adds and returns a Mobile sticky sub-header to the end of the // network list. The client is expected to use the returned pointer for // removing and rearranging the sub-header. - virtual NetworkListNetworkHeaderView* AddMobileSectionHeader() = 0; + virtual NetworkListMobileHeaderView* AddMobileSectionHeader() = 0; // Returns the network list. virtual views::View* network_list() = 0;
diff --git a/ash/system/network/network_detailed_network_view_impl.cc b/ash/system/network/network_detailed_network_view_impl.cc index 3652229..a7623ab 100644 --- a/ash/system/network/network_detailed_network_view_impl.cc +++ b/ash/system/network/network_detailed_network_view_impl.cc
@@ -41,13 +41,13 @@ new NetworkListNetworkItemView(/*listener=*/this)); } -NetworkListNetworkHeaderView* +NetworkListWifiHeaderView* NetworkDetailedNetworkViewImpl::AddWifiSectionHeader() { return scroll_content()->AddChildView( new NetworkListWifiHeaderViewImpl(/*delegate=*/this)); } -NetworkListNetworkHeaderView* +NetworkListMobileHeaderView* NetworkDetailedNetworkViewImpl::AddMobileSectionHeader() { return scroll_content()->AddChildView( new NetworkListMobileHeaderViewImpl(/*delegate=*/this));
diff --git a/ash/system/network/network_detailed_network_view_impl.h b/ash/system/network/network_detailed_network_view_impl.h index 79487785..d1813e2d 100644 --- a/ash/system/network/network_detailed_network_view_impl.h +++ b/ash/system/network/network_detailed_network_view_impl.h
@@ -8,8 +8,9 @@ #include "ash/ash_export.h" #include "ash/system/network/network_detailed_network_view.h" -#include "ash/system/network/network_list_network_header_view.h" +#include "ash/system/network/network_list_mobile_header_view_impl.h" #include "ash/system/network/network_list_network_item_view.h" +#include "ash/system/network/network_list_wifi_header_view_impl.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/views/view.h" @@ -41,8 +42,8 @@ void NotifyNetworkListChanged() override; views::View* GetAsView() override; NetworkListNetworkItemView* AddNetworkListItem() override; - NetworkListNetworkHeaderView* AddMobileSectionHeader() override; - NetworkListNetworkHeaderView* AddWifiSectionHeader() override; + NetworkListMobileHeaderView* AddMobileSectionHeader() override; + NetworkListWifiHeaderView* AddWifiSectionHeader() override; views::View* network_list() override; // NetworkListNetworkHeaderView::Delegate:
diff --git a/ash/system/network/network_detailed_network_view_unittest.cc b/ash/system/network/network_detailed_network_view_unittest.cc index 2a9649be..4364f67 100644 --- a/ash/system/network/network_detailed_network_view_unittest.cc +++ b/ash/system/network/network_detailed_network_view_unittest.cc
@@ -9,8 +9,9 @@ #include "ash/constants/ash_features.h" #include "ash/system/network/network_detailed_network_view.h" #include "ash/system/network/network_detailed_view.h" -#include "ash/system/network/network_list_network_header_view.h" +#include "ash/system/network/network_list_mobile_header_view.h" #include "ash/system/network/network_list_network_item_view.h" +#include "ash/system/network/network_list_wifi_header_view.h" #include "ash/system/tray/detailed_view_delegate.h" #include "ash/test/ash_test_base.h" #include "base/test/scoped_feature_list.h" @@ -138,11 +139,11 @@ network_detailed_network_view()->NotifyNetworkListChanged(); } - NetworkListNetworkHeaderView* AddWifiSectionHeader() { + NetworkListWifiHeaderView* AddWifiSectionHeader() { return network_detailed_network_view()->AddWifiSectionHeader(); } - NetworkListNetworkHeaderView* AddMobileSectionHeader() { + NetworkListMobileHeaderView* AddMobileSectionHeader() { return network_detailed_network_view()->AddMobileSectionHeader(); } @@ -180,11 +181,11 @@ ASSERT_NE(nullptr, network_list_item); EXPECT_STREQ("NetworkListNetworkItemView", network_list_item->GetClassName()); - NetworkListNetworkHeaderView* wifi_section = AddWifiSectionHeader(); + NetworkListWifiHeaderView* wifi_section = AddWifiSectionHeader(); ASSERT_NE(nullptr, wifi_section); EXPECT_STREQ("NetworkListWifiHeaderView", wifi_section->GetClassName()); - NetworkListNetworkHeaderView* mobile_section = AddMobileSectionHeader(); + NetworkListMobileHeaderView* mobile_section = AddMobileSectionHeader(); ASSERT_NE(nullptr, mobile_section); EXPECT_STREQ("NetworkListMobileHeaderView", mobile_section->GetClassName()); }
diff --git a/ash/system/network/network_list_mobile_header_view_impl.cc b/ash/system/network/network_list_mobile_header_view_impl.cc index 5e418be..685e727 100644 --- a/ash/system/network/network_list_mobile_header_view_impl.cc +++ b/ash/system/network/network_list_mobile_header_view_impl.cc
@@ -83,7 +83,8 @@ IconButton::Type::kSmall, &icon, GetAddESimTooltipMessageId()); add_esim_button.get()->SetID(kAddESimButtonId); add_esim_button_ = add_esim_button.get(); - container()->AddView(TriView::Container::END, add_esim_button.release()); + container()->AddViewAt(TriView::Container::END, add_esim_button.release(), + /*index=*/0); }; void NetworkListMobileHeaderViewImpl::OnToggleToggled(bool is_on) {
diff --git a/ash/system/network/network_list_network_header_view.cc b/ash/system/network/network_list_network_header_view.cc index 2f5e1409..97379f91 100644 --- a/ash/system/network/network_list_network_header_view.cc +++ b/ash/system/network/network_list_network_header_view.cc
@@ -13,6 +13,7 @@ #include "ash/system/tray/tray_popup_utils.h" #include "ash/system/tray/tray_toggle_button.h" #include "ash/system/tray/tri_view.h" +#include "base/memory/weak_ptr.h" #include "ui/views/view.h" namespace ash { @@ -22,14 +23,17 @@ : NetworkListHeaderView(label_id), model_(Shell::Get()->system_tray_model()->network_state_model()), delegate_(delegate) { - toggle_ = new TrayToggleButton( + std::unique_ptr<TrayToggleButton> toggle = std::make_unique<TrayToggleButton>( base::BindRepeating(&NetworkListNetworkHeaderView::ToggleButtonPressed, - base::Unretained(this)), + weak_factory_.GetWeakPtr()), label_id); - toggle_->SetID(kToggleButtonId); - container()->AddView(TriView::Container::END, toggle_); + toggle->SetID(kToggleButtonId); + toggle_ = toggle.get(); + container()->AddView(TriView::Container::END, toggle.release()); } +NetworkListNetworkHeaderView::~NetworkListNetworkHeaderView() = default; + void NetworkListNetworkHeaderView::SetToggleState(bool enabled, bool is_on) { toggle_->SetEnabled(enabled); toggle_->SetAcceptsEvents(enabled);
diff --git a/ash/system/network/network_list_network_header_view.h b/ash/system/network/network_list_network_header_view.h index 81d7df1..04de5cf 100644 --- a/ash/system/network/network_list_network_header_view.h +++ b/ash/system/network/network_list_network_header_view.h
@@ -9,6 +9,7 @@ #include "ash/system/network/network_list_header_view.h" #include "ash/system/network/network_row_title_view.h" #include "ash/system/tray/tri_view.h" +#include "base/memory/weak_ptr.h" #include "ui/views/controls/button/toggle_button.h" #include "ui/views/view.h" @@ -34,10 +35,12 @@ NetworkListNetworkHeaderView(const NetworkListNetworkHeaderView&) = delete; NetworkListNetworkHeaderView& operator=(const NetworkListNetworkHeaderView&) = delete; - ~NetworkListNetworkHeaderView() override = default; + ~NetworkListNetworkHeaderView() override; virtual void SetToggleState(bool enabled, bool is_on); + void SetToggleVisibility(bool visible); + protected: virtual void AddExtraButtons(); @@ -45,13 +48,10 @@ // enabled/disable their respective technology. virtual void OnToggleToggled(bool is_on); - void SetToggleVisibility(bool visible); - Delegate* delegate() const { return delegate_; }; TrayNetworkStateModel* model() { return model_; } - protected: // Used for testing. static constexpr int kToggleButtonId = NetworkListHeaderView::kTitleLabelViewId + 1; @@ -60,6 +60,7 @@ friend class NetworkListNetworkHeaderViewTest; friend class NetworkListMobileHeaderViewTest; friend class NetworkListWifiHeaderViewTest; + friend class NetworkListViewControllerTest; void ToggleButtonPressed(); @@ -69,6 +70,8 @@ views::ToggleButton* toggle_ = nullptr; Delegate* delegate_ = nullptr; + + base::WeakPtrFactory<NetworkListNetworkHeaderView> weak_factory_{this}; }; } // namespace ash
diff --git a/ash/system/network/network_list_network_item_view.h b/ash/system/network/network_list_network_item_view.h index e44034a1..ff182d4 100644 --- a/ash/system/network/network_list_network_item_view.h +++ b/ash/system/network/network_list_network_item_view.h
@@ -30,14 +30,14 @@ delete; ~NetworkListNetworkItemView() override; - private: - friend class NetworkListNetworkItemViewTest; - // NetworkListItemView: void UpdateViewForNetwork( const chromeos::network_config::mojom::NetworkStatePropertiesPtr& network_properties) override; + private: + friend class NetworkListNetworkItemViewTest; + void SetupCellularSubtext(); void SetupNetworkSubtext(); void UpdateDisabledTextColor();
diff --git a/ash/system/network/network_list_view_controller_impl.cc b/ash/system/network/network_list_view_controller_impl.cc index c24d64f..1a4cc693 100644 --- a/ash/system/network/network_list_view_controller_impl.cc +++ b/ash/system/network/network_list_view_controller_impl.cc
@@ -5,19 +5,120 @@ #include "ash/system/network/network_list_view_controller_impl.h" #include "ash/constants/ash_features.h" +#include "ash/public/cpp/bluetooth_config_service.h" +#include "ash/resources/vector_icons/vector_icons.h" +#include "ash/session/session_controller_impl.h" #include "ash/shell.h" +#include "ash/strings/grit/ash_strings.h" +#include "ash/style/ash_color_provider.h" #include "ash/system/model/system_tray_model.h" -#include "ash/system/network/network_detailed_network_view.h" +#include "ash/system/network/network_detailed_network_view_impl.h" +#include "ash/system/network/network_list_mobile_header_view.h" +#include "ash/system/network/network_list_network_header_view.h" +#include "ash/system/network/network_list_network_item_view.h" #include "ash/system/network/tray_network_state_model.h" +#include "ash/system/tray/tray_info_label.h" +#include "ash/system/tray/tri_view.h" +#include "chromeos/dbus/hermes/hermes_manager_client.h" +#include "chromeos/services/network_config/public/cpp/cros_network_config_util.h" +#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/gfx/image/image_skia_operations.h" +#include "ui/gfx/paint_vector_icon.h" +#include "ui/views/controls/image_view.h" +#include "ui/views/controls/separator.h" namespace ash { +namespace { + +using chromeos::network_config::NetworkTypeMatchesType; +using chromeos::network_config::StateIsConnected; + +using chromeos::network_config::mojom::DeviceStateProperties; +using chromeos::network_config::mojom::DeviceStateType; +using chromeos::network_config::mojom::FilterType; +using chromeos::network_config::mojom::GlobalPolicy; +using chromeos::network_config::mojom::NetworkFilter; +using chromeos::network_config::mojom::NetworkStateProperties; +using chromeos::network_config::mojom::NetworkStatePropertiesPtr; +using chromeos::network_config::mojom::NetworkType; +using chromeos::network_config::mojom::ProxyMode; + +using chromeos::bluetooth_config::mojom::BluetoothSystemPropertiesPtr; +using chromeos::bluetooth_config::mojom::BluetoothSystemState; + +// Helper function to remove |*view| from its view hierarchy, delete the view, +// and reset the value of |*view| to be |nullptr|. +template <class T> +void RemoveAndResetViewIfExists(T** view) { + DCHECK(view); + + if (!*view) + return; + + views::View* parent = (*view)->parent(); + + if (parent) { + parent->RemoveChildViewT(*view); + *view = nullptr; + } +} + +bool IsSecondaryUser() { + SessionControllerImpl* session_controller = + Shell::Get()->session_controller(); + return session_controller->IsActiveUserSessionStarted() && + !session_controller->IsUserPrimary(); +} + +bool IsCellularDeviceInhibited() { + const DeviceStateProperties* cellular_device = + Shell::Get()->system_tray_model()->network_state_model()->GetDevice( + NetworkType::kCellular); + if (!cellular_device) + return false; + return cellular_device->inhibit_reason != + chromeos::network_config::mojom::InhibitReason::kNotInhibited; +} + +bool IsESimSupported() { + const DeviceStateProperties* cellular_device = + Shell::Get()->system_tray_model()->network_state_model()->GetDevice( + NetworkType::kCellular); + + if (!cellular_device || !cellular_device->sim_infos) + return false; + + // Check both the SIM slot infos and the number of EUICCs because the former + // comes from Shill and the latter from Hermes, and so there may be instances + // where one may be true while they other isn't. + if (chromeos::HermesManagerClient::Get()->GetAvailableEuiccs().empty()) + return false; + + for (const auto& sim_info : *cellular_device->sim_infos) { + if (!sim_info->eid.empty()) + return true; + } + return false; +} + +} // namespace NetworkListViewControllerImpl::NetworkListViewControllerImpl( NetworkDetailedNetworkView* network_detailed_network_view) - : network_detailed_network_view_(network_detailed_network_view) { + : model_(Shell::Get()->system_tray_model()->network_state_model()), + network_detailed_network_view_(network_detailed_network_view) { DCHECK(ash::features::IsQuickSettingsNetworkRevampEnabled()); + DCHECK(ash::features::IsBluetoothRevampEnabled()); DCHECK(network_detailed_network_view_); Shell::Get()->system_tray_model()->network_state_model()->AddObserver(this); + + GetBluetoothConfigService( + remote_cros_bluetooth_config_.BindNewPipeAndPassReceiver()); + remote_cros_bluetooth_config_->ObserveSystemProperties( + cros_system_properties_observer_receiver_.BindNewPipeAndPassRemote()); + + GetNetworkStateList(); } NetworkListViewControllerImpl::~NetworkListViewControllerImpl() { @@ -26,15 +127,419 @@ } void NetworkListViewControllerImpl::ActiveNetworkStateChanged() { - // TODO(b/207089013): Implement this function. + GetNetworkStateList(); } void NetworkListViewControllerImpl::NetworkListChanged() { - // TODO(b/207089013): Implement this function. + GetNetworkStateList(); } -void NetworkListViewControllerImpl::DeviceStateListChanged() { - // TODO(b/207089013): Implement this function. +void NetworkListViewControllerImpl::GlobalPolicyChanged() { + UpdateMobileSectionHeader(); +}; + +void NetworkListViewControllerImpl::OnPropertiesUpdated( + BluetoothSystemPropertiesPtr properties) { + if (bluetooth_system_state_ == properties->system_state) + return; + + bluetooth_system_state_ = properties->system_state; + UpdateMobileSectionHeader(); +} + +void NetworkListViewControllerImpl::GetNetworkStateList() { + model()->cros_network_config()->GetNetworkStateList( + NetworkFilter::New(FilterType::kVisible, NetworkType::kAll, + chromeos::network_config::mojom::kNoLimit), + base::BindOnce(&NetworkListViewControllerImpl::OnGetNetworkStateList, + weak_ptr_factory_.GetWeakPtr())); +} + +void NetworkListViewControllerImpl::OnGetNetworkStateList( + std::vector<NetworkStatePropertiesPtr> networks) { + // Indicates the current position a view will be added to in + // NetworkDetailedNetworkView scroll list. + int index = 0; + + // Store current views in |previous_network_views|, views which have + // a corresponding network in |networks| will be added back to + // |network_id_to_view_map_| any remaining views in |previous_network_views| + // would be deleted. + NetworkIdToViewMap previous_network_views = + std::move(network_id_to_view_map_); + network_id_to_view_map_.clear(); + + UpdateNetworkTypeExistence(networks); + + // Show a warning that the connection might be monitored if connected to a VPN + // or if the default network has a proxy installed. + index = ShowConnectionWarningIfVpnOrProxy(index); + + if (ShouldMobileDataSectionBeShown()) { + // Add separator if mobile section is not the first view child, else + // delete unused separator. + if (index > 0) { + if (!mobile_separator_view_) + CreateMobileSeparator(); + network_detailed_network_view()->network_list()->ReorderChildView( + mobile_separator_view_, index++); + } else { + RemoveAndResetViewIfExists(&mobile_separator_view_); + } + + if (!mobile_header_view_) { + mobile_header_view_ = + network_detailed_network_view()->AddMobileSectionHeader(); + mobile_header_view_->SetID(static_cast<int>( + NetworkListViewControllerViewChildId::kMobileSectionHeader)); + } + + UpdateMobileSectionHeader(); + + network_detailed_network_view()->network_list()->ReorderChildView( + mobile_header_view_, index++); + + index = CreateItemViewsIfMissingAndReorder( + NetworkType::kMobile, index, networks, &previous_network_views); + + // Add mobile status message to NetworkDetailedNetworkView scroll list if it + // exist. + if (mobile_status_message_) { + network_detailed_network_view()->network_list()->ReorderChildView( + mobile_status_message_, index++); + } + + } else { + RemoveAndResetViewIfExists(&mobile_header_view_); + RemoveAndResetViewIfExists(&mobile_separator_view_); + } + + // Remaining views in |previous_network_views| are no longer needed + // and should be deleted. + for (const auto& id_and_view : previous_network_views) { + network_detailed_network_view()->network_list()->RemoveChildViewT( + id_and_view.second); + } + + FocusLastSelectedView(); + network_detailed_network_view()->NotifyNetworkListChanged(); +} + +void NetworkListViewControllerImpl::UpdateNetworkTypeExistence( + const std::vector<NetworkStatePropertiesPtr>& networks) { + has_mobile_networks_ = false; + is_vpn_connected_ = false; + + for (auto& network : networks) { + if (NetworkTypeMatchesType(network->type, NetworkType::kMobile)) { + has_mobile_networks_ = true; + } else if (NetworkTypeMatchesType(network->type, NetworkType::kVPN) && + StateIsConnected(network->connection_state)) { + is_vpn_connected_ = true; + } + } + + is_mobile_network_enabled_ = + model()->GetDeviceState(NetworkType::kCellular) == + DeviceStateType::kEnabled || + model()->GetDeviceState(NetworkType::kTether) == + DeviceStateType::kEnabled; +} + +int NetworkListViewControllerImpl::ShowConnectionWarningIfVpnOrProxy( + int index) { + const NetworkStateProperties* default_network = model()->default_network(); + bool using_proxy = + default_network && default_network->proxy_mode != ProxyMode::kDirect; + + if (is_vpn_connected_ || using_proxy) { + if (!connection_warning_) + ShowConnectionWarning(); + + network_detailed_network_view()->network_list()->ReorderChildView( + connection_warning_, index++); + } else if (!is_vpn_connected_ && !using_proxy) { + RemoveAndResetViewIfExists(&connection_warning_); + } + + return index; +} + +bool NetworkListViewControllerImpl::ShouldMobileDataSectionBeShown() { + // The section should always be shown if Cellular networks are available. + if (model()->GetDeviceState(NetworkType::kCellular) != + DeviceStateType::kUnavailable) { + return true; + } + + const DeviceStateType tether_state = + model()->GetDeviceState(NetworkType::kTether); + + // Hide the section if both Cellular and Tether are UNAVAILABLE. + if (tether_state == DeviceStateType::kUnavailable) + return false; + + // Hide the section if Tether is PROHIBITED. + if (tether_state == DeviceStateType::kProhibited) + return false; + + // Secondary users cannot enable Bluetooth, and Tether is only UNINITIALIZED + // if Bluetooth is disabled. Hide the section in this case. + if (tether_state == DeviceStateType::kUninitialized && IsSecondaryUser()) + return false; + + return true; +} + +void NetworkListViewControllerImpl::CreateMobileSeparator() { + DCHECK(!mobile_separator_view_); + + std::unique_ptr<views::Separator> mobile_separator_view = + base::WrapUnique(TrayPopupUtils::CreateListSubHeaderSeparator()); + mobile_separator_view->SetID( + static_cast<int>(NetworkListViewControllerViewChildId::kMobileSeperator)); + mobile_separator_view_ = + network_detailed_network_view()->network_list()->AddChildView( + std::move(mobile_separator_view)); +} + +void NetworkListViewControllerImpl::UpdateMobileSectionHeader() { + if (!mobile_header_view_) + return; + + const bool is_add_esim_enabled = + is_mobile_network_enabled_ && !IsCellularDeviceInhibited(); + + bool is_add_esim_visible = IsESimSupported(); + const GlobalPolicy* global_policy = model()->global_policy(); + + // Adding new cellular networks is disallowed when only policy cellular + // networks are allowed by admin. + if (ash::features::IsESimPolicyEnabled() && + (!global_policy || global_policy->allow_only_policy_cellular_networks)) { + is_add_esim_visible = false; + } + + mobile_header_view_->SetAddESimButtonState(/*enabled=*/is_add_esim_enabled, + /*visible=*/is_add_esim_visible); + + UpdateMobileToggleAndSetStatusMessage(); +} + +void NetworkListViewControllerImpl::UpdateMobileToggleAndSetStatusMessage() { + if (!mobile_header_view_) + return; + + const DeviceStateType cellular_state = + model()->GetDeviceState(NetworkType::kCellular); + const DeviceStateType tether_state = + model()->GetDeviceState(NetworkType::kTether); + + const bool is_secondary_user = IsSecondaryUser(); + + if (cellular_state == DeviceStateType::kUninitialized) { + CreateMobileInfoLabelIfMissingAndUpdate( + IDS_ASH_STATUS_TRAY_INITIALIZING_CELLULAR); + mobile_header_view_->SetToggleVisibility(/*visible=*/false); + return; + } + + if (cellular_state != DeviceStateType::kUnavailable) { + if (IsCellularDeviceInhibited()) { + // When a device is inhibited, it cannot process any new operations. Thus, + // keep the toggle on to show users that the device is active, but set it + // to be disabled to make it clear that users cannot update it until it + // becomes uninhibited. + mobile_header_view_->SetToggleVisibility(/*visible=*/true); + mobile_header_view_->SetToggleState(/*enabled=*/false, + /*is_on=*/true); + RemoveAndResetViewIfExists(&mobile_status_message_); + return; + } + + const bool toggle_enabled = + !is_secondary_user && (cellular_state == DeviceStateType::kEnabled || + cellular_state == DeviceStateType::kDisabled); + const bool cellular_enabled = cellular_state == DeviceStateType::kEnabled; + mobile_header_view_->SetToggleVisibility(/*visibility=*/true); + mobile_header_view_->SetToggleState(/*enabled=*/toggle_enabled, + /*is_on=*/cellular_enabled); + + if (cellular_state == DeviceStateType::kDisabling) { + CreateMobileInfoLabelIfMissingAndUpdate( + IDS_ASH_STATUS_TRAY_NETWORK_MOBILE_DISABLING); + return; + } + + if (cellular_enabled) { + if (has_mobile_networks_) { + RemoveAndResetViewIfExists(&mobile_status_message_); + return; + } + + CreateMobileInfoLabelIfMissingAndUpdate( + IDS_ASH_STATUS_TRAY_NO_MOBILE_NETWORKS); + return; + } + + CreateMobileInfoLabelIfMissingAndUpdate( + IDS_ASH_STATUS_TRAY_NETWORK_MOBILE_DISABLED); + return; + } + + // When Cellular is not available, always show the toggle. + mobile_header_view_->SetToggleVisibility(/*visibility=*/true); + + // Otherwise, toggle state and status message reflect Tether. + if (tether_state == DeviceStateType::kUninitialized) { + if (bluetooth_system_state_ == BluetoothSystemState::kEnabling) { + mobile_header_view_->SetToggleState(/*toggle_enabled=*/false, + /*is_on=*/true); + CreateMobileInfoLabelIfMissingAndUpdate( + IDS_ASH_STATUS_TRAY_INITIALIZING_CELLULAR); + return; + } + mobile_header_view_->SetToggleState( + /*toggle_enabled=*/!is_secondary_user, /*is_on=*/false); + CreateMobileInfoLabelIfMissingAndUpdate( + IDS_ASH_STATUS_TRAY_ENABLING_MOBILE_ENABLES_BLUETOOTH); + return; + } + + const bool tether_enabled = tether_state == DeviceStateType::kEnabled; + + // Ensure that the toggle state and status message match the tether state. + mobile_header_view_->SetToggleState(/*toggle_enabled=*/!is_secondary_user, + /*is_on=*/tether_enabled); + if (tether_enabled && !has_mobile_networks_) { + CreateMobileInfoLabelIfMissingAndUpdate( + IDS_ASH_STATUS_TRAY_NO_MOBILE_DEVICES_FOUND); + return; + } + + RemoveAndResetViewIfExists(&mobile_status_message_); +} + +void NetworkListViewControllerImpl::CreateMobileInfoLabelIfMissingAndUpdate( + int message_id) { + DCHECK(message_id); + + if (mobile_status_message_) { + mobile_status_message_->Update(message_id); + return; + } + + std::unique_ptr<TrayInfoLabel> info = + std::make_unique<TrayInfoLabel>(message_id); + info->SetID(static_cast<int>( + NetworkListViewControllerViewChildId::kMobileStatusMessage)); + mobile_status_message_ = + network_detailed_network_view()->network_list()->AddChildView( + std::move(info)); +} + +int NetworkListViewControllerImpl::CreateItemViewsIfMissingAndReorder( + NetworkType type, + int index, + std::vector<NetworkStatePropertiesPtr>& networks, + NetworkIdToViewMap* previous_views) { + NetworkIdToViewMap id_to_view_map; + NetworkListNetworkItemView* network_view = nullptr; + + for (const auto& network : networks) { + if (!NetworkTypeMatchesType(network->type, type)) + continue; + + const std::string& network_id = network->guid; + auto it = previous_views->find(network_id); + + if (it == previous_views->end()) { + network_view = network_detailed_network_view()->AddNetworkListItem(); + } else { + network_view = it->second; + previous_views->erase(it); + } + network_id_to_view_map_.emplace(network_id, network_view); + + network_view->UpdateViewForNetwork(network); + network_detailed_network_view()->network_list()->ReorderChildView( + network_view, index); + + // Increment |index| since this position was taken by |network_view|. + index++; + } + + return index; +} + +void NetworkListViewControllerImpl::ShowConnectionWarning() { + // Set up layout and apply sticky row property. + std::unique_ptr<TriView> connection_warning( + TrayPopupUtils::CreateDefaultRowView()); + TrayPopupUtils::ConfigureAsStickyHeader(connection_warning.get()); + + // Set 'info' icon on left side. + std::unique_ptr<views::ImageView> image_view = + base::WrapUnique(TrayPopupUtils::CreateMainImageView()); + image_view->SetImage(gfx::CreateVectorIcon( + kSystemMenuInfoIcon, + AshColorProvider::Get()->GetContentLayerColor( + AshColorProvider::ContentLayerType::kIconColorPrimary))); + image_view->SetBackground(views::CreateSolidBackground(SK_ColorTRANSPARENT)); + connection_warning->AddView(TriView::Container::START, image_view.release()); + + // Set message label in middle of row. + std::unique_ptr<views::Label> label = + base::WrapUnique(TrayPopupUtils::CreateDefaultLabel()); + label->SetText( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_MONITORED_WARNING)); + label->SetBackground(views::CreateSolidBackground(SK_ColorTRANSPARENT)); + label->SetEnabledColor(AshColorProvider::Get()->GetContentLayerColor( + AshColorProvider::ContentLayerType::kTextColorPrimary)); + TrayPopupUtils::SetLabelFontList( + label.get(), TrayPopupUtils::FontStyle::kDetailedViewLabel); + label->SetID(static_cast<int>( + NetworkListViewControllerViewChildId::kConnectionWarningLabel)); + + connection_warning->AddView(TriView::Container::CENTER, label.release()); + connection_warning->SetContainerBorder( + TriView::Container::CENTER, views::CreateEmptyBorder(gfx::Insets::TLBR( + 0, 0, 0, kTrayPopupLabelRightPadding))); + + // Nothing to the right of the text. + connection_warning->SetContainerVisible(TriView::Container::END, false); + + connection_warning->SetID(static_cast<int>( + NetworkListViewControllerViewChildId::kConnectionWarning)); + connection_warning_ = + network_detailed_network_view()->network_list()->AddChildView( + std::move(connection_warning)); +} + +void NetworkListViewControllerImpl::FocusLastSelectedView() { + views::View* selected_view = nullptr; + views::View* parent_view = network_detailed_network_view()->network_list(); + for (const auto& [network_id, view] : network_id_to_view_map_) { + // The within_bounds check is necessary when the network list goes beyond + // the visible area (i.e. scrolling) and the mouse is below the tray pop-up. + // The items not in view in the tray pop-up keep going down and have + // View::GetVisibility() == true but they are masked and not seen by the + // user. When the mouse is below the list where the item would be if the + // list continued downward, IsMouseHovered() is true and this will trigger + // an incorrect programmatic scroll if we don't stop it. The bounds check + // ensures the view is actually visible within the tray pop-up. + bool within_bounds = + parent_view->GetBoundsInScreen().Intersects(view->GetBoundsInScreen()); + if (within_bounds && view->IsMouseHovered()) { + selected_view = view; + break; + } + } + + parent_view->SizeToPreferredSize(); + parent_view->Layout(); + if (selected_view) + parent_view->ScrollRectToVisible(selected_view->bounds()); } } // namespace ash
diff --git a/ash/system/network/network_list_view_controller_impl.h b/ash/system/network/network_list_view_controller_impl.h index fca975b..704462e 100644 --- a/ash/system/network/network_list_view_controller_impl.h +++ b/ash/system/network/network_list_view_controller_impl.h
@@ -7,17 +7,31 @@ #include "ash/ash_export.h" +#include "ash/system/network/network_detailed_network_view_impl.h" +#include "ash/system/network/network_list_mobile_header_view.h" +#include "ash/system/network/network_list_network_header_view.h" +#include "ash/system/network/network_list_network_item_view.h" #include "ash/system/network/network_list_view_controller.h" #include "ash/system/network/tray_network_state_observer.h" +#include "ash/system/tray/tray_info_label.h" +#include "ash/system/tray/tray_popup_utils.h" +#include "ash/system/tray/tray_utils.h" +#include "ash/system/tray/tri_view.h" +#include "chromeos/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "ui/views/controls/separator.h" namespace ash { class NetworkDetailedNetworkView; -// Implementation of NetworkListViewController +// Implementation of NetworkListViewController. class ASH_EXPORT NetworkListViewControllerImpl : public TrayNetworkStateObserver, - public NetworkListViewController { + public NetworkListViewController, + public chromeos::bluetooth_config::mojom::SystemPropertiesObserver { public: NetworkListViewControllerImpl( NetworkDetailedNetworkView* network_detailed_network_view); @@ -27,17 +41,110 @@ ~NetworkListViewControllerImpl() override; protected: + TrayNetworkStateModel* model() { return model_; } + NetworkDetailedNetworkView* network_detailed_network_view() { return network_detailed_network_view_; } private: + friend class NetworkListViewControllerTest; + friend class FakeNetworkDetailedNetworkView; + + // Used for testing. Starts at 1 because 0 is default view id. + enum class NetworkListViewControllerViewChildId { + kConnectionWarning = 1, + kConnectionWarningLabel = 2, + kMobileSeperator = 3, + kMobileStatusMessage = 4, + kMobileSectionHeader = 5, + }; + + // Map of network guids and their corresponding list item views. + using NetworkIdToViewMap = + base::flat_map<std::string, NetworkListNetworkItemView*>; + // TrayNetworkStateObserver: void ActiveNetworkStateChanged() override; void NetworkListChanged() override; - void DeviceStateListChanged() override; + void GlobalPolicyChanged() override; + + // chromeos::bluetooth_config::mojom::SystemPropertiesObserver: + void OnPropertiesUpdated( + chromeos::bluetooth_config::mojom::BluetoothSystemPropertiesPtr + properties) override; + + // Called to initialize views and when network list is recently updated. + void GetNetworkStateList(); + void OnGetNetworkStateList( + std::vector<chromeos::network_config::mojom::NetworkStatePropertiesPtr> + networks); + + // Checks |networks| and caches whether mobile network exist in the list + // of |networks|. Also caches if a Mobile networks are enabled. + void UpdateNetworkTypeExistence( + const std::vector< + chromeos::network_config::mojom::NetworkStatePropertiesPtr>& + networks); + + // Adds a warning indicator if connected to a VPN or if the default network + // has a proxy installed. + int ShowConnectionWarningIfVpnOrProxy(int index); + + // Returns true if mobile data section should be added to view. + bool ShouldMobileDataSectionBeShown(); + + // Creates and adds a Mobile separator to the view. + void CreateMobileSeparator(); + + // Updates mobile data section, updates add eSIM button states and + // calls UpdateMobileToggleAndSetStatusMessage(). + void UpdateMobileSectionHeader(); + + // Updated mobile data toggle states and sets mobile data status message. + void UpdateMobileToggleAndSetStatusMessage(); + void CreateMobileInfoLabelIfMissingAndUpdate(int message_id); + + // Creates a NetworkListNetworkItem if it does not exist else uses the + // existing view, also reorders it in NetworkDetailedNetworkView scroll list. + int CreateItemViewsIfMissingAndReorder( + chromeos::network_config::mojom::NetworkType type, + int index, + std::vector<chromeos::network_config::mojom::NetworkStatePropertiesPtr>& + networks, + NetworkIdToViewMap* previous_views); + + // Creates a view that indicates connections might be monitored if + // connected to a VPN or if the default network has a proxy installed. + void ShowConnectionWarning(); + + // Focuses on last selected view in NetworkDetailedNetworkView scroll list. + void FocusLastSelectedView(); + + TrayNetworkStateModel* model_; + + mojo::Remote<chromeos::bluetooth_config::mojom::CrosBluetoothConfig> + remote_cros_bluetooth_config_; + mojo::Receiver<chromeos::bluetooth_config::mojom::SystemPropertiesObserver> + cros_system_properties_observer_receiver_{this}; + + chromeos::bluetooth_config::mojom::BluetoothSystemState + bluetooth_system_state_ = + chromeos::bluetooth_config::mojom::BluetoothSystemState::kUnavailable; + + TrayInfoLabel* mobile_status_message_ = nullptr; + NetworkListMobileHeaderView* mobile_header_view_ = nullptr; + views::Separator* mobile_separator_view_ = nullptr; + TriView* connection_warning_ = nullptr; + + bool has_mobile_networks_; + bool is_vpn_connected_; + bool is_mobile_network_enabled_; NetworkDetailedNetworkView* network_detailed_network_view_; + NetworkIdToViewMap network_id_to_view_map_; + + base::WeakPtrFactory<NetworkListViewControllerImpl> weak_ptr_factory_{this}; }; } // namespace ash
diff --git a/ash/system/network/network_list_view_controller_unittest.cc b/ash/system/network/network_list_view_controller_unittest.cc index 2e5f2421..75252ee 100644 --- a/ash/system/network/network_list_view_controller_unittest.cc +++ b/ash/system/network/network_list_view_controller_unittest.cc
@@ -7,15 +7,126 @@ #include <memory> #include "ash/constants/ash_features.h" +#include "ash/session/session_controller_impl.h" +#include "ash/shell.h" +#include "ash/strings/grit/ash_strings.h" +#include "ash/system/model/system_tray_model.h" #include "ash/system/network/fake_network_detailed_network_view.h" +#include "ash/system/network/fake_network_list_mobile_header_view.h" +#include "ash/system/network/tray_network_state_model.h" +#include "ash/system/tray/tray_info_label.h" +#include "ash/system/tray/tri_view.h" #include "ash/test/ash_test_base.h" +#include "ash/test/ash_test_helper.h" +#include "base/run_loop.h" +#include "base/test/bind.h" #include "base/test/scoped_feature_list.h" +#include "chromeos/network/mock_managed_network_configuration_handler.h" +#include "chromeos/network/network_state_handler.h" +#include "chromeos/services/bluetooth_config/fake_adapter_state_controller.h" +#include "chromeos/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom.h" +#include "chromeos/services/bluetooth_config/scoped_bluetooth_config_test_helper.h" +#include "chromeos/services/network_config/public/cpp/cros_network_config_test_helper.h" +#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" +#include "components/session_manager/session_manager_types.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "third_party/cros_system_api/dbus/shill/dbus-constants.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/views/controls/button/toggle_button.h" namespace ash { +namespace { + +using testing::_; +using testing::Return; + +using chromeos::bluetooth_config::ScopedBluetoothConfigTestHelper; +using chromeos::bluetooth_config::mojom::BluetoothSystemState; + +using chromeos::network_config::CrosNetworkConfigTestHelper; + +using chromeos::network_config::mojom::ActivationStateType; +using chromeos::network_config::mojom::ConnectionStateType; +using chromeos::network_config::mojom::NetworkStatePropertiesPtr; +using chromeos::network_config::mojom::NetworkType; +using chromeos::network_config::mojom::OncSource; +using chromeos::network_config::mojom::SecurityType; + +const std::string kCellularName = "cellular"; +const std::string kCellularName2 = "cellular_2"; +const char kCellularDeviceName[] = "cellular_device"; +const char kCellularDevicePath[] = "/device/cellular_device"; +const char kCellularTestIccid[] = "1234567890"; + +const char kTetherName[] = "tether"; +const char kTetherGuid[] = "tetherNetworkGuid"; +const char kTetherCarrier[] = "TetherNetworkCarrier"; +const char kWifiServiceGuid[] = "wifiServiceGuid"; + +const char kVpnName[] = "vpn"; +const char kVpnDevicePath[] = "device/vpn"; + +const char kTestEuiccBasePath[] = "/org/chromium/Hermes/Euicc/"; +const char kTestBaseEid[] = "12345678901234567890123456789012"; + +const int kSignalStrength = 50; +constexpr char kUser1Email[] = "user1@quicksettings.com"; + +// Delay used to simulate running process when setting device technology state. +constexpr base::TimeDelta kInteractiveDelay = base::Milliseconds(3000); + +std::string CreateConfigurationJsonString(const std::string& guid, + const std::string& type, + const std::string& state) { + std::stringstream ss; + ss << "{" + << " \"GUID\": \"" << guid << "\"," + << " \"Type\": \"" << type << "\"," + << " \"State\": \"" << state << "\"" + << "}"; + return ss.str(); +} + +std::string CreateTestEuiccPath(int euicc_num) { + return base::StringPrintf("%s%d", kTestEuiccBasePath, euicc_num); +} + +std::string CreateTestEid(int euicc_num) { + return base::StringPrintf("%s%d", kTestBaseEid, euicc_num); +} + +} // namespace + class NetworkListViewControllerTest : public AshTestBase { public: + NetworkListViewControllerTest() + : AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {} + NetworkListViewControllerTest(const NetworkListViewControllerTest&) = delete; + NetworkListViewControllerTest& operator=( + const NetworkListViewControllerTest&) = delete; + ~NetworkListViewControllerTest() override = default; + void SetUp() override { + // Initialize CrosNetworkConfigTestHelper here, so we can use + // MockManagedNetworkConfigurationHandler. + cros_network_config_test_helper_ = + std::make_unique<network_config::CrosNetworkConfigTestHelper>( + /*initialize=*/false); + + mock_managed_network_configuration_manager_ = base::WrapUnique( + new testing::NiceMock<MockManagedNetworkConfigurationHandler>); + + SetGlobalPolicyConfig(/*allow_only_policy=*/false); + + ON_CALL(*mock_managed_network_configuration_manager_, + GetGlobalConfigFromPolicy(_)) + .WillByDefault(Return(&global_config_)); + + cros_network_config_test_helper_->Initialize( + mock_managed_network_configuration_manager_.get()); + base::RunLoop().RunUntilIdle(); + AshTestBase::SetUp(); feature_list_.InitAndEnableFeature(features::kQuickSettingsNetworkRevamp); @@ -29,31 +140,562 @@ fake_network_detailed_network_view_.get()); } + void SetGlobalPolicyConfig(bool allow_only_policy) { + base::Value::Dict global_config_dict; + global_config_dict.Set( + ::onc::global_network_config::kAllowOnlyPolicyCellularNetworks, + allow_only_policy); + + global_config_ = base::Value(std::move(global_config_dict)); + + // This function can be called before AshTestBase::SetUp(), Shell is not + // initialized, make sure to only call FlushGlobalPolicyForTesting + // after initialization. + if (Shell::HasInstance()) { + Shell::Get() + ->system_tray_model() + ->network_state_model() + ->FlushGlobalPolicyForTesting(); + base::RunLoop().RunUntilIdle(); + } + } + void TearDown() override { network_list_view_controller_impl_.reset(); fake_network_detailed_network_view_.reset(); + cros_network_config_test_helper_.reset(); AshTestBase::TearDown(); } - FakeNetworkDetailedNetworkView* fake_network_detailed_network_view() { - return fake_network_detailed_network_view_.get(); + views::ToggleButton* GetToggleButton() { + return static_cast<views::ToggleButton*>(GetMobileSubHeader()->GetViewByID( + static_cast<int>(NetworkListNetworkHeaderView::kToggleButtonId))); } - NetworkListViewController* network_list_view_controller_impl() { - return network_list_view_controller_impl_.get(); + FakeNetworkListMobileHeaderView* GetMobileSubHeader() { + return FindViewById<FakeNetworkListMobileHeaderView*>( + NetworkListViewControllerImpl::NetworkListViewControllerViewChildId:: + kMobileSectionHeader); } + views::Separator* GetMobileSeparator() { + return FindViewById<views::Separator*>( + NetworkListViewControllerImpl::NetworkListViewControllerViewChildId:: + kMobileSeperator); + } + + TrayInfoLabel* GetMobileStatusMessage() { + return FindViewById<TrayInfoLabel*>( + NetworkListViewControllerImpl::NetworkListViewControllerViewChildId:: + kMobileStatusMessage); + } + + TriView* GetConnectionWarning() { + return FindViewById<TriView*>( + NetworkListViewControllerImpl::NetworkListViewControllerViewChildId:: + kConnectionWarning); + } + + views::Label* GetConnectionLabelView() { + return FindViewById<views::Label*>( + NetworkListViewControllerImpl::NetworkListViewControllerViewChildId:: + kConnectionWarningLabel); + } + + views::View* GetViewInNetworkList(std::string id) { + return network_list_view_controller_impl_->network_id_to_view_map_[id]; + } + + void UpdateNetworkList( + const std::vector<NetworkStatePropertiesPtr>& networks) { + network_list_view_controller_impl_->OnGetNetworkStateList( + mojo::Clone(networks)); + } + + // Checks that network list items are in the right order. This function + // assumes that Mobile device is present and enabled. + void CheckNetworkListOrdering(size_t mobile_network_count) { + // TODO(tjohnsonkanu): add Ethernet and WiFi networks. + if (mobile_network_count) { + // We expect to see all network item views and Mobile subheader. + // Separator is null because only mobile networks are available. + EXPECT_EQ(mobile_network_count + 1, network_list()->children().size()); + EXPECT_NE(nullptr, GetMobileSubHeader()); + EXPECT_EQ(nullptr, GetMobileStatusMessage()); + EXPECT_EQ(nullptr, GetMobileSeparator()); + + EXPECT_EQ(network_list()->children().at(0), GetMobileSubHeader()); + return; + } + + // Mobile header is shown and mobile status message is also shown. + EXPECT_EQ(2u, network_list()->children().size()); + EXPECT_NE(nullptr, GetMobileSubHeader()); + EXPECT_NE(nullptr, GetMobileStatusMessage()); + + EXPECT_EQ(network_list()->children().at(0), GetMobileSubHeader()); + EXPECT_EQ(network_list()->children().at(1), GetMobileStatusMessage()); + } + + void CheckNetworkListItem(size_t index, const std::string& guid) { + ASSERT_GT(network_list()->children().size(), index); + EXPECT_STREQ(network_list()->children().at(index)->GetClassName(), + "NetworkListNetworkItemView"); + EXPECT_EQ(static_cast<NetworkListNetworkItemView*>( + network_list()->children().at(index)) + ->network_properties() + ->guid, + guid); + } + + void SetupCellular() { + network_state_helper()->manager_test()->AddTechnology(shill::kTypeCellular, + /*enabled=*/true); + network_state_helper()->device_test()->AddDevice( + kCellularDevicePath, shill::kTypeCellular, kCellularDeviceName); + + base::Value::ListStorage sim_slot_infos; + base::Value slot_info_item(base::Value::Type::DICTIONARY); + slot_info_item.SetKey(shill::kSIMSlotInfoICCID, + base::Value(kCellularTestIccid)); + slot_info_item.SetBoolKey(shill::kSIMSlotInfoPrimary, true); + slot_info_item.SetStringKey(shill::kSIMSlotInfoEID, kTestBaseEid); + sim_slot_infos.push_back(std::move(slot_info_item)); + network_state_helper()->device_test()->SetDeviceProperty( + kCellularDevicePath, shill::kSIMSlotInfoProperty, + base::Value(sim_slot_infos), /*notify_changed=*/true); + + // Wait for network state and device change events to be handled. + base::RunLoop().RunUntilIdle(); + } + + void AddEuicc() { + network_state_helper()->hermes_manager_test()->AddEuicc( + dbus::ObjectPath(CreateTestEuiccPath(/*euicc_num=*/1)), + CreateTestEid(/*euicc_num=*/1), /*is_active=*/true, + /*physical_slot=*/0); + + // Wait for network state change events to be handled. + base::RunLoop().RunUntilIdle(); + } + + // Adds a Tether network state, adds a Wifi network to be used as the Wifi + // hotspot, and associates the two networks. + void AddTetherNetworkState() { + network_state_handler()->SetTetherTechnologyState( + chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED); + network_state_handler()->AddTetherNetworkState( + kTetherGuid, kTetherName, kTetherCarrier, /*battery_percentage=*/100, + kSignalStrength, /*has_connected_to_host=*/false); + network_state_helper()->ConfigureService(CreateConfigurationJsonString( + kWifiServiceGuid, shill::kTypeWifi, shill::kStateReady)); + network_state_handler()->AssociateTetherNetworkStateWithWifiNetwork( + kTetherGuid, kWifiServiceGuid); + } + + void AddVpnDevice() { + network_state_helper()->manager_test()->AddTechnology(shill::kTypeVPN, + /*enabled=*/true); + network_state_helper()->device_test()->AddDevice(kVpnDevicePath, + shill::kTypeVPN, kVpnName); + + // Wait for network state and device change events to be handled. + base::RunLoop().RunUntilIdle(); + } + + std::unique_ptr<CellularInhibitor::InhibitLock> InhibitCellularScanning() { + base::RunLoop inhibit_loop; + CellularInhibitor::InhibitReason inhibit_reason = + CellularInhibitor::InhibitReason::kInstallingProfile; + std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock; + cros_network_config_test_helper_->cellular_inhibitor() + ->InhibitCellularScanning( + inhibit_reason, + base::BindLambdaForTesting( + [&](std::unique_ptr<CellularInhibitor::InhibitLock> result) { + inhibit_lock = std::move(result); + inhibit_loop.Quit(); + })); + inhibit_loop.Run(); + return inhibit_lock; + } + + NetworkStatePropertiesPtr CreateStandaloneNetworkProperties( + const std::string& id, + NetworkType type, + ConnectionStateType connection_state) { + return cros_network_config_test_helper_->CreateStandaloneNetworkProperties( + id, type, connection_state, kSignalStrength); + } + + void SetBluetoothAdapterState(BluetoothSystemState system_state) { + bluetooth_config_test_helper() + ->fake_adapter_state_controller() + ->SetSystemState(system_state); + base::RunLoop().RunUntilIdle(); + } + + void LoginAsSecondaryUser() { + GetSessionControllerClient()->AddUserSession(kUser1Email); + SimulateUserLogin(kUser1Email); + GetSessionControllerClient()->SetSessionState( + session_manager::SessionState::LOGIN_SECONDARY); + base::RunLoop().RunUntilIdle(); + } + + chromeos::NetworkStateHandler* network_state_handler() { + return network_state_helper()->network_state_handler(); + } + + chromeos::NetworkStateTestHelper* network_state_helper() { + return &cros_network_config_test_helper_->network_state_helper(); + } + + views::View* network_list() { + return static_cast<NetworkDetailedNetworkView*>( + fake_network_detailed_network_view_.get()) + ->network_list(); + } + + protected: + const std::vector<NetworkStatePropertiesPtr> empty_list_; + private: + template <class T> + T FindViewById( + NetworkListViewControllerImpl::NetworkListViewControllerViewChildId id) { + return static_cast<T>(network_list()->GetViewByID(static_cast<int>(id))); + } + + ScopedBluetoothConfigTestHelper* bluetooth_config_test_helper() { + return ash_test_helper()->bluetooth_config_test_helper(); + } + base::test::ScopedFeatureList feature_list_; std::unique_ptr<FakeNetworkDetailedNetworkView> fake_network_detailed_network_view_; std::unique_ptr<NetworkListViewControllerImpl> network_list_view_controller_impl_; + + std::unique_ptr<network_config::CrosNetworkConfigTestHelper> + cros_network_config_test_helper_; + + std::unique_ptr<MockManagedNetworkConfigurationHandler> + mock_managed_network_configuration_manager_; + + base::Value global_config_; }; -TEST_F(NetworkListViewControllerTest, CanConstruct) { - EXPECT_TRUE(true); +TEST_F(NetworkListViewControllerTest, MobileDataSectionIsShown) { + EXPECT_EQ(nullptr, GetMobileSubHeader()); + EXPECT_EQ(nullptr, GetMobileSeparator()); + + AddEuicc(); + SetupCellular(); + EXPECT_NE(nullptr, GetMobileSubHeader()); + + // Mobile separator is still null because mobile data is at index 0. + EXPECT_EQ(nullptr, GetMobileSeparator()); + + // Clear device list and check if Mobile subheader is shown with just + // tether device. + network_state_helper()->ClearDevices(); + EXPECT_EQ(nullptr, GetMobileSubHeader()); + + // Add tether networks + AddTetherNetworkState(); + EXPECT_NE(nullptr, GetMobileSubHeader()); + + // Tether device is prohibited. + network_state_handler()->SetTetherTechnologyState( + chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_PROHIBITED); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(nullptr, GetMobileSubHeader()); + + // Tether device is uninitialized but is primary user. + network_state_handler()->SetTetherTechnologyState( + chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNINITIALIZED); + base::RunLoop().RunUntilIdle(); + EXPECT_NE(nullptr, GetMobileSubHeader()); + + // Simulate login as secondary user. + LoginAsSecondaryUser(); + UpdateNetworkList(empty_list_); + EXPECT_EQ(nullptr, GetMobileSubHeader()); + + // Add tether networks + AddTetherNetworkState(); + EXPECT_NE(nullptr, GetMobileSubHeader()); +} + +TEST_F(NetworkListViewControllerTest, MobileSectionHeaderAddEsimButtonStates) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndDisableFeature(ash::features::kESimPolicy); + EXPECT_EQ(nullptr, GetMobileSubHeader()); + EXPECT_EQ(nullptr, GetMobileStatusMessage()); + + SetupCellular(); + EXPECT_NE(nullptr, GetMobileSubHeader()); + EXPECT_TRUE(GetMobileSubHeader()->is_add_esim_enabled()); + + // Since no Euicc was added, this means device is not eSIM capable, do not + // show add eSIM button. + EXPECT_FALSE(GetMobileSubHeader()->is_add_esim_visible()); + + AddEuicc(); + UpdateNetworkList(empty_list_); + + EXPECT_TRUE(GetMobileSubHeader()->is_add_esim_visible()); + EXPECT_EQ(nullptr, GetMobileSeparator()); + EXPECT_NE(nullptr, GetMobileStatusMessage()); + + // Add eSIM button is not enabled when inhibited. + std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock = + InhibitCellularScanning(); + EXPECT_TRUE(inhibit_lock); + base::RunLoop().RunUntilIdle(); + + EXPECT_FALSE(GetMobileSubHeader()->is_add_esim_enabled()); + EXPECT_TRUE(GetMobileSubHeader()->is_add_esim_visible()); + + // Uninhibit the device. + inhibit_lock.reset(); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(GetMobileSubHeader()->is_add_esim_enabled()); + EXPECT_TRUE(GetMobileSubHeader()->is_add_esim_visible()); + + // When no Mobile networks are available and eSIM policy is set to allow only + // cellular devices which means adding a new eSIM is disallowed by enterprise + // policy, add eSIM button is not displayed. + SetGlobalPolicyConfig(/*allow_only_policy=*/true); + scoped_feature_list.Reset(); + scoped_feature_list.InitAndEnableFeature(ash::features::kESimPolicy); + UpdateNetworkList(empty_list_); + EXPECT_FALSE(GetMobileSubHeader()->is_add_esim_visible()); +} + +TEST_F(NetworkListViewControllerTest, HasCorrectNetworkList) { + EXPECT_EQ(0u, network_list()->children().size()); + EXPECT_EQ(nullptr, GetMobileSubHeader()); + EXPECT_EQ(nullptr, GetMobileStatusMessage()); + + AddEuicc(); + SetupCellular(); + + CheckNetworkListOrdering(/*mobile_network_count=*/0u); + + std::vector<NetworkStatePropertiesPtr> networks; + + NetworkStatePropertiesPtr cellular_network = + CreateStandaloneNetworkProperties(kCellularName, NetworkType::kCellular, + ConnectionStateType::kConnected); + networks.push_back(std::move(cellular_network)); + UpdateNetworkList(networks); + + CheckNetworkListOrdering(/*mobile_network_count=*/1u); + CheckNetworkListItem(/*index=*/1u, /*guid=*/kCellularName); + + cellular_network = CreateStandaloneNetworkProperties( + kCellularName2, NetworkType::kCellular, ConnectionStateType::kConnected); + networks.push_back(std::move(cellular_network)); + UpdateNetworkList(networks); + + CheckNetworkListOrdering(/*mobile_network_count=*/2u); + CheckNetworkListItem(/*index=*/2u, /*guid=*/kCellularName2); + + // Update a network and make sure it is still in network list. + networks.front()->connection_state = ConnectionStateType::kNotConnected; + UpdateNetworkList(networks); + + CheckNetworkListOrdering(/*mobile_network_count=*/2u); + CheckNetworkListItem(/*index=*/1u, /*guid=*/kCellularName); + CheckNetworkListItem(/*index=*/2u, /*guid=*/kCellularName2); + + // Remove all networks and add Tether networks. Only one network should be in + // list. + networks.clear(); + NetworkStatePropertiesPtr tether_network = CreateStandaloneNetworkProperties( + kTetherName, NetworkType::kTether, ConnectionStateType::kConnected); + networks.push_back(std::move(tether_network)); + UpdateNetworkList(networks); + + CheckNetworkListOrdering(/*mobile_network_count=*/1u); + CheckNetworkListItem(/*index=*/1u, /*guid=*/kTetherName); +} + +TEST_F(NetworkListViewControllerTest, + CellularStatusMessageAndToggleButtonState) { + EXPECT_EQ(nullptr, GetMobileStatusMessage()); + + AddEuicc(); + SetupCellular(); + + // Update cellular device state to be Uninitialized. + network_state_helper()->manager_test()->SetTechnologyInitializing( + shill::kTypeCellular, /*initializing=*/true); + base::RunLoop().RunUntilIdle(); + + EXPECT_NE(nullptr, GetMobileStatusMessage()); + EXPECT_FALSE(GetToggleButton()->GetVisible()); + EXPECT_EQ( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_INITIALIZING_CELLULAR), + GetMobileStatusMessage()->label()->GetText()); + + network_state_helper()->manager_test()->SetTechnologyInitializing( + shill::kTypeCellular, /*initializing=*/false); + base::RunLoop().RunUntilIdle(); + + SetupCellular(); + EXPECT_NE(nullptr, GetMobileStatusMessage()); + EXPECT_NE(nullptr, GetMobileSubHeader()); + EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NO_MOBILE_NETWORKS), + GetMobileStatusMessage()->label()->GetText()); + EXPECT_TRUE(GetMobileSubHeader()->is_toggle_enabled()); + EXPECT_TRUE(GetMobileSubHeader()->is_toggle_on()); + EXPECT_TRUE(GetToggleButton()->GetVisible()); + + // No message is shown when there are available networks. + std::vector<NetworkStatePropertiesPtr> networks; + networks.push_back(CreateStandaloneNetworkProperties( + kCellularName, NetworkType::kCellular, ConnectionStateType::kConnected)); + UpdateNetworkList(networks); + EXPECT_EQ(nullptr, GetMobileStatusMessage()); + EXPECT_TRUE(GetMobileSubHeader()->is_toggle_enabled()); + EXPECT_TRUE(GetMobileSubHeader()->is_toggle_on()); + EXPECT_TRUE(GetToggleButton()->GetVisible()); + + // Message shown again when list is empty. + UpdateNetworkList(empty_list_); + EXPECT_NE(nullptr, GetMobileStatusMessage()); + EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NO_MOBILE_NETWORKS), + GetMobileStatusMessage()->label()->GetText()); + EXPECT_TRUE(GetToggleButton()->GetVisible()); + + // No message is shown when inhibited. + std::unique_ptr<CellularInhibitor::InhibitLock> inhibit_lock = + InhibitCellularScanning(); + EXPECT_TRUE(inhibit_lock); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(nullptr, GetMobileStatusMessage()); + EXPECT_FALSE(GetMobileSubHeader()->is_toggle_enabled()); + EXPECT_TRUE(GetMobileSubHeader()->is_toggle_on()); + EXPECT_TRUE(GetToggleButton()->GetVisible()); + + // Uninhibit the device. + inhibit_lock.reset(); + base::RunLoop().RunUntilIdle(); + + // Message is shown when uninhibited. + EXPECT_NE(nullptr, GetMobileStatusMessage()); + EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NO_MOBILE_NETWORKS), + GetMobileStatusMessage()->label()->GetText()); + EXPECT_TRUE(GetMobileSubHeader()->is_toggle_enabled()); + EXPECT_TRUE(GetMobileSubHeader()->is_toggle_on()); + EXPECT_TRUE(GetToggleButton()->GetVisible()); + + // When device is in disabling message is shown. + network_state_helper()->manager_test()->SetInteractiveDelay( + kInteractiveDelay); + network_state_handler()->SetTechnologyEnabled( + chromeos::NetworkTypePattern::Cellular(), /*enabled=*/false, + base::DoNothing()); + + base::RunLoop().RunUntilIdle(); + + EXPECT_NE(nullptr, GetMobileStatusMessage()); + EXPECT_EQ( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_MOBILE_DISABLING), + GetMobileStatusMessage()->label()->GetText()); + EXPECT_FALSE(GetMobileSubHeader()->is_toggle_enabled()); + EXPECT_FALSE(GetMobileSubHeader()->is_toggle_on()); + EXPECT_TRUE(GetToggleButton()->GetVisible()); + task_environment()->FastForwardBy(kInteractiveDelay); + + // Message is shown when device is disabled. + EXPECT_NE(nullptr, GetMobileStatusMessage()); + EXPECT_EQ( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_MOBILE_DISABLED), + GetMobileStatusMessage()->label()->GetText()); + EXPECT_TRUE(GetMobileSubHeader()->is_toggle_enabled()); + EXPECT_FALSE(GetMobileSubHeader()->is_toggle_on()); + EXPECT_TRUE(GetToggleButton()->GetVisible()); +} + +TEST_F(NetworkListViewControllerTest, HasCorrectTetherStatusMessage) { + // Mobile section is not shown if Tether network is unavailable. + EXPECT_EQ(nullptr, GetMobileStatusMessage()); + + // Tether is enabled but no devices are added. + network_state_handler()->SetTetherTechnologyState( + chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED); + base::RunLoop().RunUntilIdle(); + + EXPECT_NE(nullptr, GetMobileStatusMessage()); + EXPECT_NE(nullptr, GetMobileSubHeader()); + EXPECT_TRUE(GetMobileSubHeader()->is_toggle_enabled()); + EXPECT_TRUE(GetMobileSubHeader()->is_toggle_on()); + EXPECT_EQ( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NO_MOBILE_DEVICES_FOUND), + GetMobileStatusMessage()->label()->GetText()); + + // Tether network is uninitialized and Bluetooth state enabling. + network_state_handler()->SetTetherTechnologyState( + chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNINITIALIZED); + base::RunLoop().RunUntilIdle(); + + SetBluetoothAdapterState(BluetoothSystemState::kEnabling); + EXPECT_FALSE(GetMobileSubHeader()->is_toggle_enabled()); + EXPECT_TRUE(GetMobileSubHeader()->is_toggle_on()); + EXPECT_NE(nullptr, GetMobileStatusMessage()); + EXPECT_EQ( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_INITIALIZING_CELLULAR), + GetMobileStatusMessage()->label()->GetText()); + + // Set Bluetooth device to disabling. + SetBluetoothAdapterState(BluetoothSystemState::kDisabling); + EXPECT_TRUE(GetMobileSubHeader()->is_toggle_enabled()); + EXPECT_FALSE(GetMobileSubHeader()->is_toggle_on()); + EXPECT_NE(nullptr, GetMobileStatusMessage()); + EXPECT_EQ(l10n_util::GetStringUTF16( + IDS_ASH_STATUS_TRAY_ENABLING_MOBILE_ENABLES_BLUETOOTH), + GetMobileStatusMessage()->label()->GetText()); + + // Simulate login as secondary user and disable Bluetooth device. + LoginAsSecondaryUser(); + SetBluetoothAdapterState(BluetoothSystemState::kDisabled); + EXPECT_FALSE(GetMobileSubHeader()->is_toggle_enabled()); + EXPECT_FALSE(GetMobileSubHeader()->is_toggle_on()); + EXPECT_NE(nullptr, GetMobileStatusMessage()); + EXPECT_EQ(l10n_util::GetStringUTF16( + IDS_ASH_STATUS_TRAY_ENABLING_MOBILE_ENABLES_BLUETOOTH), + GetMobileStatusMessage()->label()->GetText()); + + // No message shown when Tether devices are added. + AddTetherNetworkState(); + EXPECT_EQ(nullptr, GetMobileStatusMessage()); +} + +TEST_F(NetworkListViewControllerTest, HasConnectionWarning) { + EXPECT_EQ(nullptr, GetConnectionWarning()); + + AddVpnDevice(); + std::vector<NetworkStatePropertiesPtr> networks; + networks.push_back(CreateStandaloneNetworkProperties( + kVpnName, NetworkType::kVPN, ConnectionStateType::kConnected)); + UpdateNetworkList(networks); + + EXPECT_NE(nullptr, GetConnectionWarning()); + EXPECT_NE(nullptr, GetConnectionLabelView()); + EXPECT_EQ( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_NETWORK_MONITORED_WARNING), + GetConnectionLabelView()->GetText()); + EXPECT_EQ(1u, network_list()->children().size()); + EXPECT_EQ(network_list()->children().at(0), GetConnectionWarning()); + + // Clear all devices and make sure warning is no longer being shown. + network_state_helper()->ClearDevices(); + EXPECT_EQ(nullptr, GetConnectionWarning()); } } // namespace ash
diff --git a/ash/system/palette/palette_tool.cc b/ash/system/palette/palette_tool.cc index 42240ab..117674d 100644 --- a/ash/system/palette/palette_tool.cc +++ b/ash/system/palette/palette_tool.cc
@@ -23,10 +23,8 @@ void PaletteTool::RegisterToolInstances(PaletteToolManager* tool_manager) { tool_manager->AddTool(std::make_unique<EnterCaptureMode>(tool_manager)); tool_manager->AddTool(std::make_unique<CreateNoteAction>(tool_manager)); - if (!ash::features::IsDeprecateAssistantStylusFeaturesEnabled() && - assistant::util::IsGoogleDevice()) { + if (assistant::util::IsGoogleDevice()) tool_manager->AddTool(std::make_unique<MetalayerMode>(tool_manager)); - } tool_manager->AddTool(std::make_unique<LaserPointerMode>(tool_manager)); tool_manager->AddTool(std::make_unique<MagnifierMode>(tool_manager)); }
diff --git a/ash/system/palette/tools/metalayer_mode.cc b/ash/system/palette/tools/metalayer_mode.cc index 86fe59e..3222b5372 100644 --- a/ash/system/palette/tools/metalayer_mode.cc +++ b/ash/system/palette/tools/metalayer_mode.cc
@@ -8,6 +8,7 @@ #include "ash/public/cpp/system/toast_catalog.h" #include "ash/public/cpp/system/toast_data.h" #include "ash/resources/vector_icons/vector_icons.h" +#include "ash/session/session_controller_impl.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" #include "ash/style/ash_color_provider.h" @@ -18,6 +19,7 @@ #include "ash/system/tray/tray_constants.h" #include "ash/system/tray/tray_popup_utils.h" #include "base/bind.h" +#include "chromeos/services/assistant/public/cpp/assistant_prefs.h" #include "ui/base/l10n/l10n_util.h" #include "ui/events/event.h" #include "ui/gfx/paint_vector_icon.h" @@ -32,10 +34,19 @@ const char kToastId[] = "palette_metalayer_mode"; +// Toast ID for toast that shows for long press stylus actions when metalayer +// mode is deprecated. +const char kDeprecateAssistantStylusToastId[] = "deprecate_assistant_stylus"; + // If the last stroke happened within this amount of time, // assume writing/sketching usage. const int kMaxStrokeGapWhenWritingMs = 1000; +// Returns the last active user pref service. +PrefService* GetPrefs() { + return Shell::Get()->session_controller()->GetLastActiveUserPrefService(); +} + } // namespace MetalayerMode::MetalayerMode(Delegate* delegate) : CommonPaletteTool(delegate) { @@ -93,6 +104,9 @@ } views::View* MetalayerMode::CreateView() { + if (ash::features::IsDeprecateAssistantStylusFeaturesEnabled()) + return nullptr; + views::View* view = CreateDefaultView(std::u16string()); UpdateView(); return view; @@ -134,6 +148,30 @@ if (palette_utils::PaletteContainsPointInScreen(event->root_location())) return; + // Assistant stylus features are in the process of being deprecated. + // After deprecation, which is currently gated by a feature flag, long + // press stylus events will not trigger the metalayer mode. + if (ash::features::IsDeprecateAssistantStylusFeaturesEnabled()) { + // Only show the toast once when the metalayer is triggered for the first + // time. + if (!GetPrefs()->GetBoolean( + chromeos::assistant::prefs::kAssistantDeprecateStylusToast)) { + // Set the deprecate stylus toast assistant pref so that the toast doesn't + // repeatedly show. + GetPrefs()->SetBoolean( + chromeos::assistant::prefs::kAssistantDeprecateStylusToast, true); + Shell::Get()->toast_manager()->Show( + ToastData(kDeprecateAssistantStylusToastId, + ToastCatalogName::kDeprecateAssistantStylus, + l10n_util::GetStringUTF16( + IDS_ASH_STYLUS_TOOLS_METALAYER_TOAST_DEPRECATE), + ToastData::kDefaultToastDuration, + /*visible_on_lock_screen=*/false, + /*has_dismiss_button=*/true)); + } + return; + } + if (loading()) { // Repetitive presses will create toasts with the same id which will be // ignored.
diff --git a/ash/system/unified/unified_system_tray_controller.cc b/ash/system/unified/unified_system_tray_controller.cc index 3b3099af..87d71d0 100644 --- a/ash/system/unified/unified_system_tray_controller.cc +++ b/ash/system/unified/unified_system_tray_controller.cc
@@ -354,7 +354,8 @@ base::RecordAction(base::UserMetricsAction("StatusArea_Network_Detailed")); - if (ash::features::IsQuickSettingsNetworkRevampEnabled()) { + if (ash::features::IsQuickSettingsNetworkRevampEnabled() && + ash::features::IsBluetoothRevampEnabled()) { ShowDetailedView(std::make_unique<NetworkDetailedViewController>(this)); } else { ShowDetailedView(
diff --git a/ash/webui/os_feedback_ui/os_feedback_ui.cc b/ash/webui/os_feedback_ui/os_feedback_ui.cc index 3f1646b5..573a2b55 100644 --- a/ash/webui/os_feedback_ui/os_feedback_ui.cc +++ b/ash/webui/os_feedback_ui/os_feedback_ui.cc
@@ -42,6 +42,7 @@ void AddLocalizedStrings(content::WebUIDataSource* source) { static constexpr webui::LocalizedString kLocalizedStrings[] = { {"continueButtonLabel", IDS_FEEDBACK_TOOL_CONTINUE_BUTTON_LABEL}, + {"descriptionHint", IDS_FEEDBACK_TOOL_DESCRIPTION_HINT}, {"descriptionLabel", IDS_FEEDBACK_TOOL_DESCRIPTION_LABEL}, {"descriptionRequired", IDS_FEEDBACK_TOOL_DESCRIPTION_REQUIRED}, {"feedbackHelpLinkLabel", IDS_FEEDBACK_TOOL_FEEDBACK_HELP_LINK_LABEL},
diff --git a/ash/webui/os_feedback_ui/resources/search_page.html b/ash/webui/os_feedback_ui/resources/search_page.html index 7e6821d..b8bf53ab 100644 --- a/ash/webui/os_feedback_ui/resources/search_page.html +++ b/ash/webui/os_feedback_ui/resources/search_page.html
@@ -42,7 +42,7 @@ </a> </div> <textarea id="descriptionText" aria-labelledby="descriptionTitle" - aria-required="true" on-input="handleInputChanged_"> + aria-required="true" on-input="handleInputChanged_" placeholder="[[i18n('descriptionHint')]]"> </textarea> <p id="descriptionEmptyError" aria-hidden="true" hidden> [[i18n('descriptionRequired')]]
diff --git a/ash/webui/personalization_app/resources/BUILD.gn b/ash/webui/personalization_app/resources/BUILD.gn index 4c2ef63..156df15 100644 --- a/ash/webui/personalization_app/resources/BUILD.gn +++ b/ash/webui/personalization_app/resources/BUILD.gn
@@ -6,7 +6,7 @@ import("//chrome/browser/resources/tools/optimize_webui.gni") import("//third_party/closure_compiler/compile_js.gni") import("//tools/grit/preprocess_if_expr.gni") -import("//tools/polymer/html_to_js.gni") +import("//tools/polymer/css_to_wrapper.gni") import("//tools/polymer/html_to_wrapper.gni") import("//tools/typescript/ts_library.gni") import("//ui/webui/resources/tools/generate_grd.gni") @@ -18,7 +18,7 @@ # When adding a new file to personalization app, add it to one of the lists # below. `non_web_component_files` are plain ts files, `web_component_files` are -# polymer based ts files, `css_wrapper_files` are css related ts files, +# polymer based ts files, `css_wrapper_files` are Polymer css files, # `static_resource_files` are non-js files, e.g. image, html, css non_web_component_files = [ "common/constants.ts", @@ -122,22 +122,30 @@ html_files += [ string_replace(f, ".ts", ".html") ] } +icons_html_files = [ "common/icons.html" ] + # Files that are generated by html_to_wrapper(). html_wrapper_files = [] -foreach(f, html_files) { +foreach(f, html_files + icons_html_files) { html_wrapper_files += [ f + ".ts" ] } ts_files = web_component_files + non_web_component_files -css_wrapper_files = [ - "common/icons.ts", - "common/styles.ts", +# Files that are passed as input to css_to_wrapper(). +css_files = [ + "common/common_style.css", - "trusted/cros_button_style.ts", - "trusted/wallpaper/styles.ts", + "trusted/cros_button_style.css", + "trusted/wallpaper/trusted_style.css", ] +# Files that are generated by css_to_wrapper(). +css_wrapper_files = [] +foreach(f, css_files) { + css_wrapper_files += [ f + ".ts" ] +} + static_resource_files = [ "hub_icon_64.png", "hub_icon_128.png", @@ -159,12 +167,12 @@ "trusted/index.html", ] -html_to_js("css_wrapper_files") { - js_files = css_wrapper_files +css_to_wrapper("css_wrapper_files") { + in_files = css_files } html_to_wrapper("html_to_wrapper_files") { - in_files = html_files + in_files = html_files + icons_html_files } preprocess_if_expr("preprocess") {
diff --git a/ash/webui/personalization_app/resources/common/common_style.css b/ash/webui/personalization_app/resources/common/common_style.css new file mode 100644 index 0000000..4f922df --- /dev/null +++ b/ash/webui/personalization_app/resources/common/common_style.css
@@ -0,0 +1,355 @@ +/* Copyright 2022 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. */ + +/* #css_wrapper_metadata_start + * #type=style + * #import=chrome://resources/cr_elements/shared_vars_css.m.js + * #css_wrapper_metadata_end */ + +[hidden] { + /* The |hidden| attribute does not hide an element with an explicitly + * specified |display| property. Handle this by forcing display to |none| + * when the |hidden| attribute is present. */ + display: none !important; +} + +:host { + --personalization-app-grid-item-background-color: var(--google-grey-100); + --personalization-app-grid-item-border-radius: 12px; + --personalization-app-grid-item-height: 120px; + --personalization-app-grid-item-spacing: 16px; + + --personalization-app-text-shadow-elevation-1: 0 1px 3px + rgba(0, 0, 0, 15%), 0 1px 2px rgba(0, 0, 0, 30%); + + /* copied from |AshColorProvider| |kSecondToneOpacity| constant. */ + --personalization-app-second-tone-opacity: 0.3; + + --personalization-app-label-font: 500 13px/20px + var(--cros-font-family-google-sans); +} + +@media (prefers-color-scheme: dark) { + :host { + --personalization-app-grid-item-background-color: + rgba(var(--google-grey-700-rgb), 0.3); + } +} + +iron-list { + height: 100%; +} + +.photo-container { + box-sizing: border-box; + height: calc( + var(--personalization-app-grid-item-height) + + var(--personalization-app-grid-item-spacing)); + overflow: hidden; + padding: calc(var(--personalization-app-grid-item-spacing) / 2); + /* Media queries in trusted and untrusted code will resize to 25% at + * correct widths. Subtract 0.34px to fix subpixel rounding issues with + * iron-list. This makes sure all photo containers on a row add up to at + * least 1px smaller than the parent width.*/ + width: calc(100% / 3 - 0.34px); +} + +.photo-container:focus-visible { + outline: none; +} + +/* This extra position: relative element corrects for absolutely positioned + elements ignoring parent interior padding. */ +.photo-inner-container { + align-items: center; + border-radius: var(--personalization-app-grid-item-border-radius); + cursor: pointer; + display: flex; + height: 100%; + justify-content: center; + overflow: hidden; + position: relative; + width: 100%; +} + +@keyframes ripple { + /* 0 ms */ + from { + opacity: 1; + } + /* 200 ms */ + 9% { + opacity: 0.15; + } + /* 350 ms */ + 15.8% { + opacity: 0.15; + } + /* 550 ms, hold for 83ms * 20 and then restart */ + 24.9% { + opacity: 1; + } + /* 2210 ms */ + to { + opacity: 1; + } +} + +.placeholder { + animation: 2210ms linear var(--animation-delay, 1s) infinite ripple; +} + +.photo-inner-container:focus-visible, +.photo-loading-placeholder:focus-visible { + border: 2px solid var(--cros-focus-ring-color); + border-radius: 14px; + outline: none; +} + +.photo-images-container { + background-color: var(--personalization-app-grid-item-background-color); + border: 1px solid rgba(0, 0, 0, 0.08); + border-radius: 12px; + box-sizing: border-box; + display: flex; + flex-flow: row wrap; + height: 100%; + /* stop img and gradient-mask from ignoring above border-radius. */ + overflow: hidden; + position: relative; + width: 100%; +} + +.photo-images-container img { + flex: 1 1 0; + height: 100%; + min-width: 50%; + object-fit: cover; + width: 100%; +} + +.photo-images-container img.left { + clip-path: inset(0 50% 0 0); + position: absolute; +} + +.photo-images-container img.right { + clip-path: inset(0 0 0 50%); + position: absolute; +} + +@keyframes scale-up { + from { + transform: scale(0); + } + to { + transform: scale(1); + } +} + +.photo-container iron-icon[icon='personalization:checkmark'] { + --iron-icon-height: 20px; + --iron-icon-width: 20px; + animation-duration: 200ms; + animation-name: scale-up; + animation-timing-function: cubic-bezier(0.40, 0.00, 0.20, 1.00); + left: 4px; + position: absolute; + top: 4px; +} + +.photo-inner-container:not([aria-selected='true']) +iron-icon[icon='personalization:checkmark'] { + display: none; +} + +.photo-inner-container[aria-selected='true'] { + background-color: rgba(var(--cros-icon-color-prominent-rgb), + var(--personalization-app-second-tone-opacity)); + border-radius: 16px; +} + +@keyframes resize { + 100% { + height: calc(100% - 8px); + width: calc(100% - 8px); + } +} + +.photo-inner-container[aria-selected='true'] .photo-images-container { + animation-duration: 200ms; + animation-fill-mode: forwards; + animation-name: resize; + animation-timing-function: cubic-bezier(0.40, 0.00, 0.20, 1.00); + border: 0; +} + +.photo-inner-container:focus-visible:not([aria-selected='true']) +.photo-images-container { + height: calc(100% - 4px); + width: calc(100% - 4px); +} + +cr-button { + border-color: var(--cros-button-stroke-color-secondary); + border-radius: 16px; +} + +cr-button[aria-pressed=true], +cr-button[aria-selected=true] { + background-color: var(--cros-highlight-color); + border: 0; +} + +cr-button + cr-button { + margin-inline-start: 8px; +} + +.preview-container { + border: 1px solid var(--cros-separator-color); + border-radius: 16px; +} + +.preview-text-container, +.preview-text-placeholder { + align-items: flex-start; + display: flex; + flex-flow: column nowrap; + margin: 0; +} + +.preview-text-container { + justify-content: flex-end; +} + +.preview-text-placeholder { + justify-content: center; +} + +.placeholder { + background-color: var(--personalization-app-grid-item-background-color); + border-radius: 12px; +} + +.preview-image-container { + border: 1px solid rgba(0, 0, 0, 0.08); + border-radius: 12px; + box-sizing: border-box; + overflow: hidden; + position: relative; +} + +.preview-image { + height: 100%; + object-fit: cover; + width: 100%; +} + +.preview-text-container > *, +.preview-text-placeholder > * { + margin: 0; + max-width: 100%; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.preview-text-container > * + * { + margin-top: 4px; +} + +.preview-text-placeholder > * + * { + margin-top: 8px; +} + +.preview-text-container > span:first-child { + color: var(--cros-text-color-secondary); + font: var(--cros-body-2-font); +} + +.preview-text-placeholder > .placeholder:first-child { + /* Each row is 83 ms after the prior element. */ + --animation-delay: calc(1s + 83ms); + width: 20%; + height: 20px; +} + +.preview-text-container > span:nth-child(2) { + color: var(--cros-text-color-primary); + font: var(--cros-display-6-font); +} + +.preview-text-placeholder > .placeholder:nth-child(2) { + --animation-delay: calc(1s + 83ms * 2); + width: 75%; + height: 24px; +} + +.preview-text-container > span:nth-child(n+3) { + color: var(--cros-text-color-secondary); + font: var(--cros-body-1-font); +} + +.preview-text-placeholder > .placeholder:nth-child(n+3) { + --animation-delay: calc(1s + 83ms * 3); + width: 33%; + height: 20px; +} + +.ambient-subpage-element-title { + color: var(--cros-text-color-primary); + font: var(--personalization-app-label-font); + margin: 34px 8px 16px 8px; +} + +.ambient-toggle-row-container { + border: 1px solid var(--cros-separator-color); + border-radius: 8px; + display: flex; + flex-flow: column nowrap; + height: 48px; + width: 100%; +} + +.ambient-toggle-row { + align-items: center; + display: flex; + flex: 1; + flex-flow: row nowrap; + justify-content: space-between; + margin: 0 20px; +} + +.ambient-toggle-row + .ambient-toggle-row { + border-top: 1px solid var(--cros-separator-color); +} + +.ambient-toggle-row > p { + font: var(--cros-body-1-font); + height: 20px; + margin: 0; +} + +.clickable { + cursor: pointer; +} + +paper-tooltip::part(tooltip) { + align-items: flex-end; + display: flex; + flex-direction: row; + height: 18px; + padding: 3px 8px; +} + +paper-tooltip { + --paper-tooltip-background: var(--cros-tooltip-background-color); + --paper-tooltip-text-color: var(--cros-tooltip-label-color); +} + +paper-tooltip span { + align-items: center; + display: flex; + font: var(--cros-body-2-font); +}
diff --git a/ash/webui/personalization_app/resources/common/icons.ts b/ash/webui/personalization_app/resources/common/icons.ts deleted file mode 100644 index 72fade81..0000000 --- a/ash/webui/personalization_app/resources/common/icons.ts +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview Icons specific to personalization app. - * - * These icons should have transparent fill color to adapt to its container's - * light/dark theme. - * - * Following the demo here: - * @see https://github.com/PolymerElements/iron-iconset-svg/blob/v3.0.1/demo/svg-sample-icons.js - */ - -import '//resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js'; - -const template = document.createElement('template'); -template.innerHTML = `{__html_template__}`; -document.head.appendChild(template.content);
diff --git a/ash/webui/personalization_app/resources/common/styles.html b/ash/webui/personalization_app/resources/common/styles.html deleted file mode 100644 index 8871d7a6..0000000 --- a/ash/webui/personalization_app/resources/common/styles.html +++ /dev/null
@@ -1,326 +0,0 @@ -<template> - <style> - [hidden] { - /* The |hidden| attribute does not hide an element with an explicitly - * specified |display| property. Handle this by forcing display to |none| - * when the |hidden| attribute is present. */ - display: none !important; - } - :host { - --personalization-app-grid-item-background-color: var(--google-grey-100); - --personalization-app-grid-item-border-radius: 12px; - --personalization-app-grid-item-height: 120px; - --personalization-app-grid-item-spacing: 16px; - - --personalization-app-text-shadow-elevation-1: 0 1px 3px - rgba(0, 0, 0, 15%), 0 1px 2px rgba(0, 0, 0, 30%); - - /* copied from |AshColorProvider| |kSecondToneOpacity| constant. */ - --personalization-app-second-tone-opacity: 0.3; - - --personalization-app-label-font: 500 13px/20px - var(--cros-font-family-google-sans); - } - @media (prefers-color-scheme: dark) { - :host { - --personalization-app-grid-item-background-color: - rgba(var(--google-grey-700-rgb), 0.3); - } - } - iron-list { - height: 100%; - } - .photo-container { - box-sizing: border-box; - height: calc( - var(--personalization-app-grid-item-height) + - var(--personalization-app-grid-item-spacing)); - overflow: hidden; - padding: calc(var(--personalization-app-grid-item-spacing) / 2); - /* Media queries in trusted and untrusted code will resize to 25% at - * correct widths. Subtract 0.34px to fix subpixel rounding issues with - * iron-list. This makes sure all photo containers on a row add up to at - * least 1px smaller than the parent width.*/ - width: calc(100% / 3 - 0.34px); - } - .photo-container:focus-visible { - outline: none; - } - /* This extra position: relative element corrects for absolutely positioned - elements ignoring parent interior padding. */ - .photo-inner-container { - align-items: center; - border-radius: var(--personalization-app-grid-item-border-radius); - cursor: pointer; - display: flex; - height: 100%; - justify-content: center; - overflow: hidden; - position: relative; - width: 100%; - } - @keyframes ripple { - /* 0 ms */ - from { - opacity: 1; - } - /* 200 ms */ - 9% { - opacity: 0.15; - } - /* 350 ms */ - 15.8% { - opacity: 0.15; - } - /* 550 ms, hold for 83ms * 20 and then restart */ - 24.9% { - opacity: 1; - } - /* 2210 ms */ - to { - opacity: 1; - } - } - .placeholder { - animation: 2210ms linear var(--animation-delay, 1s) infinite ripple; - } - .photo-inner-container:focus-visible, - .photo-loading-placeholder:focus-visible { - border: 2px solid var(--cros-focus-ring-color); - border-radius: 14px; - outline: none; - } - .photo-images-container { - background-color: var(--personalization-app-grid-item-background-color); - border: 1px solid rgba(0, 0, 0, 0.08); - border-radius: 12px; - box-sizing: border-box; - display: flex; - flex-flow: row wrap; - height: 100%; - /* stop img and gradient-mask from ignoring above border-radius. */ - overflow: hidden; - position: relative; - width: 100%; - } - .photo-images-container img { - flex: 1 1 0; - height: 100%; - min-width: 50%; - object-fit: cover; - width: 100%; - } - .photo-images-container img.left { - clip-path: inset(0 50% 0 0); - position: absolute; - } - .photo-images-container img.right { - clip-path: inset(0 0 0 50%); - position: absolute; - } - @keyframes scale-up { - from { - transform: scale(0); - } - to { - transform: scale(1); - } - } - .photo-container iron-icon[icon='personalization:checkmark'] { - --iron-icon-height: 20px; - --iron-icon-width: 20px; - animation-duration: 200ms; - animation-name: scale-up; - animation-timing-function: cubic-bezier(0.40, 0.00, 0.20, 1.00); - left: 4px; - position: absolute; - top: 4px; - } - .photo-inner-container:not([aria-selected='true']) - iron-icon[icon='personalization:checkmark'] { - display: none; - } - .photo-inner-container[aria-selected='true'] { - background-color: rgba(var(--cros-icon-color-prominent-rgb), - var(--personalization-app-second-tone-opacity)); - border-radius: 16px; - } - @keyframes resize { - 100% { - height: calc(100% - 8px); - width: calc(100% - 8px); - } - } - .photo-inner-container[aria-selected='true'] .photo-images-container { - animation-duration: 200ms; - animation-fill-mode: forwards; - animation-name: resize; - animation-timing-function: cubic-bezier(0.40, 0.00, 0.20, 1.00); - border: 0; - } - .photo-inner-container:focus-visible:not([aria-selected='true']) - .photo-images-container { - height: calc(100% - 4px); - width: calc(100% - 4px); - } - cr-button { - border-color: var(--cros-button-stroke-color-secondary); - border-radius: 16px; - } - cr-button[aria-pressed=true], - cr-button[aria-selected=true] { - background-color: var(--cros-highlight-color); - border: 0; - } - cr-button + cr-button { - margin-inline-start: 8px; - } - .preview-container { - border: 1px solid var(--cros-separator-color); - border-radius: 16px; - } - - .preview-text-container, - .preview-text-placeholder { - align-items: flex-start; - display: flex; - flex-flow: column nowrap; - margin: 0; - } - - .preview-text-container { - justify-content: flex-end; - } - - .preview-text-placeholder { - justify-content: center; - } - - .placeholder { - background-color: var(--personalization-app-grid-item-background-color); - border-radius: 12px; - } - - .preview-image-container { - border: 1px solid rgba(0, 0, 0, 0.08); - border-radius: 12px; - box-sizing: border-box; - overflow: hidden; - position: relative; - } - - .preview-image { - height: 100%; - object-fit: cover; - width: 100%; - } - - .preview-text-container > *, - .preview-text-placeholder > * { - margin: 0; - max-width: 100%; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - - .preview-text-container > * + * { - margin-top: 4px; - } - - .preview-text-placeholder > * + * { - margin-top: 8px; - } - - .preview-text-container > span:first-child { - color: var(--cros-text-color-secondary); - font: var(--cros-body-2-font); - } - - .preview-text-placeholder > .placeholder:first-child { - /* Each row is 83 ms after the prior element. */ - --animation-delay: calc(1s + 83ms); - width: 20%; - height: 20px; - } - - .preview-text-container > span:nth-child(2) { - color: var(--cros-text-color-primary); - font: var(--cros-display-6-font); - } - - .preview-text-placeholder > .placeholder:nth-child(2) { - --animation-delay: calc(1s + 83ms * 2); - width: 75%; - height: 24px; - } - - .preview-text-container > span:nth-child(n+3) { - color: var(--cros-text-color-secondary); - font: var(--cros-body-1-font); - } - - .preview-text-placeholder > .placeholder:nth-child(n+3) { - --animation-delay: calc(1s + 83ms * 3); - width: 33%; - height: 20px; - } - - .ambient-subpage-element-title { - color: var(--cros-text-color-primary); - font: var(--personalization-app-label-font); - margin: 34px 8px 16px 8px; - } - - .ambient-toggle-row-container { - border: 1px solid var(--cros-separator-color); - border-radius: 8px; - display: flex; - flex-flow: column nowrap; - height: 48px; - width: 100%; - } - - .ambient-toggle-row { - align-items: center; - display: flex; - flex: 1; - flex-flow: row nowrap; - justify-content: space-between; - margin: 0 20px; - } - - .ambient-toggle-row + .ambient-toggle-row { - border-top: 1px solid var(--cros-separator-color); - } - - .ambient-toggle-row > p { - font: var(--cros-body-1-font); - height: 20px; - margin: 0; - } - - .clickable { - cursor: pointer; - } - - paper-tooltip::part(tooltip) { - align-items: flex-end; - display: flex; - flex-direction: row; - height: 18px; - padding: 3px 8px; - } - - paper-tooltip { - --paper-tooltip-background: var(--cros-tooltip-background-color); - --paper-tooltip-text-color: var(--cros-tooltip-label-color); - } - - paper-tooltip span { - align-items: center; - display: flex; - font: var(--cros-body-2-font); - } - </style> -</template>
diff --git a/ash/webui/personalization_app/resources/common/styles.ts b/ash/webui/personalization_app/resources/common/styles.ts deleted file mode 100644 index 9d40053..0000000 --- a/ash/webui/personalization_app/resources/common/styles.ts +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview Common styles for polymer components in both trusted and - * untrusted code. - */ - -// Force tsc to consider this file a module. -export {}; - -const template = document.createElement('dom-module'); -template.innerHTML = `{__html_template__}`; -template.register('common-style');
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/album_list_element.ts b/ash/webui/personalization_app/resources/trusted/ambient/album_list_element.ts index 5782bfa7..9f975da1 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/album_list_element.ts +++ b/ash/webui/personalization_app/resources/trusted/ambient/album_list_element.ts
@@ -7,7 +7,7 @@ */ import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js'; -import '../../common/styles.js'; +import '../../common/common_style.css.js'; import {IronListElement} from 'chrome://resources/polymer/v3_0/iron-list/iron-list.js'; import {afterNextRender} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -16,6 +16,7 @@ import {AmbientModeAlbum, TopicSource} from '../personalization_app.mojom-webui.js'; import {WithPersonalizationStore} from '../personalization_store.js'; import {isRecentHighlightsAlbum} from '../utils.js'; + import {getTemplate} from './album_list_element.html.js'; export interface AlbumList {
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/albums_subpage_element.ts b/ash/webui/personalization_app/resources/trusted/ambient/albums_subpage_element.ts index ee5878e..2f251d3648 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/albums_subpage_element.ts +++ b/ash/webui/personalization_app/resources/trusted/ambient/albums_subpage_element.ts
@@ -12,7 +12,7 @@ import 'chrome://resources/cr_elements/shared_vars_css.m.js'; import './album_list_element.js'; import './art_album_dialog_element.js'; -import '../../common/styles.js'; +import '../../common/common_style.css.js'; import {assert} from 'chrome://resources/js/assert.m.js';
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.ts b/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.ts index 6150379f..33ef4cac 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.ts +++ b/ash/webui/personalization_app/resources/trusted/ambient/ambient_preview_element.ts
@@ -10,11 +10,12 @@ import 'chrome://resources/cr_elements/cr_auto_img/cr_auto_img.js'; import 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import 'chrome://resources/polymer/v3_0/paper-tooltip/paper-tooltip.js'; -import '../../common/styles.js'; -import '../cros_button_style.js'; +import '../../common/common_style.css.js'; +import '../cros_button_style.css.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js'; + import {isNonEmptyArray} from '../../common/utils.js'; import {AmbientModeAlbum, TopicSource} from '../personalization_app.mojom-webui.js'; import {logAmbientModeOptInUMA} from '../personalization_metrics_logger.js';
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/ambient_subpage_element.ts b/ash/webui/personalization_app/resources/trusted/ambient/ambient_subpage_element.ts index ffe5421..9add348 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/ambient_subpage_element.ts +++ b/ash/webui/personalization_app/resources/trusted/ambient/ambient_subpage_element.ts
@@ -7,7 +7,7 @@ * the ambient mode settings. */ -import '../../common/styles.js'; +import '../../common/common_style.css.js'; import './albums_subpage_element.js'; import './ambient_weather_element.js'; import './ambient_preview_element.js';
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/ambient_weather_element.ts b/ash/webui/personalization_app/resources/trusted/ambient/ambient_weather_element.ts index 1a5cd474..1665ceb 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/ambient_weather_element.ts +++ b/ash/webui/personalization_app/resources/trusted/ambient/ambient_weather_element.ts
@@ -7,7 +7,7 @@ * behaviors similar to a radio button group, e.g. single selection. */ -import '../../common/styles.js'; +import '../../common/common_style.css.js'; import 'chrome://resources/cr_elements/cr_radio_button/cr_radio_button.m.js'; import 'chrome://resources/cr_elements/cr_radio_group/cr_radio_group.m.js'; import 'chrome://resources/cr_elements/shared_style_css.m.js';
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/animation_theme_item_element.ts b/ash/webui/personalization_app/resources/trusted/ambient/animation_theme_item_element.ts index c7fff7d..91366c1 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/animation_theme_item_element.ts +++ b/ash/webui/personalization_app/resources/trusted/ambient/animation_theme_item_element.ts
@@ -6,7 +6,7 @@ * @fileoverview The element for displaying an animation theme. */ -import '../../common/styles.js'; +import '../../common/common_style.css.js'; import 'chrome://resources/cr_elements/cr_auto_img/cr_auto_img.js'; import 'chrome://resources/cr_elements/shared_vars_css.m.js';
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/animation_theme_list_element.ts b/ash/webui/personalization_app/resources/trusted/ambient/animation_theme_list_element.ts index ef3b0952..a78ab87 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/animation_theme_list_element.ts +++ b/ash/webui/personalization_app/resources/trusted/ambient/animation_theme_list_element.ts
@@ -6,7 +6,7 @@ * @fileoverview The element for displaying a list of animation themes. */ import './animation_theme_item_element.js'; -import '../../common/styles.js'; +import '../../common/common_style.css.js'; import {AnimationTheme} from '../personalization_app.mojom-webui.js'; import {WithPersonalizationStore} from '../personalization_store.js';
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/toggle_row_element.ts b/ash/webui/personalization_app/resources/trusted/ambient/toggle_row_element.ts index 9ef47a4..5968268 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/toggle_row_element.ts +++ b/ash/webui/personalization_app/resources/trusted/ambient/toggle_row_element.ts
@@ -6,7 +6,7 @@ * @fileoverview This component displays a description text and a toggle button. */ -import '../../common/styles.js'; +import '../../common/common_style.css.js'; import 'chrome://resources/cr_elements/cr_toggle/cr_toggle.m.js'; import {CrToggleElement} from 'chrome://resources/cr_elements/cr_toggle/cr_toggle.m.js';
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/topic_source_list_element.ts b/ash/webui/personalization_app/resources/trusted/ambient/topic_source_list_element.ts index 67b9742..953e534 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/topic_source_list_element.ts +++ b/ash/webui/personalization_app/resources/trusted/ambient/topic_source_list_element.ts
@@ -7,7 +7,7 @@ * behaviors similar to a radio button group, e.g. single selection. */ -import '../../common/styles.js'; +import '../../common/common_style.css.js'; import './topic_source_item_element.js'; import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js';
diff --git a/ash/webui/personalization_app/resources/trusted/ambient/zero_state_element.ts b/ash/webui/personalization_app/resources/trusted/ambient/zero_state_element.ts index bd456cc1..345173e 100644 --- a/ash/webui/personalization_app/resources/trusted/ambient/zero_state_element.ts +++ b/ash/webui/personalization_app/resources/trusted/ambient/zero_state_element.ts
@@ -6,7 +6,7 @@ * @fileoverview Polymer element that displays the Ambient zero state. */ -import '../../common/styles.js'; +import '../../common/common_style.css.js'; import 'chrome://resources/polymer/v3_0/iron-media-query/iron-media-query.js'; import {WithPersonalizationStore} from '../personalization_store.js';
diff --git a/ash/webui/personalization_app/resources/trusted/cros_button_style.css b/ash/webui/personalization_app/resources/trusted/cros_button_style.css new file mode 100644 index 0000000..dd1bb48 --- /dev/null +++ b/ash/webui/personalization_app/resources/trusted/cros_button_style.css
@@ -0,0 +1,74 @@ +/* Copyright 2022 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. */ + +/* #css_wrapper_metadata_start + * #type=style + * #css_wrapper_metadata_end */ + +cr-button.primary { + background-color: var(--cros-button-background-color-primary); + --text-color: var(--cros-button-label-color-primary); + --ink-color: var(--cros-button-ripple-color-primary); + --hover-bg-color: var(--cros-button-background-color-primary-hover-preblended); + --disabled-bg: var(--cros-button-background-color-primary-disabled); + --disabled-text-color: var(--cros-button-label-color-primary-disabled); +} + +cr-button.primary:hover { + background-color: var(--cros-button-background-color-primary-hover-preblended); +} + +cr-button.secondary { + --text-color: var(--cros-button-label-color-secondary); + --border-color: var(--cros-button-stroke-color-secondary); + --ink-color: var(--cros-button-ripple-color-secondary); + --hover-border-color: var(--cros-button-stroke-color-secondary-hover); + --hover-bg-color: var(--cros-button-background-color-secondary-hover); + --disabled-text-color: var(--cros-button-label-color-secondary-disabled); + --disabled-border-color: var(--cros-button-stroke-color-secondary-disabled); +} + +cr-button.secondary:hover { + background-color: var(--cros-button-background-color-secondary-hover); +} + +cr-icon-button:focus-visible, +cr-button:focus-visible { + box-shadow: none; + outline: 2px solid var(--cros-focus-ring-color); +} + +cr-icon-button:hover, +cr-button:hover { + background-color: var(--cros-ripple-color); + box-shadow: none; +} + +cr-button[aria-pressed=true], +cr-button[aria-selected=true] { + background-color: var(--cros-button-background-color-primary) !important; +} + +cr-button[aria-pressed=true] .text, +cr-button[aria-selected=true] .text { + color: var(--cros-button-label-color-primary) !important; +} + +cr-button[aria-pressed=true] iron-icon, +cr-button[aria-selected=true] iron-icon { + --iron-icon-fill-color: var(--cros-button-label-color-primary) !important; +} + +cr-button:focus-visible { + outline: 2px solid var(--cros-focus-ring-color); +} + +iron-icon { + --iron-icon-height: 20px; + --iron-icon-width: 20px; +} + +cr-icon-button { + --cr-icon-button-fill-color: var(--cros-menu-icon-color); +}
diff --git a/ash/webui/personalization_app/resources/trusted/cros_button_style.html b/ash/webui/personalization_app/resources/trusted/cros_button_style.html deleted file mode 100644 index 287b4595..0000000 --- a/ash/webui/personalization_app/resources/trusted/cros_button_style.html +++ /dev/null
@@ -1,70 +0,0 @@ -<template> - <style> - cr-button.primary { - background-color: var(--cros-button-background-color-primary); - --text-color: var(--cros-button-label-color-primary); - --ink-color: var(--cros-button-ripple-color-primary); - --hover-bg-color: var(--cros-button-background-color-primary-hover-preblended); - --disabled-bg: var(--cros-button-background-color-primary-disabled); - --disabled-text-color: var(--cros-button-label-color-primary-disabled); - } - - cr-button.primary:hover { - background-color: var(--cros-button-background-color-primary-hover-preblended); - } - - cr-button.secondary { - --text-color: var(--cros-button-label-color-secondary); - --border-color: var(--cros-button-stroke-color-secondary); - --ink-color: var(--cros-button-ripple-color-secondary); - --hover-border-color: var(--cros-button-stroke-color-secondary-hover); - --hover-bg-color: var(--cros-button-background-color-secondary-hover); - --disabled-text-color: var(--cros-button-label-color-secondary-disabled); - --disabled-border-color: var(--cros-button-stroke-color-secondary-disabled); - } - - cr-button.secondary:hover { - background-color: var(--cros-button-background-color-secondary-hover); - } - - cr-icon-button:focus-visible, - cr-button:focus-visible { - box-shadow: none; - outline: 2px solid var(--cros-focus-ring-color); - } - - cr-icon-button:hover, - cr-button:hover { - background-color: var(--cros-ripple-color); - box-shadow: none; - } - - cr-button[aria-pressed=true], - cr-button[aria-selected=true] { - background-color: var(--cros-button-background-color-primary) !important; - } - - cr-button[aria-pressed=true] .text, - cr-button[aria-selected=true] .text { - color: var(--cros-button-label-color-primary) !important; - } - - cr-button[aria-pressed=true] iron-icon, - cr-button[aria-selected=true] iron-icon { - --iron-icon-fill-color: var(--cros-button-label-color-primary) !important; - } - - cr-button:focus-visible { - outline: 2px solid var(--cros-focus-ring-color); - } - - iron-icon { - --iron-icon-height: 20px; - --iron-icon-width: 20px; - } - - cr-icon-button { - --cr-icon-button-fill-color: var(--cros-menu-icon-color); - } - </style> -</template>
diff --git a/ash/webui/personalization_app/resources/trusted/cros_button_style.ts b/ash/webui/personalization_app/resources/trusted/cros_button_style.ts deleted file mode 100644 index 17aa3c25..0000000 --- a/ash/webui/personalization_app/resources/trusted/cros_button_style.ts +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview Common styles for adapting cr-button with cros colors. - */ - -// Force tsc to consider this file a module. -export {}; - -const template = document.createElement('dom-module'); -template.innerHTML = `{__html_template__}`; -template.register('cros-button-style');
diff --git a/ash/webui/personalization_app/resources/trusted/keyboard_backlight/keyboard_backlight_element.ts b/ash/webui/personalization_app/resources/trusted/keyboard_backlight/keyboard_backlight_element.ts index 9683ca0b..2d1b015 100644 --- a/ash/webui/personalization_app/resources/trusted/keyboard_backlight/keyboard_backlight_element.ts +++ b/ash/webui/personalization_app/resources/trusted/keyboard_backlight/keyboard_backlight_element.ts
@@ -6,8 +6,8 @@ import 'chrome://resources/polymer/v3_0/iron-selector/iron-selector.js'; import 'chrome://resources/polymer/v3_0/paper-ripple/paper-ripple.js'; import 'chrome://resources/polymer/v3_0/paper-tooltip/paper-tooltip.js'; -import '../../common/styles.js'; -import '../cros_button_style.js'; +import '../../common/common_style.css.js'; +import '../cros_button_style.css.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; import {SkColor} from 'chrome://resources/mojo/skia/public/mojom/skcolor.mojom-webui.js';
diff --git a/ash/webui/personalization_app/resources/trusted/personalization_breadcrumb_element.ts b/ash/webui/personalization_app/resources/trusted/personalization_breadcrumb_element.ts index eb97158..67d43de1 100644 --- a/ash/webui/personalization_app/resources/trusted/personalization_breadcrumb_element.ts +++ b/ash/webui/personalization_app/resources/trusted/personalization_breadcrumb_element.ts
@@ -15,8 +15,8 @@ import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; import 'chrome://resources/polymer/v3_0/iron-a11y-keys/iron-a11y-keys.js'; import 'chrome://resources/polymer/v3_0/iron-selector/iron-selector.js'; -import '../common/styles.js'; -import './cros_button_style.js'; +import '../common/common_style.css.js'; +import './cros_button_style.css.js'; import {IronA11yKeysElement} from 'chrome://resources/polymer/v3_0/iron-a11y-keys/iron-a11y-keys.js'; import {IronSelectorElement} from 'chrome://resources/polymer/v3_0/iron-selector/iron-selector.js';
diff --git a/ash/webui/personalization_app/resources/trusted/personalization_main_element.ts b/ash/webui/personalization_app/resources/trusted/personalization_main_element.ts index 6eb752c..c126df5 100644 --- a/ash/webui/personalization_app/resources/trusted/personalization_main_element.ts +++ b/ash/webui/personalization_app/resources/trusted/personalization_main_element.ts
@@ -7,7 +7,7 @@ * the personalization hub. */ -import './cros_button_style.js'; +import './cros_button_style.css.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
diff --git a/ash/webui/personalization_app/resources/trusted/personalization_theme_element.ts b/ash/webui/personalization_app/resources/trusted/personalization_theme_element.ts index 550a775..01793a9 100644 --- a/ash/webui/personalization_app/resources/trusted/personalization_theme_element.ts +++ b/ash/webui/personalization_app/resources/trusted/personalization_theme_element.ts
@@ -11,13 +11,15 @@ import 'chrome://resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js'; import 'chrome://resources/polymer/v3_0/iron-a11y-keys/iron-a11y-keys.js'; import 'chrome://resources/polymer/v3_0/iron-selector/iron-selector.js'; -import '../common/styles.js'; -import './cros_button_style.js'; +import '../common/common_style.css.js'; +import './cros_button_style.css.js'; import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; import {IronA11yKeysElement} from 'chrome://resources/polymer/v3_0/iron-a11y-keys/iron-a11y-keys.js'; import {IronSelectorElement} from 'chrome://resources/polymer/v3_0/iron-selector/iron-selector.js'; + import {isSelectionEvent} from '../common/utils.js'; + import {WithPersonalizationStore} from './personalization_store.js'; import {getTemplate} from './personalization_theme_element.html.js'; import {initializeData, setColorModeAutoSchedule, setColorModePref} from './theme/theme_controller.js';
diff --git a/ash/webui/personalization_app/resources/trusted/user/avatar_camera_element.ts b/ash/webui/personalization_app/resources/trusted/user/avatar_camera_element.ts index 4b3d3c5..07d0af2 100644 --- a/ash/webui/personalization_app/resources/trusted/user/avatar_camera_element.ts +++ b/ash/webui/personalization_app/resources/trusted/user/avatar_camera_element.ts
@@ -10,7 +10,7 @@ import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js'; import 'chrome://resources/polymer/v3_0/paper-spinner/paper-spinner-lite.js'; -import '../cros_button_style.js'; +import '../cros_button_style.css.js'; import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js'; import {assertInstanceof, assertNotReached} from 'chrome://resources/js/assert_ts.js';
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_albums_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_albums_element.ts index a02deaef..1af300e 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_albums_element.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_albums_element.ts
@@ -8,8 +8,8 @@ import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js'; import 'chrome://resources/polymer/v3_0/iron-scroll-threshold/iron-scroll-threshold.js'; -import './styles.js'; -import '../../common/styles.js'; +import './trusted_style.css.js'; +import '../../common/common_style.css.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; import {IronListElement} from 'chrome://resources/polymer/v3_0/iron-list/iron-list.js';
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_collection_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_collection_element.ts index fd5dd1b..320d516 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_collection_element.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_collection_element.ts
@@ -8,8 +8,8 @@ */ import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; -import './styles.js'; -import '../../common/styles.js'; +import './trusted_style.css.js'; +import '../../common/common_style.css.js'; import {assertNotReached} from 'chrome://resources/js/assert_ts.js';
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_photos_by_album_id_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_photos_by_album_id_element.ts index e3d4764a..449a6505 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_photos_by_album_id_element.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_photos_by_album_id_element.ts
@@ -9,8 +9,8 @@ import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js'; import 'chrome://resources/polymer/v3_0/iron-scroll-threshold/iron-scroll-threshold.js'; -import './styles.js'; -import '../../common/styles.js'; +import './trusted_style.css.js'; +import '../../common/common_style.css.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; import {IronListElement} from 'chrome://resources/polymer/v3_0/iron-list/iron-list.js';
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_photos_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_photos_element.ts index 9f7f766..8329bbff 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_photos_element.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_photos_element.ts
@@ -8,8 +8,8 @@ import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js'; import 'chrome://resources/polymer/v3_0/iron-scroll-threshold/iron-scroll-threshold.js'; -import './styles.js'; -import '../../common/styles.js'; +import './trusted_style.css.js'; +import '../../common/common_style.css.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; import {IronListElement} from 'chrome://resources/polymer/v3_0/iron-list/iron-list.js';
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_zero_state_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_zero_state_element.ts index b66d3b5..743dd5f 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_zero_state_element.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/google_photos_zero_state_element.ts
@@ -6,8 +6,8 @@ * @fileoverview Polymer element that displays the Google Photos zero state. */ -import './styles.js'; -import '../../common/styles.js'; +import './trusted_style.css.js'; +import '../../common/common_style.css.js'; import {WithPersonalizationStore} from '../personalization_store.js';
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/index.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/index.ts index 451abd7..774b046 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/index.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/index.ts
@@ -18,7 +18,7 @@ import './wallpaper_subpage_element.js'; import '../../untrusted/collections_grid.js'; import '../../untrusted/images_grid.js'; -import './styles.js'; +import './trusted_style.css.js'; import {WallpaperObserver} from './wallpaper_observer.js';
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/local_images_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/local_images_element.ts index fe09a558..ee25e29 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/local_images_element.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/local_images_element.ts
@@ -11,9 +11,9 @@ import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js'; import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; -import './styles.js'; -import '../../common/icons.js'; -import '../../common/styles.js'; +import './trusted_style.css.js'; +import '../../common/icons.html.js'; +import '../../common/common_style.css.js'; import {assert, assertNotReached} from 'chrome://resources/js/assert.m.js'; import {FilePath} from 'chrome://resources/mojo/mojo/public/mojom/base/file_path.mojom-webui.js';
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/styles.html b/ash/webui/personalization_app/resources/trusted/wallpaper/styles.html deleted file mode 100644 index a29c0ad..0000000 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/styles.html +++ /dev/null
@@ -1,23 +0,0 @@ -<template> - <style> - /* Use !important to make sure there are no css ordering issues. - * Subtract 0.25px to fix subpixel rounding issues with iron-list. This - * makes sure all photo containers on a row add up to at least 1px smaller - * than the parent width.*/ - - @media (min-width: 720px) { - .photo-container { - width: calc(25% - 0.25px) !important; - } - } - main { - height: 100%; - width: 100%; - } - main:focus, - main:focus-visible, - main:focus-within { - outline: none; - } - </style> -</template>
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/styles.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/styles.ts deleted file mode 100644 index 71f34935..0000000 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/styles.ts +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/** - * @fileoverview styles for polymer components in trusted code. - */ - -import 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import 'chrome://resources/cr_elements/chromeos/cros_color_overrides.m.js'; -import 'chrome://resources/cr_elements/shared_vars_css.m.js'; -import 'chrome://resources/polymer/v3_0/paper-styles/color.js'; - -const template = document.createElement('dom-module'); -template.innerHTML = `{__html_template__}`; -template.register('trusted-style');
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/trusted_style.css b/ash/webui/personalization_app/resources/trusted/wallpaper/trusted_style.css new file mode 100644 index 0000000..f2bc1d28 --- /dev/null +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/trusted_style.css
@@ -0,0 +1,32 @@ +/* Copyright 2022 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. */ + +/* #css_wrapper_metadata_start + * #type=style + * import=chrome://resources/cr_elements/chromeos/cros_color_overrides.m.js + * import=chrome://resources/cr_elements/shared_vars_css.m.js + * import=chrome://resources/polymer/v3_0/paper-styles/color.js + * #css_wrapper_metadata_end */ + +/* Use !important to make sure there are no css ordering issues. + * Subtract 0.25px to fix subpixel rounding issues with iron-list. This + * makes sure all photo containers on a row add up to at least 1px smaller + * than the parent width.*/ + +@media (min-width: 720px) { + .photo-container { + width: calc(25% - 0.25px) !important; + } +} + +main { + height: 100%; + width: 100%; +} + +main:focus, +main:focus-visible, +main:focus-within { + outline: none; +}
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_collections_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_collections_element.ts index 912d4b4..56a8112 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_collections_element.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_collections_element.ts
@@ -8,7 +8,7 @@ * objects. */ -import './styles.js'; +import './trusted_style.css.js'; import {FilePath} from 'chrome://resources/mojo/mojo/public/mojom/base/file_path.mojom-webui.js';
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_fullscreen_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_fullscreen_element.ts index ef10e41fc3..fc8d9690 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_fullscreen_element.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_fullscreen_element.ts
@@ -9,7 +9,7 @@ import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; -import '../../common/icons.js'; +import '../../common/icons.html.js'; import {assert} from 'chrome://resources/js/assert_ts.js';
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_grid_item_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_grid_item_element.ts index da9bcae..8a96f134 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_grid_item_element.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_grid_item_element.ts
@@ -7,10 +7,12 @@ */ import 'chrome://resources/cr_elements/cr_auto_img/cr_auto_img.js'; -import '../../common/styles.js'; +import '../../common/common_style.css.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + import {getLoadingPlaceholderAnimationDelay} from '../../common/utils.js'; + import {getTemplate} from './wallpaper_grid_item_element.html.js'; export interface WallpaperGridItem {
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_images_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_images_element.ts index 09f579f..e3efd94 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_images_element.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_images_element.ts
@@ -10,7 +10,7 @@ */ import 'chrome://resources/polymer/v3_0/iron-media-query/iron-media-query.js'; -import './styles.js'; +import './trusted_style.css.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_preview_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_preview_element.ts index 02d5803..16d1ea3 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_preview_element.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_preview_element.ts
@@ -9,10 +9,10 @@ import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; -import '../../common/icons.js'; -import '../../common/styles.js'; -import './styles.js'; -import '../cros_button_style.js'; +import '../../common/icons.html.js'; +import '../../common/common_style.css.js'; +import './trusted_style.css.js'; +import '../cros_button_style.css.js'; import {getLocalStorageAttribution, isNonEmptyArray} from '../../common/utils.js'; import {CurrentWallpaper, WallpaperProviderInterface, WallpaperType} from '../personalization_app.mojom-webui.js';
diff --git a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_selected_element.ts b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_selected_element.ts index 7391297..0ec26b9f 100644 --- a/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_selected_element.ts +++ b/ash/webui/personalization_app/resources/trusted/wallpaper/wallpaper_selected_element.ts
@@ -10,8 +10,8 @@ import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; import 'chrome://resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js'; -import '../../common/icons.js'; -import './styles.js'; +import '../../common/icons.html.js'; +import './trusted_style.css.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
diff --git a/ash/webui/personalization_app/resources/untrusted/collections_grid.ts b/ash/webui/personalization_app/resources/untrusted/collections_grid.ts index 20d7a70..e4a5b6f4 100644 --- a/ash/webui/personalization_app/resources/untrusted/collections_grid.ts +++ b/ash/webui/personalization_app/resources/untrusted/collections_grid.ts
@@ -4,7 +4,7 @@ import '//resources/polymer/v3_0/iron-list/iron-list.js'; import './setup.js'; -import '../trusted/wallpaper/styles.js'; +import '../trusted/wallpaper/trusted_style.css.js'; import {loadTimeData} from '//resources/js/load_time_data.m.js'; import {afterNextRender, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/ash/webui/personalization_app/resources/untrusted/images_grid.ts b/ash/webui/personalization_app/resources/untrusted/images_grid.ts index 17ac993..cbdc3e2 100644 --- a/ash/webui/personalization_app/resources/untrusted/images_grid.ts +++ b/ash/webui/personalization_app/resources/untrusted/images_grid.ts
@@ -5,7 +5,7 @@ import '//resources/cr_elements/cr_auto_img/cr_auto_img.js'; import '//resources/polymer/v3_0/iron-list/iron-list.js'; import './setup.js'; -import '../trusted/wallpaper/styles.js'; +import '../trusted/wallpaper/trusted_style.css.js'; import {assertNotReached} from '//resources/js/assert.m.js'; import {afterNextRender, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
diff --git a/ash/webui/personalization_app/resources/untrusted/setup.ts b/ash/webui/personalization_app/resources/untrusted/setup.ts index 1d218df..4dc1fe8 100644 --- a/ash/webui/personalization_app/resources/untrusted/setup.ts +++ b/ash/webui/personalization_app/resources/untrusted/setup.ts
@@ -11,6 +11,6 @@ // guarantee that polymer and certain polymer elements are loaded first. import '//resources/polymer/v3_0/iron-icon/iron-icon.js'; import '//resources/cr_elements/shared_vars_css.m.js'; -import '../common/icons.js'; -import '../common/styles.js'; +import '../common/icons.html.js'; +import '../common/common_style.css.js'; import '/strings.m.js';
diff --git a/ash/wm/desks/desks_textfield.cc b/ash/wm/desks/desks_textfield.cc index ce2cd11..60abe33 100644 --- a/ash/wm/desks/desks_textfield.cc +++ b/ash/wm/desks/desks_textfield.cc
@@ -86,6 +86,10 @@ return event.key_code() == ui::VKEY_TAB; } +std::u16string DesksTextfield::GetTooltipText(const gfx::Point& p) const { + return GetPreferredSize().width() > width() ? GetText() : std::u16string(); +} + void DesksTextfield::GetAccessibleNodeData(ui::AXNodeData* node_data) { Textfield::GetAccessibleNodeData(node_data); node_data->SetName(GetAccessibleName());
diff --git a/ash/wm/desks/desks_textfield.h b/ash/wm/desks/desks_textfield.h index 1507427d..c57eaa7 100644 --- a/ash/wm/desks/desks_textfield.h +++ b/ash/wm/desks/desks_textfield.h
@@ -38,6 +38,7 @@ gfx::Size CalculatePreferredSize() const override; void SetBorder(std::unique_ptr<views::Border> b) override; bool SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) override; + std::u16string GetTooltipText(const gfx::Point& p) const override; void GetAccessibleNodeData(ui::AXNodeData* node_data) override; void OnMouseEntered(const ui::MouseEvent& event) override; void OnMouseExited(const ui::MouseEvent& event) override;
diff --git a/ash/wm/desks/desks_unittests.cc b/ash/wm/desks/desks_unittests.cc index 9fdb8df..3a726122 100644 --- a/ash/wm/desks/desks_unittests.cc +++ b/ash/wm/desks/desks_unittests.cc
@@ -501,6 +501,36 @@ controller->RemoveObserver(&observer); } +TEST_F(DesksTest, DesksTextfieldAddTooltipText) { + NewDesk(); + + auto* controller = DesksController::Get(); + + // Set the first desk with a name which is short enough to be fit in the desk + // name view. + controller->desks()[0]->SetName(u"test1", /*set_by_user=*/true); + + // Set the second desk with a name which is long enough to be truncated in the + // desk name view. + std::u16string desk_name2( + u"test2 a very long desk name to test tooltip text"); + controller->desks()[1]->SetName(desk_name2, /*set_by_user=*/true); + + // Start overview. + auto* overview_controller = Shell::Get()->overview_controller(); + EnterOverview(); + EXPECT_TRUE(overview_controller->InOverviewSession()); + + // Expect there to be no tooltip when the desk name is short enough. + auto* desks_bar_view = + GetOverviewGridForRoot(Shell::GetPrimaryRootWindow())->desks_bar_view(); + auto* desk_name_view1 = desks_bar_view->mini_views()[0]->desk_name_view(); + EXPECT_TRUE(desk_name_view1->GetTooltipText(gfx::Point()).empty()); + + auto* desk_name_view2 = desks_bar_view->mini_views()[1]->desk_name_view(); + EXPECT_EQ(desk_name2, desk_name_view2->GetTooltipText(gfx::Point())); +} + TEST_F(DesksTest, DesksBarViewDeskCreation) { auto* controller = DesksController::Get();
diff --git a/ash/wm/overview/overview_test_base.cc b/ash/wm/overview/overview_test_base.cc index 61c3f00..ae05f19 100644 --- a/ash/wm/overview/overview_test_base.cc +++ b/ash/wm/overview/overview_test_base.cc
@@ -177,8 +177,8 @@ cache_ = std::make_unique<apps::AppRegistryCache>(); desk_model_ = std::make_unique<desks_storage::LocalDeskDataManager>( user_data_temp_dir_.GetPath(), account_id_); + base::RunLoop().RunUntilIdle(); desk_model_->SetExcludeSaveAndRecallDeskInMaxEntryCountForTesting(false); - desk_model_->EnsureCacheIsLoaded(); desks_storage::desk_template_util::PopulateAppRegistryCache(account_id_, cache_.get()); static_cast<TestDesksTemplatesDelegate*>(
diff --git a/base/BUILD.gn b/base/BUILD.gn index 58e6fcb7..5ad34ee 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -592,6 +592,8 @@ "sampling_heap_profiler/poisson_allocation_sampler.h", "sampling_heap_profiler/sampling_heap_profiler.cc", "sampling_heap_profiler/sampling_heap_profiler.h", + "scoped_add_feature_flags.cc", + "scoped_add_feature_flags.h", "scoped_clear_last_error.h", "scoped_environment_variable_override.cc", "scoped_environment_variable_override.h", @@ -3173,6 +3175,7 @@ "run_loop_unittest.cc", "safe_numerics_unittest.cc", "sampling_heap_profiler/lock_free_address_hash_set_unittest.cc", + "scoped_add_feature_flags_unittest.cc", "scoped_clear_last_error_unittest.cc", "scoped_generic_unittest.cc", "scoped_multi_source_observation_unittest.cc",
diff --git a/base/scoped_add_feature_flags.cc b/base/scoped_add_feature_flags.cc new file mode 100644 index 0000000..ce57399 --- /dev/null +++ b/base/scoped_add_feature_flags.cc
@@ -0,0 +1,88 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/scoped_add_feature_flags.h" + +#include "base/base_switches.h" +#include "base/command_line.h" +#include "base/containers/contains.h" +#include "base/strings/strcat.h" +#include "base/strings/string_util.h" + +namespace base { + +ScopedAddFeatureFlags::ScopedAddFeatureFlags(CommandLine* command_line) + : command_line_(command_line) { + std::string enabled_features = + command_line->GetSwitchValueASCII(switches::kEnableFeatures); + std::string disabled_features = + command_line->GetSwitchValueASCII(switches::kDisableFeatures); + for (const StringPiece& feature : + FeatureList::SplitFeatureListString(enabled_features)) { + enabled_features_.emplace_back(feature); + } + for (const StringPiece& feature : + FeatureList::SplitFeatureListString(disabled_features)) { + disabled_features_.emplace_back(feature); + } +} + +ScopedAddFeatureFlags::~ScopedAddFeatureFlags() { + command_line_->AppendSwitchASCII(switches::kEnableFeatures, + JoinString(enabled_features_, ",")); + command_line_->AppendSwitchASCII(switches::kDisableFeatures, + JoinString(disabled_features_, ",")); +} + +void ScopedAddFeatureFlags::EnableIfNotSet(const Feature& feature) { + AddFeatureIfNotSet(feature, /*suffix=*/"", /*enable=*/true); +} + +void ScopedAddFeatureFlags::EnableIfNotSetWithParameter(const Feature& feature, + StringPiece name, + StringPiece value) { + std::string suffix = StrCat({":", name, "/", value}); + AddFeatureIfNotSet(feature, suffix, true /* enable */); +} + +void ScopedAddFeatureFlags::DisableIfNotSet(const Feature& feature) { + AddFeatureIfNotSet(feature, /*suffix=*/"", /*enable=*/false); +} + +bool ScopedAddFeatureFlags::IsEnabled(const Feature& feature) { + return IsEnabledWithParameter(feature, /*parameter_name=*/"", + /*parameter_value=*/""); +} + +bool ScopedAddFeatureFlags::IsEnabledWithParameter( + const Feature& feature, + StringPiece parameter_name, + StringPiece parameter_value) { + std::string feature_name = feature.name; + if (!parameter_name.empty()) { + StrAppend(&feature_name, {":", parameter_name, "/", parameter_value}); + } + if (Contains(disabled_features_, feature_name)) + return false; + if (Contains(enabled_features_, feature_name)) + return true; + return feature.default_state == FEATURE_ENABLED_BY_DEFAULT; +} + +void ScopedAddFeatureFlags::AddFeatureIfNotSet(const Feature& feature, + StringPiece suffix, + bool enable) { + std::string feature_name = StrCat({feature.name, suffix}); + if (Contains(enabled_features_, feature_name) || + Contains(disabled_features_, feature_name)) { + return; + } + if (enable) { + enabled_features_.emplace_back(feature_name); + } else { + disabled_features_.emplace_back(feature_name); + } +} + +} // namespace base
diff --git a/base/scoped_add_feature_flags.h b/base/scoped_add_feature_flags.h new file mode 100644 index 0000000..e562ad46 --- /dev/null +++ b/base/scoped_add_feature_flags.h
@@ -0,0 +1,62 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_SCOPED_ADD_FEATURE_FLAGS_H_ +#define BASE_SCOPED_ADD_FEATURE_FLAGS_H_ + +#include <string> +#include <vector> + +#include "base/base_export.h" +#include "base/feature_list.h" +#include "base/memory/raw_ptr.h" + +namespace base { + +class CommandLine; + +// Helper class to enable and disable features if they are not already set in +// the command line. It reads the command line on construction, allows user to +// enable and disable features during its lifetime, and writes the modified +// --enable-features=... and --disable-features=... flags back to the command +// line on destruction. +class BASE_EXPORT ScopedAddFeatureFlags { + public: + explicit ScopedAddFeatureFlags(CommandLine* command_line); + + ScopedAddFeatureFlags(const ScopedAddFeatureFlags&) = delete; + ScopedAddFeatureFlags& operator=(const ScopedAddFeatureFlags&) = delete; + + ~ScopedAddFeatureFlags(); + + // Any existing (user set) enable/disable takes precedence. + void EnableIfNotSet(const Feature& feature); + void DisableIfNotSet(const Feature& feature); + void EnableIfNotSetWithParameter(const Feature& feature, + StringPiece name, + StringPiece value); + + // Check if the feature is enabled from command line or functions above + bool IsEnabled(const Feature& feature); + + // Check if the feature with the given parameter name and value is enabled + // from command line or functions above. An empty parameter name means that we + // are checking if the feature is enabled without any parameter. + bool IsEnabledWithParameter(const Feature& feature, + StringPiece parameter_name, + StringPiece parameter_value); + + private: + void AddFeatureIfNotSet(const Feature& feature, + StringPiece suffix, + bool enable); + + const raw_ptr<CommandLine> command_line_; + std::vector<std::string> enabled_features_; + std::vector<std::string> disabled_features_; +}; + +} // namespace base + +#endif // BASE_SCOPED_ADD_FEATURE_FLAGS_H_
diff --git a/android_webview/browser/scoped_add_feature_flags_unittests.cc b/base/scoped_add_feature_flags_unittest.cc similarity index 68% rename from android_webview/browser/scoped_add_feature_flags_unittests.cc rename to base/scoped_add_feature_flags_unittest.cc index 4a05e11d..d105aa2 100644 --- a/android_webview/browser/scoped_add_feature_flags_unittests.cc +++ b/base/scoped_add_feature_flags_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 "android_webview/browser/scoped_add_feature_flags.h" +#include "base/scoped_add_feature_flags.h" #include <string> @@ -11,9 +11,7 @@ #include "base/feature_list.h" #include "testing/gtest/include/gtest/gtest.h" -using base::CommandLine; - -namespace android_webview { +namespace base { TEST(ScopedAddFeatureFlags, ConflictWithExistingFlags) { CommandLine command_line(CommandLine::NO_PROGRAM); @@ -22,14 +20,12 @@ command_line.AppendSwitchASCII(switches::kDisableFeatures, "ExistingDisabledFoo,ExistingDisabledBar"); - const base::Feature kExistingEnabledFoo{"ExistingEnabledFoo", - base::FEATURE_DISABLED_BY_DEFAULT}; - const base::Feature kExistingDisabledFoo{"ExistingDisabledFoo", - base::FEATURE_DISABLED_BY_DEFAULT}; - const base::Feature kEnabledBaz{"EnabledBaz", - base::FEATURE_DISABLED_BY_DEFAULT}; - const base::Feature kDisabledBaz{"DisabledBaz", - base::FEATURE_DISABLED_BY_DEFAULT}; + const Feature kExistingEnabledFoo{"ExistingEnabledFoo", + FEATURE_DISABLED_BY_DEFAULT}; + const Feature kExistingDisabledFoo{"ExistingDisabledFoo", + FEATURE_DISABLED_BY_DEFAULT}; + const Feature kEnabledBaz{"EnabledBaz", FEATURE_DISABLED_BY_DEFAULT}; + const Feature kDisabledBaz{"DisabledBaz", FEATURE_DISABLED_BY_DEFAULT}; { ScopedAddFeatureFlags scoped_add(&command_line); scoped_add.EnableIfNotSet(kExistingEnabledFoo); @@ -50,10 +46,10 @@ CommandLine command_line(CommandLine::NO_PROGRAM); command_line.AppendSwitchASCII(switches::kEnableFeatures, "ExistingEnabledFoo"); - const base::Feature kExistingEnabledFoo{"ExistingEnabledFoo", - base::FEATURE_DISABLED_BY_DEFAULT}; - const base::Feature kFeatureWithParameter{"FeatureWithParam", - base::FEATURE_DISABLED_BY_DEFAULT}; + const Feature kExistingEnabledFoo{"ExistingEnabledFoo", + FEATURE_DISABLED_BY_DEFAULT}; + const Feature kFeatureWithParameter{"FeatureWithParam", + FEATURE_DISABLED_BY_DEFAULT}; { ScopedAddFeatureFlags scoped_add(&command_line); @@ -68,4 +64,4 @@ command_line.GetSwitchValueASCII(switches::kEnableFeatures)); } -} // namespace android_webview +} // namespace base
diff --git a/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc b/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc index a03e0d5..86e99b3 100644 --- a/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc +++ b/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc
@@ -40,7 +40,7 @@ } // Feature to run tasks by batches before pumping out messages. -const Feature kRunTasksByBatches = {"RunThreadControllerTasksByBatches", +const Feature kRunTasksByBatches = {"RunTasksByBatches", base::FEATURE_DISABLED_BY_DEFAULT}; std::atomic_bool g_align_wake_ups = false;
diff --git a/base/task/task_features.cc b/base/task/task_features.cc index 3a07ae39..5a075212 100644 --- a/base/task/task_features.cc +++ b/base/task/task_features.cc
@@ -63,6 +63,6 @@ "ExplicitHighResolutionTimerWin", base::FEATURE_DISABLED_BY_DEFAULT}; const BASE_EXPORT Feature kRunTasksByBatches = { - "RunThreadControllerTasksByBatches", base::FEATURE_DISABLED_BY_DEFAULT}; + "RunTasksByBatches", base::FEATURE_DISABLED_BY_DEFAULT}; } // namespace base
diff --git a/build/args/headless.gn b/build/args/headless.gn index 79297f2..fa52b43 100644 --- a/build/args/headless.gn +++ b/build/args/headless.gn
@@ -17,9 +17,6 @@ # Embed resource.pak into binary to simplify deployment. headless_use_embedded_resources = true -# Expose headless bindings for freetype library bundled with Chromium. -headless_fontconfig_utils = true - # Don't use Prefs component, disabling access to Local State prefs. headless_use_prefs = false
diff --git a/build/fuchsia/cipd/BUILD.gn b/build/fuchsia/cipd/BUILD.gn index 839ce6fd..6718cf35 100644 --- a/build/fuchsia/cipd/BUILD.gn +++ b/build/fuchsia/cipd/BUILD.gn
@@ -207,8 +207,8 @@ package_subdirectory = _web_engine_directory description = "Prebuilt WebRunner binaries for Fuchsia." - deps = [ "//fuchsia/runners:web_runner_pkg" ] - sources = [ "${root_gen_dir}/fuchsia/runners/web_runner/web_runner.far" ] + deps = [ "//fuchsia_web/runners:web_runner_pkg" ] + sources = [ "${root_gen_dir}/fuchsia_web/runners/web_runner/web_runner.far" ] } cipd_archive("web_engine") { @@ -223,8 +223,9 @@ package_subdirectory = _web_engine_directory description = "Prebuilt Cast application Runner binaries for Fuchsia." - deps = [ "//fuchsia/runners:cast_runner_pkg" ] - sources = [ "${root_gen_dir}/fuchsia/runners/cast_runner/cast_runner.far" ] + deps = [ "//fuchsia_web/runners:cast_runner_pkg" ] + sources = + [ "${root_gen_dir}/fuchsia_web/runners/cast_runner/cast_runner.far" ] } cipd_archive("web_engine_shell") { @@ -278,8 +279,8 @@ deps = [ "//base:base_unittests_pkg", "//fuchsia/engine:web_engine_integration_tests_pkg", - "//fuchsia/runners:cast_runner_integration_tests_pkg", - "//fuchsia/runners:web_runner_integration_tests_pkg", + "//fuchsia_web/runners:cast_runner_integration_tests_pkg", + "//fuchsia_web/runners:web_runner_integration_tests_pkg", "//ipc:ipc_tests_pkg", "//media:media_unittests_pkg", "//mojo:mojo_unittests_pkg", @@ -298,8 +299,8 @@ ] cfv1_far_sources = [ "${root_gen_dir}/fuchsia/engine/web_engine_integration_tests/web_engine_integration_tests.far", - "${root_gen_dir}/fuchsia/runners/cast_runner_integration_tests/cast_runner_integration_tests.far", - "${root_gen_dir}/fuchsia/runners/web_runner_integration_tests/web_runner_integration_tests.far", + "${root_gen_dir}/fuchsia_web/runners/cast_runner_integration_tests/cast_runner_integration_tests.far", + "${root_gen_dir}/fuchsia_web/runners/web_runner_integration_tests/web_runner_integration_tests.far", "${root_gen_dir}/media/media_unittests/media_unittests.far", "${root_gen_dir}/skia/skia_unittests/skia_unittests.far", ] @@ -321,12 +322,12 @@ manifest_path = "${target_gen_dir}/web_engine_tests_manifest.json" cfv1_far_sources = [ "${root_gen_dir}/fuchsia/engine/web_engine_integration_tests/web_engine_integration_tests.far", - "${root_gen_dir}/fuchsia/runners/web_runner_integration_tests/web_runner_integration_tests.far", + "${root_gen_dir}/fuchsia_web/runners/web_runner_integration_tests/web_runner_integration_tests.far", ] }, { manifest_path = "${target_gen_dir}/cast_runner_tests_manifest.json" - cfv1_far_sources = [ "${root_gen_dir}/fuchsia/runners/cast_runner_integration_tests/cast_runner_integration_tests.far" ] + cfv1_far_sources = [ "${root_gen_dir}/fuchsia_web/runners/cast_runner_integration_tests/cast_runner_integration_tests.far" ] }, ] }
diff --git a/cc/base/math_util.h b/cc/base/math_util.h index a29fc49..02aaebdc 100644 --- a/cc/base/math_util.h +++ b/cc/base/math_util.h
@@ -5,22 +5,18 @@ #ifndef CC_BASE_MATH_UTIL_H_ #define CC_BASE_MATH_UTIL_H_ +#include <cmath> #include <limits> -#include <memory> -#include <vector> #include "base/check.h" #include "base/cxx17_backports.h" #include "build/build_config.h" #include "cc/base/base_export.h" #include "third_party/skia/include/core/SkM44.h" +#include "third_party/skia/include/core/SkScalar.h" #include "ui/gfx/geometry/box_f.h" #include "ui/gfx/geometry/point3_f.h" #include "ui/gfx/geometry/point_f.h" -#include "ui/gfx/geometry/rounded_corners_f.h" -#include "ui/gfx/geometry/size.h" -#include "ui/gfx/geometry/transform.h" -#include "ui/gfx/geometry/vector2d_f.h" namespace base { class Value; @@ -34,6 +30,7 @@ class Rect; class RectF; class RRectF; +class Size; class SizeF; class Transform; class Vector2dF;
diff --git a/cc/debug/debug_colors.cc b/cc/debug/debug_colors.cc index a90c7d34..6b91453 100644 --- a/cc/debug/debug_colors.cc +++ b/cc/debug/debug_colors.cc
@@ -16,48 +16,48 @@ // ======= Layer border colors ======= // Tiled content layers are orange. -SkColor DebugColors::TiledContentLayerBorderColor() { - return SkColorSetARGB(128, 255, 128, 0); +SkColor4f DebugColors::TiledContentLayerBorderColor() { + return {1.0f, 0.5f, 0.0f, 0.5f}; } int DebugColors::TiledContentLayerBorderWidth(float device_scale_factor) { return Scale(2, device_scale_factor); } // Image layers are olive. -SkColor DebugColors::ImageLayerBorderColor() { - return SkColorSetARGB(128, 128, 128, 0); +SkColor4f DebugColors::ImageLayerBorderColor() { + return {0.5f, 0.5f, 0.0f, 0.5f}; } int DebugColors::ImageLayerBorderWidth(float device_scale_factor) { return Scale(2, device_scale_factor); } // Non-tiled content layers area green. -SkColor DebugColors::ContentLayerBorderColor() { - return SkColorSetARGB(128, 0, 128, 32); +SkColor4f DebugColors::ContentLayerBorderColor() { + return {0.0f, 0.5f, 32.0f / 255.0f, 0.5f}; } int DebugColors::ContentLayerBorderWidth(float device_scale_factor) { return Scale(2, device_scale_factor); } // Other container layers are yellow. -SkColor DebugColors::ContainerLayerBorderColor() { - return SkColorSetARGB(192, 255, 255, 0); +SkColor4f DebugColors::ContainerLayerBorderColor() { + return {1.0f, 1.0f, 0.0f, 0.75f}; } int DebugColors::ContainerLayerBorderWidth(float device_scale_factor) { return Scale(2, device_scale_factor); } // Surface layers are a blue-ish green. -SkColor DebugColors::SurfaceLayerBorderColor() { - return SkColorSetARGB(128, 0, 255, 136); +SkColor4f DebugColors::SurfaceLayerBorderColor() { + return {0.0f, 1.0f, 136.0f / 255.0f, 0.5f}; } int DebugColors::SurfaceLayerBorderWidth(float device_scale_factor) { return Scale(2, device_scale_factor); } // Render surfaces are blue. -SkColor DebugColors::SurfaceBorderColor() { - return SkColorSetARGB(100, 0, 0, 255); +SkColor4f DebugColors::SurfaceBorderColor() { + return {0.0f, 0.0f, 1.0f, 100.0f / 255.0f}; } int DebugColors::SurfaceBorderWidth(float device_scale_factor) { return Scale(2, device_scale_factor); @@ -66,64 +66,64 @@ // ======= Tile colors ======= // High-res tile borders are cyan. -SkColor DebugColors::HighResTileBorderColor() { - return SkColorSetARGB(100, 80, 200, 200); +SkColor4f DebugColors::HighResTileBorderColor() { + return {80.0f / 255.0f, 200.0f / 255.0f, 200.0f / 255.0f, 100.0f / 255.0f}; } int DebugColors::HighResTileBorderWidth(float device_scale_factor) { return Scale(1, device_scale_factor); } // Low-res tile borders are purple. -SkColor DebugColors::LowResTileBorderColor() { - return SkColorSetARGB(100, 212, 83, 192); +SkColor4f DebugColors::LowResTileBorderColor() { + return {212.0f / 255.0f, 83.0f / 255.0f, 0.75f, 100.0f / 255.0f}; } int DebugColors::LowResTileBorderWidth(float device_scale_factor) { return Scale(2, device_scale_factor); } // Other high-resolution tile borders are yellow. -SkColor DebugColors::ExtraHighResTileBorderColor() { - return SkColorSetARGB(100, 239, 231, 20); +SkColor4f DebugColors::ExtraHighResTileBorderColor() { + return {239.0f / 255.0f, 231.0f / 255.0f, 20.0f / 255.0f, 100.0f / 255.0f}; } int DebugColors::ExtraHighResTileBorderWidth(float device_scale_factor) { return Scale(2, device_scale_factor); } // Other low-resolution tile borders are green. -SkColor DebugColors::ExtraLowResTileBorderColor() { - return SkColorSetARGB(100, 93, 186, 18); +SkColor4f DebugColors::ExtraLowResTileBorderColor() { + return {93.0f / 255.0f, 186.0f / 255.0f, 18.0f / 255.0f, 100.0f / 255.0f}; } int DebugColors::ExtraLowResTileBorderWidth(float device_scale_factor) { return Scale(2, device_scale_factor); } // Missing tile borders are dark grey. -SkColor DebugColors::MissingTileBorderColor() { - return SkColorSetARGB(64, 64, 64, 0); +SkColor4f DebugColors::MissingTileBorderColor() { + return {0.25f, 0.25f, 0.0f, 0.25f}; } int DebugColors::MissingTileBorderWidth(float device_scale_factor) { return Scale(1, device_scale_factor); } // Solid color tile borders are grey. -SkColor DebugColors::SolidColorTileBorderColor() { - return SkColorSetARGB(128, 128, 128, 128); +SkColor4f DebugColors::SolidColorTileBorderColor() { + return {0.5f, 0.5f, 0.5f, 0.5f}; } int DebugColors::SolidColorTileBorderWidth(float device_scale_factor) { return Scale(1, device_scale_factor); } // OOM tile borders are red. -SkColor DebugColors::OOMTileBorderColor() { - return SkColorSetARGB(100, 255, 0, 0); +SkColor4f DebugColors::OOMTileBorderColor() { + return {1.0f, 0.0f, 0.0f, 100.0f / 255.0f}; } int DebugColors::OOMTileBorderWidth(float device_scale_factor) { return Scale(1, device_scale_factor); } // Direct picture borders are chartreuse. -SkColor DebugColors::DirectPictureBorderColor() { - return SkColorSetARGB(255, 127, 255, 0); +SkColor4f DebugColors::DirectPictureBorderColor() { + return {127.0f / 255.0f, 1.0f, 0.0f, 1.0f}; } int DebugColors::DirectPictureBorderWidth(float device_scale_factor) { return Scale(1, device_scale_factor); @@ -146,8 +146,8 @@ } // Compressed tile borders are blue. -SkColor DebugColors::CompressedTileBorderColor() { - return SkColorSetARGB(100, 20, 20, 240); +SkColor4f DebugColors::CompressedTileBorderColor() { + return {20.0f / 255.0f, 20.0f / 255.0f, 240.0f / 255.0f, 100.0f / 255.0f}; } int DebugColors::CompressedTileBorderWidth(float device_scale_factor) { return Scale(2, device_scale_factor); @@ -156,211 +156,214 @@ // ======= Checkerboard colors ======= // Non-debug checkerboards are grey. -SkColor DebugColors::DefaultCheckerboardColor() { - return SkColorSetRGB(241, 241, 241); +SkColor4f DebugColors::DefaultCheckerboardColor() { + return {241.0f / 255.0f, 241.0f / 255.0f, 241.0f / 255.0f, 1.0f}; } // Invalidated tiles get sky blue checkerboards. -SkColor DebugColors::InvalidatedTileCheckerboardColor() { - return SkColorSetRGB(128, 200, 245); +SkColor4f DebugColors::InvalidatedTileCheckerboardColor() { + return {0.5f, 200.0f / 255.0f, 245.0f / 255.0f, 1.0f}; } // Evicted tiles get pale red checkerboards. -SkColor DebugColors::EvictedTileCheckerboardColor() { - return SkColorSetRGB(255, 200, 200); +SkColor4f DebugColors::EvictedTileCheckerboardColor() { + return {1.0f, 200.0f / 255.0f, 200.0f / 255.0f, 1.0f}; } // ======= Debug rect colors ======= -static SkColor FadedGreen(int initial_value, int step) { +static SkColor4f FadedGreen(int initial_value, int step) { DCHECK_GE(step, 0); DCHECK_LE(step, DebugColors::kFadeSteps); int value = step * initial_value / DebugColors::kFadeSteps; - return SkColorSetARGB(value, 0, 195, 0); + return {0.0f, 195.0f / 255.0f, 0.0f, static_cast<float>(value) / 255.0f}; } // Paint rects in green. -SkColor DebugColors::PaintRectBorderColor(int step) { +SkColor4f DebugColors::PaintRectBorderColor(int step) { return FadedGreen(255, step); } int DebugColors::PaintRectBorderWidth() { return 2; } -SkColor DebugColors::PaintRectFillColor(int step) { +SkColor4f DebugColors::PaintRectFillColor(int step) { return FadedGreen(60, step); } -static SkColor FadedBlue(int initial_value, int step) { +static SkColor4f FadedBlue(int initial_value, int step) { DCHECK_GE(step, 0); DCHECK_LE(step, DebugColors::kFadeSteps); int value = step * initial_value / DebugColors::kFadeSteps; - return SkColorSetARGB(value, 0, 0, 255); + return {0.0f, 0.0f, 1.0f, static_cast<float>(value) / 255.0f}; } /// Layout Shift rects in blue. -SkColor DebugColors::LayoutShiftRectBorderColor() { - return SkColorSetARGB(0, 0, 0, 255); +SkColor4f DebugColors::LayoutShiftRectBorderColor() { + return {0.0f, 0.0f, 1.0f, 0.0f}; } int DebugColors::LayoutShiftRectBorderWidth() { // We don't want any border showing for the layout shift debug rects so we set // the border width to be equal to 0. return 0; } -SkColor DebugColors::LayoutShiftRectFillColor(int step) { +SkColor4f DebugColors::LayoutShiftRectFillColor(int step) { return FadedBlue(60, step); } // Property-changed rects in blue. -SkColor DebugColors::PropertyChangedRectBorderColor() { - return SkColorSetARGB(255, 0, 0, 255); +SkColor4f DebugColors::PropertyChangedRectBorderColor() { + return {0.0f, 0.0f, 1.0f, 1.0f}; } int DebugColors::PropertyChangedRectBorderWidth() { return 2; } -SkColor DebugColors::PropertyChangedRectFillColor() { - return SkColorSetARGB(30, 0, 0, 255); +SkColor4f DebugColors::PropertyChangedRectFillColor() { + return {0.0f, 0.0f, 1.0f, 30.0f / 255.0f}; } // Surface damage rects in yellow-orange. -SkColor DebugColors::SurfaceDamageRectBorderColor() { - return SkColorSetARGB(255, 200, 100, 0); +SkColor4f DebugColors::SurfaceDamageRectBorderColor() { + return {200.0f / 255.0f, 100.0f / 255.0f, 0.0f, 1.0f}; } int DebugColors::SurfaceDamageRectBorderWidth() { return 2; } -SkColor DebugColors::SurfaceDamageRectFillColor() { - return SkColorSetARGB(30, 200, 100, 0); +SkColor4f DebugColors::SurfaceDamageRectFillColor() { + return {200.0f / 255.0f, 100.0f / 255.0f, 0.0f, 30.0f / 255.0f}; } // Surface screen space rects in yellow-green. -SkColor DebugColors::ScreenSpaceLayerRectBorderColor() { - return SkColorSetARGB(255, 100, 200, 0); +SkColor4f DebugColors::ScreenSpaceLayerRectBorderColor() { + return {100.0f / 255.0f, 200.0f / 255.0f, 0.0f, 1.0f}; } int DebugColors::ScreenSpaceLayerRectBorderWidth() { return 2; } -SkColor DebugColors::ScreenSpaceLayerRectFillColor() { - return SkColorSetARGB(30, 100, 200, 0); +SkColor4f DebugColors::ScreenSpaceLayerRectFillColor() { + return {100.0f / 255.0f, 200.0f / 255.0f, 0.0f, 30.0f / 255.0f}; } // Touch-event-handler rects in yellow. -SkColor DebugColors::TouchEventHandlerRectBorderColor() { - return SkColorSetARGB(255, 239, 229, 60); +SkColor4f DebugColors::TouchEventHandlerRectBorderColor() { + return {239.0f / 255.0f, 229.0f / 255.0f, 60.0f / 255.0f, 1.0f}; } int DebugColors::TouchEventHandlerRectBorderWidth() { return 2; } -SkColor DebugColors::TouchEventHandlerRectFillColor() { - return SkColorSetARGB(30, 239, 229, 60); +SkColor4f DebugColors::TouchEventHandlerRectFillColor() { + return {239.0f / 255.0f, 229.0f / 255.0f, 60.0f / 255.0f, 30.0f / 255.0f}; } // Wheel-event-handler rects in green. -SkColor DebugColors::WheelEventHandlerRectBorderColor() { - return SkColorSetARGB(255, 189, 209, 57); +SkColor4f DebugColors::WheelEventHandlerRectBorderColor() { + return {189.0f / 255.0f, 209.0f / 255.0f, 57.0f / 255.0f, 1.0f}; } int DebugColors::WheelEventHandlerRectBorderWidth() { return 2; } -SkColor DebugColors::WheelEventHandlerRectFillColor() { - return SkColorSetARGB(30, 189, 209, 57); +SkColor4f DebugColors::WheelEventHandlerRectFillColor() { + return {189.0f / 255.0f, 209.0f / 255.0f, 57.0f / 255.0f, 30.0f / 255.0f}; } // Scroll-event-handler rects in teal. -SkColor DebugColors::ScrollEventHandlerRectBorderColor() { - return SkColorSetARGB(255, 24, 167, 181); +SkColor4f DebugColors::ScrollEventHandlerRectBorderColor() { + return {24.0f / 255.0f, 167.0f / 255.0f, 181.0f / 255.0f, 1.0f}; } int DebugColors::ScrollEventHandlerRectBorderWidth() { return 2; } -SkColor DebugColors::ScrollEventHandlerRectFillColor() { - return SkColorSetARGB(30, 24, 167, 181); +SkColor4f DebugColors::ScrollEventHandlerRectFillColor() { + return {24.0f / 255.0f, 167.0f / 255.0f, 181.0f / 255.0f, 30.0f / 255.0f}; } // Non-fast-scrollable rects in orange. -SkColor DebugColors::NonFastScrollableRectBorderColor() { - return SkColorSetARGB(255, 238, 163, 59); +SkColor4f DebugColors::NonFastScrollableRectBorderColor() { + return {238.0f / 255.0f, 163.0f / 255.0f, 59.0f / 255.0f, 1.0f}; } int DebugColors::NonFastScrollableRectBorderWidth() { return 2; } -SkColor DebugColors::NonFastScrollableRectFillColor() { - return SkColorSetARGB(30, 238, 163, 59); +SkColor4f DebugColors::NonFastScrollableRectFillColor() { + return {238.0f / 255.0f, 163.0f / 255.0f, 59.0f / 255.0f, 30.0f / 255.0f}; } // Main-thread scrolling reason rects in yellow-orange. -SkColor DebugColors::MainThreadScrollingReasonRectBorderColor() { - return SkColorSetARGB(255, 200, 100, 0); +SkColor4f DebugColors::MainThreadScrollingReasonRectBorderColor() { + return {200.0f / 255.0f, 100.0f / 255.0f, 0.0f, 1.0f}; } int DebugColors::MainThreadScrollingReasonRectBorderWidth() { return 2; } -SkColor DebugColors::MainThreadScrollingReasonRectFillColor() { - return SkColorSetARGB(30, 200, 100, 0); +SkColor4f DebugColors::MainThreadScrollingReasonRectFillColor() { + return {200.0f / 255.0f, 100.0f / 255.0f, 0.0f, 30.0f / 255.0f}; } // Animation bounds are lime-green. -SkColor DebugColors::LayerAnimationBoundsBorderColor() { - return SkColorSetARGB(255, 112, 229, 0); +SkColor4f DebugColors::LayerAnimationBoundsBorderColor() { + return {112.0f / 255.0f, 229.0f / 255.0f, 0.0f, 1.0f}; } int DebugColors::LayerAnimationBoundsBorderWidth() { return 2; } -SkColor DebugColors::LayerAnimationBoundsFillColor() { - return SkColorSetARGB(30, 112, 229, 0); +SkColor4f DebugColors::LayerAnimationBoundsFillColor() { + return {112.0f / 255.0f, 229.0f / 255.0f, 0.0f, 30.0f / 255.0f}; } // Picture borders in transparent blue. -SkColor DebugColors::PictureBorderColor() { - return SkColorSetARGB(100, 0, 0, 200); +SkColor4f DebugColors::PictureBorderColor() { + return {0.0f, 0.0f, 200.0f / 255.0f, 100.0f / 255.0f}; } // ======= HUD widget colors ======= -SkColor DebugColors::HUDBackgroundColor() { - return SkColorSetARGB(217, 0, 0, 0); +SkColor4f DebugColors::HUDBackgroundColor() { + return {0.0f, 0.0f, 0.0f, 217.0f / 255.0f}; } -SkColor DebugColors::HUDSeparatorLineColor() { - return SkColorSetARGB(64, 0, 255, 0); +SkColor4f DebugColors::HUDSeparatorLineColor() { + return {0.0f, 1.0f, 0.0f, 0.25f}; } -SkColor DebugColors::HUDIndicatorLineColor() { - return SK_ColorYELLOW; +SkColor4f DebugColors::HUDIndicatorLineColor() { + return SkColors::kYellow; } -SkColor DebugColors::HUDTitleColor() { - return SkColorSetARGB(255, 232, 232, 232); +SkColor4f DebugColors::HUDTitleColor() { + return {232.0f / 255.0f, 232.0f / 255.0f, 232.0f / 255.0f, 1.0f}; } -SkColor DebugColors::PlatformLayerTreeTextColor() { return SK_ColorRED; } -SkColor DebugColors::FPSDisplayTextAndGraphColor() { - return SK_ColorGREEN; +SkColor4f DebugColors::PlatformLayerTreeTextColor() { + return SkColors::kRed; +} +SkColor4f DebugColors::FPSDisplayTextAndGraphColor() { + return SkColors::kGreen; } // Color used to represent dropped compositor frames. -SkColor DebugColors::FPSDisplayDroppedFrame() { - return SkColorSetRGB(202, 91, 29); +SkColor4f DebugColors::FPSDisplayDroppedFrame() { + return {202.0f / 255.0f, 91.0f / 255.0f, 29.0f / 255.0f, 1.0f}; } // Color used to represent a "partial" frame, i.e. a frame that missed // its commit deadline. -SkColor DebugColors::FPSDisplayMissedFrame() { - return SkColorSetRGB(255, 245, 0); +SkColor4f DebugColors::FPSDisplayMissedFrame() { + return {1.0f, 245.0f / 255.0f, 0.0f, 1.0f}; } // Color used to represent a frame that successfully rendered. -SkColor DebugColors::FPSDisplaySuccessfulFrame() { - return SkColorSetARGB(191, 174, 221, 255); +SkColor4f DebugColors::FPSDisplaySuccessfulFrame() { + return {174.0f / 255.0f, 221.0f / 255.0f, 1.0f, 191.0f / 255.0f}; } -SkColor DebugColors::MemoryDisplayTextColor() { - return SK_ColorCYAN; +SkColor4f DebugColors::MemoryDisplayTextColor() { + return SkColors::kCyan; } // Paint time display in green (similar to paint times in the WebInspector) -SkColor DebugColors::PaintTimeDisplayTextAndGraphColor() { - return SkColorSetRGB(75, 155, 55); +SkColor4f DebugColors::PaintTimeDisplayTextAndGraphColor() { + return {75.0f / 255.0f, 155.0f / 255.0f, 55.0f / 255.0f, 1.0f}; } -SkColor DebugColors::NonLCDTextHighlightColor(LCDTextDisallowedReason reason) { +SkColor4f DebugColors::NonLCDTextHighlightColor( + LCDTextDisallowedReason reason) { switch (reason) { case LCDTextDisallowedReason::kNone: case LCDTextDisallowedReason::kNoText: - return SK_ColorTRANSPARENT; + return SkColors::kTransparent; case LCDTextDisallowedReason::kSetting: - return SkColorSetARGB(96, 128, 255, 0); + return {0.5f, 1.0f, 0.0f, 96.0f / 255.0f}; case LCDTextDisallowedReason::kBackgroundColorNotOpaque: - return SkColorSetARGB(96, 128, 128, 0); + return {0.5f, 0.5f, 0.0f, 96.0f / 255.0f}; case LCDTextDisallowedReason::kContentsNotOpaque: - return SkColorSetARGB(96, 255, 0, 0); + return {1.0f, 0.0f, 0.0f, 96.0f / 255.0f}; case LCDTextDisallowedReason::kNonIntegralTranslation: - return SkColorSetARGB(96, 255, 128, 0); + return {1.0f, 0.5f, 0.0f, 96.0f / 255.0f}; case LCDTextDisallowedReason::kNonIntegralXOffset: case LCDTextDisallowedReason::kNonIntegralYOffset: - return SkColorSetARGB(96, 255, 0, 128); + return {1.0f, 0.0f, 0.5f, 96.0f / 255.0f}; case LCDTextDisallowedReason::kWillChangeTransform: case LCDTextDisallowedReason::kTransformAnimation: - return SkColorSetARGB(96, 128, 0, 255); + return {0.5f, 0.0f, 1.0f, 96.0f / 255.0f}; case LCDTextDisallowedReason::kPixelOrColorEffect: - return SkColorSetARGB(96, 0, 128, 0); + return {0.0f, 0.5f, 0.0f, 96.0f / 255.0f}; } NOTREACHED(); - return SK_ColorTRANSPARENT; + return SkColors::kTransparent; } } // namespace cc
diff --git a/cc/debug/debug_colors.h b/cc/debug/debug_colors.h index 109bb13..49ad7f3 100644 --- a/cc/debug/debug_colors.h +++ b/cc/debug/debug_colors.h
@@ -16,121 +16,121 @@ public: DebugColors() = delete; - static SkColor TiledContentLayerBorderColor(); + static SkColor4f TiledContentLayerBorderColor(); static int TiledContentLayerBorderWidth(float device_scale_factor); - static SkColor ImageLayerBorderColor(); + static SkColor4f ImageLayerBorderColor(); static int ImageLayerBorderWidth(float device_scale_factor); - static SkColor ContentLayerBorderColor(); + static SkColor4f ContentLayerBorderColor(); static int ContentLayerBorderWidth(float device_scale_factor); - static SkColor ContainerLayerBorderColor(); + static SkColor4f ContainerLayerBorderColor(); static int ContainerLayerBorderWidth(float device_scale_factor); - static SkColor SurfaceLayerBorderColor(); + static SkColor4f SurfaceLayerBorderColor(); static int SurfaceLayerBorderWidth(float device_scale_factor); - static SkColor SurfaceBorderColor(); + static SkColor4f SurfaceBorderColor(); static int SurfaceBorderWidth(float device_scale_factor); - static SkColor HighResTileBorderColor(); + static SkColor4f HighResTileBorderColor(); static int HighResTileBorderWidth(float device_scale_factor); - static SkColor LowResTileBorderColor(); + static SkColor4f LowResTileBorderColor(); static int LowResTileBorderWidth(float device_scale_factor); - static SkColor ExtraHighResTileBorderColor(); + static SkColor4f ExtraHighResTileBorderColor(); static int ExtraHighResTileBorderWidth(float device_scale_factor); - static SkColor ExtraLowResTileBorderColor(); + static SkColor4f ExtraLowResTileBorderColor(); static int ExtraLowResTileBorderWidth(float device_scale_factor); - static SkColor MissingTileBorderColor(); + static SkColor4f MissingTileBorderColor(); static int MissingTileBorderWidth(float device_scale_factor); - static SkColor SolidColorTileBorderColor(); + static SkColor4f SolidColorTileBorderColor(); static int SolidColorTileBorderWidth(float device_scale_factor); - static SkColor OOMTileBorderColor(); + static SkColor4f OOMTileBorderColor(); static int OOMTileBorderWidth(float device_scale_factor); - static SkColor DirectPictureBorderColor(); + static SkColor4f DirectPictureBorderColor(); static int DirectPictureBorderWidth(float device_scale_factor); - static SkColor CompressedTileBorderColor(); + static SkColor4f CompressedTileBorderColor(); static int CompressedTileBorderWidth(float device_scale_factor); - static SkColor DefaultCheckerboardColor(); - static SkColor EvictedTileCheckerboardColor(); - static SkColor InvalidatedTileCheckerboardColor(); + static SkColor4f DefaultCheckerboardColor(); + static SkColor4f EvictedTileCheckerboardColor(); + static SkColor4f InvalidatedTileCheckerboardColor(); static const int kFadeSteps = 50; - static SkColor PaintRectBorderColor(int step); + static SkColor4f PaintRectBorderColor(int step); static int PaintRectBorderWidth(); - static SkColor PaintRectFillColor(int step); + static SkColor4f PaintRectFillColor(int step); - static SkColor LayoutShiftRectBorderColor(); + static SkColor4f LayoutShiftRectBorderColor(); static int LayoutShiftRectBorderWidth(); - static SkColor LayoutShiftRectFillColor(int step); + static SkColor4f LayoutShiftRectFillColor(int step); - static SkColor PropertyChangedRectBorderColor(); + static SkColor4f PropertyChangedRectBorderColor(); static int PropertyChangedRectBorderWidth(); - static SkColor PropertyChangedRectFillColor(); + static SkColor4f PropertyChangedRectFillColor(); - static SkColor SurfaceDamageRectBorderColor(); + static SkColor4f SurfaceDamageRectBorderColor(); static int SurfaceDamageRectBorderWidth(); - static SkColor SurfaceDamageRectFillColor(); + static SkColor4f SurfaceDamageRectFillColor(); - static SkColor ScreenSpaceLayerRectBorderColor(); + static SkColor4f ScreenSpaceLayerRectBorderColor(); static int ScreenSpaceLayerRectBorderWidth(); - static SkColor ScreenSpaceLayerRectFillColor(); + static SkColor4f ScreenSpaceLayerRectFillColor(); - static SkColor TouchEventHandlerRectBorderColor(); + static SkColor4f TouchEventHandlerRectBorderColor(); static int TouchEventHandlerRectBorderWidth(); - static SkColor TouchEventHandlerRectFillColor(); + static SkColor4f TouchEventHandlerRectFillColor(); - static SkColor WheelEventHandlerRectBorderColor(); + static SkColor4f WheelEventHandlerRectBorderColor(); static int WheelEventHandlerRectBorderWidth(); - static SkColor WheelEventHandlerRectFillColor(); + static SkColor4f WheelEventHandlerRectFillColor(); - static SkColor ScrollEventHandlerRectBorderColor(); + static SkColor4f ScrollEventHandlerRectBorderColor(); static int ScrollEventHandlerRectBorderWidth(); - static SkColor ScrollEventHandlerRectFillColor(); + static SkColor4f ScrollEventHandlerRectFillColor(); - static SkColor NonFastScrollableRectBorderColor(); + static SkColor4f NonFastScrollableRectBorderColor(); static int NonFastScrollableRectBorderWidth(); - static SkColor NonFastScrollableRectFillColor(); + static SkColor4f NonFastScrollableRectFillColor(); - static SkColor MainThreadScrollingReasonRectBorderColor(); + static SkColor4f MainThreadScrollingReasonRectBorderColor(); static int MainThreadScrollingReasonRectBorderWidth(); - static SkColor MainThreadScrollingReasonRectFillColor(); + static SkColor4f MainThreadScrollingReasonRectFillColor(); - static SkColor LayerAnimationBoundsBorderColor(); + static SkColor4f LayerAnimationBoundsBorderColor(); static int LayerAnimationBoundsBorderWidth(); - static SkColor LayerAnimationBoundsFillColor(); + static SkColor4f LayerAnimationBoundsFillColor(); - static SkColor NonPaintedFillColor(); - static SkColor MissingPictureFillColor(); - static SkColor MissingResizeInvalidations(); - static SkColor PictureBorderColor(); + static SkColor4f NonPaintedFillColor(); + static SkColor4f MissingPictureFillColor(); + static SkColor4f MissingResizeInvalidations(); + static SkColor4f PictureBorderColor(); static base::span<const float> TintCompositedContentColorTransformMatrix(); - static SkColor HUDBackgroundColor(); - static SkColor HUDSeparatorLineColor(); - static SkColor HUDIndicatorLineColor(); - static SkColor HUDTitleColor(); + static SkColor4f HUDBackgroundColor(); + static SkColor4f HUDSeparatorLineColor(); + static SkColor4f HUDIndicatorLineColor(); + static SkColor4f HUDTitleColor(); - static SkColor PlatformLayerTreeTextColor(); - static SkColor FPSDisplayTextAndGraphColor(); - static SkColor FPSDisplayDroppedFrame(); - static SkColor FPSDisplayMissedFrame(); - static SkColor FPSDisplaySuccessfulFrame(); - static SkColor MemoryDisplayTextColor(); - static SkColor PaintTimeDisplayTextAndGraphColor(); + static SkColor4f PlatformLayerTreeTextColor(); + static SkColor4f FPSDisplayTextAndGraphColor(); + static SkColor4f FPSDisplayDroppedFrame(); + static SkColor4f FPSDisplayMissedFrame(); + static SkColor4f FPSDisplaySuccessfulFrame(); + static SkColor4f MemoryDisplayTextColor(); + static SkColor4f PaintTimeDisplayTextAndGraphColor(); - static SkColor NonLCDTextHighlightColor(LCDTextDisallowedReason); + static SkColor4f NonLCDTextHighlightColor(LCDTextDisallowedReason); }; } // namespace cc
diff --git a/cc/layers/heads_up_display_layer_impl.cc b/cc/layers/heads_up_display_layer_impl.cc index 96b098f..bf883bd1 100644 --- a/cc/layers/heads_up_display_layer_impl.cc +++ b/cc/layers/heads_up_display_layer_impl.cc
@@ -685,7 +685,8 @@ void HeadsUpDisplayLayerImpl::DrawGraphBackground(PaintCanvas* canvas, PaintFlags* flags, const SkRect& bounds) const { - flags->setColor(DebugColors::HUDBackgroundColor()); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. + flags->setColor(DebugColors::HUDBackgroundColor().toSkColor()); canvas->drawRect(bounds, *flags); } @@ -693,7 +694,8 @@ PaintFlags* flags, const SkRect& bounds) const { // Draw top and bottom line. - flags->setColor(DebugColors::HUDSeparatorLineColor()); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. + flags->setColor(DebugColors::HUDSeparatorLineColor().toSkColor()); canvas->drawLine(bounds.left(), bounds.top() - 1, bounds.right(), bounds.top() - 1, *flags); canvas->drawLine(bounds.left(), bounds.bottom(), bounds.right(), @@ -755,11 +757,13 @@ } VLOG(1) << value_text; - flags.setColor(DebugColors::HUDTitleColor()); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. + flags.setColor(DebugColors::HUDTitleColor().toSkColor()); DrawText(canvas, flags, title, TextAlign::kLeft, kTitleFontHeight, title_bounds.left(), title_bounds.bottom()); - flags.setColor(DebugColors::FPSDisplayTextAndGraphColor()); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. + flags.setColor(DebugColors::FPSDisplayTextAndGraphColor().toSkColor()); DrawText(canvas, flags, value_text, TextAlign::kRight, kFontHeight, text_bounds.right(), text_bounds.bottom()); @@ -786,13 +790,15 @@ flags.setStyle(PaintFlags::kStroke_Style); flags.setStrokeWidth(1); - flags.setColor(DebugColors::FPSDisplaySuccessfulFrame()); + // TODO(crbug/1308932): Remove all instances of toSkColor below and make all + // SkColor4f. + flags.setColor(DebugColors::FPSDisplaySuccessfulFrame().toSkColor()); canvas->drawPath(good_path, flags); - flags.setColor(DebugColors::FPSDisplayDroppedFrame()); + flags.setColor(DebugColors::FPSDisplayDroppedFrame().toSkColor()); canvas->drawPath(dropped_path, flags); - flags.setColor(DebugColors::FPSDisplayMissedFrame()); + flags.setColor(DebugColors::FPSDisplayMissedFrame().toSkColor()); canvas->drawPath(partial_path, flags); return area; @@ -822,11 +828,13 @@ SkPoint stat2_pos = SkPoint::Make(left + width - kPadding - 1, top + 2 * kPadding + 3 * kFontHeight); - flags.setColor(DebugColors::HUDTitleColor()); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. + flags.setColor(DebugColors::HUDTitleColor().toSkColor()); DrawText(canvas, flags, "GPU memory", TextAlign::kLeft, kTitleFontHeight, title_pos); - flags.setColor(DebugColors::MemoryDisplayTextColor()); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. + flags.setColor(DebugColors::MemoryDisplayTextColor().toSkColor()); std::string text = base::StringPrintf( "%6.1f MB used", memory_entry_.total_bytes_used / kMegabyte); DrawText(canvas, flags, text, TextAlign::kRight, kFontHeight, stat1_pos); @@ -916,7 +924,8 @@ SkPoint gpu_status_pos = SkPoint::Make(left + width - kPadding, top + 2 * kFontHeight + 2 * kPadding); - flags.setColor(DebugColors::HUDTitleColor()); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. + flags.setColor(DebugColors::HUDTitleColor().toSkColor()); DrawText(canvas, flags, "GPU raster", TextAlign::kLeft, kTitleFontHeight, left + kPadding, top + kFontHeight + kPadding); flags.setColor(color); @@ -995,6 +1004,8 @@ std::string label_text; switch (debug_rects[i].type) { + // TODO(crbug/1308932): Remove all instances of toSkColor below and make + // all SkColor4f. case LAYOUT_SHIFT_RECT_TYPE: new_layout_shift_rects.push_back(debug_rects[i]); continue; @@ -1002,56 +1013,65 @@ new_paint_rects.push_back(debug_rects[i]); continue; case PROPERTY_CHANGED_RECT_TYPE: - stroke_color = DebugColors::PropertyChangedRectBorderColor(); - fill_color = DebugColors::PropertyChangedRectFillColor(); + stroke_color = + DebugColors::PropertyChangedRectBorderColor().toSkColor(); + fill_color = DebugColors::PropertyChangedRectFillColor().toSkColor(); stroke_width = DebugColors::PropertyChangedRectBorderWidth(); break; case SURFACE_DAMAGE_RECT_TYPE: - stroke_color = DebugColors::SurfaceDamageRectBorderColor(); - fill_color = DebugColors::SurfaceDamageRectFillColor(); + stroke_color = DebugColors::SurfaceDamageRectBorderColor().toSkColor(); + fill_color = DebugColors::SurfaceDamageRectFillColor().toSkColor(); stroke_width = DebugColors::SurfaceDamageRectBorderWidth(); break; case SCREEN_SPACE_RECT_TYPE: - stroke_color = DebugColors::ScreenSpaceLayerRectBorderColor(); - fill_color = DebugColors::ScreenSpaceLayerRectFillColor(); + stroke_color = + DebugColors::ScreenSpaceLayerRectBorderColor().toSkColor(); + fill_color = DebugColors::ScreenSpaceLayerRectFillColor().toSkColor(); stroke_width = DebugColors::ScreenSpaceLayerRectBorderWidth(); break; case TOUCH_EVENT_HANDLER_RECT_TYPE: - stroke_color = DebugColors::TouchEventHandlerRectBorderColor(); - fill_color = DebugColors::TouchEventHandlerRectFillColor(); + stroke_color = + DebugColors::TouchEventHandlerRectBorderColor().toSkColor(); + fill_color = DebugColors::TouchEventHandlerRectFillColor().toSkColor(); stroke_width = DebugColors::TouchEventHandlerRectBorderWidth(); label_text = "touch event listener: "; label_text.append(TouchActionToString(debug_rects[i].touch_action)); break; case WHEEL_EVENT_HANDLER_RECT_TYPE: - stroke_color = DebugColors::WheelEventHandlerRectBorderColor(); - fill_color = DebugColors::WheelEventHandlerRectFillColor(); + stroke_color = + DebugColors::WheelEventHandlerRectBorderColor().toSkColor(); + fill_color = DebugColors::WheelEventHandlerRectFillColor().toSkColor(); stroke_width = DebugColors::WheelEventHandlerRectBorderWidth(); label_text = "mousewheel event listener"; break; case SCROLL_EVENT_HANDLER_RECT_TYPE: - stroke_color = DebugColors::ScrollEventHandlerRectBorderColor(); - fill_color = DebugColors::ScrollEventHandlerRectFillColor(); + stroke_color = + DebugColors::ScrollEventHandlerRectBorderColor().toSkColor(); + fill_color = DebugColors::ScrollEventHandlerRectFillColor().toSkColor(); stroke_width = DebugColors::ScrollEventHandlerRectBorderWidth(); label_text = "scroll event listener"; break; case NON_FAST_SCROLLABLE_RECT_TYPE: - stroke_color = DebugColors::NonFastScrollableRectBorderColor(); - fill_color = DebugColors::NonFastScrollableRectFillColor(); + stroke_color = + DebugColors::NonFastScrollableRectBorderColor().toSkColor(); + fill_color = DebugColors::NonFastScrollableRectFillColor().toSkColor(); stroke_width = DebugColors::NonFastScrollableRectBorderWidth(); label_text = "repaints on scroll"; break; case MAIN_THREAD_SCROLLING_REASON_RECT_TYPE: - stroke_color = DebugColors::MainThreadScrollingReasonRectBorderColor(); - fill_color = DebugColors::MainThreadScrollingReasonRectFillColor(); + stroke_color = + DebugColors::MainThreadScrollingReasonRectBorderColor().toSkColor(); + fill_color = + DebugColors::MainThreadScrollingReasonRectFillColor().toSkColor(); stroke_width = DebugColors::MainThreadScrollingReasonRectBorderWidth(); label_text = "main thread scrolling: "; label_text.append(base::ToLowerASCII(MainThreadScrollingReason::AsText( debug_rects[i].main_thread_scrolling_reasons))); break; case ANIMATION_BOUNDS_RECT_TYPE: - stroke_color = DebugColors::LayerAnimationBoundsBorderColor(); - fill_color = DebugColors::LayerAnimationBoundsFillColor(); + stroke_color = + DebugColors::LayerAnimationBoundsBorderColor().toSkColor(); + fill_color = DebugColors::LayerAnimationBoundsFillColor().toSkColor(); stroke_width = DebugColors::LayerAnimationBoundsBorderWidth(); label_text = "animation bounds"; break; @@ -1067,11 +1087,14 @@ } if (paint_rects_fade_step_ > 0) { paint_rects_fade_step_--; - for (size_t i = 0; i < paint_rects_.size(); ++i) { - DrawDebugRect(canvas, &flags, paint_rects_[i], - DebugColors::PaintRectBorderColor(paint_rects_fade_step_), - DebugColors::PaintRectFillColor(paint_rects_fade_step_), - DebugColors::PaintRectBorderWidth(), ""); + for (auto& paint_rect : paint_rects_) { + // TODO(crbug/1308932): Remove all instances of toSkColor below and make + // all SkColor4f. + DrawDebugRect( + canvas, &flags, paint_rect, + DebugColors::PaintRectBorderColor(paint_rects_fade_step_).toSkColor(), + DebugColors::PaintRectFillColor(paint_rects_fade_step_).toSkColor(), + DebugColors::PaintRectBorderWidth(), ""); } } if (new_layout_shift_rects.size()) { @@ -1080,11 +1103,14 @@ } if (layout_shift_rects_fade_step_ > 0) { layout_shift_rects_fade_step_--; - for (size_t i = 0; i < layout_shift_debug_rects_.size(); ++i) { + for (auto& layout_shift_debug_rect : layout_shift_debug_rects_) { + // TODO(crbug/1308932): Remove all instances of toSkColor below and make + // all SkColor4f. DrawDebugRect( - canvas, &flags, layout_shift_debug_rects_[i], - DebugColors::LayoutShiftRectBorderColor(), - DebugColors::LayoutShiftRectFillColor(layout_shift_rects_fade_step_), + canvas, &flags, layout_shift_debug_rect, + DebugColors::LayoutShiftRectBorderColor().toSkColor(), + DebugColors::LayoutShiftRectFillColor(layout_shift_rects_fade_step_) + .toSkColor(), DebugColors::LayoutShiftRectBorderWidth(), ""); } } @@ -1100,7 +1126,8 @@ bool has_value, double value) const { std::string value_str = "-"; - SkColor metrics_color = DebugColors::HUDTitleColor(); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. + SkColor metrics_color = DebugColors::HUDTitleColor().toSkColor(); SkColor badge_color = SK_ColorGREEN; if (has_value) { value_str = ToStringTwoDecimalPrecision(value) + info.UnitToString(); @@ -1148,7 +1175,8 @@ // Draw the label and values of the metric. PaintFlags flags; - flags.setColor(DebugColors::HUDTitleColor()); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. + flags.setColor(DebugColors::HUDTitleColor().toSkColor()); DrawText(canvas, flags, name, TextAlign::kLeft, metrics_sizes.kFontHeight, left + metrics_sizes.kSidePadding + metrics_sizes.kBadgeWidth, top); flags.setColor(metrics_color); @@ -1201,11 +1229,13 @@ std::string name, double value) const { std::string value_str = "-"; - SkColor metrics_color = DebugColors::HUDTitleColor(); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. + SkColor metrics_color = DebugColors::HUDTitleColor().toSkColor(); value_str = ToStringTwoDecimalPrecision(value) + "%"; PaintFlags flags; - flags.setColor(DebugColors::HUDTitleColor()); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. + flags.setColor(DebugColors::HUDTitleColor().toSkColor()); DrawText(canvas, flags, name, TextAlign::kLeft, metrics_sizes.kFontHeight, left + metrics_sizes.kSidePadding + metrics_sizes.kBadgeWidth, top); flags.setColor(metrics_color);
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index aee80650..516dc9d 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc
@@ -1204,6 +1204,7 @@ EnsureRareInputs().capture_bounds = std::move(bounds); SetPropertyTreesNeedRebuild(); SetNeedsCommit(); + SetSubtreePropertyChanged(); } void Layer::SetWheelEventRegion(Region wheel_event_region) {
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index f657d64..0612288 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc
@@ -233,12 +233,14 @@ layer_tree_impl() ? layer_tree_impl()->device_scale_factor() : 1; if (draws_content_) { - *color = DebugColors::ContentLayerBorderColor(); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. + *color = DebugColors::ContentLayerBorderColor().toSkColor(); *width = DebugColors::ContentLayerBorderWidth(device_scale_factor); return; } - *color = DebugColors::ContainerLayerBorderColor(); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. + *color = DebugColors::ContainerLayerBorderColor().toSkColor(); *width = DebugColors::ContainerLayerBorderWidth(device_scale_factor); }
diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc index 112d869b..e822609 100644 --- a/cc/layers/layer_unittest.cc +++ b/cc/layers/layer_unittest.cc
@@ -87,6 +87,21 @@ EXPECT_FALSE(child->subtree_property_changed()); \ EXPECT_FALSE(grand_child->subtree_property_changed()); +// TODO(https://crbug.com/1330728): tests should be cleaned up to eliminate +// mixing of EXPECT_CALL with calls to the mock functions. This method +// should be deduped with EXPECT_SET_NEEDS_COMMIT as part of this cleanup. +#define EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(code_to_test) \ + do { \ + code_to_test; \ + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); \ + } while (false) + +#define EXPECT_SET_NEEDS_COMMIT_WAS_NOT_CALLED(code_to_test) \ + do { \ + code_to_test; \ + EXPECT_FALSE(layer_tree_host_->GetNeedsCommitAndReset()); \ + } while (false) + namespace cc { namespace { @@ -110,9 +125,18 @@ return thread_unsafe_commit_state(); } - MOCK_METHOD0(SetNeedsCommit, void()); - MOCK_METHOD0(SetNeedsUpdateLayers, void()); - MOCK_METHOD0(SetNeedsFullTreeSync, void()); + MOCK_METHOD(void, SetNeedsUpdateLayers, (), (override)); + MOCK_METHOD(void, SetNeedsFullTreeSync, (), (override)); + + void SetNeedsCommit() override { needs_commit_ = true; } + bool GetNeedsCommitAndReset() { + const bool out = needs_commit_; + needs_commit_ = false; + return out; + } + + private: + bool needs_commit_ = false; }; bool LayerNeedsDisplay(Layer* layer) { @@ -259,11 +283,7 @@ scoped_refptr<Layer> test_layer = Layer::Create(); ASSERT_TRUE(test_layer.get()); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0); test_layer->SetLayerTreeHost(layer_tree_host_.get()); - Mock::VerifyAndClearExpectations(layer_tree_host_.get()); - - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0); test_layer->SetLayerTreeHost(nullptr); } @@ -283,21 +303,22 @@ top->AddChild(child); top->AddChild(child2); child->AddChild(grand_child); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); + // To force a transform node for |top|. gfx::Transform top_transform; top_transform.Scale3d(1, 2, 3); top->SetTransform(top_transform); child->SetForceRenderSurfaceForTesting(true); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); // Resizing without a mask layer or masks_to_bounds, should only require a // regular commit. Note that a layer and its mask should match sizes, but // the mask isn't in the tree yet, so won't need its own commit. gfx::Size arbitrary_size = gfx::Size(1, 2); - EXPECT_SET_NEEDS_COMMIT(1, top->SetBounds(arbitrary_size)); - EXPECT_SET_NEEDS_COMMIT(0, mask_layer1->SetBounds(arbitrary_size)); - EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(1); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(top->SetBounds(arbitrary_size)); + EXPECT_SET_NEEDS_COMMIT_WAS_NOT_CALLED( + mask_layer1->SetBounds(arbitrary_size)); + EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()); layer_tree_host_->WillCommit(/*completion=*/nullptr, /*has_updates=*/true); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetMaskLayer(mask_layer1)); @@ -335,11 +356,11 @@ // Once there is a mask layer, resizes require subtree properties to update. arbitrary_size = gfx::Size(11, 22); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetBounds(arbitrary_size)); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(mask_layer1->SetBounds(arbitrary_size)); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetMasksToBounds(true)); commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr, @@ -351,9 +372,10 @@ grand_child->PushPropertiesTo(grand_child_impl.get(), *commit_state, unsafe_state)); layer_tree_host_->CommitComplete({base::TimeTicks(), base::TimeTicks::Now()}); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetContentsOpaque(true)); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr, /*has_updates=*/true); @@ -365,8 +387,8 @@ unsafe_state)); layer_tree_host_->CommitComplete({base::TimeTicks(), base::TimeTicks::Now()}); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetTrilinearFiltering(true)); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr, /*has_updates=*/true); @@ -378,8 +400,8 @@ unsafe_state)); layer_tree_host_->CommitComplete({base::TimeTicks(), base::TimeTicks::Now()}); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetTrilinearFiltering(false)); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr, /*has_updates=*/true); @@ -391,9 +413,10 @@ unsafe_state)); layer_tree_host_->CommitComplete({base::TimeTicks(), base::TimeTicks::Now()}); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2); top->SetRoundedCorner({1, 2, 3, 4}); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetIsFastRoundedCorner(true)); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr, /*has_updates=*/true); @@ -405,8 +428,8 @@ unsafe_state)); layer_tree_host_->CommitComplete({base::TimeTicks(), base::TimeTicks::Now()}); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetHideLayerAndSubtree(true)); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr, /*has_updates=*/true); @@ -418,8 +441,8 @@ unsafe_state)); layer_tree_host_->CommitComplete({base::TimeTicks(), base::TimeTicks::Now()}); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetBlendMode(arbitrary_blend_mode)); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr, /*has_updates=*/true); @@ -434,9 +457,10 @@ // Should be a different size than previous call, to ensure it marks tree // changed. arbitrary_size = gfx::Size(111, 222); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetBounds(arbitrary_size)); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(mask_layer1->SetBounds(arbitrary_size)); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr, /*has_updates=*/true); @@ -450,8 +474,8 @@ FilterOperations arbitrary_filters; arbitrary_filters.Append(FilterOperation::CreateOpacityFilter(0.5f)); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetFilters(arbitrary_filters)); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr, /*has_updates=*/true); @@ -463,7 +487,6 @@ unsafe_state)); layer_tree_host_->CommitComplete({base::TimeTicks(), base::TimeTicks::Now()}); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2); EXECUTE_AND_VERIFY_SUBTREE_CHANGED( top->SetBackdropFilters(arbitrary_filters)); @@ -476,9 +499,9 @@ grand_child->PushPropertiesTo(grand_child_impl.get(), *commit_state, unsafe_state)); layer_tree_host_->CommitComplete({base::TimeTicks(), base::TimeTicks::Now()}); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); gfx::PointF arbitrary_point_f = gfx::PointF(0.125f, 0.25f); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); top->SetPosition(arbitrary_point_f); TransformNode* node = layer_tree_host_->property_trees()->transform_tree_mutable().Node( @@ -496,12 +519,13 @@ layer_tree_host_->property_trees()->ResetAllChangeTracking()); layer_tree_host_->CommitComplete({base::TimeTicks(), base::TimeTicks::Now()}); EXPECT_FALSE(node->transform_changed); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); child->SetPosition(arbitrary_point_f); node = layer_tree_host_->property_trees()->transform_tree_mutable().Node( child->transform_tree_index()); EXPECT_TRUE(node->transform_changed); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr, /*has_updates=*/true); @@ -516,11 +540,11 @@ EXPECT_FALSE(node->transform_changed); gfx::Point3F arbitrary_point_3f = gfx::Point3F(0.125f, 0.25f, 0.f); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); top->SetTransformOrigin(arbitrary_point_3f); node = layer_tree_host_->property_trees()->transform_tree_mutable().Node( top->transform_tree_index()); EXPECT_TRUE(node->transform_changed); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr, /*has_updates=*/true); @@ -535,11 +559,11 @@ gfx::Transform arbitrary_transform; arbitrary_transform.Scale3d(0.1f, 0.2f, 0.3f); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); top->SetTransform(arbitrary_transform); node = layer_tree_host_->property_trees()->transform_tree_mutable().Node( top->transform_tree_index()); EXPECT_TRUE(node->transform_changed); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); } TEST_F(LayerTest, AddAndRemoveChild) { @@ -787,8 +811,8 @@ EXPECT_FALSE(child4->parent()); - EXPECT_SET_NEEDS_FULL_TREE_SYNC( - AtLeast(1), parent_->ReplaceChild(child2_.get(), child4)); + EXPECT_SET_NEEDS_FULL_TREE_SYNC(AtLeast(1), + parent_->ReplaceChild(child2_.get(), child4)); EXPECT_FALSE(LayerNeedsDisplay(parent_.get())); EXPECT_FALSE(LayerNeedsDisplay(child1_.get())); EXPECT_FALSE(LayerNeedsDisplay(child2_.get())); @@ -815,8 +839,8 @@ EXPECT_EQ(child4, test_layer->children()[0]); EXPECT_EQ(test_layer.get(), child4->parent()); - EXPECT_SET_NEEDS_FULL_TREE_SYNC( - AtLeast(1), parent_->ReplaceChild(child2_.get(), child4)); + EXPECT_SET_NEEDS_FULL_TREE_SYNC(AtLeast(1), + parent_->ReplaceChild(child2_.get(), child4)); ASSERT_EQ(3U, parent_->children().size()); EXPECT_EQ(child1_, parent_->children()[0]); @@ -833,10 +857,8 @@ TEST_F(LayerTest, ReplaceChildWithSameChild) { CreateSimpleTestTree(); - // SetNeedsFullTreeSync / SetNeedsCommit should not be called because its the - // same child. - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0); - EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(0); + // SetNeedsFullTreeSync / SetNeedsCommit should not be called because its + // the same child. parent_->ReplaceChild(child2_.get(), child2_); VerifyTestTreeInitialState(); @@ -886,7 +908,7 @@ EXPECT_EQ(parent_.get(), child1_->RootLayer()); EXPECT_EQ(parent_.get(), child2_->RootLayer()); EXPECT_EQ(parent_.get(), child3_->RootLayer()); - EXPECT_EQ(child4.get(), child4->RootLayer()); + EXPECT_EQ(child4.get(), child4->RootLayer()); EXPECT_EQ(parent_.get(), grand_child1_->RootLayer()); EXPECT_EQ(parent_.get(), grand_child2_->RootLayer()); EXPECT_EQ(parent_.get(), grand_child3_->RootLayer()); @@ -917,8 +939,8 @@ child2_->ReplaceChild(grand_child3_.get(), child1_); - // |grand_child3| gets orphaned and the child1 subtree gets planted back into - // the tree under child2. + // |grand_child3| gets orphaned and the child1 subtree gets planted back + // into the tree under child2. EXPECT_EQ(parent_.get(), parent_->RootLayer()); EXPECT_EQ(parent_.get(), child1_->RootLayer()); EXPECT_EQ(parent_.get(), child2_->RootLayer()); @@ -938,7 +960,7 @@ scoped_refptr<Layer> test_layer = Layer::Create(); EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(test_layer)); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(true)); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetIsDrawable(true)); gfx::Size test_bounds = gfx::Size(501, 508); @@ -948,9 +970,9 @@ // Before anything, test_layer should not be dirty. EXPECT_FALSE(LayerNeedsDisplay(test_layer.get())); - // This is just initialization, but SetNeedsCommit behavior is verified anyway - // to avoid warnings. - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBounds(test_bounds)); + // This is just initialization, but SetNeedsCommit behavior is verified + // anyway to avoid warnings. + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetBounds(test_bounds)); EXPECT_FALSE(LayerNeedsDisplay(test_layer.get())); // The real test begins here. @@ -972,12 +994,13 @@ // Case 3: SetNeedsDisplay() with an empty rect. EXPECT_FALSE(LayerNeedsDisplay(test_layer.get())); - EXPECT_SET_NEEDS_COMMIT(0, test_layer->SetNeedsDisplayRect(gfx::Rect())); + EXPECT_SET_NEEDS_COMMIT_WAS_NOT_CALLED( + test_layer->SetNeedsDisplayRect(gfx::Rect())); EXPECT_FALSE(LayerNeedsDisplay(test_layer.get())); SimulateCommitForLayer(test_layer.get()); // Case 4: SetNeedsDisplay() with a non-drawable layer - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(false)); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetIsDrawable(false)); SimulateCommitForLayer(test_layer.get()); EXPECT_FALSE(LayerNeedsDisplay(test_layer.get())); EXPECT_SET_NEEDS_UPDATE(0, test_layer->SetNeedsDisplayRect(dirty_rect)); @@ -988,7 +1011,7 @@ scoped_refptr<Layer> test_layer = Layer::Create(); EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(test_layer)); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(true)); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetIsDrawable(true)); FakeContentLayerClient client; scoped_refptr<PictureLayer> mask_layer1 = PictureLayer::Create(&client); @@ -999,37 +1022,50 @@ // Next, test properties that should call SetNeedsCommit (but not // SetNeedsDisplay). All properties need to be set to new values in order for // SetNeedsCommit to be called. - EXPECT_SET_NEEDS_COMMIT( - 1, test_layer->SetTransformOrigin(gfx::Point3F(1.23f, 4.56f, 0.f))); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBackgroundColor(SkColors::kLtGray)); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetMasksToBounds(true)); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetClipRect(gfx::Rect(1, 2, 3, 4))); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetRoundedCorner({1, 2, 3, 4})); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsFastRoundedCorner(true)); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetOpacity(0.5f)); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendMode(SkBlendMode::kHue)); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetContentsOpaque(true)); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPosition(gfx::PointF(4.f, 9.f))); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED( + test_layer->SetTransformOrigin(gfx::Point3F(1.23f, 4.56f, 0.f))); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED( + test_layer->SetBackgroundColor(SkColors::kLtGray)); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetMasksToBounds(true)); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED( + test_layer->SetClipRect(gfx::Rect(1, 2, 3, 4))); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED( + test_layer->SetRoundedCorner({1, 2, 3, 4})); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetIsFastRoundedCorner(true)); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetOpacity(0.5f)); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED( + test_layer->SetBlendMode(SkBlendMode::kHue)); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetContentsOpaque(true)); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED( + test_layer->SetPosition(gfx::PointF(4.f, 9.f))); // We can use any layer pointer here since we aren't syncing for real. - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetScrollable(gfx::Size(1, 1))); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUserScrollable(true, false)); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetScrollOffset(gfx::PointF(10, 10))); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetNonFastScrollableRegion( - Region(gfx::Rect(1, 1, 2, 2)))); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTransform( - gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0))); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED( + test_layer->SetScrollable(gfx::Size(1, 1))); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED( + test_layer->SetUserScrollable(true, false)); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED( + test_layer->SetScrollOffset(gfx::PointF(10, 10))); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED( + test_layer->SetNonFastScrollableRegion(Region(gfx::Rect(1, 1, 2, 2)))); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED( + test_layer->SetTransform(gfx::Transform(0.0, 0.0, 0.0, 0.0, 0.0, 0.0))); TouchActionRegion touch_action_region; touch_action_region.Union(TouchAction::kNone, gfx::Rect(10, 10)); - EXPECT_SET_NEEDS_COMMIT( - 1, test_layer->SetTouchActionRegion(std::move(touch_action_region))); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetForceRenderSurfaceForTesting(true)); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetHideLayerAndSubtree(true)); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetElementId(ElementId(2))); - - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED( + test_layer->SetTouchActionRegion(std::move(touch_action_region))); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED( + test_layer->SetForceRenderSurfaceForTesting(true)); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetHideLayerAndSubtree(true)); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetElementId(ElementId(2))); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED( + test_layer->SetCaptureBounds(viz::RegionCaptureBounds( + base::flat_map<viz::RegionCaptureCropId, gfx::Rect>{ + {viz::RegionCaptureCropId(123u, 456u), + gfx::Rect(0, 0, 640, 480)}}))); EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, test_layer->SetMaskLayer(mask_layer1)); - - // The above tests should not have caused a change to the needs_display flag. + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); + // The above tests should not have caused a change to the needs_display + // flag. EXPECT_FALSE(LayerNeedsDisplay(test_layer.get())); // As layers are removed from the tree, they will cause a tree sync. @@ -1050,8 +1086,8 @@ CommitAndPushProperties(test_layer.get(), impl_layer_ptr); EXPECT_EQ(gfx::Rect(0, 0, 5, 5), impl_layer_ptr->update_rect()); - // The LayerImpl's update_rect() should be accumulated here, since we did not - // do anything to clear it. + // The LayerImpl's update_rect() should be accumulated here, since we did + // not do anything to clear it. test_layer->SetNeedsDisplayRect(gfx::Rect(10, 10, 5, 5)); CommitAndPushProperties(test_layer.get(), impl_layer_ptr); EXPECT_EQ(gfx::Rect(0, 0, 15, 15), impl_layer_ptr->update_rect()); @@ -1074,7 +1110,7 @@ gfx::Transform transform; transform.Rotate(45.0); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTransform(transform)); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetTransform(transform)); EXPECT_FALSE(impl_layer->LayerPropertyChanged()); @@ -1094,7 +1130,8 @@ EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(test_layer)); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetRoundedCorner({1, 2, 3, 4})); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED( + test_layer->SetRoundedCorner({1, 2, 3, 4})); EXPECT_FALSE(impl_layer->LayerPropertyChanged()); @@ -1113,7 +1150,7 @@ EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(test_layer)); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetOpacity(0.5f)); + EXPECT_SET_NEEDS_COMMIT_WAS_CALLED(test_layer->SetOpacity(0.5f)); EXPECT_FALSE(impl_layer->LayerPropertyChanged()); @@ -1182,8 +1219,8 @@ FakeContentLayerClient client; scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); - // Set up a detached tree of layers. The host pointer should be nil for these - // layers. + // Set up a detached tree of layers. The host pointer should be nil for + // these layers. parent->AddChild(child); child->SetMaskLayer(mask); @@ -1255,8 +1292,9 @@ AssertLayerTreeHostMatchesForSubtree(parent.get(), first_layer_tree_host.get()); - // Now re-root the tree to a new host (simulating what we do on a context lost - // event). This should update the host pointers for all layers in the tree. + // Now re-root the tree to a new host (simulating what we do on a context + // lost event). This should update the host pointers for all layers in the + // tree. auto animation_host2 = AnimationHost::CreateForTesting(ThreadInstance::MAIN); std::unique_ptr<LayerTreeHost> second_layer_tree_host = factory.Create(animation_host2.get()); @@ -1289,8 +1327,8 @@ AssertLayerTreeHostMatchesForSubtree(first_parent.get(), first_layer_tree_host.get()); - // Now reparent the subtree starting at second_child to a layer in a different - // tree. + // Now reparent the subtree starting at second_child to a layer in a + // different tree. auto animation_host2 = AnimationHost::CreateForTesting(ThreadInstance::MAIN); std::unique_ptr<LayerTreeHost> second_layer_tree_host = factory.Create(animation_host2.get()); @@ -1327,7 +1365,8 @@ AssertLayerTreeHostMatchesForSubtree(parent.get(), layer_tree_host.get()); - // Replacing the mask should clear out the old mask's subtree's host pointers. + // Replacing the mask should clear out the old mask's subtree's host + // pointers. parent->SetMaskLayer(mask_replacement); EXPECT_EQ(nullptr, mask->layer_tree_host()); EXPECT_EQ(nullptr, mask_child->layer_tree_host()); @@ -1427,7 +1466,6 @@ LayerImpl::Create(host_impl_.active_tree(), 1); EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(root_layer)); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(5); // A layer that draws content should be hit testable. root_layer->SetIsDrawable(true); @@ -1435,6 +1473,7 @@ CommitAndPushProperties(root_layer.get(), impl_layer.get()); EXPECT_TRUE(impl_layer->draws_content()); EXPECT_TRUE(impl_layer->HitTestable()); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); // A layer that does not draw content and does not hit test without drawing // content should not be hit testable. @@ -1443,6 +1482,7 @@ CommitAndPushProperties(root_layer.get(), impl_layer.get()); EXPECT_FALSE(impl_layer->draws_content()); EXPECT_FALSE(impl_layer->HitTestable()); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); // |SetHitTestableWithoutDrawsContent| should cause a layer to become hit // testable even though it does not draw content. @@ -1450,6 +1490,7 @@ CommitAndPushProperties(root_layer.get(), impl_layer.get()); EXPECT_FALSE(impl_layer->draws_content()); EXPECT_TRUE(impl_layer->HitTestable()); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); } void ReceiveCopyOutputResult(int* result_count, @@ -1575,12 +1616,12 @@ EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(layer)); auto element_id = layer->element_id(); - EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(1); + EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()); layer_tree_host_->SetElementOpacityMutated(element_id, ElementListType::ACTIVE, 0.5f); Mock::VerifyAndClearExpectations(layer_tree_host_.get()); - EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(1); + EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()); gfx::Transform transform; transform.Rotate(45.0); layer_tree_host_->SetElementTransformMutated( @@ -1603,15 +1644,12 @@ EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, layer_tree_host_->SetRootLayer(test_layer)); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); - test_layer->SetElementId(ElementId(2)); - EXPECT_FALSE(impl_layer->element_id()); CommitAndPushProperties(test_layer.get(), impl_layer.get()); - EXPECT_EQ(ElementId(2), impl_layer->element_id()); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); } TEST_F(LayerTest, SetLayerTreeHostNotUsingLayerListsManagesElementId) { @@ -1621,7 +1659,6 @@ // Expect additional calls due to has-animation check and initialization // of keyframes. - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(3); scoped_refptr<AnimationTimeline> timeline = AnimationTimeline::Create(AnimationIdProvider::NextTimelineId()); animation_host_->AddAnimationTimeline(timeline); @@ -1629,11 +1666,13 @@ AddOpacityTransitionToElementWithAnimation(element_id, timeline, 10.0, 1.f, 0.f, false); EXPECT_TRUE(animation_host_->IsElementAnimating(element_id)); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id)); test_layer->SetLayerTreeHost(layer_tree_host_.get()); // Layer should now be registered by element id. EXPECT_EQ(test_layer, layer_tree_host_->LayerByElementId(element_id)); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); // We're expected to remove the animations before calling // SetLayerTreeHost(nullptr). @@ -1648,7 +1687,6 @@ // compositor is expensive and updated counts can wait until the next // commit to be pushed. See https://crbug.com/1083244. TEST_F(LayerTest, PushAnimationCountsLazily) { - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0); animation_host_->SetAnimationCounts(0); animation_host_->SetCurrentFrameHadRaf(true); animation_host_->SetNextFrameHasPendingRaf(true); @@ -1660,19 +1698,20 @@ *layer_tree_host_->property_trees()); EXPECT_TRUE(host_impl_.animation_host()->CurrentFrameHadRAF()); EXPECT_TRUE(host_impl_.animation_host()->HasSmilAnimation()); + EXPECT_FALSE(layer_tree_host_->GetNeedsCommitAndReset()); } TEST_F(LayerTest, SetElementIdNotUsingLayerLists) { scoped_refptr<Layer> test_layer = Layer::Create(); test_layer->SetLayerTreeHost(layer_tree_host_.get()); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(2); ElementId element_id = ElementId(2); EXPECT_EQ(nullptr, layer_tree_host_->LayerByElementId(element_id)); test_layer->SetElementId(element_id); // Layer should now be registered by element id. EXPECT_EQ(test_layer, layer_tree_host_->LayerByElementId(element_id)); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); ElementId other_element_id = ElementId(3); test_layer->SetElementId(other_element_id); @@ -1682,6 +1721,7 @@ EXPECT_EQ(test_layer, layer_tree_host_->LayerByElementId(other_element_id)); test_layer->SetLayerTreeHost(nullptr); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); } // Verifies that when mirror count of the layer is incremented or decremented, @@ -1701,7 +1741,8 @@ EXPECT_EQ(0u, layer_tree_host_->GetPendingCommitState() ->layers_that_should_push_properties.size()); - // Incrementing mirror count from zero should trigger property trees rebuild. + // Incrementing mirror count from zero should trigger property trees + // rebuild. test_layer->IncrementMirrorCount(); EXPECT_EQ(1, test_layer->mirror_count()); EXPECT_TRUE(layer_tree_host_->property_trees()->needs_rebuild()); @@ -1745,6 +1786,64 @@ test_layer->SetLayerTreeHost(nullptr); } +TEST_F(LayerTest, UpdatingCaptureBounds) { + static const viz::RegionCaptureBounds kEmptyBounds; + static const viz::RegionCaptureBounds kPopulatedBounds( + base::flat_map<viz::RegionCaptureCropId, gfx::Rect>{ + {viz::RegionCaptureCropId(123u, 456u), gfx::Rect(0, 0, 640, 480)}}); + static const viz::RegionCaptureBounds kUpdatedBounds( + base::flat_map<viz::RegionCaptureCropId, gfx::Rect>{ + {viz::RegionCaptureCropId(123u, 456u), gfx::Rect(0, 0, 1280, 720)}}); + + // We don't track full tree syncs in this test. + EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AtLeast(1)); + + scoped_refptr<Layer> layer = Layer::Create(); + layer_tree_host_->SetRootLayer(layer); + + // Clear the updates caused by setting a new root layer. + layer->ClearSubtreePropertyChangedForTesting(); + layer_tree_host_->property_trees()->set_needs_rebuild(false); + + // An empty bounds when none is currently set should not cause an update. + layer->SetCaptureBounds(kEmptyBounds); + EXPECT_FALSE(layer_tree_host_->property_trees()->needs_rebuild()); + EXPECT_FALSE(layer->subtree_property_changed()); + EXPECT_FALSE(layer_tree_host_->GetNeedsCommitAndReset()); + + // Setting to a new bounds should cause an update. + layer->SetCaptureBounds(kPopulatedBounds); + EXPECT_TRUE(layer_tree_host_->property_trees()->needs_rebuild()); + EXPECT_TRUE(layer->subtree_property_changed()); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); + + // Reset properties. + layer->ClearSubtreePropertyChangedForTesting(); + layer_tree_host_->property_trees()->set_needs_rebuild(false); + + // Setting to the same bounds should not, however. + layer->SetCaptureBounds(kPopulatedBounds); + EXPECT_FALSE(layer_tree_host_->property_trees()->needs_rebuild()); + EXPECT_FALSE(layer->subtree_property_changed()); + EXPECT_FALSE(layer_tree_host_->GetNeedsCommitAndReset()); + + // Switching to a differently valued bounds should cause an update. + layer->SetCaptureBounds(kUpdatedBounds); + EXPECT_TRUE(layer_tree_host_->property_trees()->needs_rebuild()); + EXPECT_TRUE(layer->subtree_property_changed()); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); + + // Reset properties. + layer->ClearSubtreePropertyChangedForTesting(); + layer_tree_host_->property_trees()->set_needs_rebuild(false); + + // Finally, setting to empty should cause an update. + layer->SetCaptureBounds(kEmptyBounds); + EXPECT_TRUE(layer_tree_host_->property_trees()->needs_rebuild()); + EXPECT_TRUE(layer->subtree_property_changed()); + EXPECT_TRUE(layer_tree_host_->GetNeedsCommitAndReset()); +} + TEST_F(LayerTest, UpdatingClipRect) { const gfx::Size kRootSize(200, 200); const gfx::Vector2dF kParentOffset(10.f, 20.f); @@ -1763,7 +1862,6 @@ scoped_refptr<Layer> clipped_4 = Layer::Create(); EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AtLeast(1)); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); layer_tree_host_->SetRootLayer(root); root->AddChild(parent); parent->AddChild(clipped_1); @@ -1805,9 +1903,9 @@ EXPECT_EQ(gfx::RectF(kClipRect) + kParentOffset, node_3->clip); EXPECT_EQ(gfx::RectF(kClipRect) + kParentOffset, node_4->clip); - // The following layer properties should result in the layer being clipped to - // its bounds along with being clipped by the clip rect. Check if the final - // rect on the clip node is set correctly. + // The following layer properties should result in the layer being clipped + // to its bounds along with being clipped by the clip rect. Check if the + // final rect on the clip node is set correctly. // Setting clip to layer bounds. clipped_1->SetMasksToBounds(true); @@ -1869,7 +1967,6 @@ scoped_refptr<Layer> layer_5 = Layer::Create(); EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AtLeast(1)); - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); layer_tree_host_->SetRootLayer(root); root->AddChild(layer_1); root->AddChild(layer_2);
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 438dabcd..8993cc58 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc
@@ -295,9 +295,10 @@ if (current_draw_mode_ == DRAW_MODE_RESOURCELESS_SOFTWARE) { DCHECK(shared_quad_state->quad_layer_rect.origin() == gfx::Point(0, 0)); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. AppendDebugBorderQuad( render_pass, shared_quad_state->quad_layer_rect, shared_quad_state, - append_quads_data, DebugColors::DirectPictureBorderColor(), + append_quads_data, DebugColors::DirectPictureBorderColor().toSkColor(), DebugColors::DirectPictureBorderWidth(device_scale_factor)); gfx::Rect geometry_rect = shared_quad_state->visible_quad_layer_rect; @@ -369,28 +370,30 @@ SkColor color; float width; if (*iter && iter->draw_info().IsReadyToDraw()) { + // TODO(crbug/1308932): Remove all instances of toSkColor below and make + // all SkColor4f. TileDrawInfo::Mode mode = iter->draw_info().mode(); if (mode == TileDrawInfo::SOLID_COLOR_MODE) { - color = DebugColors::SolidColorTileBorderColor(); + color = DebugColors::SolidColorTileBorderColor().toSkColor(); width = DebugColors::SolidColorTileBorderWidth(device_scale_factor); } else if (mode == TileDrawInfo::OOM_MODE) { - color = DebugColors::OOMTileBorderColor(); + color = DebugColors::OOMTileBorderColor().toSkColor(); width = DebugColors::OOMTileBorderWidth(device_scale_factor); } else if (iter.resolution() == HIGH_RESOLUTION) { - color = DebugColors::HighResTileBorderColor(); + color = DebugColors::HighResTileBorderColor().toSkColor(); width = DebugColors::HighResTileBorderWidth(device_scale_factor); } else if (iter.resolution() == LOW_RESOLUTION) { - color = DebugColors::LowResTileBorderColor(); + color = DebugColors::LowResTileBorderColor().toSkColor(); width = DebugColors::LowResTileBorderWidth(device_scale_factor); } else if (iter->contents_scale_key() > max_contents_scale) { - color = DebugColors::ExtraHighResTileBorderColor(); + color = DebugColors::ExtraHighResTileBorderColor().toSkColor(); width = DebugColors::ExtraHighResTileBorderWidth(device_scale_factor); } else { - color = DebugColors::ExtraLowResTileBorderColor(); + color = DebugColors::ExtraLowResTileBorderColor().toSkColor(); width = DebugColors::ExtraLowResTileBorderWidth(device_scale_factor); } } else { - color = DebugColors::MissingTileBorderColor(); + color = DebugColors::MissingTileBorderColor().toSkColor(); width = DebugColors::MissingTileBorderWidth(device_scale_factor); } @@ -408,14 +411,16 @@ } if (layer_tree_impl()->debug_state().highlight_non_lcd_text_layers) { - SkColor color = + // TODO(crbug/1308932): Remove all instances of toSkColor below and make all + // SkColor4f. + SkColor4f color = DebugColors::NonLCDTextHighlightColor(lcd_text_disallowed_reason()); - if (color != SK_ColorTRANSPARENT && + if (color != SkColors::kTransparent && GetRasterSource()->GetDisplayItemList()->AreaOfDrawText( gfx::Rect(bounds()))) { render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>()->SetNew( - shared_quad_state, debug_border_rect, debug_border_rect, color, - append_quads_data); + shared_quad_state, debug_border_rect, debug_border_rect, + color.toSkColor(), append_quads_data); } } @@ -516,7 +521,8 @@ SkColor color = safe_opaque_background_color(); if (ShowDebugBorders(DebugBorderType::LAYER)) { // Fill the whole tile with the missing tile color. - color = DebugColors::DefaultCheckerboardColor(); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. + color = DebugColors::DefaultCheckerboardColor().toSkColor(); } auto* quad = render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>(); @@ -1868,10 +1874,12 @@ layer_tree_impl() ? layer_tree_impl()->device_scale_factor() : 1; if (IsDirectlyCompositedImage()) { - *color = DebugColors::ImageLayerBorderColor(); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. + *color = DebugColors::ImageLayerBorderColor().toSkColor(); *width = DebugColors::ImageLayerBorderWidth(device_scale_factor); } else { - *color = DebugColors::TiledContentLayerBorderColor(); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. + *color = DebugColors::TiledContentLayerBorderColor().toSkColor(); *width = DebugColors::TiledContentLayerBorderWidth(device_scale_factor); } }
diff --git a/cc/layers/render_surface_impl.cc b/cc/layers/render_surface_impl.cc index 6636586..d274baf 100644 --- a/cc/layers/render_surface_impl.cc +++ b/cc/layers/render_surface_impl.cc
@@ -111,7 +111,8 @@ } SkColor RenderSurfaceImpl::GetDebugBorderColor() const { - return DebugColors::SurfaceBorderColor(); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. + return DebugColors::SurfaceBorderColor().toSkColor(); } float RenderSurfaceImpl::GetDebugBorderWidth() const {
diff --git a/cc/layers/surface_layer_impl.cc b/cc/layers/surface_layer_impl.cc index b58be06..4739957 100644 --- a/cc/layers/surface_layer_impl.cc +++ b/cc/layers/surface_layer_impl.cc
@@ -219,7 +219,8 @@ void SurfaceLayerImpl::GetDebugBorderProperties(SkColor* color, float* width) const { - *color = DebugColors::SurfaceLayerBorderColor(); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. + *color = DebugColors::SurfaceLayerBorderColor().toSkColor(); *width = DebugColors::SurfaceLayerBorderWidth( layer_tree_impl() ? layer_tree_impl()->device_scale_factor() : 1); }
diff --git a/cc/paint/display_item_list_unittest.cc b/cc/paint/display_item_list_unittest.cc index 3246ef6..90608ac 100644 --- a/cc/paint/display_item_list_unittest.cc +++ b/cc/paint/display_item_list_unittest.cc
@@ -31,6 +31,7 @@ #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/skia_conversions.h" +#include "ui/gfx/geometry/transform.h" namespace cc {
diff --git a/cc/test/pixel_test_output_surface.cc b/cc/test/pixel_test_output_surface.cc index d0c52621..fb3c64d 100644 --- a/cc/test/pixel_test_output_surface.cc +++ b/cc/test/pixel_test_output_surface.cc
@@ -21,9 +21,7 @@ PixelTestOutputSurface::PixelTestOutputSurface( std::unique_ptr<viz::SoftwareOutputDevice> software_device) - : OutputSurface(std::move(software_device)) { - capabilities_.supports_stencil = true; -} + : OutputSurface(std::move(software_device)) {} PixelTestOutputSurface::~PixelTestOutputSurface() = default; @@ -35,18 +33,10 @@ void PixelTestOutputSurface::DiscardBackbuffer() {} -void PixelTestOutputSurface::BindFramebuffer() {} - void PixelTestOutputSurface::Reshape(const ReshapeParams& params) { software_device()->Resize(params.size, params.device_scale_factor); } -bool PixelTestOutputSurface::HasExternalStencilTest() const { - return false; -} - -void PixelTestOutputSurface::ApplyExternalStencil() {} - void PixelTestOutputSurface::SwapBuffers(viz::OutputSurfaceFrame frame) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&PixelTestOutputSurface::SwapBuffersCallback, @@ -66,21 +56,6 @@ return false; } -unsigned PixelTestOutputSurface::GetOverlayTextureId() const { - return 0; -} - -uint32_t PixelTestOutputSurface::GetFramebufferCopyTextureFormat() { - // This format will work if the |context_provider| has an RGB or RGBA - // framebuffer. For now assume tests do not want/care about alpha in - // the root render pass. - return GL_RGB; -} - -unsigned PixelTestOutputSurface::UpdateGpuFence() { - return 0; -} - void PixelTestOutputSurface::SetUpdateVSyncParametersCallback( viz::UpdateVSyncParametersCallback callback) {}
diff --git a/cc/test/pixel_test_output_surface.h b/cc/test/pixel_test_output_surface.h index 95dc609..7dc4eedf 100644 --- a/cc/test/pixel_test_output_surface.h +++ b/cc/test/pixel_test_output_surface.h
@@ -24,15 +24,9 @@ void BindToClient(viz::OutputSurfaceClient* client) override; void EnsureBackbuffer() override; void DiscardBackbuffer() override; - void BindFramebuffer() override; void Reshape(const ReshapeParams& params) override; - bool HasExternalStencilTest() const override; - void ApplyExternalStencil() override; void SwapBuffers(viz::OutputSurfaceFrame frame) override; bool IsDisplayedAsOverlayPlane() const override; - unsigned GetOverlayTextureId() const override; - uint32_t GetFramebufferCopyTextureFormat() override; - unsigned UpdateGpuFence() override; void SetUpdateVSyncParametersCallback( viz::UpdateVSyncParametersCallback callback) override; void SetDisplayTransformHint(gfx::OverlayTransform transform) override {}
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index 6c60156..abbbfc5db 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -1594,12 +1594,6 @@ } if (is_android) { - java_cpp_enum("assist_ranker_prediction_enum_javagen") { - sources = [ - "browser/android/contextualsearch/contextual_search_ranker_logger_impl.h", - ] - } - java_cpp_enum("partner_bookmarks_javagen") { sources = [ "browser/android/bookmarks/partner_bookmarks_reader.h" ] }
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index fb017b9..2f9b30d0 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -666,7 +666,6 @@ ":chrome_strict_mode_switch", ":resource_id_javagen", ":vr_build_config", - "//chrome:assist_ranker_prediction_enum_javagen", "//chrome:instant_apps_reasons_enum_javagen", "//chrome:offline_pages_enum_javagen", "//chrome:quick_action_category_enum_javagen",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelMetrics.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelMetrics.java index 0f475fbe..f4cddb1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelMetrics.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanelMetrics.java
@@ -344,8 +344,6 @@ mInteractionRecorder.logOutcome( ContextualSearchInteractionRecorder.Feature.OUTCOME_WAS_PANEL_OPENED, mWasSearchContentViewSeen); - ContextualSearchUma.logRankerInference(mWasSearchContentViewSeen, - mInteractionRecorder.getPredictionForTapSuppression()); mInteractionRecorder.logOutcome( ContextualSearchInteractionRecorder.Feature.OUTCOME_WAS_CARDS_DATA_SHOWN, mWasContextualCardsDataShown);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchHeuristic.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchHeuristic.java index 0388246a2..72e5b76 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchHeuristic.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchHeuristic.java
@@ -52,14 +52,6 @@ } /** - * Logs the heuristic to UMA and UKM through Ranker logging for the purpose of Tap Suppression. - * @param recorder A logger to log to. - */ - protected void logRankerTapSuppression(ContextualSearchInteractionRecorder recorder) { - // Default is to not log. - } - - /** * Logs a Ranker outcome using the heuristic for the purpose of Ranker Tap Suppression. * @param recorder A logger to log to. */ @@ -68,13 +60,6 @@ } /** - * Allows a heuristic to override a machine-learning model's Tap Suppression. - */ - protected boolean shouldOverrideMlTapSuppression() { - return false; - } - - /** * Clamps an input value into a range of 1-10 inclusive. * @param value The value to limit. * @return A value that's at least 1 and at most 10.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchHeuristics.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchHeuristics.java index 4161dce..8832cc5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchHeuristics.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchHeuristics.java
@@ -64,16 +64,6 @@ } /** - * Logs all the heuristics that want to provide a Ranker "feature" to the given recorder. - * @param recorder The recorder to log to. - */ - public void logRankerTapSuppression(ContextualSearchInteractionRecorder recorder) { - for (ContextualSearchHeuristic heuristic : mHeuristics) { - heuristic.logRankerTapSuppression(recorder); - } - } - - /** * Logs all the heuristics that want to provide outcomes to Ranker to the given recorder. * @param recorder The logger to log to. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInteractionRecorder.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInteractionRecorder.java index 5a9dd62..74d84e4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInteractionRecorder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchInteractionRecorder.java
@@ -97,26 +97,6 @@ */ void logOutcome(@Feature int feature, Object value); - /** - * Tries to run the machine intelligence model for tap suppression and returns an int that - * describes whether the prediction was obtainable and what it was. - * See chrome/browser/android/contextualsearch/contextual_search_ranker_logger_impl.h for - * details on the {@link AssistRankerPrediction} possibilities. - * @return An integer that encodes the prediction result. - */ - @AssistRankerPrediction - int runPredictionForTapSuppression(); - - /** - * Gets the previous result from trying to run the machine intelligence model for tap - * suppression. A previous call to {@link #runPredictionForTapSuppression} is required. - * See chrome/browser/android/contextualsearch/contextual_search_ranker_logger_impl.h for - * details on the {@link AssistRankerPrediction} possibilities. - * @return An integer that encodes the prediction. - */ - @AssistRankerPrediction - int getPredictionForTapSuppression(); - /** Stores an Event ID from the server that we should persist along with user interactions. */ void persistInteraction(long eventId);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRankerLoggerImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRankerLoggerImpl.java index 8eed3c8..2c49605 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRankerLoggerImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchRankerLoggerImpl.java
@@ -27,14 +27,6 @@ // The WebContents of the base page that the log data is associated with. private WebContents mBasePageWebContents; - // Whether inference has already occurred for this interaction (and calling #logFeature is no - // longer allowed). - private boolean mHasInferenceOccurred; - - // What kind of ML prediction we were able to get. - private @AssistRankerPrediction int mAssistRankerPrediction = - AssistRankerPrediction.UNDETERMINED; - // Map that accumulates all of the Features to log for a specific user-interaction. private Map<Integer /* @Feature */, Object> mFeaturesToLog; @@ -111,7 +103,6 @@ public void setupLoggingForPage(@Nullable WebContents basePageWebContents) { mIsLoggingReadyForPage = true; mBasePageWebContents = basePageWebContents; - mHasInferenceOccurred = false; ContextualSearchRankerLoggerImplJni.get().setupLoggingAndRanker( mNativePointer, ContextualSearchRankerLoggerImpl.this, basePageWebContents); } @@ -125,37 +116,16 @@ @Override public void logOutcome(@Feature int feature, Object value) { assert mIsLoggingReadyForPage; - assert mHasInferenceOccurred; if (!isEnabled()) return; logInternal(feature, value); } @Override - public @AssistRankerPrediction int runPredictionForTapSuppression() { - assert mIsLoggingReadyForPage; - assert !mHasInferenceOccurred; - mHasInferenceOccurred = true; - if (isEnabled() && mBasePageWebContents != null) { - mAssistRankerPrediction = ContextualSearchRankerLoggerImplJni.get().runInference( - mNativePointer, ContextualSearchRankerLoggerImpl.this); - ContextualSearchUma.logRecordedFeaturesToRanker(); - } - return mAssistRankerPrediction; - } - - @Override - public @AssistRankerPrediction int getPredictionForTapSuppression() { - return mAssistRankerPrediction; - } - - @Override public void reset() { mIsLoggingReadyForPage = false; - mHasInferenceOccurred = false; mFeaturesToLog = null; mBasePageWebContents = null; - mAssistRankerPrediction = AssistRankerPrediction.UNDETERMINED; } @Override @@ -164,7 +134,6 @@ if (mBasePageWebContents != null && mFeaturesToLog != null && !mFeaturesToLog.isEmpty()) { assert mIsLoggingReadyForPage; - assert mHasInferenceOccurred; mOutcomesLoggedForTesting = mFeaturesToLog; ContextualSearchUma.logRecordedOutcomesToRanker(); @@ -230,9 +199,6 @@ ContextualSearchRankerLoggerImpl caller); void setupLoggingAndRanker(long nativeContextualSearchRankerLoggerImpl, ContextualSearchRankerLoggerImpl caller, WebContents basePageWebContents); - // Returns an AssistRankerPrediction integer value. - int runInference(long nativeContextualSearchRankerLoggerImpl, - ContextualSearchRankerLoggerImpl caller); void writeLogAndReset(long nativeContextualSearchRankerLoggerImpl, ContextualSearchRankerLoggerImpl caller);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionController.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionController.java index 1687e76..4dd881b4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchSelectionController.java
@@ -467,31 +467,10 @@ mHandler.handleMetricsForWouldSuppressTap(tapHeuristics); boolean shouldSuppressTapBasedOnHeuristics = tapHeuristics.shouldSuppressTap(); - boolean shouldOverrideMlTapSuppression = tapHeuristics.shouldOverrideMlTapSuppression(); - - // Make sure Tap Suppression features are consistent. - assert !ContextualSearchFieldTrial.getSwitch( - ContextualSearchSwitch.IS_CONTEXTUAL_SEARCH_ML_TAP_SUPPRESSION_ENABLED) - || interactionRecorder.isQueryEnabled() - : "Tap Suppression requires the Ranker Query feature to be enabled!"; - - // If we're suppressing based on heuristics then Ranker doesn't need to know about it. - @AssistRankerPrediction - int tapPrediction = AssistRankerPrediction.UNDETERMINED; - if (!shouldSuppressTapBasedOnHeuristics) { - tapHeuristics.logRankerTapSuppression(interactionRecorder); - tapPrediction = interactionRecorder.runPredictionForTapSuppression(); - ContextualSearchUma.logRankerPrediction(tapPrediction); - } // Make the suppression decision and act upon it. - boolean shouldSuppressTapBasedOnRanker = (tapPrediction == AssistRankerPrediction.SUPPRESS) - && ContextualSearchFieldTrial.getSwitch( - ContextualSearchSwitch.IS_CONTEXTUAL_SEARCH_ML_TAP_SUPPRESSION_ENABLED) - && !shouldOverrideMlTapSuppression; - if (shouldSuppressTapBasedOnHeuristics || shouldSuppressTapBasedOnRanker) { - Log.i(TAG, "Tap suppressed due to Ranker: %s, heuristics: %s", - shouldSuppressTapBasedOnRanker, shouldSuppressTapBasedOnHeuristics); + if (shouldSuppressTapBasedOnHeuristics) { + Log.i(TAG, "Tap suppressed due to heuristics: %s", shouldSuppressTapBasedOnHeuristics); mHandler.handleSuppressedTap(); } else { mHandler.handleNonSuppressedTap(mTapTimeNanoseconds); @@ -499,8 +478,7 @@ if (mTapTimeNanoseconds != 0) { // Remember the tap state for subsequent tap evaluation. - mLastTapState = new ContextualSearchTapState( - x, y, mTapTimeNanoseconds, shouldSuppressTapBasedOnRanker); + mLastTapState = new ContextualSearchTapState(x, y, mTapTimeNanoseconds); } else { mLastTapState = null; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapState.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapState.java index 43d8bb2..491a69b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapState.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTapState.java
@@ -5,27 +5,24 @@ package org.chromium.chrome.browser.contextualsearch; /** - * Encapsulates the state of a recent Tap gesture; x, y position and if ML-suppressed. + * Encapsulates the state of a recent Tap gesture; x, y position and the timestamp. * Instances of this class are immutable. */ class ContextualSearchTapState { private final float mX; private final float mY; private final long mTapTimeNanoseconds; - private final boolean mWasMlSuppressed; /** * Constructs a Tap at the given x,y position and indicates if the tap was suppressed or not. * @param x The x coordinate of the current tap. * @param y The y coordinate of the current tap. * @param tapTimeNanoseconds The timestamp when the Tap occurred. - * @param wasMlSuppressed Whether this tap was suppressed by the ML model. */ - ContextualSearchTapState(float x, float y, long tapTimeNanoseconds, boolean wasMlSuppressed) { + ContextualSearchTapState(float x, float y, long tapTimeNanoseconds) { mX = x; mY = y; mTapTimeNanoseconds = tapTimeNanoseconds; - mWasMlSuppressed = wasMlSuppressed; } /** @@ -48,11 +45,4 @@ long tapTimeNanoseconds() { return mTapTimeNanoseconds; } - - /** - * @return Whether this Tap was suppressed by an ML model. - */ - boolean wasMlSuppressed() { - return mWasMlSuppressed; - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java index 711f551..edfccf3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchUma.java
@@ -769,43 +769,6 @@ "Search.ContextualSearch.CardTag", cardTagEnum, CardTag.NUM_ENTRIES); } - /** - * Logs results-seen when we have a useful Ranker prediction inference. - * @param wasPanelSeen Whether the panel was seen. - * @param predictionKind An integer reflecting the Ranker prediction, e.g. that this is a good - * time to suppress triggering because the likelihood of opening the panel is relatively - * low. - */ - public static void logRankerInference( - boolean wasPanelSeen, @AssistRankerPrediction int predictionKind) { - if (predictionKind == AssistRankerPrediction.SHOW) { - RecordHistogram.recordEnumeratedHistogram( - "Search.ContextualSearch.Ranker.NotSuppressed.ResultsSeen", - wasPanelSeen ? Results.SEEN : Results.NOT_SEEN, Results.NUM_ENTRIES); - } else if (predictionKind == AssistRankerPrediction.SUPPRESS) { - RecordHistogram.recordEnumeratedHistogram( - "Search.ContextualSearch.Ranker.WouldSuppress.ResultsSeen", - wasPanelSeen ? Results.SEEN : Results.NOT_SEEN, Results.NUM_ENTRIES); - } - } - - /** - * Logs Ranker's prediction of whether or not to suppress. - * @param predictionKind An integer reflecting the Ranker prediction, e.g. that this is a good - * time to suppress triggering because the likelihood of opening the panel is relatively - * low. - */ - public static void logRankerPrediction(@AssistRankerPrediction int predictionKind) { - // For now we just log whether or not suppression is predicted. - RecordHistogram.recordBooleanHistogram("Search.ContextualSearch.Ranker.Suppressed", - predictionKind == AssistRankerPrediction.SUPPRESS); - } - - /** Logs that Ranker recorded a set of features for training or inference. */ - public static void logRecordedFeaturesToRanker() { - logRecordedToRanker(false); - } - /** Logs that Ranker recorded a set of outcomes for training or inference. */ public static void logRecordedOutcomesToRanker() { logRecordedToRanker(true);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/TapSuppressionHeuristics.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/TapSuppressionHeuristics.java index 0f3aafdd..1ff21851 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/TapSuppressionHeuristics.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/TapSuppressionHeuristics.java
@@ -54,14 +54,4 @@ } return false; } - - /** - * @return Whether the Tap should override an ML suppression. - */ - boolean shouldOverrideMlTapSuppression() { - for (ContextualSearchHeuristic heuristic : mHeuristics) { - if (heuristic.shouldOverrideMlTapSuppression()) return true; - } - return false; - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabObserver.java index ef2ec96f..8a58f6a5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabObserver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabObserver.java
@@ -187,7 +187,7 @@ boolean firstNavigation = mFirstCommitTimestamp == 0; boolean isFirstMainFrameCommit = firstNavigation && navigation.hasCommitted() && !navigation.isErrorPage() && navigation.isInPrimaryMainFrame() - && !navigation.isSameDocument() && !navigation.isFragmentNavigation(); + && !navigation.isSameDocument(); if (isFirstMainFrameCommit) mFirstCommitTimestamp = SystemClock.elapsedRealtime(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java index e967362..6f1ea7f7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java
@@ -181,7 +181,6 @@ boolean isTrackedPage = navigation.hasCommitted() && navigation.isInPrimaryMainFrame() && !navigation.isErrorPage() && !navigation.isSameDocument() - && !navigation.isFragmentNavigation() && UrlUtilities.isHttpOrHttps(navigation.getUrl()); registerFinishNavigation(isTrackedPage); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountsReloadingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountsReloadingTest.java index 5847eda..bf60bcf 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountsReloadingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/AccountsReloadingTest.java
@@ -4,8 +4,6 @@ package org.chromium.chrome.browser.signin; -import android.os.Build; - import androidx.test.filters.MediumTest; import org.junit.Assert; @@ -19,7 +17,6 @@ import org.chromium.base.Callback; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CriteriaHelper; -import org.chromium.base.test.util.DisableIf; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.signin.services.IdentityServicesProvider; @@ -197,7 +194,6 @@ @Test @MediumTest - @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.O, message = "crbug/1254427") public void testRefreshTokenUpdateWhenSignedInAndSyncUserAddsNewAccount() { final CoreAccountInfo account1 = mAccountManagerTestRule.addTestAccountThenSigninAndEnableSync();
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc index b5a7c2f..c2c7039 100644 --- a/chrome/app/chrome_main_delegate.cc +++ b/chrome/app/chrome_main_delegate.cc
@@ -24,6 +24,7 @@ #include "base/process/memory.h" #include "base/process/process.h" #include "base/process/process_handle.h" +#include "base/scoped_add_feature_flags.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/task/sequence_manager/sequence_manager_impl.h" @@ -80,6 +81,7 @@ #include "ppapi/buildflags/buildflags.h" #include "printing/buildflags/buildflags.h" #include "services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.h" +#include "third_party/blink/public/common/features.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/ui_base_switches.h" @@ -911,6 +913,16 @@ #endif // BUILDFLAG(IS_WIN) + { + base::ScopedAddFeatureFlags features( + base::CommandLine::ForCurrentProcess()); + + // Disable Event.path on Canary and Dev to help the deprecation and removal. + // See crbug.com/1277431 for more details. + if (chrome::GetChannel() < version_info::Channel::BETA) + features.DisableIfNotSet(::blink::features::kEventPath); + } + chrome::RegisterPathProvider(); #if BUILDFLAG(IS_CHROMEOS_ASH) ash::RegisterPathProvider();
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 2b3b6e6..9040867 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -5302,55 +5302,54 @@ <!-- End Extension Settings Overridden Dialog strings. --> <!-- Force Installed Deprecated Apps Deletion Dialog strings. --> <message name="IDS_FORCE_INSTALLED_DEPRECATED_APPS_CONTENT" desc="Content of the force installed deprecated app dialog"> - Your administrator installed "<ph name="EXTENSION_NAME">$1<ex>Google Docs</ex></ph>" but this Chrome App is no longer supported. Contact your administrator to remove it. - </message> - <message name="IDS_FORCE_INSTALLED_PREINSTALLED_DEPRECATED_APPS_TITLE" desc="Title of the force installed and pre-installed deprecated app dialog"> - <ph name="EXTENSION_NAME">$1<ex>Google Docs</ex></ph> needs to be updated - </message> - <message name="IDS_FORCE_INSTALLED_PREINSTALLED_DEPRECATED_APPS_CONTENT" desc="Content of the force installed and pre-installed deprecated app dialog"> - Contact your administrator for the newest version. - </message> - <message name="IDS_FORCE_INSTALLED_DEPRECATED_APPS_LEARN_MORE_AX_LABEL" desc="Accessibility label text for IDS_DEPRECATED_APPS_LEARN_MORE link"> - Learn more about unsupported Chrome Apps + Old versions of Chrome Apps won't open after December 2022. Contact your administrator to update to a new version or remove this app. </message> <!-- End Force Installed Deprecated Apps Deletion Dialog strings. --> <!-- Deprecated Apps Deletion Dialog strings. --> - <message name="IDS_DEPRECATED_APPS_RENDERER_TITLE" desc="The title of the deprecated app dialog"> - {NUM_APPS, plural, - =1 {Unsupported App} - other {Unsupported Apps}} + <message name="IDS_DEPRECATED_APPS_RENDERER_TITLE_PLURAL" desc="The title of the deprecated app dialog"> + <ph name="APPS">$1<ex>2</ex></ph> apps are no longer supported </message> - <message name="IDS_DEPRECATED_APPS_MONITOR_RENDERER" desc="States how many deprecated apps are present, with a link to a help article"> - {NUM_APPS, plural, - =1 {1 of your apps is no longer supported.} - other {# of your apps are no longer supported.}} + <message name="IDS_DEPRECATED_APPS_RENDERER_TITLE_WITH_APP_NAME" desc="The title of the deprecated app dialog with the app name"> + "<ph name="EXTENSION_NAME">$1<ex>Google Docs</ex></ph>" is no longer supported + </message> + <message name="IDS_DEPRECATED_APPS_MONITOR_RENDERER" desc="Dialog content that educates users that Chrome Apps will soon no longer launch."> + Old versions of Chrome apps won't open after December 2022. You can check if there's a new version available. </message> <message name="IDS_DEPRECATED_APPS_LEARN_MORE" desc="Redirects to a link with more information on chrome apps deprecation"> Learn more </message> + <message name="IDS_DEPRECATED_APPS_LEARN_MORE_AX_LABEL" desc="Accessibility label text for IDS_DEPRECATED_APPS_LEARN_MORE link"> + Learn more about unsupported Chrome apps + </message> <message name="IDS_DEPRECATED_APPS_DELETION_LINK" desc="Contains link to trigger the deprecated apps deletion dialog from chrome://apps"> {NUM_APPS, plural, - =1 {Delete 1 unsupported app} - other {Delete # unsupported apps}} + =1 {Remove 1 unsupported app} + other {Remove # unsupported apps}} </message> <if expr="use_titlecase"> - <message name="IDS_DEPRECATED_APPS_OK_LABEL" desc="Label for OK button on deprecated apps dialog"> + <message name="IDS_DEPRECATED_APPS_OK_LABEL" desc="Label for OK button to delete deprecated apps on deprecated apps dialog"> {NUM_APPS, plural, - =1 {Delete App Now} - other {Delete Apps Now}} + =1 {Remove App} + other {Remove Apps}} </message> <message name="IDS_DEPRECATED_APPS_CANCEL_LABEL" desc="Label for Cancel button on deprecated apps dialog"> - Ask Next Time + Cancel + </message> + <message name="IDS_DEPRECATED_APPS_LAUNCH_ANYWAY_LABEL" desc="Label for button cancel button to launch the app anyways in the deprecated apps dialog"> + Open Anyway </message> </if> <if expr="not use_titlecase"> - <message name="IDS_DEPRECATED_APPS_OK_LABEL" desc="Label for OK button on deprecated apps dialog"> + <message name="IDS_DEPRECATED_APPS_OK_LABEL" desc="Label for OK button to delete deprecated apps on deprecated apps dialog"> {NUM_APPS, plural, - =1 {Delete app now} - other {Delete apps now}} + =1 {Remove app} + other {Remove apps}} </message> <message name="IDS_DEPRECATED_APPS_CANCEL_LABEL" desc="Label for Cancel button on deprecated apps dialog"> - Ask next time + Cancel + </message> + <message name="IDS_DEPRECATED_APPS_LAUNCH_ANYWAY_LABEL" desc="Label for button cancel button to launch the app anyways in the deprecated apps dialog"> + Open anyway </message> </if> <!-- End Deprecated Apps Deletion Dialog strings. --> @@ -13040,6 +13039,12 @@ <!-- Input overlay strings --> <if expr="chromeos_ash"> + <message name="IDS_INPUT_OVERLAY_GAME_CONTROLS_ALPHA" desc="Generic feature name during alpha phase, to be displayed in educational and settigns UI."> + Game controls + </message> + <message name="IDS_INPUT_OVERLAY_ACCESSIBILITY_ALPHA" desc="Text tied to the close button on Settings menu, readable via Chromevox."> + Close game controls + </message> <message name="IDS_INPUT_OVERLAY_MENU_ENTRY_BUTTON" desc="Button to access Input Overlay's settings menu."> Game Control </message>
diff --git a/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_CANCEL_LABEL.png.sha1 b/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_CANCEL_LABEL.png.sha1 index e20a484..26ea844 100644 --- a/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_CANCEL_LABEL.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_CANCEL_LABEL.png.sha1
@@ -1 +1 @@ -d9b944ef5ef27e0f1295241c9f406b9c8cb72aee \ No newline at end of file +1e123c34e823e2462febf9190afc628a2ce8e57c \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_DELETION_LINK.png.sha1 b/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_DELETION_LINK.png.sha1 index b9455dd3..af82f71 100644 --- a/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_DELETION_LINK.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_DELETION_LINK.png.sha1
@@ -1 +1 @@ -6ff2631811c45b9f3b84abc7c67b5c5afcd547e5 \ No newline at end of file +7a07c53c45948b89a41926c6db34d2789d145eee \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_LAUNCH_ANYWAY_LABEL.png.sha1 b/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_LAUNCH_ANYWAY_LABEL.png.sha1 new file mode 100644 index 0000000..ff28de0 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_LAUNCH_ANYWAY_LABEL.png.sha1
@@ -0,0 +1 @@ +cba71d69dd28b563b84d8f711f75b512dd087540 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_LEARN_MORE_AX_LABEL.png.sha1 b/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_LEARN_MORE_AX_LABEL.png.sha1 new file mode 100644 index 0000000..18ae197 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_LEARN_MORE_AX_LABEL.png.sha1
@@ -0,0 +1 @@ +b76eea7f0c5ea4eb7e989849d710a4ebd29730f3 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_MONITOR_RENDERER.png.sha1 b/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_MONITOR_RENDERER.png.sha1 index 1b2ad4ec..ae4936a95 100644 --- a/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_MONITOR_RENDERER.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_MONITOR_RENDERER.png.sha1
@@ -1 +1 @@ -9e28ad20100395c69d134fa5af69a1b20a557d8d \ No newline at end of file +d5ff0b22ce14fcea1fc49a2c7de9b15f730c131a \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_OK_LABEL.png.sha1 b/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_OK_LABEL.png.sha1 index e20a484..bd48885 100644 --- a/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_OK_LABEL.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_OK_LABEL.png.sha1
@@ -1 +1 @@ -d9b944ef5ef27e0f1295241c9f406b9c8cb72aee \ No newline at end of file +5237e4a51724524f17f62063829e5f73555821f3 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_RENDERER_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_RENDERER_TITLE.png.sha1 deleted file mode 100644 index e20a484..0000000 --- a/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_RENDERER_TITLE.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -d9b944ef5ef27e0f1295241c9f406b9c8cb72aee \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_RENDERER_TITLE_PLURAL.png.sha1 b/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_RENDERER_TITLE_PLURAL.png.sha1 new file mode 100644 index 0000000..c48a3de --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_RENDERER_TITLE_PLURAL.png.sha1
@@ -0,0 +1 @@ +0489408824bfd6e642d234e9d96445ad9d4a2299 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_RENDERER_TITLE_WITH_APP_NAME.png.sha1 b/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_RENDERER_TITLE_WITH_APP_NAME.png.sha1 new file mode 100644 index 0000000..227f05d5 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_DEPRECATED_APPS_RENDERER_TITLE_WITH_APP_NAME.png.sha1
@@ -0,0 +1 @@ +8a964ff06f8f3ce67a0e5e13029a4316e17731a8 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_FORCE_INSTALLED_DEPRECATED_APPS_CONTENT.png.sha1 b/chrome/app/generated_resources_grd/IDS_FORCE_INSTALLED_DEPRECATED_APPS_CONTENT.png.sha1 index 204e0f04..10790c7b 100644 --- a/chrome/app/generated_resources_grd/IDS_FORCE_INSTALLED_DEPRECATED_APPS_CONTENT.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_FORCE_INSTALLED_DEPRECATED_APPS_CONTENT.png.sha1
@@ -1 +1 @@ -69621246a4875aff9ab7a1d0d9528316415fe560 \ No newline at end of file +0beafb213eafd8a58fd41a4bbd830a216cc85cbe \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_FORCE_INSTALLED_DEPRECATED_APPS_LEARN_MORE_AX_LABEL.png.sha1 b/chrome/app/generated_resources_grd/IDS_FORCE_INSTALLED_DEPRECATED_APPS_LEARN_MORE_AX_LABEL.png.sha1 deleted file mode 100644 index 8ec600b..0000000 --- a/chrome/app/generated_resources_grd/IDS_FORCE_INSTALLED_DEPRECATED_APPS_LEARN_MORE_AX_LABEL.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -767a804ffadd4122174e17e900980fc7eb77f42b \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_FORCE_INSTALLED_PREINSTALLED_DEPRECATED_APPS_CONTENT.png.sha1 b/chrome/app/generated_resources_grd/IDS_FORCE_INSTALLED_PREINSTALLED_DEPRECATED_APPS_CONTENT.png.sha1 deleted file mode 100644 index 34a2322..0000000 --- a/chrome/app/generated_resources_grd/IDS_FORCE_INSTALLED_PREINSTALLED_DEPRECATED_APPS_CONTENT.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -cc0483851ef3f43bde9de8ffaae445e13f21402d \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_FORCE_INSTALLED_PREINSTALLED_DEPRECATED_APPS_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_FORCE_INSTALLED_PREINSTALLED_DEPRECATED_APPS_TITLE.png.sha1 deleted file mode 100644 index 34a2322..0000000 --- a/chrome/app/generated_resources_grd/IDS_FORCE_INSTALLED_PREINSTALLED_DEPRECATED_APPS_TITLE.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -cc0483851ef3f43bde9de8ffaae445e13f21402d \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_INPUT_OVERLAY_ACCESSIBILITY_ALPHA.png.sha1 b/chrome/app/generated_resources_grd/IDS_INPUT_OVERLAY_ACCESSIBILITY_ALPHA.png.sha1 new file mode 100644 index 0000000..0189dad --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_INPUT_OVERLAY_ACCESSIBILITY_ALPHA.png.sha1
@@ -0,0 +1 @@ +cf5cd1210f6c174c79c88237c31e533f9d0ab17b \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_INPUT_OVERLAY_GAME_CONTROLS_ALPHA.png.sha1 b/chrome/app/generated_resources_grd/IDS_INPUT_OVERLAY_GAME_CONTROLS_ALPHA.png.sha1 new file mode 100644 index 0000000..0189dad --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_INPUT_OVERLAY_GAME_CONTROLS_ALPHA.png.sha1
@@ -0,0 +1 @@ +cf5cd1210f6c174c79c88237c31e533f9d0ab17b \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 55f74f0..31ab001 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -4686,8 +4686,8 @@ "apps/digital_goods/digital_goods_impl.h", "apps/digital_goods/util.cc", "apps/digital_goods/util.h", - "browser_process_platform_part_chromeos.cc", - "browser_process_platform_part_chromeos.h", + "browser_process_platform_part_ash.cc", + "browser_process_platform_part_ash.h", "component_updater/app_provisioning_component_installer.cc", "component_updater/app_provisioning_component_installer.h", "component_updater/cros_component_installer_chromeos.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index fcc94b734..b599285 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1021,17 +1021,17 @@ {"omnibox_action_with_pedals", "true"}, }; const FeatureEntry::FeatureParam - kJourneysOmniboxActionOnNonNavigationIntentsParams[] = { + kJourneysOmniboxActionOnNavigationIntentsParams[] = { {"omnibox_action_on_urls", "false"}, {"omnibox_action_on_noisy_urls", "false"}, - {"omnibox_action_on_navigation_intents", "false"}, - {"omnibox_action_with_pedals", "true"}, + {"omnibox_action_on_navigation_intents", "true"}, + {"omnibox_action_with_pedals", "false"}, }; const FeatureEntry::FeatureParam kJourneysOmniboxActionWithPedalsParams[] = { {"omnibox_action_on_urls", "false"}, {"omnibox_action_on_noisy_urls", "false"}, - {"omnibox_action_on_navigation_intents", "true"}, - {"omnibox_action_with_pedals", "false"}, + {"omnibox_action_on_navigation_intents", "false"}, + {"omnibox_action_with_pedals", "true"}, }; const FeatureEntry::FeatureVariation kJourneysOmniboxActionVariations[] = { {"Action Chips on All URLs", kJourneysOmniboxActionOnAllURLsParams, @@ -1039,11 +1039,10 @@ {"Action Chips on Non-Noisy URLs", kJourneysOmniboxActionOnNonNoisyURLsParams, std::size(kJourneysOmniboxActionOnNonNoisyURLsParams), nullptr}, - {"Action Chips Disabled on Navigation Intents", - kJourneysOmniboxActionOnNonNavigationIntentsParams, - std::size(kJourneysOmniboxActionOnNonNavigationIntentsParams), nullptr}, - {"Action Chips Disabled with Pedals", - kJourneysOmniboxActionWithPedalsParams, + {"Action Chips Enabled on Navigation Intents", + kJourneysOmniboxActionOnNavigationIntentsParams, + std::size(kJourneysOmniboxActionOnNavigationIntentsParams), nullptr}, + {"Action Chips Enabled with Pedals", kJourneysOmniboxActionWithPedalsParams, std::size(kJourneysOmniboxActionWithPedalsParams), nullptr}, }; const FeatureEntry::FeatureParam kJourneysLabelsWithEntitiesParams[] = { @@ -6303,6 +6302,10 @@ {"tangible-sync", flag_descriptions::kTangibleSyncName, flag_descriptions::kTangibleSyncDescription, kOsAndroid, FEATURE_VALUE_TYPE(switches::kTangibleSync)}, + + {"enable-cbd-sign-out", flag_descriptions::kEnableCbdSignOutName, + flag_descriptions::kEnableCbdSignOutDescription, kOsAndroid, + FEATURE_VALUE_TYPE(switches::kEnableCbdSignOut)}, #endif // BUILDFLAG(IS_ANDROID) {"autofill-use-improved-label-disambiguation",
diff --git a/chrome/browser/android/contextualsearch/contextual_search_ranker_logger_impl.cc b/chrome/browser/android/contextualsearch/contextual_search_ranker_logger_impl.cc index 01beecb..1a268d3 100644 --- a/chrome/browser/android/contextualsearch/contextual_search_ranker_logger_impl.cc +++ b/chrome/browser/android/contextualsearch/contextual_search_ranker_logger_impl.cc
@@ -69,33 +69,6 @@ } } -AssistRankerPrediction ContextualSearchRankerLoggerImpl::RunInference( - JNIEnv* env, - jobject obj) { - has_predicted_decision_ = true; - bool prediction = false; - bool was_able_to_predict = false; - if (IsQueryEnabledInternal()) { - was_able_to_predict = predictor_->Predict(*ranker_example_, &prediction); - // Log to UMA whether we were able to predict or not. - base::UmaHistogramBoolean("Search.ContextualSearch.Ranker.WasAbleToPredict", - was_able_to_predict); - } - AssistRankerPrediction prediction_enum; - if (was_able_to_predict) { - if (prediction) { - prediction_enum = ASSIST_RANKER_PREDICTION_SHOW; - } else { - prediction_enum = ASSIST_RANKER_PREDICTION_SUPPRESS; - } - } else { - prediction_enum = ASSIST_RANKER_PREDICTION_UNAVAILABLE; - } - // TODO(donnd): remove when behind-the-flag bug fixed (crbug.com/786589). - DVLOG(0) << "prediction: " << prediction_enum; - return prediction_enum; -} - void ContextualSearchRankerLoggerImpl::WriteLogAndReset(JNIEnv* env, jobject obj) { if (predictor_ && ranker_example_ && source_id_ != ukm::kInvalidSourceId) {
diff --git a/chrome/browser/android/contextualsearch/contextual_search_ranker_logger_impl.h b/chrome/browser/android/contextualsearch/contextual_search_ranker_logger_impl.h index d5dab2b4..68351f03 100644 --- a/chrome/browser/android/contextualsearch/contextual_search_ranker_logger_impl.h +++ b/chrome/browser/android/contextualsearch/contextual_search_ranker_logger_impl.h
@@ -20,15 +20,6 @@ class RankerExample; } // namespace assist_ranker -// A Java counterpart will be generated for this enum. -// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.contextualsearch -enum AssistRankerPrediction { - ASSIST_RANKER_PREDICTION_UNDETERMINED, - ASSIST_RANKER_PREDICTION_UNAVAILABLE, - ASSIST_RANKER_PREDICTION_SUPPRESS, - ASSIST_RANKER_PREDICTION_SHOW, -}; - // Provides the native portion of the Java class by the same name. // Runs Ranker inference and logging through UKM for Ranker model development. // This is used to prediction whether a tap gesture will be useful to the user @@ -57,10 +48,6 @@ jobject obj, const base::android::JavaParamRef<jobject>& java_web_contents); - // Runs the model and returns the inference result as an - // AssistRankerPrediction enum. - AssistRankerPrediction RunInference(JNIEnv* env, jobject obj); - // Writes the currently logged data and resets the current builder to be // ready to start logging the next set of data. void WriteLogAndReset(JNIEnv* env, jobject obj);
diff --git a/chrome/browser/apps/icon_standardizer.cc b/chrome/browser/apps/icon_standardizer.cc index 15fde45..7bd2c98 100644 --- a/chrome/browser/apps/icon_standardizer.cc +++ b/chrome/browser/apps/icon_standardizer.cc
@@ -16,7 +16,7 @@ constexpr int kMinimumVisibleAlpha = 40; -constexpr float kCircleShapePixelDifferenceThreshold = 0.01f; +constexpr float kCircleShapePixelDifferenceThreshold = 0.02f; constexpr float kIconScaleToFit = 0.85f;
diff --git a/chrome/browser/apps/platform_apps/platform_app_launch.cc b/chrome/browser/apps/platform_apps/platform_app_launch.cc index c132936..10f4cd2 100644 --- a/chrome/browser/apps/platform_apps/platform_app_launch.cc +++ b/chrome/browser/apps/platform_apps/platform_app_launch.cc
@@ -138,7 +138,7 @@ url = GURL(chrome::kChromeUIAppsWithForceInstalledDeprecationDialogURL + app_id); } else { - url = GURL(chrome::kChromeUIAppsWithDeprecationDialogURL); + url = GURL(chrome::kChromeUIAppsWithDeprecationDialogURL + app_id); } NavigateParams params(browser, url, ui::PAGE_TRANSITION_AUTO_TOPLEVEL);
diff --git a/chrome/browser/ash/account_manager/account_manager_facade_factory_ash.cc b/chrome/browser/ash/account_manager/account_manager_facade_factory_ash.cc index 98d1169..76a650d 100644 --- a/chrome/browser/ash/account_manager/account_manager_facade_factory_ash.cc +++ b/chrome/browser/ash/account_manager/account_manager_facade_factory_ash.cc
@@ -12,7 +12,7 @@ #include "ash/components/account_manager/account_manager_factory.h" #include "base/no_destructor.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "components/account_manager_core/account_manager_facade_impl.h" #include "components/account_manager_core/chromeos/account_manager.h" #include "components/account_manager_core/chromeos/account_manager_mojo_service.h"
diff --git a/chrome/browser/ash/app_mode/kiosk_app_update_service.cc b/chrome/browser/ash/app_mode/kiosk_app_update_service.cc index 919656b..6b77ad1b 100644 --- a/chrome/browser/ash/app_mode/kiosk_app_update_service.cc +++ b/chrome/browser/ash/app_mode/kiosk_app_update_service.cc
@@ -9,7 +9,7 @@ #include "chrome/browser/ash/app_mode/kiosk_app_manager.h" #include "chrome/browser/ash/system/automatic_reboot_manager.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/profiles/profile.h"
diff --git a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc index 44c5609..172bb3b7 100644 --- a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc +++ b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc
@@ -170,10 +170,8 @@ // TODO(djacobo): Set proper positioning based on specs and responding to // resize. menu_entry->SetPosition(CalculateMenuEntryPosition()); - // TODO(djacobo): come up with a new resource for this so it can be - // translated, or just keep reusing the one I set here. menu_entry->SetAccessibleName( - l10n_util::GetStringUTF16(IDS_INPUT_OVERLAY_MENU_ENTRY_BUTTON)); + l10n_util::GetStringUTF16(IDS_INPUT_OVERLAY_GAME_CONTROLS_ALPHA)); auto* parent_view = overlay_widget->GetContentsView(); DCHECK(parent_view);
diff --git a/chrome/browser/ash/arc/input_overlay/ui/educational_view.cc b/chrome/browser/ash/arc/input_overlay/ui/educational_view.cc index 75c1292d..a8c7291b 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/educational_view.cc +++ b/chrome/browser/ash/arc/input_overlay/ui/educational_view.cc
@@ -98,13 +98,13 @@ AddChildView(std::move(banner)); } { - // |Game Control [Alpha]| title tag. + // |Game controls [Alpha]| title tag. auto container_view = std::make_unique<views::View>(); container_view->SetLayoutManager(std::make_unique<views::FlexLayout>()) ->SetOrientation(views::LayoutOrientation::kHorizontal) .SetMainAxisAlignment(views::LayoutAlignment::kCenter); auto* game_control = ash::login_views_utils::CreateBubbleLabel( - l10n_util::GetStringUTF16(IDS_INPUT_OVERLAY_EDUCATIONAL_TITLE), + l10n_util::GetStringUTF16(IDS_INPUT_OVERLAY_GAME_CONTROLS_ALPHA), /*view_defining_max_width=*/nullptr, /*color=*/ GetContentLayerColor(
diff --git a/chrome/browser/ash/arc/input_overlay/ui/input_menu_view.cc b/chrome/browser/ash/arc/input_overlay/ui/input_menu_view.cc index 096048f..fc1bab6 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/input_menu_view.cc +++ b/chrome/browser/ash/arc/input_overlay/ui/input_menu_view.cc
@@ -166,7 +166,7 @@ .SetCrossAxisAlignment(views::LayoutAlignment::kStretch); auto* menu_title = ash::login_views_utils::CreateBubbleLabel( - l10n_util::GetStringUTF16(IDS_INPUT_OVERLAY_MENU_GAME_CONTROL), + l10n_util::GetStringUTF16(IDS_INPUT_OVERLAY_GAME_CONTROLS_ALPHA), /*view_defining_max_width=*/nullptr, color, /*font_list=*/ gfx::FontList({kGoogleSansFont}, gfx::Font::FontStyle::NORMAL, @@ -179,7 +179,7 @@ base::BindRepeating(&InputMenuView::OnToggleGameControlPressed, base::Unretained(this)))); game_control_toggle_->SetAccessibleName( - l10n_util::GetStringUTF16(IDS_INPUT_OVERLAY_MENU_GAME_CONTROL)); + l10n_util::GetStringUTF16(IDS_INPUT_OVERLAY_GAME_CONTROLS_ALPHA)); game_control_toggle_->SetIsOn( display_overlay_controller_->GetTouchInjectorEnable()); @@ -196,7 +196,7 @@ close_button->SetImageHorizontalAlignment(views::ImageButton::ALIGN_CENTER); close_button->SetImageVerticalAlignment(views::ImageButton::ALIGN_MIDDLE); close_button->SetAccessibleName( - l10n_util::GetStringUTF16(IDS_INPUT_OVERLAY_CLOSE_MENU)); + l10n_util::GetStringUTF16(IDS_INPUT_OVERLAY_ACCESSIBILITY_ALPHA)); close_button_ = header_view->AddChildView(std::move(close_button)); menu_title->SetBorder(views::CreateEmptyBorder(CalculateInsets( header_view.get(), /*left=*/20, /*right=*/8, /*other_spacing=*/16))); @@ -299,7 +299,7 @@ return; const bool enabled = game_control_toggle_->GetIsOn(); display_overlay_controller_->SetTouchInjectorEnable(enabled); - // Adjust |enabled_| and |visible_| properties to match |Game Control|. + // Adjust |enabled_| and |visible_| properties to match |Game controls|. show_hint_toggle_->SetIsOn(enabled); display_overlay_controller_->SetInputMappingVisible(enabled); show_hint_toggle_->SetEnabled(enabled);
diff --git a/chrome/browser/ash/arc/input_overlay/ui/input_menu_view.h b/chrome/browser/ash/arc/input_overlay/ui/input_menu_view.h index 6aeba958..e408708 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/input_menu_view.h +++ b/chrome/browser/ash/arc/input_overlay/ui/input_menu_view.h
@@ -24,7 +24,7 @@ // // The class reports back to DisplayOverlayController, who owns this. // +---------------------------------+ -// | Game Control [ o] [x] | +// | Game controls [ o] [x] | // | | // | Key mapping [Customize] | // | |
diff --git a/chrome/browser/ash/attestation/tpm_challenge_key_subtle.cc b/chrome/browser/ash/attestation/tpm_challenge_key_subtle.cc index 0ef696e..d7c2eea1 100644 --- a/chrome/browser/ash/attestation/tpm_challenge_key_subtle.cc +++ b/chrome/browser/ash/attestation/tpm_challenge_key_subtle.cc
@@ -23,7 +23,7 @@ #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/ash/settings/cros_settings.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/extensions/chrome_extension_function_details.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/pref_names.h"
diff --git a/chrome/browser/ash/chrome_browser_main_parts_ash.cc b/chrome/browser/ash/chrome_browser_main_parts_ash.cc index b987c19..e67c603 100644 --- a/chrome/browser/ash/chrome_browser_main_parts_ash.cc +++ b/chrome/browser/ash/chrome_browser_main_parts_ash.cc
@@ -166,7 +166,7 @@ #include "chrome/browser/ash/usb/cros_usb_detector.h" #include "chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_manager.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/extensions/default_app_order.h" #include "chrome/browser/chromeos/extensions/login_screen/login_screen_ui/ui_handler.h"
diff --git a/chrome/browser/ash/crosapi/browser_manager.cc b/chrome/browser/ash/crosapi/browser_manager.cc index d8d96cb..619b733 100644 --- a/chrome/browser/ash/crosapi/browser_manager.cc +++ b/chrome/browser/ash/crosapi/browser_manager.cc
@@ -61,7 +61,7 @@ #include "chrome/browser/ash/policy/core/user_cloud_policy_manager_ash.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/component_updater/cros_component_manager.h" #include "chrome/browser/notifications/system_notification_helper.h" #include "chrome/browser/prefs/incognito_mode_prefs.h"
diff --git a/chrome/browser/ash/crosapi/browser_manager_unittest.cc b/chrome/browser/ash/crosapi/browser_manager_unittest.cc index b03fd9c..95160c4 100644 --- a/chrome/browser/ash/crosapi/browser_manager_unittest.cc +++ b/chrome/browser/ash/crosapi/browser_manager_unittest.cc
@@ -113,6 +113,7 @@ fake_user_manager_->UserLoggedIn(account_id, user->username_hash(), /*browser_restart=*/false, /*is_child=*/false); + fake_user_manager_->SimulateUserProfileLoad(account_id); ash::ProfileHelper::Get()->SetUserToProfileMappingForTesting( user, &testing_profile_); }
diff --git a/chrome/browser/ash/crosapi/device_settings_ash.cc b/chrome/browser/ash/crosapi/device_settings_ash.cc index 593f2333..0dcbd85 100644 --- a/chrome/browser/ash/crosapi/device_settings_ash.cc +++ b/chrome/browser/ash/crosapi/device_settings_ash.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/policy/chrome_policy_conversions_client.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/webui/policy/status_provider/device_cloud_policy_status_provider_chromeos.h" #include "mojo/public/cpp/bindings/remote.h" namespace crosapi { @@ -44,9 +45,9 @@ } void DeviceSettingsAsh::GetDevicePolicy(GetDevicePolicyCallback callback) { - if (!g_browser_process->platform_part() - ->browser_policy_connector_ash() - ->IsDeviceEnterpriseManaged()) { + const policy::BrowserPolicyConnectorAsh* connector = + g_browser_process->platform_part()->browser_policy_connector_ash(); + if (!connector->IsDeviceEnterpriseManaged()) { std::move(callback).Run(base::Value(), base::Value()); return; } @@ -54,11 +55,11 @@ auto client = std::make_unique<policy::ChromePolicyConversionsClient>( ProfileManager::GetActiveUserProfile()); client->EnableUserPolicies(false); - - // TODO(crbug.com/1243869): Get device_status from |client| and pass as the - // second parameter. + DeviceCloudPolicyStatusProviderChromeOS provider(connector); + base::DictionaryValue status; + provider.GetStatus(&status); std::move(callback).Run(base::Value(client->GetChromePolicies()), - base::Value()); + std::move(status)); } } // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/document_scan_ash_unittest.cc b/chrome/browser/ash/crosapi/document_scan_ash_unittest.cc index 92d7709..81305a7 100644 --- a/chrome/browser/ash/crosapi/document_scan_ash_unittest.cc +++ b/chrome/browser/ash/crosapi/document_scan_ash_unittest.cc
@@ -54,6 +54,7 @@ fake_user_manager->UserLoggedIn(account_id, user->username_hash(), /*browser_restart=*/false, /*is_child=*/false); + fake_user_manager->SimulateUserProfileLoad(account_id); return fake_user_manager; }
diff --git a/chrome/browser/ash/crosapi/networking_attributes_ash_unittest.cc b/chrome/browser/ash/crosapi/networking_attributes_ash_unittest.cc index 0ea9467..fa80c79 100644 --- a/chrome/browser/ash/crosapi/networking_attributes_ash_unittest.cc +++ b/chrome/browser/ash/crosapi/networking_attributes_ash_unittest.cc
@@ -107,6 +107,7 @@ user_manager->AddUserWithAffiliation(account_id, is_affiliated); user_manager->UserLoggedIn(account_id, user->username_hash(), /*browser_restart=*/false, /*is_child=*/false); + user_manager->SimulateUserProfileLoad(account_id); ash::ProfileHelper::Get()->SetUserToProfileMappingForTesting(user, &profile_); }
diff --git a/chrome/browser/ash/crostini/termina_installer.cc b/chrome/browser/ash/crostini/termina_installer.cc index 2ee9c4e..18400ee 100644 --- a/chrome/browser/ash/crostini/termina_installer.cc +++ b/chrome/browser/ash/crostini/termina_installer.cc
@@ -18,7 +18,7 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "chrome/browser/ash/crostini/crostini_util.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chromeos/dbus/dlcservice/dlcservice.pb.h" #include "content/public/browser/network_service_instance.h" #include "services/network/public/cpp/network_connection_tracker.h"
diff --git a/chrome/browser/ash/dbus/dlp_files_policy_service_provider_unittest.cc b/chrome/browser/ash/dbus/dlp_files_policy_service_provider_unittest.cc index 614eafb4..427c2fd 100644 --- a/chrome/browser/ash/dbus/dlp_files_policy_service_provider_unittest.cc +++ b/chrome/browser/ash/dbus/dlp_files_policy_service_provider_unittest.cc
@@ -56,6 +56,7 @@ user_manager_->UserLoggedIn(account_id, user->username_hash(), /*browser_restart=*/false, /*is_child=*/false); + user_manager_->SimulateUserProfileLoad(account_id); policy::DlpRulesManagerFactory::GetInstance()->SetTestingFactory( profile_.get(),
diff --git a/chrome/browser/ash/input_method/input_method_manager_impl.cc b/chrome/browser/ash/input_method/input_method_manager_impl.cc index bf6623a..d4fde8e 100644 --- a/chrome/browser/ash/input_method/input_method_manager_impl.cc +++ b/chrome/browser/ash/input_method/input_method_manager_impl.cc
@@ -36,7 +36,7 @@ #include "chrome/browser/ash/language_preferences.h" #include "chrome/browser/ash/login/session/user_session_manager.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/lifetime/termination_notification.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h"
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/DIR_METADATA b/chrome/browser/ash/login/oobe_quick_start/connectivity/DIR_METADATA new file mode 100644 index 0000000..771cf65 --- /dev/null +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/DIR_METADATA
@@ -0,0 +1,4 @@ +team_email: "chromeos-cross-device-eng@google.com" +buganizer { + component_id: 1155263 +}
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/OWNERS b/chrome/browser/ash/login/oobe_quick_start/connectivity/OWNERS new file mode 100644 index 0000000..4eaeef4 --- /dev/null +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/OWNERS
@@ -0,0 +1,4 @@ +hansenmichael@google.com +cclem@google.com +bhartmire@google.com +hansberry@chromium.org
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/README.md b/chrome/browser/ash/login/oobe_quick_start/connectivity/README.md new file mode 100644 index 0000000..b035fcb --- /dev/null +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/README.md
@@ -0,0 +1,6 @@ +This directory contains the functionality needed to connect to a phone over +Bluetooth and drive the device-to-device communication for Quick Start, and is +owned by the Cross Device team. + +TargetDeviceBootstrapControllerImpl is the main entry point. Calling code is +expected to instantiate and own a member of this class.
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_bootstrap_controller.cc b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_bootstrap_controller.cc new file mode 100644 index 0000000..3e90bba --- /dev/null +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_bootstrap_controller.cc
@@ -0,0 +1,9 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +namespace ash::quick_start { + +// TODO impl + +} // namespace ash::quick_start
diff --git a/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_bootstrap_controller.h b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_bootstrap_controller.h new file mode 100644 index 0000000..0329807 --- /dev/null +++ b/chrome/browser/ash/login/oobe_quick_start/connectivity/target_device_bootstrap_controller.h
@@ -0,0 +1,22 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ASH_LOGIN_OOBE_QUICK_START_CONNECTIVITY_TARGET_DEVICE_BOOTSTRAP_CONTROLLER_H_ +#define CHROME_BROWSER_ASH_LOGIN_OOBE_QUICK_START_CONNECTIVITY_TARGET_DEVICE_BOOTSTRAP_CONTROLLER_H_ + +namespace ash::quick_start { + +class TargetDeviceBootstrapController { + public: + TargetDeviceBootstrapController() = default; + virtual ~TargetDeviceBootstrapController() = default; + + // Checks to see whether the feature can be supported on the device's + // hardware. Returns true if Bluetooth is supported and an adapter is present. + virtual bool IsFeatureSupported() = 0; +} + +} // namespace ash::quick_start + +#endif // CHROME_BROWSER_ASH_LOGIN_OOBE_QUICK_START_CONNECTIVITY_TARGET_DEVICE_BOOTSTRAP_CONTROLLER_H_
diff --git a/chrome/browser/ash/login/saml/in_session_password_change_manager.cc b/chrome/browser/ash/login/saml/in_session_password_change_manager.cc index fae5440..ff1bf73 100644 --- a/chrome/browser/ash/login/saml/in_session_password_change_manager.cc +++ b/chrome/browser/ash/login/saml/in_session_password_change_manager.cc
@@ -16,7 +16,7 @@ #include "chrome/browser/ash/login/saml/password_expiry_notification.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/chromeos/in_session_password_change/password_change_dialogs.h" #include "chrome/common/chrome_features.h"
diff --git a/chrome/browser/ash/login/screens/packaged_license_screen.cc b/chrome/browser/ash/login/screens/packaged_license_screen.cc index 3920f1f..5bf4880b8 100644 --- a/chrome/browser/ash/login/screens/packaged_license_screen.cc +++ b/chrome/browser/ash/login/screens/packaged_license_screen.cc
@@ -8,7 +8,7 @@ #include "chrome/browser/ash/policy/core/browser_policy_connector_ash.h" #include "chrome/browser/ash/policy/enrollment/enrollment_config.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/ui/webui/chromeos/login/packaged_license_screen_handler.h" namespace ash {
diff --git a/chrome/browser/ash/login/screens/reset_screen.cc b/chrome/browser/ash/login/screens/reset_screen.cc index 37615cd9..8ca66056 100644 --- a/chrome/browser/ash/login/screens/reset_screen.cc +++ b/chrome/browser/ash/login/screens/reset_screen.cc
@@ -25,7 +25,7 @@ #include "chrome/browser/ash/tpm_firmware_update.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/ui/webui/chromeos/login/reset_screen_handler.h" #include "chrome/common/pref_names.h" #include "chromeos/dbus/dbus_thread_manager.h"
diff --git a/chrome/browser/ash/login/session/chrome_session_manager.cc b/chrome/browser/ash/login/session/chrome_session_manager.cc index e3beaa7..3d13b170 100644 --- a/chrome/browser/ash/login/session/chrome_session_manager.cc +++ b/chrome/browser/ash/login/session/chrome_session_manager.cc
@@ -41,7 +41,7 @@ #include "chrome/browser/ash/tpm_firmware_update_notification.h" #include "chrome/browser/ash/u2f_notification.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/profiles/profile.h"
diff --git a/chrome/browser/ash/login/session/user_session_initializer.cc b/chrome/browser/ash/login/session/user_session_initializer.cc index 07aad93d..0186ffee 100644 --- a/chrome/browser/ash/login/session/user_session_initializer.cc +++ b/chrome/browser/ash/login/session/user_session_initializer.cc
@@ -33,7 +33,7 @@ #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/ash/settings/cros_settings.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/component_updater/crl_set_component_installer.h" #include "chrome/browser/google/google_brand_chromeos.h" #include "chrome/browser/net/nss_service.h"
diff --git a/chrome/browser/ash/login/session/user_session_manager.cc b/chrome/browser/ash/login/session/user_session_manager.cc index 2adb025..a31d2c19 100644 --- a/chrome/browser/ash/login/session/user_session_manager.cc +++ b/chrome/browser/ash/login/session/user_session_manager.cc
@@ -104,7 +104,7 @@ #include "chrome/browser/ash/u2f_notification.h" #include "chrome/browser/ash/web_applications/help_app/help_app_notification_controller.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/first_run/first_run.h" #include "chrome/browser/lifetime/application_lifetime.h"
diff --git a/chrome/browser/ash/platform_keys/platform_keys_service_nss.cc b/chrome/browser/ash/platform_keys/platform_keys_service_nss.cc index 1f400b3..1707037c 100644 --- a/chrome/browser/ash/platform_keys/platform_keys_service_nss.cc +++ b/chrome/browser/ash/platform_keys/platform_keys_service_nss.cc
@@ -31,7 +31,7 @@ #include "chrome/browser/ash/net/client_cert_store_ash.h" #include "chrome/browser/ash/platform_keys/chaps_util.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h" #include "chrome/browser/platform_keys/platform_keys.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h"
diff --git a/chrome/browser/ash/policy/core/browser_policy_connector_ash_browsertest.cc b/chrome/browser/ash/policy/core/browser_policy_connector_ash_browsertest.cc index f99b0f02..40b22ad 100644 --- a/chrome/browser/ash/policy/core/browser_policy_connector_ash_browsertest.cc +++ b/chrome/browser/ash/policy/core/browser_policy_connector_ash_browsertest.cc
@@ -8,7 +8,7 @@ #include "chrome/browser/ash/policy/core/device_cloud_policy_store_ash.h" #include "chrome/browser/ash/policy/core/device_policy_cros_browser_test.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "components/policy/core/common/cloud/mock_cloud_policy_store.h" #include "components/policy/core/common/cloud/test/policy_builder.h" #include "components/policy/proto/device_management_backend.pb.h"
diff --git a/chrome/browser/ash/policy/core/device_attributes_browsertest.cc b/chrome/browser/ash/policy/core/device_attributes_browsertest.cc index b1151cc2..5c2caf0 100644 --- a/chrome/browser/ash/policy/core/device_attributes_browsertest.cc +++ b/chrome/browser/ash/policy/core/device_attributes_browsertest.cc
@@ -12,7 +12,7 @@ #include "chrome/browser/ash/policy/core/device_cloud_policy_store_ash.h" #include "chrome/browser/ash/policy/core/device_policy_cros_browser_test.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" #include "components/policy/core/common/cloud/mock_cloud_policy_store.h" #include "components/policy/core/common/cloud/test/policy_builder.h"
diff --git a/chrome/browser/ash/policy/core/device_attributes_impl.cc b/chrome/browser/ash/policy/core/device_attributes_impl.cc index 35836b3..bc43afa 100644 --- a/chrome/browser/ash/policy/core/device_attributes_impl.cc +++ b/chrome/browser/ash/policy/core/device_attributes_impl.cc
@@ -7,7 +7,7 @@ #include "chrome/browser/ash/policy/core/browser_policy_connector_ash.h" #include "chrome/browser/ash/policy/core/device_attributes_impl.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" namespace policy {
diff --git a/chrome/browser/ash/policy/core/device_policy_cros_browser_test.cc b/chrome/browser/ash/policy/core/device_policy_cros_browser_test.cc index 208cdf8..2d586a6 100644 --- a/chrome/browser/ash/policy/core/device_policy_cros_browser_test.cc +++ b/chrome/browser/ash/policy/core/device_policy_cros_browser_test.cc
@@ -21,7 +21,7 @@ #include "chrome/browser/ash/policy/core/device_policy_builder.h" #include "chrome/browser/ash/settings/cros_settings.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/common/chrome_paths.h" #include "chromeos/dbus/constants/dbus_paths.h" #include "chromeos/dbus/session_manager/fake_session_manager_client.h"
diff --git a/chrome/browser/ash/policy/dlp/dlp_files_controller_unittest.cc b/chrome/browser/ash/policy/dlp/dlp_files_controller_unittest.cc index 0c6fd1c..5563cfe 100644 --- a/chrome/browser/ash/policy/dlp/dlp_files_controller_unittest.cc +++ b/chrome/browser/ash/policy/dlp/dlp_files_controller_unittest.cc
@@ -87,6 +87,7 @@ user_manager_->UserLoggedIn(account_id, user->username_hash(), /*browser_restart=*/false, /*is_child=*/false); + user_manager_->SimulateUserProfileLoad(account_id); policy::DlpRulesManagerFactory::GetInstance()->SetTestingFactory( profile_.get(),
diff --git a/chrome/browser/ash/policy/external_data/handlers/device_wilco_dtc_configuration_external_data_handler_browsertest.cc b/chrome/browser/ash/policy/external_data/handlers/device_wilco_dtc_configuration_external_data_handler_browsertest.cc index dae5d8673..2666ebc6 100644 --- a/chrome/browser/ash/policy/external_data/handlers/device_wilco_dtc_configuration_external_data_handler_browsertest.cc +++ b/chrome/browser/ash/policy/external_data/handlers/device_wilco_dtc_configuration_external_data_handler_browsertest.cc
@@ -16,7 +16,7 @@ #include "chrome/browser/ash/policy/external_data/cloud_external_data_manager_base_test_util.h" #include "chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_manager.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/in_process_browser_test.h" #include "components/policy/core/common/external_data_fetcher.h"
diff --git a/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter.cc b/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter.cc index c41fb980..4c43e28c0 100644 --- a/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter.cc +++ b/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter.cc
@@ -11,7 +11,7 @@ #include "chrome/browser/ash/policy/core/browser_policy_connector_ash.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/policy/messaging_layer/proto/synced/add_remove_user_event.pb.h" #include "components/reporting/proto/synced/record_constants.pb.h" #include "components/user_manager/user.h"
diff --git a/chrome/browser/ash/profiles/profile_helper.cc b/chrome/browser/ash/profiles/profile_helper.cc index 8953453..ff0aae0f 100644 --- a/chrome/browser/ash/profiles/profile_helper.cc +++ b/chrome/browser/ash/profiles/profile_helper.cc
@@ -118,8 +118,6 @@ Profile* GetProfileByAccountId(const AccountId& account_id) override; Profile* GetProfileByUser(const user_manager::User* user) override; - Profile* GetProfileByUserUnsafe(const user_manager::User* user) override; - const user_manager::User* GetUserByProfile( const Profile* profile) const override; user_manager::User* GetUserByProfile(Profile* profile) const override; @@ -403,34 +401,6 @@ return profile; } -Profile* ProfileHelperImpl::GetProfileByUserUnsafe( - const user_manager::User* user) { - // This map is non-empty only in tests. - if (!user_to_profile_for_testing_.empty()) { - std::map<const user_manager::User*, Profile*>::const_iterator it = - user_to_profile_for_testing_.find(user); - if (it != user_to_profile_for_testing_.end()) - return it->second; - } - - Profile* profile = NULL; - if (user->is_profile_created()) { - profile = GetProfileByUserIdHash(user->username_hash()); - } else { - LOG(ERROR) << "ProfileHelper::GetProfileByUserUnsafe is called when " - "|user|'s profile is not created. It probably means that " - "something is wrong with a calling code. Please report in " - "http://crbug.com/361528 if you see this message."; - profile = ProfileManager::GetActiveUserProfile(); - } - - // GetActiveUserProfile() or GetProfileByUserIdHash() returns a new instance - // of ProfileImpl(), but actually its off-the-record profile should be used. - if (profile && user_manager::UserManager::Get()->IsLoggedInAsGuest()) - profile = profile->GetPrimaryOTRProfile(/*create_if_needed=*/true); - return profile; -} - const user_manager::User* ProfileHelperImpl::GetUserByProfile( const Profile* profile) const { if (!ProfileHelper::IsRegularProfile(profile)) {
diff --git a/chrome/browser/ash/profiles/profile_helper.h b/chrome/browser/ash/profiles/profile_helper.h index 115d27c..81c39cc 100644 --- a/chrome/browser/ash/profiles/profile_helper.h +++ b/chrome/browser/ash/profiles/profile_helper.h
@@ -137,16 +137,6 @@ // Otherwise, returns NULL. virtual Profile* GetProfileByUser(const user_manager::User* user) = 0; - // DEPRECATED - // Returns profile of the |user| if user's profile is created and fully - // initialized. Otherwise, if some user is active, returns their profile. - // Otherwise, returns signin profile. - // Behaviour of this function does not correspond to its name and can be - // very surprising, that's why it should not be used anymore. - // Use |GetProfileByUser| instead. - // TODO(dzhioev): remove this method. http://crbug.com/361528 - virtual Profile* GetProfileByUserUnsafe(const user_manager::User* user) = 0; - // Returns NULL if User is not created. virtual const user_manager::User* GetUserByProfile( const Profile* profile) const = 0;
diff --git a/chrome/browser/ash/system/input_device_settings_impl_ozone.cc b/chrome/browser/ash/system/input_device_settings_impl_ozone.cc index 7ee6135..f7367b46 100644 --- a/chrome/browser/ash/system/input_device_settings_impl_ozone.cc +++ b/chrome/browser/ash/system/input_device_settings_impl_ozone.cc
@@ -7,7 +7,7 @@ #include "base/bind.h" #include "chrome/browser/ash/system/fake_input_device_settings.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chromeos/system/devicemode.h" #include "content/public/browser/browser_thread.h" #include "ui/ozone/public/input_controller.h"
diff --git a/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc b/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc index 67f9502..ea20413 100644 --- a/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc +++ b/chrome/browser/ash/wallpaper_handlers/wallpaper_handlers.cc
@@ -632,7 +632,16 @@ auto resource_request = std::make_unique<network::ResourceRequest>(); resource_request->method = "GET"; - resource_request->url = service_url; + + // By default, the server will not serialize repeated proto fields if they are + // empty. This makes it impossible for us to tell if the server has broken + // compatibility with the client or just has nothing to return. Append a + // special parameter to request that the server always serializes repeated + // proto fields and any other fields which might otherwise be omitted by + // default (https://cloud.google.com/apis/docs/system-parameters#definitions). + resource_request->url = net::AppendOrReplaceQueryParameter( + service_url, "$outputDefaults", "true"); + // Cookies should not be allowed. resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit; resource_request->load_flags = net::LOAD_DISABLE_CACHE;
diff --git a/chrome/browser/browser_process_platform_part.h b/chrome/browser/browser_process_platform_part.h index 3bed4989..7e8f139 100644 --- a/chrome/browser/browser_process_platform_part.h +++ b/chrome/browser/browser_process_platform_part.h
@@ -12,7 +12,7 @@ #if BUILDFLAG(IS_ANDROID) #include "chrome/browser/browser_process_platform_part_android.h" #elif BUILDFLAG(IS_CHROMEOS_ASH) -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #elif BUILDFLAG(IS_MAC) #include "chrome/browser/browser_process_platform_part_mac.h" #elif BUILDFLAG(IS_WIN)
diff --git a/chrome/browser/browser_process_platform_part_chromeos.cc b/chrome/browser/browser_process_platform_part_ash.cc similarity index 99% rename from chrome/browser/browser_process_platform_part_chromeos.cc rename to chrome/browser/browser_process_platform_part_ash.cc index a412eb9..40ff594 100644 --- a/chrome/browser/browser_process_platform_part_chromeos.cc +++ b/chrome/browser/browser_process_platform_part_ash.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/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include <memory> #include <utility>
diff --git a/chrome/browser/browser_process_platform_part_chromeos.h b/chrome/browser/browser_process_platform_part_ash.h similarity index 96% rename from chrome/browser/browser_process_platform_part_chromeos.h rename to chrome/browser/browser_process_platform_part_ash.h index 1159890..fec9577 100644 --- a/chrome/browser/browser_process_platform_part_chromeos.h +++ b/chrome/browser/browser_process_platform_part_ash.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_BROWSER_PROCESS_PLATFORM_PART_CHROMEOS_H_ -#define CHROME_BROWSER_BROWSER_PROCESS_PLATFORM_PART_CHROMEOS_H_ +#ifndef CHROME_BROWSER_BROWSER_PROCESS_PLATFORM_PART_ASH_H_ +#define CHROME_BROWSER_BROWSER_PROCESS_PLATFORM_PART_ASH_H_ #include <memory> @@ -211,4 +211,4 @@ SEQUENCE_CHECKER(sequence_checker_); }; -#endif // CHROME_BROWSER_BROWSER_PROCESS_PLATFORM_PART_CHROMEOS_H_ +#endif // CHROME_BROWSER_BROWSER_PROCESS_PLATFORM_PART_ASH_H_
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 68042f64..18b522ab 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -275,8 +275,8 @@ // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch // of lacros-chrome is complete. -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \ - (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_FUCHSIA) #include "chrome/browser/metrics/desktop_session_duration/desktop_session_duration_tracker.h" #include "chrome/browser/metrics/desktop_session_duration/touch_mode_stats_tracker.h" #include "chrome/browser/profiles/profile_activity_metrics_recorder.h" @@ -1058,8 +1058,8 @@ // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch // of lacros-chrome is complete. -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \ - (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(IS_FUCHSIA) metrics::DesktopSessionDurationTracker::Initialize(); ProfileActivityMetricsRecorder::Initialize(); TouchModeStatsTracker::Initialize(
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 1194c79..4506640 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -1366,7 +1366,8 @@ enterprise::content::kCopyPreventionSettings); registry->RegisterIntegerPref( prefs::kUserAgentReduction, - UserAgentReductionEnterprisePolicyState::kDefault); + static_cast<int>( + embedder_support::UserAgentReductionEnterprisePolicyState::kDefault)); registry->RegisterBooleanPref(prefs::kOriginAgentClusterDefaultEnabled, true); registry->RegisterIntegerPref( prefs::kForceMajorVersionToMinorPositionInUserAgent, @@ -5897,18 +5898,26 @@ std::string ChromeContentBrowserClient::GetUserAgentBasedOnPolicy( content::BrowserContext* context) { + const PrefService* prefs = Profile::FromBrowserContext(context)->GetPrefs(); embedder_support::ForceMajorVersionToMinorPosition - force_major_version_to_minor = embedder_support::GetMajorToMinorFromPrefs( - Profile::FromBrowserContext(context)->GetPrefs()); - switch (GetUserAgentReductionEnterprisePolicyState(context)) { - case UserAgentReductionEnterprisePolicyState::kForceDisabled: - return embedder_support::GetFullUserAgent(force_major_version_to_minor); - case UserAgentReductionEnterprisePolicyState::kForceEnabled: + force_major_version_to_minor = + embedder_support::GetMajorToMinorFromPrefs(prefs); + embedder_support::UserAgentReductionEnterprisePolicyState + user_agent_reduction = + embedder_support::GetUserAgentReductionFromPrefs(prefs); + switch (user_agent_reduction) { + case embedder_support::UserAgentReductionEnterprisePolicyState:: + kForceDisabled: + return embedder_support::GetFullUserAgent(force_major_version_to_minor, + user_agent_reduction); + case embedder_support::UserAgentReductionEnterprisePolicyState:: + kForceEnabled: return embedder_support::GetReducedUserAgent( force_major_version_to_minor); - case UserAgentReductionEnterprisePolicyState::kDefault: + case embedder_support::UserAgentReductionEnterprisePolicyState::kDefault: default: - return embedder_support::GetUserAgent(force_major_version_to_minor); + return embedder_support::GetUserAgent(force_major_version_to_minor, + user_agent_reduction); } } @@ -6476,23 +6485,6 @@ *Profile::FromBrowserContext(browser_context)->GetPrefs()); } -ChromeContentBrowserClient::UserAgentReductionEnterprisePolicyState -ChromeContentBrowserClient::GetUserAgentReductionEnterprisePolicyState( - content::BrowserContext* context) { - int policy = Profile::FromBrowserContext(context)->GetPrefs()->GetInteger( - prefs::kUserAgentReduction); - switch (policy) { - case 0: - return UserAgentReductionEnterprisePolicyState::kDefault; - case 1: - return UserAgentReductionEnterprisePolicyState::kForceDisabled; - case 2: - return UserAgentReductionEnterprisePolicyState::kForceEnabled; - } - - return UserAgentReductionEnterprisePolicyState::kDefault; -} - bool ChromeContentBrowserClient::ShouldDisableOriginAgentClusterDefault( content::BrowserContext* browser_context) { // The enterprise policy for kOriginAgentClusterDefaultEnabled defaults to
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 0ca7726..d6ddbb3 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -785,12 +785,6 @@ bool ShouldPreconnectNavigation( content::BrowserContext* browser_context) override; - enum UserAgentReductionEnterprisePolicyState { - kDefault = 0, - kForceDisabled = 1, - kForceEnabled = 2, - }; - bool ShouldDisableOriginAgentClusterDefault( content::BrowserContext* browser_context) override; @@ -887,9 +881,6 @@ std::unique_ptr<ScopedKeepAlive> keep_alive_handle); #endif - UserAgentReductionEnterprisePolicyState - GetUserAgentReductionEnterprisePolicyState(content::BrowserContext* context); - // Vector of additional ChromeContentBrowserClientParts. // Parts are deleted in the reverse order they are added. std::vector<ChromeContentBrowserClientParts*> extra_parts_;
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 153789f..344c634 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -1164,6 +1164,8 @@ "../ash/login/onboarding_user_activity_counter.h", "../ash/login/oobe_configuration.cc", "../ash/login/oobe_configuration.h", + "../ash/login/oobe_quick_start/connectivity/target_device_bootstrap_controller.cc", + "../ash/login/oobe_quick_start/connectivity/target_device_bootstrap_controller.h", "../ash/login/oobe_quick_start/verification_shapes.cc", "../ash/login/oobe_quick_start/verification_shapes.h", "../ash/login/oobe_screen.cc",
diff --git a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsMediator.java b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsMediator.java index e1173bb..637bbca 100644 --- a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsMediator.java +++ b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsMediator.java
@@ -36,8 +36,8 @@ public void onDidFinishNavigation(Tab tab, NavigationHandle navigation) { if ((tab.isIncognito()) || (!navigation.hasCommitted()) || (!navigation.isInPrimaryMainFrame()) - || (navigation.isFragmentNavigation()) || (navigation.isErrorPage()) - || (navigation.getUrl() == null) + || (navigation.isPrimaryMainFrameFragmentNavigation()) + || (navigation.isErrorPage()) || (navigation.getUrl() == null) || (TextUtils.isEmpty(navigation.getUrl().getHost()))) { return; }
diff --git a/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsMediatorTest.java b/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsMediatorTest.java index c73451b..ec38c78f 100644 --- a/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsMediatorTest.java +++ b/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsMediatorTest.java
@@ -79,7 +79,7 @@ doReturn(false).when(mMockTab).isIncognito(); doReturn(true).when(mMockNavigationHandle).hasCommitted(); doReturn(true).when(mMockNavigationHandle).isInPrimaryMainFrame(); - doReturn(false).when(mMockNavigationHandle).isFragmentNavigation(); + doReturn(false).when(mMockNavigationHandle).isPrimaryMainFrameFragmentNavigation(); doReturn(false).when(mMockNavigationHandle).isErrorPage(); doReturn(mMockUrl).when(mMockNavigationHandle).getUrl(); doReturn("fake_host").when(mMockUrl).getHost(); @@ -141,8 +141,8 @@ } @Test - public void testTabObserverOnDidFinishNavigation_FragmentNavigation() { - doReturn(true).when(mMockNavigationHandle).isFragmentNavigation(); + public void testTabObserverOnDidFinishNavigation_PrimaryMainFrameFragmentNavigation() { + doReturn(true).when(mMockNavigationHandle).isPrimaryMainFrameFragmentNavigation(); mTabObserverCaptor.getValue().onDidFinishNavigation(mMockTab, mMockNavigationHandle); verify(mMockDelegate, never())
diff --git a/chrome/browser/component_updater/cros_component_installer_chromeos_unittest.cc b/chrome/browser/component_updater/cros_component_installer_chromeos_unittest.cc index 33415e2..2151ed0 100644 --- a/chrome/browser/component_updater/cros_component_installer_chromeos_unittest.cc +++ b/chrome/browser/component_updater/cros_component_installer_chromeos_unittest.cc
@@ -20,7 +20,7 @@ #include "base/test/test_simple_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/component_updater/cros_component_installer_chromeos.h" #include "chrome/browser/component_updater/metadata_table_chromeos.h" #include "chrome/common/chrome_paths.h"
diff --git a/chrome/browser/extensions/api/quick_unlock_private/quick_unlock_private_api_unittest.cc b/chrome/browser/extensions/api/quick_unlock_private/quick_unlock_private_api_unittest.cc index 43316ad..267607d 100644 --- a/chrome/browser/extensions/api/quick_unlock_private/quick_unlock_private_api_unittest.cc +++ b/chrome/browser/extensions/api/quick_unlock_private/quick_unlock_private_api_unittest.cc
@@ -225,6 +225,7 @@ fake_user_manager_->AddUser(test_account); fake_user_manager_->UserLoggedIn(test_account, kTestUserEmailHash, false, false); + fake_user_manager_->SimulateUserProfileLoad(test_account); ash::ProfileHelper::Get()->SetUserToProfileMappingForTesting( fake_user_manager_->GetPrimaryUser(), profile);
diff --git a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc index cebdf400..8ee1990 100644 --- a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc +++ b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc
@@ -52,7 +52,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) #include "chrome/browser/ash/policy/core/user_cloud_policy_manager_ash.h" #include "chrome/browser/ash/profiles/profile_helper.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "components/user_manager/user.h" #include "components/user_manager/user_manager.h" #else
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index f7941da5..c292ebf5 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -927,14 +927,6 @@ "owners": [ "yusuyoutube@google.com", "benwgold@google.com", "lens-chrome@google.com" ], "expiry_milestone": 103 }, - { "name":"context-menu-phase2", - "owners":["gambard", "bling-flags@google.com"], - "expiry_milestone":100 - }, - { "name":"context-menu-phase2-screenshot", - "owners":["christianxu", "gambard", "bling-flags@google.com"], - "expiry_milestone":103 - }, { "name": "context-menu-popup-style", "owners": [ "wenyufu", "clank-app-team@google.com" ], @@ -1620,6 +1612,11 @@ "expiry_milestone": 105 }, { + "name": "enable-cbd-sign-out", + "owners": [ "triploblastic", "chrome-signin-team" ], + "expiry_milestone":120 + }, + { "name": "enable-chrome-management-page-android", "owners": [ "ogastorga", "ftirelo" ], "expiry_milestone": 107 @@ -5422,27 +5419,27 @@ { "name": "shared-highlighting-refined-blocklist", "owners": ["jeffreycohen", "chrome-with-friends-robots@google.com" ], - "expiry_milestone": 105 + "expiry_milestone": 108 }, { "name": "shared-highlighting-refined-maxcontextwords", "owners": ["wissemgamra", "jeffreycohen", "chrome-with-friends-robots@google.com" ], - "expiry_milestone": 107 + "expiry_milestone": 108 }, { "name": "shared-highlighting-v2", "owners": ["jeffreycohen", "kristipark", "cheickcisse@google.com", "chrome-with-friends-robots@google.com"], - "expiry_milestone": 99 + "expiry_milestone": 108 }, { "name": "sharing-desktop-screenshots", "owners": ["skare", "jeffreycohen", "chrome-with-friends-robots@google.com" ], - "expiry_milestone": 104 + "expiry_milestone": 108 }, { "name": "sharing-desktop-screenshots-edit", "owners": ["skare", "jeffreycohen", "chrome-with-friends-robots@google.com" ], - "expiry_milestone": 104 + "expiry_milestone": 108 }, { "name": "sharing-desktop-share-preview",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 4144dde..58ddf13 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3138,6 +3138,12 @@ "In multi-window mode, launches share hub actions in an adjacent window. " "For internal debugging."; +const char kEnableCbdSignOutName[] = + "Decouple Sign out from clearing browsing data"; +const char kEnableCbdSignOutDescription[] = + "Enable additional affordance to sign out when clearing browsing data and " + "ensure consistent behavior for all signed-in users."; + const char kCloseTabSuggestionsName[] = "Suggest to close Tabs"; const char kCloseTabSuggestionsDescription[] = "Suggests to the user to close Tabs that haven't been used beyond a "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 721e1624..92c1142 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1769,6 +1769,9 @@ extern const char kChromeSharingHubLaunchAdjacentName[]; extern const char kChromeSharingHubLaunchAdjacentDescription[]; +extern const char kEnableCbdSignOutName[]; +extern const char kEnableCbdSignOutDescription[]; + extern const char kCloseTabSuggestionsName[]; extern const char kCloseTabSuggestionsDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 7d76673..03da2db70 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -370,6 +370,7 @@ &share::kPersistShareHubOnAppSwitch, &share::kUpcomingSharingFeatures, &switches::kAllowSyncOffForChildAccounts, + &switches::kEnableCbdSignOut, &switches::kForceStartupSigninPromo, &switches::kForceDisableExtendedSyncPromos, &switches::kTangibleSync,
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index a0bb287..67629accb 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -267,6 +267,7 @@ public static final String CHROME_SHARING_HUB_LAUNCH_ADJACENT = "ChromeSharingHubLaunchAdjacent"; public static final String CHROME_SURVEY_NEXT_ANDROID = "ChromeSurveyNextAndroid"; + public static final String ENABLE_CBD_SIGN_OUT = "EnableCbdSignOut"; public static final String COMMAND_LINE_ON_NON_ROOTED = "CommandLineOnNonRooted"; public static final String COMMERCE_MERCHANT_VIEWER = "CommerceMerchantViewer"; public static final String COMMERCE_PRICE_TRACKING = "CommercePriceTracking";
diff --git a/chrome/browser/metrics/metrics_reporting_state.cc b/chrome/browser/metrics/metrics_reporting_state.cc index ee1cadad..eb7cf85 100644 --- a/chrome/browser/metrics/metrics_reporting_state.cc +++ b/chrome/browser/metrics/metrics_reporting_state.cc
@@ -169,6 +169,7 @@ // Clear the client id and low entropy sources pref when opting out. // Note: This will not affect the running state (e.g. field trial // randomization), as the pref is only read on startup. + UMA_HISTOGRAM_BOOLEAN("UMA.ClientIdCleared", true); PrefService* local_state = g_browser_process->local_state(); @@ -180,6 +181,7 @@ #endif // BUILDFLAG(IS_CHROMEOS_ASH) local_state->ClearPref(metrics::prefs::kMetricsClientID); + local_state->ClearPref(metrics::prefs::kMetricsProvisionalClientID); metrics::EntropyState::ClearPrefs(local_state); metrics::ClonedInstallDetector::ClearClonedInstallInfo(local_state); local_state->ClearPref(metrics::prefs::kMetricsReportingEnabledTimestamp);
diff --git a/chrome/browser/metrics/usertype_by_devicetype_metrics_provider_browsertest.cc b/chrome/browser/metrics/usertype_by_devicetype_metrics_provider_browsertest.cc index 81d7b07..5cce39d6 100644 --- a/chrome/browser/metrics/usertype_by_devicetype_metrics_provider_browsertest.cc +++ b/chrome/browser/metrics/usertype_by_devicetype_metrics_provider_browsertest.cc
@@ -24,7 +24,7 @@ #include "chrome/browser/ash/policy/core/device_local_account.h" #include "chrome/browser/ash/policy/core/device_policy_cros_browser_test.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/common/chrome_features.h" #include "chromeos/dbus/session_manager/fake_session_manager_client.h" #include "components/metrics/metrics_service.h"
diff --git a/chrome/browser/nearby_sharing/sharesheet/nearby_share_action.cc b/chrome/browser/nearby_sharing/sharesheet/nearby_share_action.cc index 7a3b75f..6abf34a 100644 --- a/chrome/browser/nearby_sharing/sharesheet/nearby_share_action.cc +++ b/chrome/browser/nearby_sharing/sharesheet/nearby_share_action.cc
@@ -27,6 +27,7 @@ #include "storage/browser/file_system/file_system_url.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/gfx/geometry/rounded_corners_f.h" #include "ui/gfx/geometry/size.h" #include "ui/views/controls/webview/webview.h" #include "url/gurl.h"
diff --git a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc index 72fd6e1f..0a0d7e84d 100644 --- a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc +++ b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc
@@ -202,10 +202,16 @@ extension_watcher_ = std::make_unique<performance_manager::ExtensionWatcher>(); #endif +} +void ChromeBrowserMainExtraPartsPerformanceManager::PreMainMessageLoopRun() { #if !BUILDFLAG(IS_ANDROID) + // This object requires the host frame sink manager to exist, which is created + // after all the extra parts have run their PostCreateThreads. if (base::FeatureList::IsEnabled( - performance_manager::features::kHighEfficiencyModeAvailable)) { + performance_manager::features::kHighEfficiencyModeAvailable) || + base::FeatureList::IsEnabled( + performance_manager::features::kBatterySaverModeAvailable)) { high_efficiency_mode_policy_helper_ = std::make_unique< performance_manager::policies::HighEfficiencyModePolicyHelper>( g_browser_process->local_state());
diff --git a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.h b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.h index 08e1ef0..189b15e 100644 --- a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.h +++ b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.h
@@ -69,6 +69,7 @@ // ChromeBrowserMainExtraParts overrides. void PostCreateThreads() override; + void PreMainMessageLoopRun() override; void PostMainMessageLoopRun() override; // ProfileManagerObserver:
diff --git a/chrome/browser/performance_manager/policies/high_efficiency_mode_policy_helper.cc b/chrome/browser/performance_manager/policies/high_efficiency_mode_policy_helper.cc index a235102..fee70e4 100644 --- a/chrome/browser/performance_manager/policies/high_efficiency_mode_policy_helper.cc +++ b/chrome/browser/performance_manager/policies/high_efficiency_mode_policy_helper.cc
@@ -4,24 +4,40 @@ #include "chrome/browser/performance_manager/policies/high_efficiency_mode_policy_helper.h" +#include "base/feature_list.h" #include "chrome/browser/performance_manager/policies/high_efficiency_mode_policy.h" +#include "components/performance_manager/public/features.h" #include "components/performance_manager/public/performance_manager.h" #include "components/performance_manager/public/user_tuning/prefs.h" #include "components/prefs/pref_service.h" +#include "content/public/browser/frame_rate_throttling.h" namespace performance_manager::policies { HighEfficiencyModePolicyHelper::HighEfficiencyModePolicyHelper( PrefService* local_state) { pref_change_registrar_.Init(local_state); - pref_change_registrar_.Add( - performance_manager::user_tuning::prefs::kHighEfficiencyModeEnabled, - base::BindRepeating( - &HighEfficiencyModePolicyHelper::OnHighEfficiencyModeChanged, - base::Unretained(this))); - // Make sure the initial state of the pref is passed on to the policy. - OnHighEfficiencyModeChanged(); + if (base::FeatureList::IsEnabled( + performance_manager::features::kHighEfficiencyModeAvailable)) { + pref_change_registrar_.Add( + performance_manager::user_tuning::prefs::kHighEfficiencyModeEnabled, + base::BindRepeating( + &HighEfficiencyModePolicyHelper::OnHighEfficiencyModeChanged, + base::Unretained(this))); + // Make sure the initial state of the pref is passed on to the policy. + OnHighEfficiencyModeChanged(); + } + + if (base::FeatureList::IsEnabled( + performance_manager::features::kBatterySaverModeAvailable)) { + pref_change_registrar_.Add( + performance_manager::user_tuning::prefs::kBatterySaverModeEnabled, + base::BindRepeating( + &HighEfficiencyModePolicyHelper::OnBatterySaverModeChanged, + base::Unretained(this))); + OnBatterySaverModeChanged(); + } } void HighEfficiencyModePolicyHelper::OnHighEfficiencyModeChanged() { @@ -36,4 +52,15 @@ enabled)); } +void HighEfficiencyModePolicyHelper::OnBatterySaverModeChanged() { + bool enabled = pref_change_registrar_.prefs()->GetBoolean( + performance_manager::user_tuning::prefs::kBatterySaverModeEnabled); + + if (enabled) { + content::StartThrottlingAllFrameSinks(base::Hertz(30)); + } else { + content::StopThrottlingAllFrameSinks(); + } +} + } // namespace performance_manager::policies
diff --git a/chrome/browser/performance_manager/policies/high_efficiency_mode_policy_helper.h b/chrome/browser/performance_manager/policies/high_efficiency_mode_policy_helper.h index c947587..5c7220d 100644 --- a/chrome/browser/performance_manager/policies/high_efficiency_mode_policy_helper.h +++ b/chrome/browser/performance_manager/policies/high_efficiency_mode_policy_helper.h
@@ -17,6 +17,7 @@ private: void OnHighEfficiencyModeChanged(); + void OnBatterySaverModeChanged(); PrefChangeRegistrar pref_change_registrar_; };
diff --git a/chrome/browser/policy/schema_registry_service_builder.cc b/chrome/browser/policy/schema_registry_service_builder.cc index 00e49cd..8098c330 100644 --- a/chrome/browser/policy/schema_registry_service_builder.cc +++ b/chrome/browser/policy/schema_registry_service_builder.cc
@@ -22,7 +22,7 @@ #include "chrome/browser/ash/policy/core/device_local_account_policy_service.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/profiles/profile.h" #include "components/user_manager/user.h" #include "components/user_manager/user_manager.h"
diff --git a/chrome/browser/profiles/profile_attributes_entry.cc b/chrome/browser/profiles/profile_attributes_entry.cc index 0760f6af..860bd55 100644 --- a/chrome/browser/profiles/profile_attributes_entry.cc +++ b/chrome/browser/profiles/profile_attributes_entry.cc
@@ -655,9 +655,9 @@ } void ProfileAttributesEntry::SetIsUsingGAIAPicture(bool value) { - SetBool(kUseGAIAPictureKey, value); - // TODO(alexilin): send notification only if the value has changed. - profile_attributes_storage_->NotifyOnProfileAvatarChanged(profile_path_); + if (SetBool(kUseGAIAPictureKey, value)) { + profile_attributes_storage_->NotifyOnProfileAvatarChanged(profile_path_); + } } void ProfileAttributesEntry::SetLastDownloadedGAIAPictureUrlWithSize( @@ -666,17 +666,14 @@ } void ProfileAttributesEntry::SetSignedInWithCredentialProvider(bool value) { - if (value != GetBool(prefs::kSignedInWithCredentialProvider)) { - SetBool(prefs::kSignedInWithCredentialProvider, value); - } + SetBool(prefs::kSignedInWithCredentialProvider, value); } void ProfileAttributesEntry::LockForceSigninProfile(bool is_lock) { DCHECK(signin_util::IsForceSigninEnabled()); - if (GetBool(kForceSigninProfileLockedKey) == is_lock) - return; - SetBool(kForceSigninProfileLockedKey, is_lock); - profile_attributes_storage_->NotifyIsSigninRequiredChanged(GetPath()); + if (SetBool(kForceSigninProfileLockedKey, is_lock)) { + profile_attributes_storage_->NotifyIsSigninRequiredChanged(GetPath()); + } } void ProfileAttributesEntry::RecordAccountMetrics() const { @@ -710,24 +707,20 @@ void ProfileAttributesEntry::SetAvatarIconIndex(size_t icon_index) { std::string default_avatar_icon_url = profiles::GetDefaultAvatarIconUrl(icon_index); - if (default_avatar_icon_url == GetString(kAvatarIconKey)) { + if (SetString(kAvatarIconKey, default_avatar_icon_url)) { // On Windows, Taskbar and Desktop icons are refreshed every time // |OnProfileAvatarChanged| notification is fired. // As the current avatar icon is already set to |default_avatar_icon_url|, // it is important to avoid firing |OnProfileAvatarChanged| in this case. // See http://crbug.com/900374 - return; + base::FilePath profile_path = GetPath(); + if (!profile_attributes_storage_->GetDisableAvatarDownloadForTesting()) { + profile_attributes_storage_->DownloadHighResAvatarIfNeeded(icon_index, + profile_path); + } + + profile_attributes_storage_->NotifyOnProfileAvatarChanged(profile_path); } - - SetString(kAvatarIconKey, default_avatar_icon_url); - - base::FilePath profile_path = GetPath(); - if (!profile_attributes_storage_->GetDisableAvatarDownloadForTesting()) { - profile_attributes_storage_->DownloadHighResAvatarIfNeeded(icon_index, - profile_path); - } - - profile_attributes_storage_->NotifyOnProfileAvatarChanged(profile_path); } void ProfileAttributesEntry::SetProfileThemeColors( @@ -956,24 +949,29 @@ // Internal setters using keys; bool ProfileAttributesEntry::SetString(const char* key, const std::string& value) { - return SetValue(key, base::Value(value)); + std::string old_value = GetString(key); + return SetValue(key, base::Value(value)) && old_value != value; } bool ProfileAttributesEntry::SetString16(const char* key, const std::u16string& value) { - return SetValue(key, base::Value(value)); + std::u16string old_value = GetString16(key); + return SetValue(key, base::Value(value)) && old_value != value; } bool ProfileAttributesEntry::SetDouble(const char* key, double value) { - return SetValue(key, base::Value(value)); + double old_value = GetDouble(key); + return SetValue(key, base::Value(value)) && old_value != value; } bool ProfileAttributesEntry::SetBool(const char* key, bool value) { - return SetValue(key, base::Value(value)); + bool old_value = GetBool(key); + return SetValue(key, base::Value(value)) && old_value != value; } bool ProfileAttributesEntry::SetInteger(const char* key, int value) { - return SetValue(key, base::Value(value)); + int old_value = GetInteger(key); + return SetValue(key, base::Value(value)) && old_value != value; } bool ProfileAttributesEntry::SetValue(const char* key, base::Value value) {
diff --git a/chrome/browser/profiles/profile_attributes_entry.h b/chrome/browser/profiles/profile_attributes_entry.h index 632bf6bb..33cd025 100644 --- a/chrome/browser/profiles/profile_attributes_entry.h +++ b/chrome/browser/profiles/profile_attributes_entry.h
@@ -310,6 +310,9 @@ // Internal setters that accept basic data types. Return if the original data // is different from the new data, i.e. whether actual update is done. + // If the data was missing or was from a different type and `value` is the + // default value (e.g. false, 0, empty string...), the value is explicitly + // written but these return false. bool SetString(const char* key, const std::string& value); bool SetString16(const char* key, const std::u16string& value); bool SetDouble(const char* key, double value);
diff --git a/chrome/browser/profiles/profile_attributes_storage_unittest.cc b/chrome/browser/profiles/profile_attributes_storage_unittest.cc index 2670136..c1ec0c8c 100644 --- a/chrome/browser/profiles/profile_attributes_storage_unittest.cc +++ b/chrome/browser/profiles/profile_attributes_storage_unittest.cc
@@ -831,19 +831,19 @@ EXPECT_TRUE(entry->SetString16(key, u"efgh")); - // If previous data is not there, setters should returns true even if the + // If previous data is not there, setters should returns false even if the // defaults (empty string, 0.0, or false) are written. - EXPECT_TRUE(entry->SetString("test1", std::string())); - EXPECT_TRUE(entry->SetString16("test2", std::u16string())); - EXPECT_TRUE(entry->SetDouble("test3", 0.0)); - EXPECT_TRUE(entry->SetBool("test4", false)); + EXPECT_FALSE(entry->SetString("test1", std::string())); + EXPECT_FALSE(entry->SetString16("test2", std::u16string())); + EXPECT_FALSE(entry->SetDouble("test3", 0.0)); + EXPECT_FALSE(entry->SetBool("test4", false)); - // If previous data is in a wrong type, setters should returns true even if + // If previous data is in a wrong type, setters should returns false even if // the defaults (empty string, 0.0, or false) are written. - EXPECT_TRUE(entry->SetString("test3", std::string())); - EXPECT_TRUE(entry->SetString16("test4", std::u16string())); - EXPECT_TRUE(entry->SetDouble("test1", 0.0)); - EXPECT_TRUE(entry->SetBool("test2", false)); + EXPECT_FALSE(entry->SetString("test3", std::string())); + EXPECT_FALSE(entry->SetString16("test4", std::u16string())); + EXPECT_FALSE(entry->SetDouble("test1", 0.0)); + EXPECT_FALSE(entry->SetBool("test2", false)); } TEST_F(ProfileAttributesStorageTest, ProfileActiveTime) {
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc index 5f98cf11..fa40d882 100644 --- a/chrome/browser/profiles/profile_manager.cc +++ b/chrome/browser/profiles/profile_manager.cc
@@ -149,7 +149,7 @@ #include "chrome/browser/ash/account_manager/child_account_type_changed_user_data.h" #include "chrome/browser/ash/arc/policy/arc_policy_util.h" #include "chrome/browser/ash/profiles/profile_helper.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "components/user_manager/user.h" #include "components/user_manager/user_manager.h" #include "components/user_manager/user_type.h" @@ -712,8 +712,20 @@ if (!user) // Can be null in unit tests. return nullptr; - // Note: The ProfileHelper will take care of guest profiles. - return ash::ProfileHelper::Get()->GetProfileByUserUnsafe(user); + if (user->is_profile_created()) { + // Note: The ProfileHelper will take care of guest profiles. + return ash::ProfileHelper::Get()->GetProfileByUser(user); + } + + LOG(ERROR) << "ProfileManager::GetPrimaryUserProfile is called when " + "|user| is created but |user|'s profile is not yet created. " + "It probably means that something is wrong with a calling " + "code. Please report in http://crbug.com/361528 if you see " + "this message."; + Profile* profile = ProfileManager::GetActiveUserProfile(); + if (profile && manager->IsLoggedInAsGuest()) + profile = profile->GetPrimaryOTRProfile(/*create_if_needed=*/true); + return profile; } #endif @@ -739,7 +751,7 @@ // yet created we load the profile using the profile directly. // TODO: This should be cleaned up with the new profile manager. if (user && user->is_profile_created()) - return ash::ProfileHelper::Get()->GetProfileByUserUnsafe(user); + return ash::ProfileHelper::Get()->GetProfileByUser(user); } #endif Profile* profile = profile_manager->GetActiveUserOrOffTheRecordProfile();
diff --git a/chrome/browser/resources/access_code_cast/BUILD.gn b/chrome/browser/resources/access_code_cast/BUILD.gn index 4e7ceea8..f4d69ad 100644 --- a/chrome/browser/resources/access_code_cast/BUILD.gn +++ b/chrome/browser/resources/access_code_cast/BUILD.gn
@@ -3,39 +3,36 @@ # found in the LICENSE file. import("//tools/grit/grit_rule.gni") -import("//tools/polymer/html_to_js.gni") +import("//tools/grit/preprocess_if_expr.gni") +import("//tools/polymer/html_to_wrapper.gni") import("//tools/typescript/ts_library.gni") import("//ui/webui/resources/tools/generate_grd.gni") +import("./access_code_cast.gni") assert(!is_android, "access_code_cast is not for android.") resources_grd_file = "$target_gen_dir/resources.grd" -html_to_js("web_components") { - js_files = [ - "access_code_cast.ts", - "error_message/error_message.ts", - "passcode_input/passcode_input.ts", - ] +html_to_wrapper("html_wrapper_files") { + in_files = html_files } -copy("copy_browser_proxy") { - sources = [ "browser_proxy.ts" ] - outputs = [ "$target_gen_dir/{{source_file_part}}" ] +preprocess_if_expr("preprocess_src") { + in_folder = "." + out_folder = target_gen_dir + in_files = ts_files } copy("copy_mojo") { - deps = [ "//chrome/browser/ui/webui/access_code_cast:mojo_bindings_webui_js" ] - mojom_folder = - "$root_gen_dir/mojom-webui/chrome/browser/ui/webui/access_code_cast/" - sources = [ "$mojom_folder/access_code_cast.mojom-webui.js" ] - outputs = [ "$target_gen_dir/{{source_file_part}}" ] -} + deps = [ + "//chrome/browser/ui/webui/access_code_cast:mojo_bindings_webui_js", + "//components/media_router/common/mojom:route_request_result_code_webui_js", + ] -copy("copy_mojo_dep") { - deps = [ "//components/media_router/common/mojom:route_request_result_code_webui_js" ] - mojom_folder = "$root_gen_dir/mojom-webui/components/media_router/common/mojom/" - sources = [ "$mojom_folder/route_request_result_code.mojom-webui.js" ] + sources = [ + "$root_gen_dir/mojom-webui/chrome/browser/ui/webui/access_code_cast/access_code_cast.mojom-webui.js", + "$root_gen_dir/mojom-webui/components/media_router/common/mojom/route_request_result_code.mojom-webui.js", + ] outputs = [ "$target_gen_dir/{{source_file_part}}" ] } @@ -45,23 +42,18 @@ "//ui/webui/resources:library", ] extra_deps = [ - ":copy_browser_proxy", ":copy_mojo", - ":copy_mojo_dep", - ":web_components", + ":html_wrapper_files", + ":preprocess_src", ] - root_dir = "$target_gen_dir" + root_dir = target_gen_dir out_dir = "$target_gen_dir/tsc" composite = true tsconfig_base = "tsconfig_base.json" - in_files = [ - "access_code_cast.mojom-webui.js", - "access_code_cast.ts", - "browser_proxy.ts", - "error_message/error_message.ts", - "passcode_input/passcode_input.ts", - "route_request_result_code.mojom-webui.js", - ] + in_files = ts_files + html_wrapper_files + [ + "access_code_cast.mojom-webui.js", + "route_request_result_code.mojom-webui.js", + ] } generate_grd("build_grd") {
diff --git a/chrome/browser/resources/access_code_cast/access_code_cast.gni b/chrome/browser/resources/access_code_cast/access_code_cast.gni new file mode 100644 index 0000000..4c7ac89 --- /dev/null +++ b/chrome/browser/resources/access_code_cast/access_code_cast.gni
@@ -0,0 +1,26 @@ +# Copyright 2022 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +_non_web_component_files = [ "browser_proxy.ts" ] + +# Files holding a custom element definition and have an equivalent .html file. +_web_component_files = [ + "access_code_cast.ts", + "error_message/error_message.ts", + "passcode_input/passcode_input.ts", +] + +# Files that are passed as input to html_to_wrapper(). +html_files = [] +foreach(f, _web_component_files) { + html_files += [ string_replace(f, ".ts", ".html") ] +} + +# Files that are generated by html_to_wrapper(). +html_wrapper_files = [] +foreach(f, html_files) { + html_wrapper_files += [ f + ".ts" ] +} + +ts_files = _web_component_files + _non_web_component_files
diff --git a/chrome/browser/resources/access_code_cast/access_code_cast.ts b/chrome/browser/resources/access_code_cast/access_code_cast.ts index df906a5..4efd6bf 100644 --- a/chrome/browser/resources/access_code_cast/access_code_cast.ts +++ b/chrome/browser/resources/access_code_cast/access_code_cast.ts
@@ -4,7 +4,6 @@ import './passcode_input/passcode_input.js'; import './error_message/error_message.js'; - import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js'; import 'chrome://resources/cr_elements/icons.m.js'; @@ -18,12 +17,13 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {PluralStringProxyImpl} from 'chrome://resources/js/plural_string_proxy.js'; import {WebUIListenerMixin} from 'chrome://resources/js/web_ui_listener_mixin.js'; -import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {getTemplate} from './access_code_cast.html.js'; import {AddSinkResultCode, CastDiscoveryMethod, PageCallbackRouter} from './access_code_cast.mojom-webui.js'; import {BrowserProxy, DialogCloseReason} from './browser_proxy.js'; -import {PasscodeInputElement} from './passcode_input/passcode_input.js'; import {ErrorMessageElement} from './error_message/error_message.js'; +import {PasscodeInputElement} from './passcode_input/passcode_input.js'; import {RouteRequestResultCode} from './route_request_result_code.mojom-webui.js'; enum PageState { @@ -58,7 +58,7 @@ } static get template() { - return html`{__html_template__}`; + return getTemplate(); } static get properties() {
diff --git a/chrome/browser/resources/access_code_cast/error_message/error_message.ts b/chrome/browser/resources/access_code_cast/error_message/error_message.ts index 39a4fb16..814399a 100644 --- a/chrome/browser/resources/access_code_cast/error_message/error_message.ts +++ b/chrome/browser/resources/access_code_cast/error_message/error_message.ts
@@ -5,11 +5,13 @@ import 'chrome://resources/cr_elements/icons.m.js'; import 'chrome://resources/cr_elements/shared_vars_css.m.js'; -import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {AddSinkResultCode} from '../access_code_cast.mojom-webui.js'; import {RouteRequestResultCode} from '../route_request_result_code.mojom-webui.js'; +import {getTemplate} from './error_message.html.js'; + enum ErrorMessage { NO_ERROR, GENERIC, @@ -95,7 +97,7 @@ } static get template() { - return html`{__html_template__}`; + return getTemplate(); } private messageCode = ErrorMessage.NO_ERROR;
diff --git a/chrome/browser/resources/access_code_cast/passcode_input/passcode_input.ts b/chrome/browser/resources/access_code_cast/passcode_input/passcode_input.ts index 6fce10c1..485fc3d 100644 --- a/chrome/browser/resources/access_code_cast/passcode_input/passcode_input.ts +++ b/chrome/browser/resources/access_code_cast/passcode_input/passcode_input.ts
@@ -2,7 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {afterNextRender, html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {afterNextRender, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {getTemplate} from './passcode_input.html.js'; type ForEachCallback = (el: HTMLParagraphElement|HTMLDivElement, index: number) => void; @@ -19,7 +21,7 @@ } static get template() { - return html`{__html_template__}`; + return getTemplate(); } static get properties() {
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn index de7b6eb..5bbe48b 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
@@ -37,7 +37,6 @@ "background/event_source.js", "background/focus_bounds.js", "background/logging/log_store.js", - "background/output/output.js", "background/output/output_ancestry_info.js", "background/output/output_format_parser.js", "background/output/output_format_tree.js", @@ -115,6 +114,7 @@ "background/logging/log_url_watcher.js", "background/math_handler.js", "background/media_automation_handler.js", + "background/output/output.js", "background/page_load_sound_handler.js", "background/panel/i_search.js", "background/panel/i_search_handler.js",
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js index 23d9851..983e9731 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background.js
@@ -18,6 +18,7 @@ import {LiveRegions} from '/chromevox/background/live_regions.js'; import {MathHandler} from '/chromevox/background/math_handler.js'; import {MediaAutomationHandler} from '/chromevox/background/media_automation_handler.js'; +import {Output} from '/chromevox/background/output/output.js'; import {PageLoadSoundHandler} from '/chromevox/background/page_load_sound_handler.js'; import {PanelBackground} from '/chromevox/background/panel/panel_background.js'; import {ChromeVoxPrefs} from '/chromevox/background/prefs.js';
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js index 6e4ef0fd..4be5703 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js
@@ -44,6 +44,7 @@ await importModule( 'GestureCommandHandler', '/chromevox/background/gesture_command_handler.js'); + await importModule('Output', '/chromevox/background/output/output.js'); await importModule( 'PageLoadSoundHandler', '/chromevox/background/page_load_sound_handler.js');
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/base_automation_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/base_automation_handler.js index 9cf6e47e..73795fbf 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/base_automation_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/base_automation_handler.js
@@ -7,6 +7,7 @@ * node. */ import {ChromeVoxState} from '/chromevox/background/chromevox_state.js'; +import {Output} from '/chromevox/background/output/output.js'; import {ChromeVoxEvent} from '/chromevox/common/custom_automation_event.js'; const ActionType = chrome.automation.ActionType;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_command_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_command_handler.js index 8dff763..417257c 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_command_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_command_handler.js
@@ -7,6 +7,7 @@ */ import {ChromeVoxState} from '/chromevox/background/chromevox_state.js'; import {DesktopAutomationInterface} from '/chromevox/background/desktop_automation_interface.js'; +import {Output} from '/chromevox/background/output/output.js'; import {BrailleCommandData} from '/chromevox/common/braille/braille_command_data.js'; import {EventGenerator} from '/common/event_generator.js';
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_key_event_rewriter.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_key_event_rewriter.js index 4a9e456a..7baf4ee 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_key_event_rewriter.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_key_event_rewriter.js
@@ -5,6 +5,7 @@ /** * @fileoverview Rewrites a braille key event. */ +import {Output} from '/chromevox/background/output/output.js'; /** * A class that transforms a sequence of braille key events into a standard key
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/classic_background.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/classic_background.js index dff6b5ee..157ff8b9 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/classic_background.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/classic_background.js
@@ -11,6 +11,7 @@ import {ConsoleTts} from '/chromevox/background/console_tts.js'; import {ChromeVoxEditableTextBase, TypingEcho} from '/chromevox/background/editing/editable_text_base.js'; import {InjectedScriptLoader} from '/chromevox/background/injected_script_loader.js'; +import {Output} from '/chromevox/background/output/output.js'; import {ChromeVoxPrefs} from '/chromevox/background/prefs.js'; import {TtsBackground} from '/chromevox/background/tts_background.js'; import {AbstractTts} from '/chromevox/common/abstract_tts.js';
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js index 3caca65..8e7b7de 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js
@@ -14,6 +14,7 @@ import {DesktopAutomationInterface} from '/chromevox/background/desktop_automation_interface.js'; import {TypingEcho} from '/chromevox/background/editing/editable_text_base.js'; import {GestureInterface} from '/chromevox/background/gesture_interface.js'; +import {Output} from '/chromevox/background/output/output.js'; import {ChromeVoxPrefs} from '/chromevox/background/prefs.js'; import {SmartStickyMode} from '/chromevox/background/smart_sticky_mode.js'; import {AbstractTts} from '/chromevox/common/abstract_tts.js';
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/desktop_automation_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/desktop_automation_handler.js index 48991631..40498fe 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/desktop_automation_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/desktop_automation_handler.js
@@ -10,6 +10,7 @@ import {ChromeVoxState} from '/chromevox/background/chromevox_state.js'; import {DesktopAutomationInterface} from '/chromevox/background/desktop_automation_interface.js'; import {TextEditHandler} from '/chromevox/background/editing/editing.js'; +import {Output} from '/chromevox/background/output/output.js'; import {ChromeVoxEvent, CustomAutomationEvent} from '/chromevox/common/custom_automation_event.js'; const ActionType = chrome.automation.ActionType;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/download_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/download_handler.js index 543364f..9747dff 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/download_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/download_handler.js
@@ -6,6 +6,7 @@ * @fileoverview Listens for download events and provides corresponding * notifications in ChromeVox. */ +import {Output} from '/chromevox/background/output/output.js'; export class DownloadHandler {}
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editable_line.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editable_line.js index dbb785f..e2c80f76 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editable_line.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editable_line.js
@@ -8,6 +8,7 @@ * (e.g. start/end offsets) get saved. Line: nodes/offsets at the beginning/end * of a line get saved. */ +import {Output} from '/chromevox/background/output/output.js'; const AutomationEvent = chrome.automation.AutomationEvent; const AutomationNode = chrome.automation.AutomationNode;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing.js index e046691..ce0e2aa 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing.js
@@ -12,6 +12,7 @@ import {EditableLine} from '/chromevox/background/editing/editable_line.js'; import {ChromeVoxEditableTextBase, TextChangeEvent} from '/chromevox/background/editing/editable_text_base.js'; import {IntentHandler} from '/chromevox/background/editing/intent_handler.js'; +import {Output} from '/chromevox/background/output/output.js'; import {AbstractTts} from '/chromevox/common/abstract_tts.js'; import {ChromeVoxEvent} from '/chromevox/common/custom_automation_event.js';
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/intent_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/intent_handler.js index 890ee1729..38db752 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/intent_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/intent_handler.js
@@ -7,6 +7,7 @@ * Braille is *not* handled in this module. */ import {EditableLine} from '/chromevox/background/editing/editable_line.js'; +import {Output} from '/chromevox/background/output/output.js'; const AutomationIntent = chrome.automation.AutomationIntent; const Cursor = cursors.Cursor;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/intent_handler_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/intent_handler_test.js index 3a2c4af2..46900d5 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/intent_handler_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/intent_handler_test.js
@@ -19,6 +19,7 @@ await super.setUpDeferred(); await importModule( 'IntentHandler', '/chromevox/background/editing/intent_handler.js'); + await importModule('Output', '/chromevox/background/output/output.js'); window.Dir = constants.Dir; window.IntentTextBoundaryType = chrome.automation.IntentTextBoundaryType;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/find_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/find_handler.js index a33abd0..c3c8c13 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/find_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/find_handler.js
@@ -6,6 +6,7 @@ * @fileoverview Handles output for Chrome's built-in find. */ import {ChromeVoxState} from '/chromevox/background/chromevox_state.js'; +import {Output} from '/chromevox/background/output/output.js'; const TreeChangeObserverFilter = chrome.automation.TreeChangeObserverFilter;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/focus_automation_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/focus_automation_handler.js index f7c6105..705b9f1 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/focus_automation_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/focus_automation_handler.js
@@ -7,6 +7,7 @@ */ import {BaseAutomationHandler} from '/chromevox/background/base_automation_handler.js'; import {ChromeVoxState} from '/chromevox/background/chromevox_state.js'; +import {Output} from '/chromevox/background/output/output.js'; import {ChromeVoxEvent} from '/chromevox/common/custom_automation_event.js'; const AutomationEvent = chrome.automation.AutomationEvent;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/gesture_command_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/gesture_command_handler.js index bbd9d03..049ab7d 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/gesture_command_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/gesture_command_handler.js
@@ -7,6 +7,7 @@ */ import {ChromeVoxState} from '/chromevox/background/chromevox_state.js'; import {GestureInterface} from '/chromevox/background/gesture_interface.js'; +import {Output} from '/chromevox/background/output/output.js'; import {PointerHandler} from '/chromevox/background/pointer_handler.js'; import {UserActionMonitor} from '/chromevox/background/user_action_monitor.js'; import {GestureCommandData, GestureGranularity} from '/chromevox/common/gesture_command_data.js';
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/keyboard_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/keyboard_handler.js index 06718706..025418c 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/keyboard_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/keyboard_handler.js
@@ -7,6 +7,7 @@ */ import {ChromeVoxState} from '/chromevox/background/chromevox_state.js'; import {MathHandler} from '/chromevox/background/math_handler.js'; +import {Output} from '/chromevox/background/output/output.js'; import {ChromeVoxKbHandler} from '/chromevox/common/keyboard_handler.js'; /**
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/live_regions.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/live_regions.js index 96b409f7b..7498100 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/live_regions.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/live_regions.js
@@ -6,6 +6,7 @@ * @fileoverview Implements support for live regions in ChromeVox Next. */ import {ChromeVoxState} from '/chromevox/background/chromevox_state.js'; +import {Output} from '/chromevox/background/output/output.js'; const AutomationNode = chrome.automation.AutomationNode; const RoleType = chrome.automation.RoleType;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/live_regions_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/live_regions_test.js index 85b8ffd..da7d4293 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/live_regions_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/live_regions_test.js
@@ -16,6 +16,7 @@ await importModule( 'ChromeVoxState', '/chromevox/background/chromevox_state.js'); await importModule('LiveRegions', '/chromevox/background/live_regions.js'); + await importModule('Output', '/chromevox/background/output/output.js'); window.TreeChangeType = chrome.automation.TreeChangeType; }
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/loader.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/loader.js index 01f09de..754d229 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/loader.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/loader.js
@@ -29,8 +29,18 @@ goog.require('LogType'); goog.require('Msgs'); goog.require('NavBraille'); -goog.require('Output'); +goog.require('OutputAction'); +goog.require('OutputAncestryInfo'); +goog.require('OutputContextOrder'); +goog.require('OutputEarconAction'); goog.require('OutputEventType'); +goog.require('OutputFormatParser'); +goog.require('OutputFormatTree'); +goog.require('OutputNodeSpan'); +goog.require('OutputRoleInfo'); +goog.require('OutputRulesStr'); +goog.require('OutputSelectionSpan'); +goog.require('OutputSpeechProperties'); goog.require('PanelBridge'); goog.require('PanelCommand'); goog.require('PanelCommandType'); @@ -41,8 +51,10 @@ goog.require('Spannable'); goog.require('SpeechLog'); goog.require('StringUtil'); +goog.require('TextLog'); goog.require('TreeDumper'); goog.require('TreePathRecoveryStrategy'); +goog.require('TtsCategory'); goog.require('TtsInterface'); goog.require('ValueSelectionSpan'); goog.require('ValueSpan'); @@ -50,5 +62,7 @@ goog.require('constants'); goog.require('cursors.Cursor'); goog.require('cursors.Range'); +goog.require('cursors.Unit'); +goog.require('goog.i18n.MessageFormat'); goog.require('ALL_NODE_MENU_DATA');
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output.js index c021b331..1289c0d 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output.js
@@ -6,41 +6,6 @@ * @fileoverview Provides output services for ChromeVox. */ -goog.provide('Output'); - -goog.require('AbstractEarcons'); -goog.require('AutomationTreeWalker'); -goog.require('ChromeVox'); -goog.require('EventSourceState'); -goog.require('FocusBounds'); -goog.require('LocaleOutputHelper'); -goog.require('LogStore'); -goog.require('NavBraille'); -goog.require('OutputAction'); -goog.require('OutputAncestryInfo'); -goog.require('OutputContextOrder'); -goog.require('OutputEarconAction'); -goog.require('OutputEventType'); -goog.require('OutputFormatParser'); -goog.require('OutputFormatTree'); -goog.require('OutputNodeSpan'); -goog.require('OutputRoleInfo'); -goog.require('OutputRulesStr'); -goog.require('OutputSelectionSpan'); -goog.require('OutputSpeechProperties'); -goog.require('PhoneticData'); -goog.require('Spannable'); -goog.require('TextLog'); -goog.require('TtsCategory'); -goog.require('ValueSelectionSpan'); -goog.require('ValueSpan'); -goog.require('constants'); -goog.require('cursors.Cursor'); -goog.require('cursors.Range'); -goog.require('cursors.Unit'); -goog.require('goog.i18n.MessageFormat'); - -goog.scope(function() { const AriaCurrentState = chrome.automation.AriaCurrentState; const AutomationNode = chrome.automation.AutomationNode; const DescriptionFromType = chrome.automation.DescriptionFromType; @@ -78,7 +43,7 @@ * For example, $name= would insert the name attribute only if no name * attribute had been inserted previously. */ -Output = class { +export class Output { constructor() { // TODO(dtseng): Include braille specific rules. /** @type {!Array<!Spannable>} @private */ @@ -2564,7 +2529,7 @@ buff[buff.length - 1].setSpan(speechProps, 0, 0); } } -}; +} /** * Delimiter to use between output values. @@ -2932,4 +2897,3 @@ * @private */ Output.forceModeForNextSpeechUtterance_; -}); // goog.scope
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_test.js index 0c3e945..96d5389 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/output/output_test.js
@@ -103,6 +103,12 @@ window.Dir = AutomationUtil.Dir; this.forceContextualLastOutput(); } + + /** @override */ + async setUpDeferred() { + await super.setUpDeferred(); + await importModule('Output', '/chromevox/background/output/output.js'); + } };
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/i_search.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/i_search.js index 907100d6..f26fe88 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/i_search.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/panel/i_search.js
@@ -5,6 +5,7 @@ /** * @fileoverview The logic behind incremental search. */ +import {Output} from '/chromevox/background/output/output.js'; import {ISearchHandler} from '/chromevox/background/panel/i_search_handler.js'; const Dir = constants.Dir;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/pointer_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/pointer_handler.js index 7a15b57..ec85cf6 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/pointer_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/pointer_handler.js
@@ -9,6 +9,7 @@ import {BaseAutomationHandler} from '/chromevox/background/base_automation_handler.js'; import {ChromeVoxState} from '/chromevox/background/chromevox_state.js'; import {DesktopAutomationInterface} from '/chromevox/background/desktop_automation_interface.js'; +import {Output} from '/chromevox/background/output/output.js'; import {CustomAutomationEvent} from '/chromevox/common/custom_automation_event.js'; import {EventGenerator} from '/common/event_generator.js';
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/range_automation_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/range_automation_handler.js index 6b502dd..8e0d95d 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/range_automation_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/range_automation_handler.js
@@ -8,6 +8,7 @@ import {BaseAutomationHandler} from '/chromevox/background/base_automation_handler.js'; import {ChromeVoxState, ChromeVoxStateObserver} from '/chromevox/background/chromevox_state.js'; import {DesktopAutomationHandler} from '/chromevox/background/desktop_automation_handler.js'; +import {Output} from '/chromevox/background/output/output.js'; import {ChromeVoxEvent, CustomAutomationEvent} from '/chromevox/common/custom_automation_event.js'; const AutomationEvent = chrome.automation.AutomationEvent;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/user_action_monitor.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/user_action_monitor.js index 292dbdb3..8c32ef3 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/user_action_monitor.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/user_action_monitor.js
@@ -5,6 +5,7 @@ /** * @fileoverview Monitors user actions. */ +import {Output} from '/chromevox/background/output/output.js'; /** * The types of actions we want to monitor.
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_loader.js b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_loader.js index ff4fc54..5fce03c 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_loader.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/panel/panel_loader.js
@@ -11,18 +11,42 @@ goog.require('BackgroundBridge'); goog.require('BridgeHelper'); goog.require('EarconDescription'); +goog.require('EventSourceState'); goog.require('EventSourceType'); +goog.require('FocusBounds'); goog.require('KeyCode'); goog.require('KeySequence'); goog.require('LocaleOutputHelper'); +goog.require('LogStore'); goog.require('Msgs'); -goog.require('Output'); -goog.require('Output'); +goog.require('NavBraille'); +goog.require('OutputAction'); +goog.require('OutputAncestryInfo'); +goog.require('OutputContextOrder'); +goog.require('OutputEarconAction'); +goog.require('OutputEventType'); +goog.require('OutputFormatParser'); +goog.require('OutputFormatTree'); +goog.require('OutputNodeSpan'); +goog.require('OutputRoleInfo'); +goog.require('OutputRulesStr'); +goog.require('OutputSelectionSpan'); +goog.require('OutputSpeechProperties'); goog.require('PanelCommand'); +goog.require('PanelCommandType'); goog.require('PanelNodeMenuData'); +goog.require('PanelNodeMenuItemData'); goog.require('QueueMode'); +goog.require('Spannable'); +goog.require('TextLog'); +goog.require('TtsCategory'); +goog.require('ValueSelectionSpan'); +goog.require('ValueSpan'); goog.require('constants'); goog.require('cursors.Cursor'); goog.require('cursors.Range'); +goog.require('cursors.Unit'); +goog.require('goog.i18n.MessageFormat'); + goog.require('ALL_NODE_MENU_DATA');
diff --git a/chrome/browser/resources/support_tool/BUILD.gn b/chrome/browser/resources/support_tool/BUILD.gn index d5c8f7bb..a73e9920 100644 --- a/chrome/browser/resources/support_tool/BUILD.gn +++ b/chrome/browser/resources/support_tool/BUILD.gn
@@ -3,7 +3,7 @@ # found in the LICENSE file. import("//tools/grit/grit_rule.gni") -import("//tools/polymer/html_to_js.gni") +import("//tools/polymer/css_to_wrapper.gni") import("//tools/polymer/html_to_wrapper.gni") import("//tools/typescript/ts_library.gni") import("//ui/webui/resources/tools/generate_grd.gni") @@ -43,8 +43,8 @@ outputs = [ "$target_gen_dir/{{source_file_part}}" ] } -html_to_js("css_wrapper_files") { - js_files = css_wrapper_files +css_to_wrapper("css_wrapper_files") { + in_files = css_files } html_to_wrapper("html_wrapper_files") {
diff --git a/chrome/browser/resources/support_tool/data_collectors.ts b/chrome/browser/resources/support_tool/data_collectors.ts index 8c4c70b..1b89f1a 100644 --- a/chrome/browser/resources/support_tool/data_collectors.ts +++ b/chrome/browser/resources/support_tool/data_collectors.ts
@@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import './support_tool_shared_css.js'; +import './support_tool_shared.css.js'; import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js'; import 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + import {BrowserProxy, BrowserProxyImpl, DataCollectorItem} from './browser_proxy.js'; import {getTemplate} from './data_collectors.html.js'; @@ -51,4 +52,4 @@ } } -customElements.define(DataCollectorsElement.is, DataCollectorsElement); \ No newline at end of file +customElements.define(DataCollectorsElement.is, DataCollectorsElement);
diff --git a/chrome/browser/resources/support_tool/data_export_done.ts b/chrome/browser/resources/support_tool/data_export_done.ts index d57f30a..93f0d6e4 100644 --- a/chrome/browser/resources/support_tool/data_export_done.ts +++ b/chrome/browser/resources/support_tool/data_export_done.ts
@@ -2,13 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import './support_tool_shared_css.js'; +import './support_tool_shared.css.js'; import 'chrome://resources/cr_elements/icons.m.js'; import 'chrome://resources/cr_elements/shared_vars_css.m.js'; import 'chrome://resources/cr_elements/action_link_css.m.js'; import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + import {BrowserProxy, BrowserProxyImpl} from './browser_proxy.js'; import {getTemplate} from './data_export_done.html.js'; @@ -48,4 +49,4 @@ } } -customElements.define(DataExportDoneElement.is, DataExportDoneElement); \ No newline at end of file +customElements.define(DataExportDoneElement.is, DataExportDoneElement);
diff --git a/chrome/browser/resources/support_tool/issue_details.ts b/chrome/browser/resources/support_tool/issue_details.ts index fc4a126..1c42030 100644 --- a/chrome/browser/resources/support_tool/issue_details.ts +++ b/chrome/browser/resources/support_tool/issue_details.ts
@@ -6,10 +6,11 @@ import 'chrome://resources/cr_elements/shared_vars_css.m.js'; import 'chrome://resources/cr_elements/cr_input/cr_input.m.js'; import 'chrome://resources/cr_elements/md_select_css.m.js'; -import './support_tool_shared_css.js'; +import './support_tool_shared.css.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + import {BrowserProxy, BrowserProxyImpl, IssueDetails} from './browser_proxy.js'; import {getTemplate} from './issue_details.html.js'; @@ -81,4 +82,4 @@ } } -customElements.define(IssueDetailsElement.is, IssueDetailsElement); \ No newline at end of file +customElements.define(IssueDetailsElement.is, IssueDetailsElement);
diff --git a/chrome/browser/resources/support_tool/pii_selection.ts b/chrome/browser/resources/support_tool/pii_selection.ts index b21a52e5..1a76ce3 100644 --- a/chrome/browser/resources/support_tool/pii_selection.ts +++ b/chrome/browser/resources/support_tool/pii_selection.ts
@@ -8,7 +8,7 @@ import 'chrome://resources/cr_elements/cr_radio_button/cr_radio_button.m.js'; import 'chrome://resources/cr_elements/cr_radio_group/cr_radio_group.m.js'; import 'chrome://resources/cr_elements/shared_vars_css.m.js'; -import './support_tool_shared_css.js'; +import './support_tool_shared.css.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -111,4 +111,4 @@ } } -customElements.define(PIISelectionElement.is, PIISelectionElement); \ No newline at end of file +customElements.define(PIISelectionElement.is, PIISelectionElement);
diff --git a/chrome/browser/resources/support_tool/spinner_page.ts b/chrome/browser/resources/support_tool/spinner_page.ts index 6fe18bea..6834366 100644 --- a/chrome/browser/resources/support_tool/spinner_page.ts +++ b/chrome/browser/resources/support_tool/spinner_page.ts
@@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import './support_tool_shared_css.js'; +import './support_tool_shared.css.js'; import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; import 'chrome://resources/polymer/v3_0/paper-spinner/paper-spinner-lite.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + import {BrowserProxy, BrowserProxyImpl} from './browser_proxy.js'; import {getTemplate} from './spinner_page.html.js'; @@ -42,4 +43,4 @@ } } -customElements.define(SpinnerPageElement.is, SpinnerPageElement); \ No newline at end of file +customElements.define(SpinnerPageElement.is, SpinnerPageElement);
diff --git a/chrome/browser/resources/support_tool/support_tool.gni b/chrome/browser/resources/support_tool/support_tool.gni index 7809bfee..1044b44 100644 --- a/chrome/browser/resources/support_tool/support_tool.gni +++ b/chrome/browser/resources/support_tool/support_tool.gni
@@ -3,19 +3,19 @@ # found in the LICENSE file. # Files holding a Polymer element definition and have an equivalent .html file. -web_component_files = [ - "support_tool.ts", - "issue_details.ts", +_web_component_files = [ "data_collectors.ts", - "spinner_page.ts", - "pii_selection.ts", "data_export_done.ts", + "issue_details.ts", + "pii_selection.ts", + "spinner_page.ts", + "support_tool.ts", "url_generator.ts", ] # Files that are passed as input to html_to_wrapper(). html_files = [] -foreach(f, web_component_files) { +foreach(f, _web_component_files) { html_files += [ string_replace(f, ".ts", ".html") ] } @@ -25,6 +25,13 @@ html_wrapper_files += [ f + ".ts" ] } -ts_files = web_component_files + [ "browser_proxy.ts" ] +# Files that are passed as input to css_to_wrapper(). +css_files = [ "support_tool_shared.css" ] -css_wrapper_files = [ "support_tool_shared_css.ts" ] +# Files that are generated by css_to_wrapper(). +css_wrapper_files = [] +foreach(f, css_files) { + css_wrapper_files += [ f + ".ts" ] +} + +ts_files = _web_component_files + [ "browser_proxy.ts" ]
diff --git a/chrome/browser/resources/support_tool/support_tool.ts b/chrome/browser/resources/support_tool/support_tool.ts index 662d816..51f4723 100644 --- a/chrome/browser/resources/support_tool/support_tool.ts +++ b/chrome/browser/resources/support_tool/support_tool.ts
@@ -12,11 +12,12 @@ import './spinner_page.js'; import './pii_selection.js'; import './data_export_done.js'; -import './support_tool_shared_css.js'; +import './support_tool_shared.css.js'; import {CrToastElement} from 'chrome://resources/cr_elements/cr_toast/cr_toast.js'; import {WebUIListenerMixin} from 'chrome://resources/js/web_ui_listener_mixin.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + import {BrowserProxy, BrowserProxyImpl, PIIDataItem, StartDataCollectionResult} from './browser_proxy.js'; import {DataCollectorsElement} from './data_collectors.js'; import {DataExportDoneElement} from './data_export_done.js'; @@ -181,4 +182,4 @@ } } -customElements.define(SupportToolElement.is, SupportToolElement); \ No newline at end of file +customElements.define(SupportToolElement.is, SupportToolElement);
diff --git a/chrome/browser/resources/support_tool/support_tool_shared.css b/chrome/browser/resources/support_tool/support_tool_shared.css new file mode 100644 index 0000000..543981dc --- /dev/null +++ b/chrome/browser/resources/support_tool/support_tool_shared.css
@@ -0,0 +1,48 @@ +/* Copyright 2022 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. */ + +/* #css_wrapper_metadata_start + * #type=style + * #import=chrome://resources/cr_elements/shared_vars_css.m.js + * #css_wrapper_metadata_end */ + +/* Common styles for Support Tool components. */ +h2 { + color: var(--cr-text-color-primary); + font-size: 20px; + font-weight: normal; + margin-bottom: 18px; +} + +.support-tool-title { + color: var(--cr-title-text-color); + font-size: 14px; + line-height: 20px; + margin-bottom: 10px; + margin-top: 10px; +} + +.navigation-buttons { + float: right; + margin-bottom: 30px; + margin-top: 30px; + position: relative; + right: 0; +} + +.support-case-id { + height: 32px; + width: 248px; +} + +.data-collector-checkbox { + padding-bottom: 8px; + padding-top: 8px; +} + +.data-collector-list { + border-bottom: var(--cr-separator-line); + border-top: var(--cr-separator-line); + width: 520px; +}
diff --git a/chrome/browser/resources/support_tool/support_tool_shared_css.html b/chrome/browser/resources/support_tool/support_tool_shared_css.html deleted file mode 100644 index a3f94cc..0000000 --- a/chrome/browser/resources/support_tool/support_tool_shared_css.html +++ /dev/null
@@ -1,47 +0,0 @@ -<!-- Copyright 2022 The Chromium Authors. All rights reserved. - Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. --> - -<!-- Common styles for Support Tool components. --> -<template> - <style> - h2 { - color: var(--cr-text-color-primary); - font-size: 20px; - font-weight: normal; - margin-bottom: 18px; - } - - .support-tool-title { - color: var(--cr-title-text-color); - font-size: 14px; - line-height: 20px; - margin-bottom: 10px; - margin-top: 10px; - } - - .navigation-buttons { - float: right; - margin-bottom: 30px; - margin-top: 30px; - position: relative; - right: 0; - } - - .support-case-id { - height: 32px; - width: 248px; - } - - .data-collector-checkbox { - padding-bottom: 8px; - padding-top: 8px; - } - - .data-collector-list { - border-bottom: var(--cr-separator-line); - border-top: var(--cr-separator-line); - width: 520px; - } - </style> -</template>
diff --git a/chrome/browser/resources/support_tool/support_tool_shared_css.ts b/chrome/browser/resources/support_tool/support_tool_shared_css.ts deleted file mode 100644 index 4b97a110..0000000 --- a/chrome/browser/resources/support_tool/support_tool_shared_css.ts +++ /dev/null
@@ -1,9 +0,0 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'chrome://resources/cr_elements/shared_vars_css.m.js'; - -const styleMod = document.createElement('dom-module'); -styleMod.innerHTML = `{__html_template__}`; -styleMod.register('support-tool-shared');
diff --git a/chrome/browser/resources/support_tool/url_generator.ts b/chrome/browser/resources/support_tool/url_generator.ts index 408f46b2..d1806a70 100644 --- a/chrome/browser/resources/support_tool/url_generator.ts +++ b/chrome/browser/resources/support_tool/url_generator.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import './support_tool_shared_css.js'; +import './support_tool_shared.css.js'; import 'chrome://resources/cr_elements/cr_button/cr_button.m.js'; import 'chrome://resources/cr_elements/shared_vars_css.m.js'; import 'chrome://resources/cr_elements/cr_input/cr_input.m.js'; @@ -116,4 +116,4 @@ } } -customElements.define(UrlGeneratorElement.is, UrlGeneratorElement); \ No newline at end of file +customElements.define(UrlGeneratorElement.is, UrlGeneratorElement);
diff --git a/chrome/browser/resources/tab_strip/BUILD.gn b/chrome/browser/resources/tab_strip/BUILD.gn index a89327b..1d49aaba 100644 --- a/chrome/browser/resources/tab_strip/BUILD.gn +++ b/chrome/browser/resources/tab_strip/BUILD.gn
@@ -5,10 +5,11 @@ import("//chrome/common/features.gni") import("//tools/grit/grit_rule.gni") import("//tools/grit/preprocess_if_expr.gni") -import("//tools/polymer/html_to_js.gni") +import("//tools/polymer/html_to_wrapper.gni") import("//tools/typescript/ts_library.gni") import("//ui/webui/resources/tools/generate_grd.gni") import("//ui/webui/webui_features.gni") +import("./tab_strip.gni") assert(enable_webui_tab_strip) @@ -36,41 +37,29 @@ manifest_files = [ "$target_gen_dir/tsconfig.manifest" ] } -preprocess_if_expr("preprocess_mojo") { - deps = [ "//chrome/browser/ui/webui/tab_strip:mojo_bindings_webui_js" ] - in_folder = "$root_gen_dir/mojom-webui/chrome/browser/ui/webui/tab_strip/" - out_folder = "$target_gen_dir/$preprocess_folder" - in_files = [ "tab_strip.mojom-webui.js" ] -} - -preprocess_if_expr("preprocess_tabs") { - deps = [ "//chrome/browser/ui/webui/tabs:mojo_bindings_webui_js" ] - in_folder = "$root_gen_dir/mojom-webui/chrome/browser/ui/webui/tabs/" - out_folder = "$target_gen_dir/$preprocess_folder" - in_files = [ "tabs.mojom-webui.js" ] -} - -preprocess_if_expr("preprocess") { - in_folder = "./" - out_folder = "$target_gen_dir/$preprocess_folder" - in_files = [ - "drag_manager.ts", - "tabs_api_proxy.ts", - "tab_swiper.ts", +copy("copy_mojo") { + deps = [ + "//chrome/browser/ui/webui/tab_strip:mojo_bindings_webui_js", + "//chrome/browser/ui/webui/tabs:mojo_bindings_webui_js", ] + sources = [ + "$root_gen_dir/mojom-webui/chrome/browser/ui/webui/tab_strip/tab_strip.mojom-webui.js", + "$root_gen_dir/mojom-webui/chrome/browser/ui/webui/tabs/tabs.mojom-webui.js", + ] + outputs = [ "$target_gen_dir/$preprocess_folder/{{source_file_part}}" ] } -preprocess_if_expr("preprocess_generated") { - deps = [ ":web_components" ] +preprocess_if_expr("preprocess_src") { + in_folder = "." + out_folder = "$target_gen_dir/$preprocess_folder" + in_files = ts_files +} + +preprocess_if_expr("preprocess_gen") { + deps = [ ":html_wrapper_files" ] in_folder = target_gen_dir out_folder = "$target_gen_dir/$preprocess_folder" - in_files = [ - "alert_indicator.ts", - "alert_indicators.ts", - "tab_group.ts", - "tab_list.ts", - "tab.ts", - ] + in_files = html_wrapper_files } grit("resources") { @@ -90,14 +79,9 @@ output_dir = "$root_gen_dir/chrome" } -html_to_js("web_components") { - js_files = [ - "alert_indicator.ts", - "alert_indicators.ts", - "tab_group.ts", - "tab_list.ts", - "tab.ts", - ] +html_to_wrapper("html_wrapper_files") { + in_files = html_files + template = "native" } ts_library("build_ts") { @@ -105,27 +89,18 @@ out_dir = "$target_gen_dir/tsc" composite = true tsconfig_base = "tsconfig_base.json" - in_files = [ - "alert_indicator.ts", - "alert_indicators.ts", - "drag_manager.ts", - "tab_group.ts", - "tab.ts", - "tab_list.ts", - "tabs_api_proxy.ts", - "tabs.mojom-webui.js", - "tab_strip.mojom-webui.js", - "tab_swiper.ts", - ] + in_files = ts_files + html_wrapper_files + [ + "tabs.mojom-webui.js", + "tab_strip.mojom-webui.js", + ] deps = [ "//third_party/polymer/v3_0:library", "//ui/webui/resources:library", ] definitions = [ "//tools/typescript/definitions/metrics_private.d.ts" ] extra_deps = [ - ":preprocess", - ":preprocess_generated", - ":preprocess_mojo", - ":preprocess_tabs", + ":copy_mojo", + ":preprocess_gen", + ":preprocess_src", ] }
diff --git a/chrome/browser/resources/tab_strip/alert_indicator.ts b/chrome/browser/resources/tab_strip/alert_indicator.ts index aaf536a7..65b88e6b 100644 --- a/chrome/browser/resources/tab_strip/alert_indicator.ts +++ b/chrome/browser/resources/tab_strip/alert_indicator.ts
@@ -6,8 +6,8 @@ import {CustomElement} from 'chrome://resources/js/custom_element.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; -import {getTrustedHTML} from 'chrome://resources/js/static_types.js'; +import {getTemplate} from './alert_indicator.html.js'; import {TabAlertState} from './tabs.mojom-webui.js'; const MAX_WIDTH: string = '16px'; @@ -70,7 +70,7 @@ export class AlertIndicatorElement extends CustomElement { static override get template() { - return getTrustedHTML`{__html_template__}`; + return getTemplate(); } private alertState_: TabAlertState;
diff --git a/chrome/browser/resources/tab_strip/alert_indicators.ts b/chrome/browser/resources/tab_strip/alert_indicators.ts index 397f8247..a7ea093 100644 --- a/chrome/browser/resources/tab_strip/alert_indicators.ts +++ b/chrome/browser/resources/tab_strip/alert_indicators.ts
@@ -5,14 +5,14 @@ import './alert_indicator.js'; import {CustomElement} from 'chrome://resources/js/custom_element.js'; -import {getTrustedHTML} from 'chrome://resources/js/static_types.js'; import {AlertIndicatorElement} from './alert_indicator.js'; +import {getTemplate} from './alert_indicators.html.js'; import {TabAlertState} from './tabs.mojom-webui.js'; export class AlertIndicatorsElement extends CustomElement { static override get template() { - return getTrustedHTML`{__html_template__}`; + return getTemplate(); } private containerEl_: HTMLElement;
diff --git a/chrome/browser/resources/tab_strip/tab.ts b/chrome/browser/resources/tab_strip/tab.ts index a529c6c..dfb1a2a 100644 --- a/chrome/browser/resources/tab_strip/tab.ts +++ b/chrome/browser/resources/tab_strip/tab.ts
@@ -9,10 +9,10 @@ import {CustomElement} from 'chrome://resources/js/custom_element.js'; import {getFavicon} from 'chrome://resources/js/icon.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; -import {getTrustedHTML} from 'chrome://resources/js/static_types.js'; import {isRTL} from 'chrome://resources/js/util.m.js'; import {AlertIndicatorsElement} from './alert_indicators.js'; +import {getTemplate} from './tab.html.js'; import {Tab, TabNetworkState} from './tab_strip.mojom-webui.js'; import {TabSwiper} from './tab_swiper.js'; import {CloseTabAction, TabsApiProxy, TabsApiProxyImpl} from './tabs_api_proxy.js'; @@ -40,7 +40,7 @@ export class TabElement extends CustomElement { static override get template() { - return getTrustedHTML`{__html_template__}`; + return getTemplate(); } private alertIndicatorsEl_: AlertIndicatorsElement;
diff --git a/chrome/browser/resources/tab_strip/tab_group.ts b/chrome/browser/resources/tab_strip/tab_group.ts index 219754da..b79a731 100644 --- a/chrome/browser/resources/tab_strip/tab_group.ts +++ b/chrome/browser/resources/tab_strip/tab_group.ts
@@ -4,14 +4,14 @@ import {CustomElement} from 'chrome://resources/js/custom_element.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; -import {getTrustedHTML} from 'chrome://resources/js/static_types.js'; +import {getTemplate} from './tab_group.html.js'; import {TabGroupVisualData} from './tab_strip.mojom-webui.js'; import {TabsApiProxy, TabsApiProxyImpl} from './tabs_api_proxy.js'; export class TabGroupElement extends CustomElement { static override get template() { - return getTrustedHTML`{__html_template__}`; + return getTemplate(); } private tabsApi_: TabsApiProxy;
diff --git a/chrome/browser/resources/tab_strip/tab_list.ts b/chrome/browser/resources/tab_strip/tab_list.ts index 24241622..34c38b46 100644 --- a/chrome/browser/resources/tab_strip/tab_list.ts +++ b/chrome/browser/resources/tab_strip/tab_list.ts
@@ -11,12 +11,12 @@ import {FocusOutlineManager} from 'chrome://resources/js/cr/ui/focus_outline_manager.m.js'; import {CustomElement} from 'chrome://resources/js/custom_element.js'; import {EventTracker} from 'chrome://resources/js/event_tracker.m.js'; -import {getTrustedHTML} from 'chrome://resources/js/static_types.js'; import {isRTL} from 'chrome://resources/js/util.m.js'; import {DragManager, DragManagerDelegate} from './drag_manager.js'; import {isTabElement, TabElement} from './tab.js'; import {isDragHandle, isTabGroupElement, TabGroupElement} from './tab_group.js'; +import {getTemplate} from './tab_list.html.js'; import {Tab, TabGroupVisualData} from './tab_strip.mojom-webui.js'; import {TabsApiProxy, TabsApiProxyImpl} from './tabs_api_proxy.js'; @@ -149,7 +149,7 @@ private scrollListener_: (e: Event) => void; static override get template() { - return getTrustedHTML`{__html_template__}`; + return getTemplate(); } constructor() {
diff --git a/chrome/browser/resources/tab_strip/tab_strip.gni b/chrome/browser/resources/tab_strip/tab_strip.gni new file mode 100644 index 0000000..c5fe6b5 --- /dev/null +++ b/chrome/browser/resources/tab_strip/tab_strip.gni
@@ -0,0 +1,32 @@ +# Copyright 2022 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +_non_web_component_files = [ + "drag_manager.ts", + "tabs_api_proxy.ts", + "tab_swiper.ts", +] + +# Files holding a custom element definition and have an equivalent .html file. +_web_component_files = [ + "alert_indicator.ts", + "alert_indicators.ts", + "tab_group.ts", + "tab_list.ts", + "tab.ts", +] + +# Files that are passed as input to html_to_wrapper(). +html_files = [] +foreach(f, _web_component_files) { + html_files += [ string_replace(f, ".ts", ".html") ] +} + +# Files that are generated by html_to_wrapper(). +html_wrapper_files = [] +foreach(f, html_files) { + html_wrapper_files += [ f + ".ts" ] +} + +ts_files = _web_component_files + _non_web_component_files
diff --git a/chrome/browser/safe_browsing/tailored_security/chrome_tailored_security_service.cc b/chrome/browser/safe_browsing/tailored_security/chrome_tailored_security_service.cc index 4115d2b..048a059 100644 --- a/chrome/browser/safe_browsing/tailored_security/chrome_tailored_security_service.cc +++ b/chrome/browser/safe_browsing/tailored_security/chrome_tailored_security_service.cc
@@ -86,14 +86,6 @@ return; } - if (is_enabled) { - // TODO(crbug.com/1330723): Remove this metric. This case is being replaced - // by `kEnhancedProtectionAlreadyEnabled`. - base::UmaHistogramBoolean( - "SafeBrowsing.TailoredSecurity.SyncPromptSkippedAlreadyEnabled", - IsEnhancedProtectionEnabled(*prefs())); - } - if (is_enabled && IsEnhancedProtectionEnabled(*prefs())) { RecordEnabledNotificationResult( TailoredSecurityNotificationResult::kEnhancedProtectionAlreadyEnabled);
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 620c871..4540e1d 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -3300,6 +3300,8 @@ "views/frame/immersive_mode_controller_chromeos.h", "views/profiles/lacros_first_run_signed_in_flow_controller.cc", "views/profiles/lacros_first_run_signed_in_flow_controller.h", + "webui/policy/status_provider/device_policy_status_provider_lacros.cc", + "webui/policy/status_provider/device_policy_status_provider_lacros.h", "webui/signin/profile_picker_lacros_sign_in_provider.cc", "webui/signin/profile_picker_lacros_sign_in_provider.h", "window_sizer/window_sizer_chromeos.cc",
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/PlatformNetworksManager.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/PlatformNetworksManager.java index cce068b..432bd11 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/PlatformNetworksManager.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/PlatformNetworksManager.java
@@ -169,7 +169,7 @@ static void getAllVisibleCells(Context context, TelephonyManager telephonyManager, Callback<Set<VisibleCell>> callback) { - if (!hasLocationPermission(context)) { + if (!hasLocationPermission(context) || telephonyManager == null) { callback.onResult(Collections.emptySet()); return; }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/PlatformNetworksManagerTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/PlatformNetworksManagerTest.java index a439d2f..fedc94d 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/PlatformNetworksManagerTest.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/geo/PlatformNetworksManagerTest.java
@@ -296,6 +296,14 @@ } @Test + public void testGetAllVisibleCells_telephonyManagerUnavailable() { + PlatformNetworksManager.getAllVisibleCells(mContext, null, mVisibleCellCallback); + verify(mVisibleCellCallback).onResult(mVisibleCellsArgument.capture()); + // Empty set expected + assertEquals(0, mVisibleCellsArgument.getValue().size()); + } + + @Test public void testGetConnectedWifi_BeforeS() { VisibleWifi visibleWifi = PlatformNetworksManager.getConnectedWifi(mContext); assertEquals(CONNECTED_WIFI, visibleWifi);
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarSnapshotState.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarSnapshotState.java index a7b2f5c..44d90b2 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarSnapshotState.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarSnapshotState.java
@@ -61,7 +61,6 @@ private final ColorStateList mColorStateList; private final boolean mIsShowingUpdateBadgeDuringLastCapture; private final boolean mIsPaintPreview; - private final float mProgress; private final int mUnfocusedLocationBarLayoutWidth; public ToolbarSnapshotState(@ColorInt int tint, int tabCount, ButtonData optionalButtonData, @@ -77,7 +76,8 @@ mColorStateList = colorStateList; mIsShowingUpdateBadgeDuringLastCapture = isShowingUpdateBadgeDuringLastCapture; mIsPaintPreview = isPaintPreview; - mProgress = progress; + // Progress is not currently used for comparing snapshot states. It isn't part of the bitmap + // capture anyway. mUnfocusedLocationBarLayoutWidth = unfocusedLocationBarLayoutWidth; } @@ -105,8 +105,6 @@ return ToolbarSnapshotDifference.SHOWING_UPDATE_BADGE; } else if (mIsPaintPreview != that.mIsPaintPreview) { return ToolbarSnapshotDifference.PAINT_PREVIEW; - } else if (Float.compare(mProgress, that.mProgress) != 0) { - return ToolbarSnapshotDifference.PROGRESS; } else if (mUnfocusedLocationBarLayoutWidth != that.mUnfocusedLocationBarLayoutWidth) { return ToolbarSnapshotDifference.LOCATION_BAR_WIDTH; } else if (!Objects.equals(mUrlText, that.mUrlText)) {
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarSnapshotStateTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarSnapshotStateTest.java index 0345bcd..e54dd22 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarSnapshotStateTest.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarSnapshotStateTest.java
@@ -173,7 +173,7 @@ DEFAULT_SECURITY_ICON, mDefaultColorStateList, DEFAULT_IS_SHOWING_UPDATE_BADGE_DURING_LAST_CAPTURE, DEFAULT_IS_PAINT_PREVIEW, 0.2f, DEFAULT_UNFOCUSED_LOCATION_BAR_LAYOUT_WIDTH); - Assert.assertEquals(ToolbarSnapshotDifference.PROGRESS, + Assert.assertEquals(ToolbarSnapshotDifference.NONE, otherToolbarSnapshotState.getAnyDifference(mDefaultToolbarSnapshotState)); } @Test
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc index 35c1244..3bb0057 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -25,7 +25,7 @@ #include "chrome/browser/ash/multidevice_setup/multidevice_setup_service_factory.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/nearby_sharing/nearby_share_delegate_impl.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h"
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc index b124dec..24db640 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -665,16 +665,16 @@ } } - void ExpectBlockLaunch( - const std::string& force_installed_app_id = std::string()) { + void ExpectBlockLaunchAndLaunchAnyways(const std::string& app_id, + bool force_install_dialog, + bool tab_launch_expected) { ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile())); #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ BUILDFLAG(IS_FUCHSIA) auto waiter = views::NamedWidgetShownWaiter( views::test::AnyWidgetTestPasskey{}, - force_installed_app_id.empty() - ? "DeprecatedAppsDialogView" - : "ForceInstalledDeprecatedAppsDialogView"); + force_install_dialog ? "ForceInstalledDeprecatedAppsDialogView" + : "DeprecatedAppsDialogView"); #endif // Should have opened the requested homepage about:blank in 1st window. TabStripModel* tab_strip = browser()->tab_strip_model(); @@ -694,15 +694,48 @@ BUILDFLAG(IS_FUCHSIA) GURL expected_url = - force_installed_app_id.empty() - ? GURL(chrome::kChromeUIAppsWithDeprecationDialogURL) - : GURL(chrome::kChromeUIAppsWithForceInstalledDeprecationDialogURL + - force_installed_app_id); + force_install_dialog + ? GURL(chrome::kChromeUIAppsWithForceInstalledDeprecationDialogURL + + app_id) + : GURL(chrome::kChromeUIAppsWithDeprecationDialogURL + app_id); EXPECT_EQ(expected_url, other_tab_strip->GetWebContentsAt(0)->GetVisibleURL()); + std::set<Browser*> initial_browsers; + for (auto* initial_browser : *BrowserList::GetInstance()) + initial_browsers.insert(initial_browser); + + content::TestNavigationObserver same_tab_observer( + other_tab_strip->GetActiveWebContents(), 1, + content::MessageLoopRunner::QuitMode::DEFERRED, + /*ignore_uncommitted_navigations=*/false); + // Verify that the Deprecated Apps Dialog View also shows up. - EXPECT_TRUE(waiter.WaitIfNeededAndGet() != nullptr); + auto* dialog = waiter.WaitIfNeededAndGet(); + EXPECT_TRUE(dialog != nullptr); + if (force_install_dialog) { + // The 'accept' option in the force-install dialog is "launch anyways". + dialog->widget_delegate()->AsDialogDelegate()->Accept(); + } else { + // The 'cancel' option in the deprecation dialog is "launch anyways". + dialog->widget_delegate()->AsDialogDelegate()->Cancel(); + } + if (tab_launch_expected) { + same_tab_observer.Wait(); + } else { + Browser* app_browser = + ui_test_utils::GetBrowserNotInSet(initial_browsers); + if (!app_browser) { + app_browser = ui_test_utils::WaitForBrowserToOpen(); + // The new browser should never be in |excluded_browsers|. + DCHECK(!base::Contains(initial_browsers, app_browser)); + } + ASSERT_TRUE(app_browser); + TabStripModel* app_tab_strip = app_browser->tab_strip_model(); + EXPECT_EQ(1, app_tab_strip->count()); + EXPECT_TRUE(app_browser->is_type_app()); + EXPECT_FALSE(app_browser->is_type_normal()); + } #endif } @@ -750,7 +783,19 @@ command_line, base::FilePath(), chrome::startup::IsProcessStartup::kNo, {browser()->profile(), StartupProfileMode::kBrowserWindow}, {})); - if (IsExpectedToAllowLaunch()) { + Browser* expected_launch_browser = browser(); + + if (!IsExpectedToAllowLaunch()) { + ExpectBlockLaunchAndLaunchAnyways(extension_app->id(), + /*force_install_dialog=*/false, + /*tab_launch_expected=*/true); + // When we block the launch, we always create a new browser window to + // display chrome://apps and the dialog. + ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile())); + Browser* expected_launch_browser = FindOneOtherBrowser(browser()); + tab_strip = expected_launch_browser->tab_strip_model(); + EXPECT_EQ(1, tab_strip->count()); + } else { // No pref was set, so the app should have opened in a tab in the existing // window. tab_waiter.Wait(); @@ -758,20 +803,18 @@ EXPECT_EQ(2, tab_strip->count()); EXPECT_EQ(tab_strip->GetActiveWebContents(), tab_strip->GetWebContentsAt(1)); - - // It should be a standard tabbed window, not an app window. - EXPECT_FALSE(browser()->is_type_app()); - EXPECT_TRUE(browser()->is_type_normal()); - - // It should have loaded the requested app. - const std::u16string expected_title( - u"app_with_tab_container/empty.html title"); - content::TitleWatcher title_watcher(tab_strip->GetActiveWebContents(), - expected_title); - EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); - } else { - ExpectBlockLaunch(); } + + // It should be a standard tabbed window, not an app window. + EXPECT_FALSE(expected_launch_browser->is_type_app()); + EXPECT_TRUE(expected_launch_browser->is_type_normal()); + + // It should have loaded the requested app. + const std::u16string expected_title( + u"app_with_tab_container/empty.html title"); + content::TitleWatcher title_watcher(tab_strip->GetActiveWebContents(), + expected_title); + EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); } IN_PROC_BROWSER_TEST_P(StartupBrowserCreatorChromeAppShortcutTest, @@ -791,23 +834,27 @@ command_line, base::FilePath(), chrome::startup::IsProcessStartup::kNo, {browser()->profile(), StartupProfileMode::kBrowserWindow}, {})); - if (IsExpectedToAllowLaunch()) { - // Pref was set to open in a window, so the app should have opened in a - // window. The launch should have created a new browser. Find the new - // browser. - Browser* new_browser = browser_waiter.Wait(); - ASSERT_TRUE(new_browser); - - // Expect an app window. - EXPECT_TRUE(new_browser->is_type_app()); - - // The browser's app_name should include the app's ID. - EXPECT_NE(new_browser->app_name().find(extension_app->id()), - std::string::npos) - << new_browser->app_name(); - } else { - ExpectBlockLaunch(); + if (!IsExpectedToAllowLaunch()) { + ExpectBlockLaunchAndLaunchAnyways(extension_app->id(), + /*force_install_dialog=*/false, + /*tab_launch_expected=*/false); + // When we block the launch, we always create a new browser window to + // display chrome://apps and the dialog, and then another to launch the app. + ASSERT_EQ(3u, chrome::GetBrowserCount(browser()->profile())); } + // Pref was set to open in a window, so the app should have opened in a + // window. The launch should have created a new browser. Find the new + // browser. + Browser* new_browser = browser_waiter.Wait(); + ASSERT_TRUE(new_browser); + + // Expect an app window. + EXPECT_TRUE(new_browser->is_type_app()); + + // The browser's app_name should include the app's ID. + EXPECT_NE(new_browser->app_name().find(extension_app->id()), + std::string::npos) + << new_browser->app_name(); } IN_PROC_BROWSER_TEST_P(StartupBrowserCreatorChromeAppShortcutTest, @@ -830,7 +877,19 @@ command_line, base::FilePath(), chrome::startup::IsProcessStartup::kNo, {browser()->profile(), StartupProfileMode::kBrowserWindow}, {})); - if (IsExpectedToAllowLaunch()) { + Browser* expected_launch_browser = browser(); + + if (!IsExpectedToAllowLaunch()) { + ExpectBlockLaunchAndLaunchAnyways(extension_app->id(), + /*force_install_dialog=*/false, + /*tab_launch_expected=*/true); + // When we block the launch, we always create a new browser window to + // display chrome://apps and the dialog. + ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile())); + Browser* expected_launch_browser = FindOneOtherBrowser(browser()); + tab_strip = expected_launch_browser->tab_strip_model(); + EXPECT_EQ(1, tab_strip->count()); + } else { // When an app shortcut is open and the pref indicates a tab should open, // the tab is open in the existing browser window. tab_waiter.Wait(); @@ -838,22 +897,20 @@ EXPECT_EQ(2, tab_strip->count()); EXPECT_EQ(tab_strip->GetActiveWebContents(), tab_strip->GetWebContentsAt(1)); - - // The browser's app_name should not include the app's ID: it is in a normal - // tabbed browser. - EXPECT_EQ(browser()->app_name().find(extension_app->id()), - std::string::npos) - << browser()->app_name(); - - // It should have loaded the requested app. - const std::u16string expected_title( - u"app_with_tab_container/empty.html title"); - content::TitleWatcher title_watcher(tab_strip->GetActiveWebContents(), - expected_title); - EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); - } else { - ExpectBlockLaunch(); } + + // The browser's app_name should not include the app's ID: it is in a normal + // tabbed browser. + EXPECT_EQ(expected_launch_browser->app_name().find(extension_app->id()), + std::string::npos) + << browser()->app_name(); + + // It should have loaded the requested app. + const std::u16string expected_title( + u"app_with_tab_container/empty.html title"); + content::TitleWatcher title_watcher(tab_strip->GetActiveWebContents(), + expected_title); + EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); } IN_PROC_BROWSER_TEST_P(StartupBrowserCreatorChromeAppShortcutTest, @@ -882,32 +939,36 @@ command_line, base::FilePath(), chrome::startup::IsProcessStartup::kNo, {browser()->profile(), StartupProfileMode::kBrowserWindow}, {})); - if (IsExpectedToAllowLaunch()) { - tab_waiter.Wait(); + Browser* expected_launch_browser = browser(); - // Policy force-installed app should be allowed regardless of Chrome App - // Deprecation status. - // + if (!IsExpectedToAllowLaunch()) { + ExpectBlockLaunchAndLaunchAnyways(extension_app->id(), true, true); + // When we block the launch, we always create a new browser window to + // display chrome://apps and the dialog. + ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile())); + Browser* expected_launch_browser = FindOneOtherBrowser(browser()); + tab_strip = expected_launch_browser->tab_strip_model(); + EXPECT_EQ(1, tab_strip->count()); + } else { + tab_waiter.Wait(); + ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile())); // No app launch pref was set, so the app should have opened in a tab in the // existing window. - ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile())); EXPECT_EQ(2, tab_strip->count()); EXPECT_EQ(tab_strip->GetActiveWebContents(), tab_strip->GetWebContentsAt(1)); - - // It should be a standard tabbed window, not an app window. - EXPECT_FALSE(browser()->is_type_app()); - EXPECT_TRUE(browser()->is_type_normal()); - - // It should have loaded the requested app. - const std::u16string expected_title( - u"app_with_tab_container/empty.html title"); - content::TitleWatcher title_watcher(tab_strip->GetActiveWebContents(), - expected_title); - EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); - } else { - ExpectBlockLaunch(extension_app->id()); } + + // It should be a standard tabbed window, not an app window. + EXPECT_FALSE(expected_launch_browser->is_type_app()); + EXPECT_TRUE(expected_launch_browser->is_type_normal()); + + // It should have loaded the requested app. + const std::u16string expected_title( + u"app_with_tab_container/empty.html title"); + content::TitleWatcher title_watcher(tab_strip->GetActiveWebContents(), + expected_title); + EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); } INSTANTIATE_TEST_SUITE_P(
diff --git a/chrome/browser/ui/tab_dialogs.h b/chrome/browser/ui/tab_dialogs.h index 3b7f8ec..2b3732e 100644 --- a/chrome/browser/ui/tab_dialogs.h +++ b/chrome/browser/ui/tab_dialogs.h
@@ -52,13 +52,16 @@ // Shows the deprecated app dialog. virtual void ShowDeprecatedAppsDialog( + const extensions::ExtensionId& optional_launched_extension_id, const std::set<extensions::ExtensionId>& deprecated_app_ids, - content::WebContents* web_contents) = 0; + content::WebContents* web_contents, + base::OnceClosure launch_anyways) = 0; // Shows the force installed and deprecated app dialog. virtual void ShowForceInstalledDeprecatedAppsDialog( const extensions::ExtensionId& app_id, - content::WebContents* web_contents) = 0; + content::WebContents* web_contents, + base::OnceClosure launch_anyways) = 0; // Shows or hides the ManagePasswords bubble. // Pass true for |user_action| if this is a user initiated action.
diff --git a/chrome/browser/ui/views/javascript_tab_modal_dialog_view_views.cc b/chrome/browser/ui/views/javascript_tab_modal_dialog_view_views.cc index e6ec04e..684a1b2e 100644 --- a/chrome/browser/ui/views/javascript_tab_modal_dialog_view_views.cc +++ b/chrome/browser/ui/views/javascript_tab_modal_dialog_view_views.cc
@@ -10,6 +10,7 @@ #include "components/constrained_window/constrained_window_views.h" #include "content/public/browser/javascript_dialog_manager.h" #include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/views/accessibility/view_accessibility.h" #include "ui/views/bubble/bubble_frame_view.h" #include "ui/views/controls/label.h" #include "ui/views/controls/message_box_view.h" @@ -46,6 +47,8 @@ auto* bubble_frame_view = static_cast<views::BubbleFrameView*>( GetWidget()->non_client_view()->frame_view()); bubble_frame_view->SetTitleView(CreateTitleOriginLabel(GetWindowTitle())); + GetWidget()->GetRootView()->GetViewAccessibility().OverrideDescription( + message_text_); } JavaScriptTabModalDialogViewViews::JavaScriptTabModalDialogViewViews( @@ -110,6 +113,19 @@ constrained_window::ShowWebModalDialogViews(this, parent_web_contents); } +// static +JavaScriptTabModalDialogViewViews* +JavaScriptTabModalDialogViewViews::CreateAlertDialogForTesting( + Browser* browser, + std::u16string title, + std::u16string message) { + return new JavaScriptTabModalDialogViewViews( + browser->tab_strip_model()->GetActiveWebContents(), + browser->tab_strip_model()->GetActiveWebContents(), title, + content::JAVASCRIPT_DIALOG_TYPE_ALERT, message, std::u16string(), + base::NullCallback(), base::NullCallback()); +} + BEGIN_METADATA(JavaScriptTabModalDialogViewViews, views::DialogDelegateView) END_METADATA
diff --git a/chrome/browser/ui/views/javascript_tab_modal_dialog_view_views.h b/chrome/browser/ui/views/javascript_tab_modal_dialog_view_views.h index b472832b..b651b20 100644 --- a/chrome/browser/ui/views/javascript_tab_modal_dialog_view_views.h +++ b/chrome/browser/ui/views/javascript_tab_modal_dialog_view_views.h
@@ -8,6 +8,7 @@ #include <memory> #include "base/memory/raw_ptr.h" +#include "chrome/browser/ui/browser.h" #include "components/javascript_dialogs/tab_modal_dialog_view.h" #include "content/public/browser/javascript_dialog_manager.h" #include "ui/base/metadata/metadata_header_macros.h" @@ -45,6 +46,13 @@ // views::View: void AddedToWidget() override; + // TODO(crbug.com/1330353): We cannot use unique_ptr because ownership of + // this object gets passed to Views. + static JavaScriptTabModalDialogViewViews* CreateAlertDialogForTesting( + Browser* browser, + std::u16string title, + std::u16string message); + private: friend class JavaScriptDialog; friend class JavaScriptTabModalDialogManagerDelegateDesktop;
diff --git a/chrome/browser/ui/views/javascript_tab_modal_dialog_view_views_browsertest.cc b/chrome/browser/ui/views/javascript_tab_modal_dialog_view_views_browsertest.cc new file mode 100644 index 0000000..db23024 --- /dev/null +++ b/chrome/browser/ui/views/javascript_tab_modal_dialog_view_views_browsertest.cc
@@ -0,0 +1,59 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/bind.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/views/javascript_tab_modal_dialog_view_views.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "content/public/test/browser_test.h" +#include "ui/views/accessibility/view_accessibility.h" +#include "ui/views/bubble/bubble_frame_view.h" + +using JavaScriptTabModalDialogViewViewsBrowserTest = InProcessBrowserTest; + +IN_PROC_BROWSER_TEST_F(JavaScriptTabModalDialogViewViewsBrowserTest, + AlertDialogAccessibleNameDescriptionAndRole) { + std::u16string title = u"Title"; + std::u16string message = u"The message"; + auto* dialog_views = + JavaScriptTabModalDialogViewViews::CreateAlertDialogForTesting( + browser(), title, message); + + // The JavaScriptTabModalDialogViewViews should set the RootView's accessible + // name to the alert's title and the accessible description to the alert's + // message text. The role of the RootView should be dialog. + ui::AXNodeData data; + dialog_views->GetWidget() + ->GetRootView() + ->GetViewAccessibility() + .GetAccessibleNodeData(&data); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName), + title); + EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kDescription), + message); + EXPECT_EQ(data.role, ax::mojom::Role::kDialog); + + // TODO(crbug.com/1325879): Nothing sets the description-from attribute + // when Views override the description. If we fix that in OverrideDescription, + // the value will still not be carried over to the AXNodeData for the reason + // described in the issue. + EXPECT_EQ(data.GetIntAttribute(ax::mojom::IntAttribute::kDescriptionFrom), + static_cast<int32_t>(ax::mojom::DescriptionFrom::kNone)); +} + +IN_PROC_BROWSER_TEST_F(JavaScriptTabModalDialogViewViewsBrowserTest, + AlertDialogCloseButtonAccessibilityIgnored) { + std::u16string title = u"Title"; + std::u16string message = u"The message"; + auto* dialog_views = + JavaScriptTabModalDialogViewViews::CreateAlertDialogForTesting( + browser(), title, message); + + // In an alert, the Close button is not used. It should be removed from the + // accessibility tree ("ignored"). + auto* bubble_frame_view = static_cast<views::BubbleFrameView*>( + dialog_views->GetWidget()->non_client_view()->frame_view()); + if (auto* close_button = bubble_frame_view->GetCloseButtonForTesting()) + EXPECT_TRUE(close_button->GetViewAccessibility().IsIgnored()); +}
diff --git a/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc index ed46393..5d31ad4 100644 --- a/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc +++ b/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc
@@ -281,11 +281,14 @@ void ShowManagePasswordsBubble(bool user_action) override {} void HideManagePasswordsBubble() override {} void ShowDeprecatedAppsDialog( + const extensions::ExtensionId& optional_launched_extension_id, const std::set<extensions::ExtensionId>& deprecated_app_ids, - content::WebContents* web_contents) override {} + content::WebContents* web_contents, + base::OnceClosure launch_anyways) override {} void ShowForceInstalledDeprecatedAppsDialog( const extensions::ExtensionId& app_id, - content::WebContents* web_contents) override {} + content::WebContents* web_contents, + base::OnceClosure launch_anyways) override {} private: raw_ptr<content::WebContents> contents_;
diff --git a/chrome/browser/ui/views/tab_dialogs_views.cc b/chrome/browser/ui/views/tab_dialogs_views.cc index 26a47d3..6f520cc 100644 --- a/chrome/browser/ui/views/tab_dialogs_views.cc +++ b/chrome/browser/ui/views/tab_dialogs_views.cc
@@ -80,19 +80,23 @@ } void TabDialogsViews::ShowDeprecatedAppsDialog( + const extensions::ExtensionId& optional_launched_extension_id, const std::set<extensions::ExtensionId>& deprecated_app_ids, - content::WebContents* web_contents) { + content::WebContents* web_contents, + base::OnceClosure launch_anyways) { #if defined(TOOLKIT_VIEWS) && !BUILDFLAG(IS_CHROMEOS) - DeprecatedAppsDialogView::CreateAndShowDialog(deprecated_app_ids, - web_contents); + DeprecatedAppsDialogView::CreateAndShowDialog( + optional_launched_extension_id, deprecated_app_ids, web_contents, + std::move(launch_anyways)); #endif } void TabDialogsViews::ShowForceInstalledDeprecatedAppsDialog( const extensions::ExtensionId& app_id, - content::WebContents* web_contents) { + content::WebContents* web_contents, + base::OnceClosure launch_anyways) { #if defined(TOOLKIT_VIEWS) && !BUILDFLAG(IS_CHROMEOS) - ForceInstalledDeprecatedAppsDialogView::CreateAndShowDialog(app_id, - web_contents); + ForceInstalledDeprecatedAppsDialogView::CreateAndShowDialog( + app_id, web_contents, std::move(launch_anyways)); #endif }
diff --git a/chrome/browser/ui/views/tab_dialogs_views.h b/chrome/browser/ui/views/tab_dialogs_views.h index 3dc1d0d..de2c205 100644 --- a/chrome/browser/ui/views/tab_dialogs_views.h +++ b/chrome/browser/ui/views/tab_dialogs_views.h
@@ -30,11 +30,14 @@ void ShowManagePasswordsBubble(bool user_action) override; void HideManagePasswordsBubble() override; void ShowDeprecatedAppsDialog( + const extensions::ExtensionId& optional_launched_extension_id, const std::set<extensions::ExtensionId>& deprecated_app_ids, - content::WebContents* web_contents) override; + content::WebContents* web_contents, + base::OnceClosure launch_anyways) override; void ShowForceInstalledDeprecatedAppsDialog( const extensions::ExtensionId& app_id, - content::WebContents* web_contents) override; + content::WebContents* web_contents, + base::OnceClosure launch_anyways) override; private: raw_ptr<content::WebContents> web_contents_; // Weak. Owns this.
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 cafc58b..d0866a9 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
@@ -111,10 +111,13 @@ // static DeprecatedAppsDialogView* DeprecatedAppsDialogView::CreateAndShowDialog( + const extensions::ExtensionId& optional_launched_extension_id, const std::set<extensions::ExtensionId>& deprecated_app_ids, - content::WebContents* web_contents) { - DeprecatedAppsDialogView* view = - new DeprecatedAppsDialogView(deprecated_app_ids, web_contents); + content::WebContents* web_contents, + base::OnceClosure launch_anyways) { + DeprecatedAppsDialogView* view = new DeprecatedAppsDialogView( + optional_launched_extension_id, deprecated_app_ids, web_contents, + std::move(launch_anyways)); view->InitDialog(); constrained_window::ShowWebModalDialogViews(view, web_contents); return view; @@ -125,15 +128,42 @@ } std::u16string DeprecatedAppsDialogView::GetWindowTitle() const { - return l10n_util::GetPluralStringFUTF16( - IDS_DEPRECATED_APPS_RENDERER_TITLE, + if (launched_extension_name_) { + return l10n_util::GetStringFUTF16( + IDS_DEPRECATED_APPS_RENDERER_TITLE_WITH_APP_NAME, + launched_extension_name_.value()); + } + if (single_app_name_) { + return l10n_util::GetStringFUTF16( + IDS_DEPRECATED_APPS_RENDERER_TITLE_WITH_APP_NAME, + single_app_name_.value()); + } + return l10n_util::GetStringFUTF16Int( + IDS_DEPRECATED_APPS_RENDERER_TITLE_PLURAL, deprecated_apps_table_model_->RowCount()); } DeprecatedAppsDialogView::DeprecatedAppsDialogView( + const extensions::ExtensionId& optional_launched_extension_id, const std::set<extensions::ExtensionId>& deprecated_app_ids, - content::WebContents* web_contents) - : deprecated_app_ids_(deprecated_app_ids), web_contents_(web_contents) { + content::WebContents* web_contents, + base::OnceClosure launch_anyways) + : deprecated_app_ids_(deprecated_app_ids), + launch_anyways_(std::move(launch_anyways)), + web_contents_(web_contents) { + if (!optional_launched_extension_id.empty()) { + const extensions::Extension* extension = + extensions::ExtensionRegistry::Get(web_contents_->GetBrowserContext()) + ->GetInstalledExtension(optional_launched_extension_id); + launched_extension_name_ = base::UTF8ToUTF16(extension->name()); + } + if (deprecated_app_ids_.size() == 1) { + const extensions::Extension* extension = + extensions::ExtensionRegistry::Get(web_contents_->GetBrowserContext()) + ->GetInstalledExtension(*deprecated_app_ids_.begin()); + DCHECK(extension); + single_app_name_ = base::UTF8ToUTF16(extension->name()); + } deprecated_apps_table_model_ = std::make_unique<DeprecatedAppsTableModel>( deprecated_app_ids, web_contents, base::BindRepeating(&DeprecatedAppsDialogView::OnIconsLoadedForTable, @@ -153,24 +183,29 @@ views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); set_fixed_width(views::LayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH)); - // Set up buttons. SetButtonLabel(ui::DIALOG_BUTTON_OK, l10n_util::GetPluralStringFUTF16( IDS_DEPRECATED_APPS_OK_LABEL, deprecated_apps_table_model_->RowCount())); - SetButtonLabel(ui::DIALOG_BUTTON_CANCEL, - l10n_util::GetStringUTF16(IDS_DEPRECATED_APPS_CANCEL_LABEL)); - SetDefaultButton(ui::DIALOG_BUTTON_NONE); - SetCancelCallback(base::BindOnce(&DeprecatedAppsDialogView::CloseDialog, + SetAcceptCallback(base::BindOnce(&DeprecatedAppsDialogView::OnAccept, base::Unretained(this))); - SetAcceptCallback(base::BindOnce( - &DeprecatedAppsDialogView::UninstallExtensions, base::Unretained(this))); - info_label_ = AddChildView( - std::make_unique<views::Label>(l10n_util::GetPluralStringFUTF16( - IDS_DEPRECATED_APPS_MONITOR_RENDERER, - deprecated_apps_table_model_->RowCount()))); + if (launched_extension_name_) { + SetButtonLabel( + ui::DIALOG_BUTTON_CANCEL, + l10n_util::GetStringUTF16(IDS_DEPRECATED_APPS_LAUNCH_ANYWAY_LABEL)); + } else { + SetButtonLabel(ui::DIALOG_BUTTON_CANCEL, + l10n_util::GetStringUTF16(IDS_DEPRECATED_APPS_CANCEL_LABEL)); + } + SetCancelCallback(base::BindOnce(&DeprecatedAppsDialogView::OnCancel, + base::Unretained(this))); + + SetDefaultButton(ui::DIALOG_BUTTON_OK); + + info_label_ = AddChildView(std::make_unique<views::Label>( + l10n_util::GetStringUTF16(IDS_DEPRECATED_APPS_MONITOR_RENDERER))); info_label_->SetMultiLine(true); info_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); @@ -186,8 +221,8 @@ ui::PAGE_TRANSITION_LINK, /*is_renderer_initiated=*/false)); }, web_contents_)); - learn_more->SetAccessibleName(l10n_util::GetStringUTF16( - IDS_FORCE_INSTALLED_DEPRECATED_APPS_LEARN_MORE_AX_LABEL)); + learn_more->SetAccessibleName( + l10n_util::GetStringUTF16(IDS_DEPRECATED_APPS_LEARN_MORE_AX_LABEL)); learn_more->SetHorizontalAlignment(gfx::ALIGN_LEFT); // Set up the table view. @@ -218,7 +253,7 @@ deprecated_apps_table_view_->SchedulePaint(); } -void DeprecatedAppsDialogView::UninstallExtensions() { +void DeprecatedAppsDialogView::OnAccept() { for (extensions::ExtensionId id : deprecated_app_ids_) { extensions::ExtensionSystem::Get(web_contents_->GetBrowserContext()) ->extension_service() @@ -228,5 +263,10 @@ CloseDialog(); } +void DeprecatedAppsDialogView::OnCancel() { + std::move(launch_anyways_).Run(); + CloseDialog(); +} + BEGIN_METADATA(DeprecatedAppsDialogView, views::DialogDelegateView) END_METADATA
diff --git a/chrome/browser/ui/views/web_apps/deprecated_apps_dialog_view.h b/chrome/browser/ui/views/web_apps/deprecated_apps_dialog_view.h index 9cc73c9..4fce17c 100644 --- a/chrome/browser/ui/views/web_apps/deprecated_apps_dialog_view.h +++ b/chrome/browser/ui/views/web_apps/deprecated_apps_dialog_view.h
@@ -7,11 +7,13 @@ #include <memory> #include <set> +#include <string> #include <vector> #include "base/callback_forward.h" #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" +#include "chrome/browser/ui/tab_dialogs.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/common/extension_id.h" @@ -40,10 +42,20 @@ DeprecatedAppsDialogView& operator=(const DeprecatedAppsDialogView&) = delete; ~DeprecatedAppsDialogView() override; - // Create the dialog metadata and show it. + // Create the dialog metadata and show it. Some behavior specializations: + // * If the `optional_launched_extension_id` is passed, then the dialog will + // show the name of that chrome app in the title. + // * If `optional_launched_extension_id` is empty and `deprecated_app_ids` + // only has one entry, then the dialog will display the name of the one + // deprecated chrome app. + // * If `optional_launched_extension_id` is empty and `deprecated_app_ids` has + // more than one entry, then the title will just contain the number of + // deprecated chrome apps. static DeprecatedAppsDialogView* CreateAndShowDialog( + const extensions::ExtensionId& optional_launched_extension_id, const std::set<extensions::ExtensionId>& deprecated_app_ids, - content::WebContents* web_contents); + content::WebContents* web_contents, + base::OnceClosure launch_anyways); base::WeakPtr<DeprecatedAppsDialogView> AsWeakPtr(); @@ -55,8 +67,10 @@ private: class DeprecatedAppsTableModel; DeprecatedAppsDialogView( + const extensions::ExtensionId& optional_launched_extension_id, const std::set<extensions::ExtensionId>& deprecated_app_ids, - content::WebContents* web_contents); + content::WebContents* web_contents, + base::OnceClosure launch_anyways); // Initialize the dialog when the object is instantiated. void InitDialog(); @@ -69,7 +83,8 @@ // Callback that runs when accept button is clicked to // uninstall all extensions. - void UninstallExtensions(); + void OnAccept(); + void OnCancel(); // Controls the table view within the dialog box. raw_ptr<views::TableView> deprecated_apps_table_view_; @@ -79,7 +94,10 @@ raw_ptr<views::Label> info_label_; + absl::optional<std::u16string> launched_extension_name_; std::set<extensions::ExtensionId> deprecated_app_ids_; + absl::optional<std::u16string> single_app_name_; + base::OnceClosure launch_anyways_; raw_ptr<content::WebContents> web_contents_;
diff --git a/chrome/browser/ui/views/web_apps/deprecated_apps_dialog_view_browsertest.cc b/chrome/browser/ui/views/web_apps/deprecated_apps_dialog_view_browsertest.cc index 7e90e04..207bc1d 100644 --- a/chrome/browser/ui/views/web_apps/deprecated_apps_dialog_view_browsertest.cc +++ b/chrome/browser/ui/views/web_apps/deprecated_apps_dialog_view_browsertest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/callback_helpers.h" #include "chrome/browser/ui/views/web_apps/deprecated_apps_dialog_view.h" #include <set> @@ -9,6 +10,7 @@ #include "base/feature_list.h" #include "base/run_loop.h" #include "base/test/bind.h" +#include "base/test/mock_callback.h" #include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/platform_util.h" #include "chrome/browser/ui/browser.h" @@ -150,7 +152,8 @@ InstallExtensionForTesting(mock_app_manifest1, mock_url1); test_dialog_view_ = DeprecatedAppsDialogView::CreateAndShowDialog( - deprecated_app_ids_for_testing_, web_contents) + std::string(), deprecated_app_ids_for_testing_, + web_contents, base::DoNothing()) ->AsWeakPtr(); EXPECT_TRUE(IsDialogShown()); @@ -165,7 +168,8 @@ InstallExtensionForTesting(mock_app_manifest1, mock_url1); InstallExtensionForTesting(mock_app_manifest2, mock_url2); test_dialog_view_ = DeprecatedAppsDialogView::CreateAndShowDialog( - deprecated_app_ids_for_testing_, web_contents) + std::string(), deprecated_app_ids_for_testing_, + web_contents, base::DoNothing()) ->AsWeakPtr(); EXPECT_TRUE(IsDialogShown()); @@ -177,11 +181,14 @@ AcceptDialogAndVerify) { auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + base::MockCallback<base::OnceClosure> mock_callback; extensions::ExtensionId test_id( InstallExtensionForTesting(mock_app_manifest1, mock_url1)); test_dialog_view_ = DeprecatedAppsDialogView::CreateAndShowDialog( - deprecated_app_ids_for_testing_, web_contents) + std::string(), deprecated_app_ids_for_testing_, + web_contents, mock_callback.Get()) ->AsWeakPtr(); + EXPECT_CALL(mock_callback, Run()).Times(0); // Verify dialog is shown. ASSERT_TRUE(IsDialogShown()); @@ -203,9 +210,11 @@ CloseDialogAndVerify) { auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); + base::MockCallback<base::OnceClosure> mock_callback; InstallExtensionForTesting(mock_app_manifest1, mock_url1); test_dialog_view_ = DeprecatedAppsDialogView::CreateAndShowDialog( - deprecated_app_ids_for_testing_, web_contents) + std::string(), deprecated_app_ids_for_testing_, + web_contents, mock_callback.Get()) ->AsWeakPtr(); // Verify dialog is shown. @@ -213,6 +222,8 @@ EXPECT_EQ(static_cast<int>(deprecated_app_ids_for_testing_.size()), GetRowCountForDialog()); + EXPECT_CALL(mock_callback, Run()).Times(1); + // Verify dialog is closed on cancellation ASSERT_TRUE(test_dialog_view_->Cancel()); WaitForDialogToBeDestroyed();
diff --git a/chrome/browser/ui/views/web_apps/force_installed_deprecated_apps_dialog_view.cc b/chrome/browser/ui/views/web_apps/force_installed_deprecated_apps_dialog_view.cc index 49868a3..d0b0236 100644 --- a/chrome/browser/ui/views/web_apps/force_installed_deprecated_apps_dialog_view.cc +++ b/chrome/browser/ui/views/web_apps/force_installed_deprecated_apps_dialog_view.cc
@@ -13,6 +13,7 @@ #include "extensions/browser/extension_registry.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/base/ui_base_types.h" #include "ui/base/window_open_disposition.h" #include "ui/views/controls/link.h" #include "ui/views/controls/styled_label.h" @@ -23,9 +24,10 @@ // static void ForceInstalledDeprecatedAppsDialogView::CreateAndShowDialog( extensions::ExtensionId app_id, - content::WebContents* web_contents) { + content::WebContents* web_contents, + base::OnceClosure launch_anyways) { auto delegate = std::make_unique<views::DialogDelegate>(); - delegate->SetButtons(ui::DIALOG_BUTTON_OK); + // delegate->SetButtons(ui::DIALOG_BUTTON_OK); delegate->SetModalType(ui::MODAL_TYPE_CHILD); delegate->SetShowCloseButton(false); delegate->SetOwnedByWidget(true); @@ -34,18 +36,16 @@ extensions::ExtensionRegistry::Get(browser_context) ->GetInstalledExtension(app_id); std::u16string app_name = base::UTF8ToUTF16(extension->name()); - bool is_preinstalled_app = extensions::IsPreinstalledAppId(app_id); - delegate->SetTitle( - is_preinstalled_app - ? l10n_util::GetStringFUTF16( - IDS_FORCE_INSTALLED_PREINSTALLED_DEPRECATED_APPS_TITLE, - app_name) - : l10n_util::GetPluralStringFUTF16(IDS_DEPRECATED_APPS_RENDERER_TITLE, - 1)); + delegate->SetTitle(l10n_util::GetStringFUTF16( + IDS_DEPRECATED_APPS_RENDERER_TITLE_WITH_APP_NAME, app_name)); + delegate->SetButtonLabel( + ui::DIALOG_BUTTON_OK, + l10n_util::GetStringUTF16(IDS_DEPRECATED_APPS_LAUNCH_ANYWAY_LABEL)); + delegate->SetAcceptCallback(std::move(launch_anyways)); + delegate->SetContentsView( base::WrapUnique<ForceInstalledDeprecatedAppsDialogView>( - new ForceInstalledDeprecatedAppsDialogView( - app_name, is_preinstalled_app, web_contents))); + new ForceInstalledDeprecatedAppsDialogView(app_name, web_contents))); delegate->set_fixed_width(views::LayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH)); delegate->set_margins( @@ -56,7 +56,6 @@ ForceInstalledDeprecatedAppsDialogView::ForceInstalledDeprecatedAppsDialogView( std::u16string app_name, - bool is_preinstalled_app, content::WebContents* web_contents) : app_name_(app_name), web_contents_(web_contents) { SetLayoutManager(std::make_unique<views::BoxLayout>( @@ -64,11 +63,7 @@ ChromeLayoutProvider::Get()->GetDistanceMetric( views::DISTANCE_RELATED_CONTROL_VERTICAL))); auto* info_label = AddChildView(std::make_unique<views::Label>( - is_preinstalled_app - ? l10n_util::GetStringUTF16( - IDS_FORCE_INSTALLED_PREINSTALLED_DEPRECATED_APPS_CONTENT) - : l10n_util::GetStringFUTF16( - IDS_FORCE_INSTALLED_DEPRECATED_APPS_CONTENT, app_name_))); + l10n_util::GetStringUTF16(IDS_FORCE_INSTALLED_DEPRECATED_APPS_CONTENT))); info_label->SetMultiLine(true); info_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); @@ -84,8 +79,8 @@ ui::PAGE_TRANSITION_LINK, /*is_renderer_initiated=*/false)); }, web_contents_)); - learn_more->SetAccessibleName(l10n_util::GetStringUTF16( - IDS_FORCE_INSTALLED_DEPRECATED_APPS_LEARN_MORE_AX_LABEL)); + learn_more->SetAccessibleName( + l10n_util::GetStringUTF16(IDS_DEPRECATED_APPS_LEARN_MORE_AX_LABEL)); learn_more->SetHorizontalAlignment(gfx::ALIGN_LEFT); }
diff --git a/chrome/browser/ui/views/web_apps/force_installed_deprecated_apps_dialog_view.h b/chrome/browser/ui/views/web_apps/force_installed_deprecated_apps_dialog_view.h index 2c32b644..21feadf8 100644 --- a/chrome/browser/ui/views/web_apps/force_installed_deprecated_apps_dialog_view.h +++ b/chrome/browser/ui/views/web_apps/force_installed_deprecated_apps_dialog_view.h
@@ -21,11 +21,11 @@ // Create the dialog metadata and show it. static void CreateAndShowDialog(extensions::ExtensionId app_id, - content::WebContents* web_contents); + content::WebContents* web_contents, + base::OnceClosure launch_anyways); private: ForceInstalledDeprecatedAppsDialogView(std::u16string app_name, - bool is_preinstalled_app, content::WebContents* web_contents); std::u16string app_name_;
diff --git a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc index 006d231..9038af7 100644 --- a/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc +++ b/chrome/browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_browsertest.cc
@@ -260,6 +260,7 @@ const SkColor original_ink_drop_color = views::InkDrop::Get(app_menu_button)->GetBaseColor(); + // Change the theme-color. { content::ThemeChangeWaiter theme_change_waiter(web_contents); EXPECT_TRUE(content::ExecJs(web_contents, @@ -271,10 +272,12 @@ original_ink_drop_color); } + // Change the theme-color back to its original one. { content::ThemeChangeWaiter theme_change_waiter(web_contents); - EXPECT_TRUE(content::ExecJs( - web_contents, "document.getElementById('theme-color').remove()")); + EXPECT_TRUE(content::ExecJs(web_contents, + "document.getElementById('theme-color')." + "setAttribute('content', '#ace')")); theme_change_waiter.Wait(); EXPECT_EQ(views::InkDrop::Get(app_menu_button)->GetBaseColor(),
diff --git a/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.cc b/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.cc index f558f26d..2837c9b4 100644 --- a/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.cc +++ b/chrome/browser/ui/views/web_apps/web_app_uninstall_dialog_view.cc
@@ -184,7 +184,8 @@ /*clear_cookies=*/true, /*clear_storage=*/true, /*clear_cache=*/true, /*avoid_closing_connections=*/false, - net::CookiePartitionKey::Todo(), base::DoNothing()); + /*cookie_partition_key=*/absl::nullopt, + base::DoNothing()); } void WebAppUninstallDialogDelegateView::ProcessAutoConfirmValue() {
diff --git a/chrome/browser/ui/webui/about_ui.cc b/chrome/browser/ui/webui/about_ui.cc index 8ba2d1b..f52125b 100644 --- a/chrome/browser/ui/webui/about_ui.cc +++ b/chrome/browser/ui/webui/about_ui.cc
@@ -72,7 +72,7 @@ #include "chrome/browser/ash/customization/customization_document.h" #include "chrome/browser/ash/login/demo_mode/demo_setup_controller.h" #include "chrome/browser/ash/login/wizard_controller.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/component_updater/cros_component_manager.h" #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h" #include "chrome/common/webui_url_constants.h"
diff --git a/chrome/browser/ui/webui/chromeos/login/online_login_helper.cc b/chrome/browser/ui/webui/chromeos/login/online_login_helper.cc index e96aa48..e37a58b3 100644 --- a/chrome/browser/ui/webui/chromeos/login/online_login_helper.cc +++ b/chrome/browser/ui/webui/chromeos/login/online_login_helper.cc
@@ -74,7 +74,8 @@ const GURL gaia_url = GaiaUrls::GetInstance()->gaia_url(); std::unique_ptr<net::CanonicalCookie> cc(net::CanonicalCookie::Create( gaia_url, gaps_cookie_value, base::Time::Now(), - absl::nullopt /* server_time */, net::CookiePartitionKey::Todo())); + absl::nullopt /* server_time */, + absl::nullopt /* cookie_partition_key */)); if (!cc) return;
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc index 688de10f..bd17d21b 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -51,7 +51,7 @@ #include "chrome/browser/ash/settings/cros_settings.h" #include "chrome/browser/ash/system/system_clock.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/lifetime/browser_shutdown.h" #include "chrome/browser/profiles/profile.h"
diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc index 965a676..cb95515 100644 --- a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc +++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
@@ -96,6 +96,7 @@ #include "extensions/common/constants.h" #include "extensions/common/extension.h" #include "extensions/common/extension_icon_set.h" +#include "extensions/common/extension_id.h" #include "extensions/common/extension_set.h" #include "extensions/common/manifest_handlers/icons_handler.h" #include "net/base/url_util.h" @@ -171,6 +172,8 @@ return largest >= pixels; } +// Query string for showing the deprecation dialog with deletion options. +const char kDeprecationDialogQueryString[] = "showDeletionDialog"; // Query string for showing the force installed apps deprecation dialog. // Should match with kChromeUIAppsWithForceInstalledDeprecationDialogURL. const char kForceInstallDialogQueryString[] = "showForceInstallDialog"; @@ -742,19 +745,33 @@ install_manager_observation_.Observe(&web_app_provider_->install_manager()); WebContents* web_contents = web_ui()->GetWebContents(); - if (web_contents->GetLastCommittedURL() == - GURL(chrome::kChromeUIAppsWithDeprecationDialogURL) && - !deprecated_app_ids_.empty()) { - TabDialogs::FromWebContents(web_contents) - ->ShowDeprecatedAppsDialog(deprecated_app_ids_, web_contents); - } std::string app_id; if (net::GetValueForKeyInQuery(web_contents->GetLastCommittedURL(), + kDeprecationDialogQueryString, &app_id)) { + if (extensions::IsExtensionUnsupportedDeprecatedApp(profile, app_id) && + !deprecated_app_ids_.empty()) { + TabDialogs::FromWebContents(web_contents) + ->ShowDeprecatedAppsDialog( + app_id, deprecated_app_ids_, web_contents, + base::BindOnce( + &AppLauncherHandler::LaunchApp, + weak_ptr_factory_.GetWeakPtr(), app_id, + extension_misc::AppLaunchBucket::APP_LAUNCH_CMD_LINE_APP, + "", WindowOpenDisposition::CURRENT_TAB, true)); + } + } + if (net::GetValueForKeyInQuery(web_contents->GetLastCommittedURL(), kForceInstallDialogQueryString, &app_id)) { if (extensions::IsExtensionUnsupportedDeprecatedApp(profile, app_id) && extensions::IsExtensionForceInstalled(profile, app_id, nullptr)) { TabDialogs::FromWebContents(web_contents) - ->ShowForceInstalledDeprecatedAppsDialog(app_id, web_contents); + ->ShowForceInstalledDeprecatedAppsDialog( + app_id, web_contents, + base::BindOnce( + &AppLauncherHandler::LaunchApp, + weak_ptr_factory_.GetWeakPtr(), app_id, + extension_misc::AppLaunchBucket::APP_LAUNCH_CMD_LINE_APP, + "", WindowOpenDisposition::CURRENT_TAB, true)); } } } @@ -764,27 +781,50 @@ void AppLauncherHandler::HandleLaunchApp(const base::ListValue* args) { const std::string& extension_id = args->GetListDeprecated()[0].GetString(); double source = args->GetListDeprecated()[1].GetDouble(); - GURL override_url; extension_misc::AppLaunchBucket launch_bucket = static_cast<extension_misc::AppLaunchBucket>(static_cast<int>(source)); CHECK(launch_bucket >= 0 && launch_bucket < extension_misc::APP_LAUNCH_BUCKET_BOUNDARY); + WindowOpenDisposition disposition = + args->GetListDeprecated().size() > 3 + ? webui::GetDispositionFromClick(args, 3) + : WindowOpenDisposition::CURRENT_TAB; + std::string source_value; + if (args->GetListDeprecated().size() > 2) { + source_value = args->GetListDeprecated()[2].GetString(); + } + LaunchApp(extension_id, launch_bucket, source_value, disposition, false); +} + +void AppLauncherHandler::LaunchApp( + std::string extension_id, + extension_misc::AppLaunchBucket launch_bucket, + const std::string& source_value, + WindowOpenDisposition disposition, + bool force_launch_deprecated_apps) { Profile* profile = extension_service_->profile(); - if (extensions::IsExtensionUnsupportedDeprecatedApp(profile, extension_id) && + if (!force_launch_deprecated_apps && + extensions::IsExtensionUnsupportedDeprecatedApp(profile, extension_id) && base::FeatureList::IsEnabled(features::kChromeAppsDeprecation)) { if (!extensions::IsExtensionForceInstalled(profile, extension_id, nullptr)) { TabDialogs::FromWebContents(web_ui()->GetWebContents()) - ->ShowDeprecatedAppsDialog(deprecated_app_ids_, - web_ui()->GetWebContents()); + ->ShowDeprecatedAppsDialog( + extension_id, deprecated_app_ids_, web_ui()->GetWebContents(), + base::BindOnce(&AppLauncherHandler::LaunchApp, + weak_ptr_factory_.GetWeakPtr(), extension_id, + launch_bucket, source_value, disposition, true)); return; } else { TabDialogs::FromWebContents(web_ui()->GetWebContents()) - ->ShowForceInstalledDeprecatedAppsDialog(extension_id, - web_ui()->GetWebContents()); + ->ShowForceInstalledDeprecatedAppsDialog( + extension_id, web_ui()->GetWebContents(), + base::BindOnce(&AppLauncherHandler::LaunchApp, + weak_ptr_factory_.GetWeakPtr(), extension_id, + launch_bucket, source_value, disposition, true)); return; } } @@ -816,24 +856,15 @@ extensions::GetLaunchContainer(ExtensionPrefs::Get(profile), extension); } - WindowOpenDisposition disposition = - args->GetListDeprecated().size() > 3 - ? webui::GetDispositionFromClick(args, 3) - : WindowOpenDisposition::CURRENT_TAB; + GURL override_url; if (extension_id != extensions::kWebStoreAppId) { CHECK_NE(launch_bucket, extension_misc::APP_LAUNCH_BUCKET_INVALID); extensions::RecordAppLaunchType(launch_bucket, type); } else { extensions::RecordWebStoreLaunch(); - - if (args->GetListDeprecated().size() > 2) { - const std::string& source_value = - args->GetListDeprecated()[2].GetString(); - if (!source_value.empty()) { - override_url = net::AppendQueryParameter( - full_launch_url, extension_urls::kWebstoreSourceField, - source_value); - } + if (!source_value.empty()) { + override_url = net::AppendQueryParameter( + full_launch_url, extension_urls::kWebstoreSourceField, source_value); } } @@ -1230,8 +1261,8 @@ void AppLauncherHandler::HandleLaunchDeprecatedAppDialog( const base::ListValue* args) { TabDialogs::FromWebContents(web_ui()->GetWebContents()) - ->ShowDeprecatedAppsDialog(deprecated_app_ids_, - web_ui()->GetWebContents()); + ->ShowDeprecatedAppsDialog(extensions::ExtensionId(), deprecated_app_ids_, + web_ui()->GetWebContents(), base::DoNothing()); } void AppLauncherHandler::OnFaviconForAppInstallFromLink(
diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.h b/chrome/browser/ui/webui/ntp/app_launcher_handler.h index cbb3bd66..df3a4969 100644 --- a/chrome/browser/ui/webui/ntp/app_launcher_handler.h +++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.h
@@ -137,6 +137,12 @@ // CURRENT_TAB. void HandleLaunchApp(const base::ListValue* args); + void LaunchApp(std::string extension_id, + extension_misc::AppLaunchBucket launch_bucket, + const std::string& source_value, + WindowOpenDisposition disposition, + bool force_launch_deprecated_apps); + // Handles the "setLaunchType" message with args containing [extension_id, // launch_type]. void HandleSetLaunchType(const base::ListValue* args);
diff --git a/chrome/browser/ui/webui/policy/policy_ui_handler.cc b/chrome/browser/ui/webui/policy/policy_ui_handler.cc index f75f18d8..f46e9d6 100644 --- a/chrome/browser/ui/webui/policy/policy_ui_handler.cc +++ b/chrome/browser/ui/webui/policy/policy_ui_handler.cc
@@ -101,6 +101,7 @@ #endif #if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chrome/browser/ui/webui/policy/status_provider/device_policy_status_provider_lacros.h" #include "chromeos/crosapi/mojom/policy_service.mojom.h" #include "chromeos/lacros/lacros_service.h" #include "components/policy/core/common/policy_loader_lacros.h" @@ -531,9 +532,11 @@ #if BUILDFLAG(IS_CHROMEOS_LACROS) void PolicyUIHandler::OnGotDevicePolicy(base::Value device_policy, base::Value legend_data) { - // TODO(crbug.com/1243869): Parse also legend_data and use it. if (device_policy != device_policy_) { device_policy_ = std::move(device_policy); + static_cast<DevicePolicyStatusProviderLacros*>( + device_status_provider_.get()) + ->SetDevicePolicyStatus(std::move(legend_data)); SendPolicies(); } } @@ -663,6 +666,11 @@ } #endif // BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_LACROS) + device_status_provider_ = + std::make_unique<DevicePolicyStatusProviderLacros>(); +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + #if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) ReloadUpdaterPoliciesAndState(); #endif // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING)
diff --git a/chrome/browser/ui/webui/policy/status_provider/device_cloud_policy_status_provider_chromeos.cc b/chrome/browser/ui/webui/policy/status_provider/device_cloud_policy_status_provider_chromeos.cc index 9cdd72c..6d1ea57 100644 --- a/chrome/browser/ui/webui/policy/status_provider/device_cloud_policy_status_provider_chromeos.cc +++ b/chrome/browser/ui/webui/policy/status_provider/device_cloud_policy_status_provider_chromeos.cc
@@ -12,7 +12,7 @@ DeviceCloudPolicyStatusProviderChromeOS:: DeviceCloudPolicyStatusProviderChromeOS( - policy::BrowserPolicyConnectorAsh* connector) + const policy::BrowserPolicyConnectorAsh* connector) : CloudPolicyCoreStatusProvider( connector->GetDeviceCloudPolicyManager()->core()) { enterprise_domain_manager_ = connector->GetEnterpriseDomainManager();
diff --git a/chrome/browser/ui/webui/policy/status_provider/device_cloud_policy_status_provider_chromeos.h b/chrome/browser/ui/webui/policy/status_provider/device_cloud_policy_status_provider_chromeos.h index 53cfaae..dfbceaf 100644 --- a/chrome/browser/ui/webui/policy/status_provider/device_cloud_policy_status_provider_chromeos.h +++ b/chrome/browser/ui/webui/policy/status_provider/device_cloud_policy_status_provider_chromeos.h
@@ -20,7 +20,7 @@ : public CloudPolicyCoreStatusProvider { public: explicit DeviceCloudPolicyStatusProviderChromeOS( - policy::BrowserPolicyConnectorAsh* connector); + const policy::BrowserPolicyConnectorAsh* connector); DeviceCloudPolicyStatusProviderChromeOS( const DeviceCloudPolicyStatusProviderChromeOS&) = delete;
diff --git a/chrome/browser/ui/webui/policy/status_provider/device_policy_status_provider_lacros.cc b/chrome/browser/ui/webui/policy/status_provider/device_policy_status_provider_lacros.cc new file mode 100644 index 0000000..e5e7b0a --- /dev/null +++ b/chrome/browser/ui/webui/policy/status_provider/device_policy_status_provider_lacros.cc
@@ -0,0 +1,24 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/policy/status_provider/device_policy_status_provider_lacros.h" + +DevicePolicyStatusProviderLacros::DevicePolicyStatusProviderLacros() + : PolicyStatusProvider() {} + +DevicePolicyStatusProviderLacros::~DevicePolicyStatusProviderLacros() {} + +void DevicePolicyStatusProviderLacros::SetDevicePolicyStatus( + base::Value status) { + device_policy_status_ = std::move(status); +} + +void DevicePolicyStatusProviderLacros::GetStatus(base::DictionaryValue* dict) { + if (!device_policy_status_.is_dict()) { + return; + } + base::DictionaryValue* dict_value; + device_policy_status_.GetAsDictionary(&dict_value); + dict->Swap(dict_value); +}
diff --git a/chrome/browser/ui/webui/policy/status_provider/device_policy_status_provider_lacros.h b/chrome/browser/ui/webui/policy/status_provider/device_policy_status_provider_lacros.h new file mode 100644 index 0000000..b6f94e0c --- /dev/null +++ b/chrome/browser/ui/webui/policy/status_provider/device_policy_status_provider_lacros.h
@@ -0,0 +1,26 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WEBUI_POLICY_STATUS_PROVIDER_DEVICE_POLICY_STATUS_PROVIDER_LACROS_H_ +#define CHROME_BROWSER_UI_WEBUI_POLICY_STATUS_PROVIDER_DEVICE_POLICY_STATUS_PROVIDER_LACROS_H_ + +#include "base/values.h" +#include "components/policy/core/browser/webui/policy_status_provider.h" + +// A policy status provider for device policy for Lacros. +class DevicePolicyStatusProviderLacros : public policy::PolicyStatusProvider { + public: + DevicePolicyStatusProviderLacros(); + ~DevicePolicyStatusProviderLacros() override; + + void SetDevicePolicyStatus(base::Value status); + + // PolicyStatusProvider implementation. + void GetStatus(base::DictionaryValue* dict) override; + + private: + base::Value device_policy_status_; +}; + +#endif // CHROME_BROWSER_UI_WEBUI_POLICY_STATUS_PROVIDER_DEVICE_POLICY_STATUS_PROVIDER_LACROS_H_
diff --git a/chrome/browser/user_agent/user_agent_browsertest.cc b/chrome/browser/user_agent/user_agent_browsertest.cc index be6ef64e..c1df8bb5 100644 --- a/chrome/browser/user_agent/user_agent_browsertest.cc +++ b/chrome/browser/user_agent/user_agent_browsertest.cc
@@ -24,7 +24,7 @@ namespace policy { using ReductionPolicyState = - ChromeContentBrowserClient::UserAgentReductionEnterprisePolicyState; + embedder_support::UserAgentReductionEnterprisePolicyState; using ForceMajorVersionToMinorPolicyState = embedder_support::ForceMajorVersionToMinorPosition; @@ -48,14 +48,15 @@ InProcessBrowserTest::SetUp(); } - void set_user_agent_reduction_policy(int policy) { + void set_user_agent_reduction_policy(ReductionPolicyState policy) { browser()->profile()->GetPrefs()->SetInteger(prefs::kUserAgentReduction, - policy); + static_cast<int>(policy)); } - int user_agent_reduction_policy() { - return browser()->profile()->GetPrefs()->GetInteger( - prefs::kUserAgentReduction); + ReductionPolicyState user_agent_reduction_policy() { + return static_cast<ReductionPolicyState>( + browser()->profile()->GetPrefs()->GetInteger( + prefs::kUserAgentReduction)); } void set_force_major_version_to_minor_policy( @@ -90,7 +91,11 @@ IN_PROC_BROWSER_TEST_P(UserAgentBrowserTest, ReductionPolicyDisabled) { set_user_agent_reduction_policy(ReductionPolicyState::kForceDisabled); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), empty_url())); - EXPECT_EQ(observed_user_agent(), embedder_support::GetFullUserAgent()); + EXPECT_EQ(observed_user_agent(), + embedder_support::GetFullUserAgent( + embedder_support::ForceMajorVersionToMinorPosition::kDefault, + embedder_support::UserAgentReductionEnterprisePolicyState:: + kForceDisabled)); } IN_PROC_BROWSER_TEST_P(UserAgentBrowserTest, ReductionPolicyEnabled) {
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc index 6ac2579..05ecad6a2 100644 --- a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc +++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
@@ -722,8 +722,8 @@ }, base::Unretained(profile())), origin, kClearCookies, kClearStorage, kClearCache, - kAvoidClosingConnections, - net::CookiePartitionKey::Todo(), base::DoNothing()); + kAvoidClosingConnections, absl::nullopt, + base::DoNothing()); } apps::mojom::IconKeyPtr WebAppPublisherHelper::MakeIconKey(
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index b5905a2..d00b932 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1654170771-aca3aa80be76cbddffc868b4086dbafc406545dc.profdata +chrome-mac-arm-main-1654192625-5758f252c39321335b090c4593a40a74f10cfa06.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 627093f..5842ef5 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1654170771-34e2a5d7745eff202372efe6c59ca9a8c73d838e.profdata +chrome-win32-main-1654181823-fb3de41b167f5917c604f31a8354af7ebad78a71.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 8102d05..0aa3ea0a 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1654170771-4af9924baf9e1e2e6cf772fa553a23067250fc7c.profdata +chrome-win64-main-1654181823-28fbf3a336a3849dac7000fc271da3d17155285a.profdata
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc index 6731b459..dad88d3 100644 --- a/chrome/common/webui_url_constants.cc +++ b/chrome/common/webui_url_constants.cc
@@ -33,7 +33,7 @@ const char kChromeUIAppLauncherPageHost[] = "apps"; const char kChromeUIAppsURL[] = "chrome://apps/"; const char kChromeUIAppsWithDeprecationDialogURL[] = - "chrome://apps?showDeletionDialog"; + "chrome://apps?showDeletionDialog="; const char kChromeUIAppsWithForceInstalledDeprecationDialogURL[] = "chrome://apps?showForceInstallDialog="; const char kChromeUIAutofillInternalsHost[] = "autofill-internals";
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 9827e0f..785b8b8 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -3224,6 +3224,7 @@ "../browser/ui/views/frame/system_web_app_non_client_frame_view_browsertest.cc", "../browser/ui/views/hung_renderer_view_browsertest.cc", "../browser/ui/views/importer/import_lock_dialog_view_browsertest.cc", + "../browser/ui/views/javascript_tab_modal_dialog_view_views_browsertest.cc", "../browser/ui/views/location_bar/content_setting_bubble_dialog_browsertest.cc", "../browser/ui/views/location_bar/cookie_controls_bubble_view_browsertest.cc", "../browser/ui/views/location_bar/custom_tab_bar_view_browsertest.cc",
diff --git a/chrome/test/base/browser_process_platform_part_test_api_chromeos.cc b/chrome/test/base/browser_process_platform_part_test_api_chromeos.cc index d5b5e2b..58680b6e 100644 --- a/chrome/test/base/browser_process_platform_part_test_api_chromeos.cc +++ b/chrome/test/base/browser_process_platform_part_test_api_chromeos.cc
@@ -6,7 +6,7 @@ #include <utility> -#include "chrome/browser/browser_process_platform_part_chromeos.h" +#include "chrome/browser/browser_process_platform_part_ash.h" #include "chrome/browser/component_updater/cros_component_manager.h" BrowserProcessPlatformPartTestApi::BrowserProcessPlatformPartTestApi(
diff --git a/chrome/test/chromedriver/chrome/chrome_android_impl.cc b/chrome/test/chromedriver/chrome/chrome_android_impl.cc index 49666b7..691615f 100644 --- a/chrome/test/chromedriver/chrome/chrome_android_impl.cc +++ b/chrome/test/chromedriver/chrome/chrome_android_impl.cc
@@ -8,7 +8,6 @@ #include "base/strings/string_split.h" #include "chrome/test/chromedriver/chrome/device_manager.h" -#include "chrome/test/chromedriver/chrome/device_metrics.h" #include "chrome/test/chromedriver/chrome/devtools_client.h" #include "chrome/test/chromedriver/chrome/devtools_event_listener.h" #include "chrome/test/chromedriver/chrome/devtools_http_client.h" @@ -20,15 +19,11 @@ std::unique_ptr<DevToolsClient> websocket_client, std::vector<std::unique_ptr<DevToolsEventListener>> devtools_event_listeners, - std::unique_ptr<DeviceMetrics> device_metrics, - SyncWebSocketFactory socket_factory, std::string page_load_strategy, std::unique_ptr<Device> device) : ChromeImpl(std::move(http_client), std::move(websocket_client), std::move(devtools_event_listeners), - std::move(device_metrics), - std::move(socket_factory), page_load_strategy), device_(std::move(device)) {}
diff --git a/chrome/test/chromedriver/chrome/chrome_android_impl.h b/chrome/test/chromedriver/chrome/chrome_android_impl.h index 871dd1a..3621af23 100644 --- a/chrome/test/chromedriver/chrome/chrome_android_impl.h +++ b/chrome/test/chromedriver/chrome/chrome_android_impl.h
@@ -12,7 +12,6 @@ #include "chrome/test/chromedriver/chrome/chrome_impl.h" class Device; -struct DeviceMetrics; class DevToolsClient; class DevToolsHttpClient; @@ -22,8 +21,6 @@ std::unique_ptr<DevToolsClient> websocket_client, std::vector<std::unique_ptr<DevToolsEventListener>> devtools_event_listeners, - std::unique_ptr<DeviceMetrics> device_metrics, - SyncWebSocketFactory socket_factory, std::string page_load_strategy, std::unique_ptr<Device> device); ~ChromeAndroidImpl() override;
diff --git a/chrome/test/chromedriver/chrome/chrome_desktop_impl.cc b/chrome/test/chromedriver/chrome/chrome_desktop_impl.cc index c623f36..a0dba51 100644 --- a/chrome/test/chromedriver/chrome/chrome_desktop_impl.cc +++ b/chrome/test/chromedriver/chrome/chrome_desktop_impl.cc
@@ -17,7 +17,6 @@ #include "base/threading/platform_thread.h" #include "base/time/time.h" #include "build/build_config.h" -#include "chrome/test/chromedriver/chrome/device_metrics.h" #include "chrome/test/chromedriver/chrome/devtools_client.h" #include "chrome/test/chromedriver/chrome/devtools_event_listener.h" #include "chrome/test/chromedriver/chrome/devtools_http_client.h" @@ -76,8 +75,6 @@ std::unique_ptr<DevToolsClient> websocket_client, std::vector<std::unique_ptr<DevToolsEventListener>> devtools_event_listeners, - std::unique_ptr<DeviceMetrics> device_metrics, - SyncWebSocketFactory socket_factory, std::string page_load_strategy, base::Process process, const base::CommandLine& command, @@ -87,8 +84,6 @@ : ChromeImpl(std::move(http_client), std::move(websocket_client), std::move(devtools_event_listeners), - std::move(device_metrics), - std::move(socket_factory), page_load_strategy), process_(std::move(process)), command_(command), @@ -146,7 +141,7 @@ if (id.empty()) return Status(kUnknownError, "page could not be found: " + url); - const DeviceMetrics* device_metrics = device_metrics_.get(); + const DeviceMetrics* device_metrics = devtools_http_client_->device_metrics(); if (type == WebViewInfo::Type::kApp || type == WebViewInfo::Type::kBackgroundPage) { // Apps and extensions don't work on Android, so it doesn't make sense to @@ -157,7 +152,8 @@ } std::unique_ptr<WebView> web_view_tmp(new WebViewImpl( id, w3c_compliant, nullptr, devtools_http_client_->browser_info(), - CreateClient(id), device_metrics, page_load_strategy())); + devtools_http_client_->CreateClient(id), device_metrics, + page_load_strategy())); Status status = web_view_tmp->ConnectIfNecessary(); if (status.IsError()) return status; @@ -179,7 +175,7 @@ } bool ChromeDesktopImpl::IsMobileEmulationEnabled() const { - return static_cast<bool>(device_metrics_); + return devtools_http_client_->device_metrics() != NULL; } bool ChromeDesktopImpl::HasTouchScreen() const {
diff --git a/chrome/test/chromedriver/chrome/chrome_desktop_impl.h b/chrome/test/chromedriver/chrome/chrome_desktop_impl.h index 1fc4c14..e03f2070 100644 --- a/chrome/test/chromedriver/chrome/chrome_desktop_impl.h +++ b/chrome/test/chromedriver/chrome/chrome_desktop_impl.h
@@ -13,7 +13,6 @@ #include "base/process/process.h" #include "chrome/test/chromedriver/chrome/chrome_impl.h" #include "chrome/test/chromedriver/chrome/scoped_temp_dir_with_retry.h" -#include "chrome/test/chromedriver/net/sync_websocket_factory.h" namespace base { class TimeDelta; @@ -23,7 +22,6 @@ class DevToolsHttpClient; class Status; class WebView; -struct DeviceMetrics; class ChromeDesktopImpl : public ChromeImpl { public: @@ -31,8 +29,6 @@ std::unique_ptr<DevToolsClient> websocket_client, std::vector<std::unique_ptr<DevToolsEventListener>> devtools_event_listeners, - std::unique_ptr<DeviceMetrics> device_metrics, - SyncWebSocketFactory socket_factory, std::string page_load_strategy, base::Process process, const base::CommandLine& command,
diff --git a/chrome/test/chromedriver/chrome/chrome_impl.cc b/chrome/test/chromedriver/chrome/chrome_impl.cc index 47bf735b..7c0ef44 100644 --- a/chrome/test/chromedriver/chrome/chrome_impl.cc +++ b/chrome/test/chromedriver/chrome/chrome_impl.cc
@@ -5,19 +5,13 @@ #include "chrome/test/chromedriver/chrome/chrome_impl.h" #include <stddef.h> -#include <algorithm> #include <utility> -#include "base/bind.h" -#include "base/logging.h" #include "base/strings/string_number_conversions.h" #include "base/threading/platform_thread.h" #include "base/time/time.h" #include "base/values.h" -#include "chrome/test/chromedriver/chrome/chrome.h" -#include "chrome/test/chromedriver/chrome/device_metrics.h" #include "chrome/test/chromedriver/chrome/devtools_client.h" -#include "chrome/test/chromedriver/chrome/devtools_client_impl.h" #include "chrome/test/chromedriver/chrome/devtools_event_listener.h" #include "chrome/test/chromedriver/chrome/devtools_http_client.h" #include "chrome/test/chromedriver/chrome/page_load_strategy.h" @@ -111,7 +105,8 @@ } } if (!found) { - std::unique_ptr<DevToolsClient> client = CreateClient(view.id); + std::unique_ptr<DevToolsClient> client( + devtools_http_client_->CreateClient(view.id)); for (const auto& listener : devtools_event_listeners_) client->AddListener(listener.get()); // OnConnected will fire when DevToolsClient connects later. @@ -124,7 +119,7 @@ web_views_.push_back(std::make_unique<WebViewImpl>( view.id, w3c_compliant, nullptr, devtools_http_client_->browser_info(), std::move(client), - device_metrics_.get(), page_load_strategy_)); + devtools_http_client_->device_metrics(), page_load_strategy_)); } } } @@ -171,89 +166,6 @@ return Status(kOk); } -std::unique_ptr<DevToolsClient> ChromeImpl::CreateClient( - const std::string& id) { - auto result = std::make_unique<DevToolsClientImpl>( - id, "", devtools_http_client_->endpoint().GetDebuggerUrl(id), - socket_factory_); - result->SetFrontendCloserFunc(base::BindRepeating( - &ChromeImpl::CloseFrontends, base::Unretained(this), id)); - return result; -} - -Status ChromeImpl::CloseFrontends(const std::string& for_client_id) { - WebViewsInfo views_info; - Status status = devtools_http_client_->GetWebViewsInfo(&views_info); - if (status.IsError()) - return status; - - // Close frontends. Usually frontends are docked in the same page, although - // some may be in tabs (undocked, chrome://inspect, the DevTools - // discovery page, etc.). Tabs can be closed via the DevTools HTTP close - // URL, but docked frontends can only be closed, by design, by connecting - // to them and clicking the close button. Close the tab frontends first - // in case one of them is debugging a docked frontend, which would prevent - // the code from being able to connect to the docked one. - std::list<std::string> tab_frontend_ids; - std::list<std::string> docked_frontend_ids; - for (size_t i = 0; i < views_info.GetSize(); ++i) { - const WebViewInfo& view_info = views_info.Get(i); - if (view_info.IsFrontend()) { - if (view_info.type == WebViewInfo::kPage) - tab_frontend_ids.push_back(view_info.id); - else if (view_info.type == WebViewInfo::kOther) - docked_frontend_ids.push_back(view_info.id); - else - return Status(kUnknownError, "unknown type of DevTools frontend"); - } - } - - for (std::list<std::string>::const_iterator it = tab_frontend_ids.begin(); - it != tab_frontend_ids.end(); ++it) { - status = CloseWebView(*it); - if (status.IsError()) - return status; - } - - for (std::list<std::string>::const_iterator it = docked_frontend_ids.begin(); - it != docked_frontend_ids.end(); ++it) { - std::unique_ptr<DevToolsClient> client(new DevToolsClientImpl( - *it, "", devtools_http_client_->endpoint().GetDebuggerUrl(*it), - socket_factory_)); - std::unique_ptr<WebViewImpl> web_view(new WebViewImpl( - *it, false, nullptr, devtools_http_client_->browser_info(), - std::move(client), nullptr, page_load_strategy_)); - - status = web_view->ConnectIfNecessary(); - // Ignore disconnected error, because the debugger might have closed when - // its container page was closed above. - if (status.IsError() && status.code() != kDisconnected) - return status; - - status = CloseWebView(*it); - // Ignore disconnected error, because it may be closed already. - if (status.IsError() && status.code() != kDisconnected) - return status; - } - - // Wait until DevTools UI disconnects from the given web view. - base::TimeTicks deadline = base::TimeTicks::Now() + base::Seconds(20); - while (base::TimeTicks::Now() < deadline) { - status = devtools_http_client_->GetWebViewsInfo(&views_info); - if (status.IsError()) - return status; - - const WebViewInfo* view_info = views_info.GetForId(for_client_id); - if (!view_info) - return Status(kNoSuchWindow, "window was already closed"); - if (view_info->debugger_url.size()) - return Status(kOk); - - base::PlatformThread::Sleep(base::Milliseconds(50)); - } - return Status(kUnknownError, "failed to close UI debuggers"); -} - Status ChromeImpl::GetWindow(const std::string& target_id, Window* window) { Status status = devtools_websocket_client_->ConnectIfNecessary(); if (status.IsError()) @@ -558,26 +470,15 @@ } Status ChromeImpl::CloseWebView(const std::string& id) { - Status status = devtools_websocket_client_->ConnectIfNecessary(); - if (status.IsError()) { - return status; - } - - base::Value params{base::Value::Type::DICT}; - params.GetDict().Set("targetId", id); - status = devtools_websocket_client_->SendCommand( - "Target.closeTarget", base::Value::AsDictionaryValue(params)); - + Status status = devtools_http_client_->CloseWebView(id); if (status.IsError()) return status; - - auto it = - std::find_if(web_views_.begin(), web_views_.end(), - [&id](const auto& view) { return view->GetId() == id; }); - if (it != web_views_.end()) { - web_views_.erase(it); + for (auto iter = web_views_.begin(); iter != web_views_.end(); ++iter) { + if ((*iter)->GetId() == id) { + web_views_.erase(iter); + break; + } } - return Status(kOk); } @@ -586,17 +487,7 @@ GetWebViewById(id, &webview); if (webview && webview->IsServiceWorker()) return Status(kOk); - - Status status = devtools_websocket_client_->ConnectIfNecessary(); - if (status.IsError()) { - return status; - } - - base::Value params{base::Value::Type::DICT}; - params.GetDict().Set("targetId", id); - status = devtools_websocket_client_->SendCommand( - "Target.activateTarget", base::Value::AsDictionaryValue(params)); - return status; + return devtools_http_client_->ActivateWebView(id); } Status ChromeImpl::SetAcceptInsecureCerts() { @@ -666,11 +557,8 @@ std::unique_ptr<DevToolsClient> websocket_client, std::vector<std::unique_ptr<DevToolsEventListener>> devtools_event_listeners, - std::unique_ptr<DeviceMetrics> device_metrics, - SyncWebSocketFactory socket_factory, std::string page_load_strategy) - : device_metrics_(std::move(device_metrics)), - socket_factory_(std::move(socket_factory)), + : quit_(false), devtools_http_client_(std::move(http_client)), devtools_websocket_client_(std::move(websocket_client)), devtools_event_listeners_(std::move(devtools_event_listeners)),
diff --git a/chrome/test/chromedriver/chrome/chrome_impl.h b/chrome/test/chromedriver/chrome/chrome_impl.h index 1aa4957a..834d3255 100644 --- a/chrome/test/chromedriver/chrome/chrome_impl.h +++ b/chrome/test/chromedriver/chrome/chrome_impl.h
@@ -12,8 +12,8 @@ #include "base/values.h" #include "chrome/test/chromedriver/chrome/chrome.h" -#include "chrome/test/chromedriver/net/sync_websocket_factory.h" +struct BrowserInfo; class DevToolsClient; class DevToolsEventListener; class DevToolsHttpClient; @@ -21,8 +21,6 @@ class WebView; class WebViewImpl; class WebViewsInfo; -struct BrowserInfo; -struct DeviceMetrics; class ChromeImpl : public Chrome { public: @@ -63,15 +61,10 @@ std::unique_ptr<DevToolsClient> websocket_client, std::vector<std::unique_ptr<DevToolsEventListener>> devtools_event_listeners, - std::unique_ptr<DeviceMetrics> device_metrics, - SyncWebSocketFactory socket_factory, std::string page_load_strategy); virtual Status QuitImpl() = 0; - std::unique_ptr<DevToolsClient> CreateClient(const std::string& id); - Status CloseFrontends(const std::string& for_client_id); - struct Window { int id; std::string state; @@ -88,9 +81,7 @@ const std::string& target_id, std::unique_ptr<base::DictionaryValue> bounds); - bool quit_ = false; - std::unique_ptr<DeviceMetrics> device_metrics_; - SyncWebSocketFactory socket_factory_; + bool quit_; std::unique_ptr<DevToolsHttpClient> devtools_http_client_; std::unique_ptr<DevToolsClient> devtools_websocket_client_;
diff --git a/chrome/test/chromedriver/chrome/chrome_remote_impl.cc b/chrome/test/chromedriver/chrome/chrome_remote_impl.cc index 4154d9e..9c4547b 100644 --- a/chrome/test/chromedriver/chrome/chrome_remote_impl.cc +++ b/chrome/test/chromedriver/chrome/chrome_remote_impl.cc
@@ -6,7 +6,6 @@ #include <utility> -#include "chrome/test/chromedriver/chrome/device_metrics.h" #include "chrome/test/chromedriver/chrome/devtools_client.h" #include "chrome/test/chromedriver/chrome/devtools_event_listener.h" #include "chrome/test/chromedriver/chrome/devtools_http_client.h" @@ -17,14 +16,10 @@ std::unique_ptr<DevToolsClient> websocket_client, std::vector<std::unique_ptr<DevToolsEventListener>> devtools_event_listeners, - std::unique_ptr<DeviceMetrics> device_metrics, - SyncWebSocketFactory socket_factory, std::string page_load_strategy) : ChromeImpl(std::move(http_client), std::move(websocket_client), std::move(devtools_event_listeners), - std::move(device_metrics), - std::move(socket_factory), page_load_strategy) {} ChromeRemoteImpl::~ChromeRemoteImpl() {}
diff --git a/chrome/test/chromedriver/chrome/chrome_remote_impl.h b/chrome/test/chromedriver/chrome/chrome_remote_impl.h index 1c081a0..5abbe9d 100644 --- a/chrome/test/chromedriver/chrome/chrome_remote_impl.h +++ b/chrome/test/chromedriver/chrome/chrome_remote_impl.h
@@ -9,11 +9,9 @@ #include <string> #include "chrome/test/chromedriver/chrome/chrome_impl.h" -#include "chrome/test/chromedriver/net/sync_websocket_factory.h" class DevToolsClient; class DevToolsHttpClient; -struct DeviceMetrics; class ChromeRemoteImpl : public ChromeImpl { public: @@ -21,8 +19,6 @@ std::unique_ptr<DevToolsClient> websocket_client, std::vector<std::unique_ptr<DevToolsEventListener>> devtools_event_listeners, - std::unique_ptr<DeviceMetrics> device_metrics, - SyncWebSocketFactory socket_factory, std::string page_load_strategy); ~ChromeRemoteImpl() override;
diff --git a/chrome/test/chromedriver/chrome/devtools_endpoint.cc b/chrome/test/chromedriver/chrome/devtools_endpoint.cc index 85de9db..9bba6b5 100644 --- a/chrome/test/chromedriver/chrome/devtools_endpoint.cc +++ b/chrome/test/chromedriver/chrome/devtools_endpoint.cc
@@ -52,3 +52,7 @@ std::string DevToolsEndpoint::GetCloseUrl(const std::string& id) const { return server_url_.Resolve("json/close/" + id).spec(); } + +std::string DevToolsEndpoint::GetActivateUrl(const std::string& id) const { + return server_url_.Resolve("json/activate/" + id).spec(); +}
diff --git a/chrome/test/chromedriver/chrome/devtools_endpoint.h b/chrome/test/chromedriver/chrome/devtools_endpoint.h index a446abd..702447b7 100644 --- a/chrome/test/chromedriver/chrome/devtools_endpoint.h +++ b/chrome/test/chromedriver/chrome/devtools_endpoint.h
@@ -26,6 +26,7 @@ std::string GetVersionUrl() const; std::string GetListUrl() const; std::string GetCloseUrl(const std::string& id) const; + std::string GetActivateUrl(const std::string& id) const; private: GURL server_url_;
diff --git a/chrome/test/chromedriver/chrome/devtools_endpoint_unittest.cc b/chrome/test/chromedriver/chrome/devtools_endpoint_unittest.cc index 93d366b..b138095 100644 --- a/chrome/test/chromedriver/chrome/devtools_endpoint_unittest.cc +++ b/chrome/test/chromedriver/chrome/devtools_endpoint_unittest.cc
@@ -24,6 +24,8 @@ ASSERT_EQ(endpoint.GetListUrl(), "http://localhost:9999/json/list"); ASSERT_EQ(endpoint.GetCloseUrl("xyz"), "http://localhost:9999/json/close/xyz"); + ASSERT_EQ(endpoint.GetActivateUrl("xyz"), + "http://localhost:9999/json/activate/xyz"); } TEST(DevToolsEndpoint, FromNetAddress) { @@ -38,6 +40,8 @@ ASSERT_EQ(endpoint.GetListUrl(), "http://localhost:9222/json/list"); ASSERT_EQ(endpoint.GetCloseUrl("xyz"), "http://localhost:9222/json/close/xyz"); + ASSERT_EQ(endpoint.GetActivateUrl("xyz"), + "http://localhost:9222/json/activate/xyz"); } TEST(DevToolsEndpoint, FromHttpUrl) { @@ -54,6 +58,8 @@ ASSERT_EQ(endpoint.GetListUrl(), "http://remote:9223/custom/path/json/list"); ASSERT_EQ(endpoint.GetCloseUrl("xyz"), "http://remote:9223/custom/path/json/close/xyz"); + ASSERT_EQ(endpoint.GetActivateUrl("xyz"), + "http://remote:9223/custom/path/json/activate/xyz"); } TEST(DevToolsEndpoint, FromHttpsUrl) { @@ -70,4 +76,6 @@ ASSERT_EQ(endpoint.GetListUrl(), "https://secure:9224/custom/path/json/list"); ASSERT_EQ(endpoint.GetCloseUrl("xyz"), "https://secure:9224/custom/path/json/close/xyz"); + ASSERT_EQ(endpoint.GetActivateUrl("xyz"), + "https://secure:9224/custom/path/json/activate/xyz"); }
diff --git a/chrome/test/chromedriver/chrome/devtools_http_client.cc b/chrome/test/chromedriver/chrome/devtools_http_client.cc index 439425b..45e5a95 100644 --- a/chrome/test/chromedriver/chrome/devtools_http_client.cc +++ b/chrome/test/chromedriver/chrome/devtools_http_client.cc
@@ -15,9 +15,11 @@ #include "base/threading/platform_thread.h" #include "base/time/time.h" #include "base/values.h" +#include "chrome/test/chromedriver/chrome/device_metrics.h" #include "chrome/test/chromedriver/chrome/devtools_client_impl.h" #include "chrome/test/chromedriver/chrome/log.h" #include "chrome/test/chromedriver/chrome/status.h" +#include "chrome/test/chromedriver/chrome/web_view_impl.h" #include "chrome/test/chromedriver/net/net_util.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" @@ -65,10 +67,16 @@ DevToolsHttpClient::DevToolsHttpClient( const DevToolsEndpoint& endpoint, network::mojom::URLLoaderFactory* factory, - std::unique_ptr<std::set<WebViewInfo::Type>> window_types) + const SyncWebSocketFactory& socket_factory, + std::unique_ptr<DeviceMetrics> device_metrics, + std::unique_ptr<std::set<WebViewInfo::Type>> window_types, + std::string page_load_strategy) : url_loader_factory_(factory), + socket_factory_(socket_factory), endpoint_(endpoint), - window_types_(std::move(window_types)) { + device_metrics_(std::move(device_metrics)), + window_types_(std::move(window_types)), + page_load_strategy_(page_load_strategy) { window_types_->insert(WebViewInfo::kPage); window_types_->insert(WebViewInfo::kApp); } @@ -103,17 +111,127 @@ return internal::ParseWebViewsInfo(data, views_info); } +std::unique_ptr<DevToolsClient> DevToolsHttpClient::CreateClient( + const std::string& id) { + auto result = std::make_unique<DevToolsClientImpl>( + id, "", endpoint_.GetDebuggerUrl(id), socket_factory_); + result->SetFrontendCloserFunc(base::BindRepeating( + &DevToolsHttpClient::CloseFrontends, base::Unretained(this), id)); + return result; +} + +Status DevToolsHttpClient::CloseWebView(const std::string& id) { + std::string data; + if (!FetchUrlAndLog(endpoint_.GetCloseUrl(id), &data)) { + return Status(kOk); // Closing the last web view leads chrome to quit. + } + + // Wait for the target window to be completely closed. + base::TimeTicks deadline = base::TimeTicks::Now() + base::Seconds(20); + while (base::TimeTicks::Now() < deadline) { + WebViewsInfo views_info; + Status status = GetWebViewsInfo(&views_info); + if (status.code() == kChromeNotReachable) + return Status(kOk); + if (status.IsError()) + return status; + if (!views_info.GetForId(id)) + return Status(kOk); + base::PlatformThread::Sleep(base::Milliseconds(50)); + } + return Status(kUnknownError, "failed to close window in 20 seconds"); +} + +Status DevToolsHttpClient::ActivateWebView(const std::string& id) { + std::string data; + if (!FetchUrlAndLog(endpoint_.GetActivateUrl(id), &data)) + return Status(kUnknownError, "cannot activate web view"); + return Status(kOk); +} + const BrowserInfo* DevToolsHttpClient::browser_info() { return &browser_info_; } +const DeviceMetrics* DevToolsHttpClient::device_metrics() { + return device_metrics_.get(); +} + bool DevToolsHttpClient::IsBrowserWindow(const WebViewInfo& view) const { return base::Contains(*window_types_, view.type) || (view.type == WebViewInfo::kOther && view.url == "chrome://print/"); } -const DevToolsEndpoint& DevToolsHttpClient::endpoint() const { - return endpoint_; +Status DevToolsHttpClient::CloseFrontends(const std::string& for_client_id) { + WebViewsInfo views_info; + Status status = GetWebViewsInfo(&views_info); + if (status.IsError()) + return status; + + // Close frontends. Usually frontends are docked in the same page, although + // some may be in tabs (undocked, chrome://inspect, the DevTools + // discovery page, etc.). Tabs can be closed via the DevTools HTTP close + // URL, but docked frontends can only be closed, by design, by connecting + // to them and clicking the close button. Close the tab frontends first + // in case one of them is debugging a docked frontend, which would prevent + // the code from being able to connect to the docked one. + std::list<std::string> tab_frontend_ids; + std::list<std::string> docked_frontend_ids; + for (size_t i = 0; i < views_info.GetSize(); ++i) { + const WebViewInfo& view_info = views_info.Get(i); + if (view_info.IsFrontend()) { + if (view_info.type == WebViewInfo::kPage) + tab_frontend_ids.push_back(view_info.id); + else if (view_info.type == WebViewInfo::kOther) + docked_frontend_ids.push_back(view_info.id); + else + return Status(kUnknownError, "unknown type of DevTools frontend"); + } + } + + for (std::list<std::string>::const_iterator it = tab_frontend_ids.begin(); + it != tab_frontend_ids.end(); ++it) { + status = CloseWebView(*it); + if (status.IsError()) + return status; + } + + for (std::list<std::string>::const_iterator it = docked_frontend_ids.begin(); + it != docked_frontend_ids.end(); ++it) { + std::unique_ptr<DevToolsClient> client(new DevToolsClientImpl( + *it, "", endpoint_.GetDebuggerUrl(*it), socket_factory_)); + std::unique_ptr<WebViewImpl> web_view( + new WebViewImpl(*it, false, nullptr, &browser_info_, std::move(client), + nullptr, page_load_strategy_)); + + status = web_view->ConnectIfNecessary(); + // Ignore disconnected error, because the debugger might have closed when + // its container page was closed above. + if (status.IsError() && status.code() != kDisconnected) + return status; + + status = CloseWebView(*it); + // Ignore disconnected error, because it may be closed already. + if (status.IsError() && status.code() != kDisconnected) + return status; + } + + // Wait until DevTools UI disconnects from the given web view. + base::TimeTicks deadline = base::TimeTicks::Now() + base::Seconds(20); + while (base::TimeTicks::Now() < deadline) { + status = GetWebViewsInfo(&views_info); + if (status.IsError()) + return status; + + const WebViewInfo* view_info = views_info.GetForId(for_client_id); + if (!view_info) + return Status(kNoSuchWindow, "window was already closed"); + if (view_info->debugger_url.size()) + return Status(kOk); + + base::PlatformThread::Sleep(base::Milliseconds(50)); + } + return Status(kUnknownError, "failed to close UI debuggers"); } bool DevToolsHttpClient::FetchUrlAndLog(const std::string& url,
diff --git a/chrome/test/chromedriver/chrome/devtools_http_client.h b/chrome/test/chromedriver/chrome/devtools_http_client.h index 11515d3..7b74380 100644 --- a/chrome/test/chromedriver/chrome/devtools_http_client.h +++ b/chrome/test/chromedriver/chrome/devtools_http_client.h
@@ -16,6 +16,7 @@ #include "base/memory/ref_counted.h" #include "chrome/test/chromedriver/chrome/browser_info.h" #include "chrome/test/chromedriver/chrome/devtools_endpoint.h" +#include "chrome/test/chromedriver/net/sync_websocket_factory.h" namespace base { class TimeDelta; @@ -27,6 +28,8 @@ } } // namespace network +struct DeviceMetrics; +class DevToolsClient; class Status; struct WebViewInfo { @@ -78,7 +81,10 @@ public: DevToolsHttpClient(const DevToolsEndpoint& endpoint, network::mojom::URLLoaderFactory* factory, - std::unique_ptr<std::set<WebViewInfo::Type>> window_types); + const SyncWebSocketFactory& socket_factory, + std::unique_ptr<DeviceMetrics> device_metrics, + std::unique_ptr<std::set<WebViewInfo::Type>> window_types, + std::string page_load_strategy); DevToolsHttpClient(const DevToolsHttpClient&) = delete; DevToolsHttpClient& operator=(const DevToolsHttpClient&) = delete; @@ -89,17 +95,27 @@ Status GetWebViewsInfo(WebViewsInfo* views_info); + std::unique_ptr<DevToolsClient> CreateClient(const std::string& id); + + Status CloseWebView(const std::string& id); + + Status ActivateWebView(const std::string& id); + const BrowserInfo* browser_info(); + const DeviceMetrics* device_metrics(); bool IsBrowserWindow(const WebViewInfo& view) const; - const DevToolsEndpoint& endpoint() const; private: + Status CloseFrontends(const std::string& for_client_id); virtual bool FetchUrlAndLog(const std::string& url, std::string* response); raw_ptr<network::mojom::URLLoaderFactory> url_loader_factory_; + SyncWebSocketFactory socket_factory_; DevToolsEndpoint endpoint_; BrowserInfo browser_info_; + std::unique_ptr<DeviceMetrics> device_metrics_; std::unique_ptr<std::set<WebViewInfo::Type>> window_types_; + std::string page_load_strategy_; }; Status ParseType(const std::string& data, WebViewInfo::Type* type);
diff --git a/chrome/test/chromedriver/chrome_launcher.cc b/chrome/test/chromedriver/chrome_launcher.cc index d29a628..756410a 100644 --- a/chrome/test/chromedriver/chrome_launcher.cc +++ b/chrome/test/chromedriver/chrome_launcher.cc
@@ -234,12 +234,19 @@ Status WaitForDevToolsAndCheckVersion( const DevToolsEndpoint& endpoint, network::mojom::URLLoaderFactory* factory, + const SyncWebSocketFactory& socket_factory, const Capabilities* capabilities, int wait_time, std::unique_ptr<DevToolsHttpClient>* user_client, bool* retry, ChromeType ct, std::string fp = "") { + std::unique_ptr<DeviceMetrics> device_metrics; + if (capabilities && capabilities->device_metrics) { + device_metrics = + std::make_unique<DeviceMetrics>(*capabilities->device_metrics); + } + std::unique_ptr<std::set<WebViewInfo::Type>> window_types; if (capabilities && !capabilities->window_types.empty()) { window_types = std::make_unique<std::set<WebViewInfo::Type>>( @@ -255,10 +262,13 @@ cmd_line->GetSwitchValueNative("devtools-replay"); base::FilePath log_file_path(log_path); client = std::make_unique<ReplayHttpClient>( - endpoint, factory, std::move(window_types), log_file_path); + endpoint, factory, socket_factory, std::move(device_metrics), + std::move(window_types), capabilities->page_load_strategy, + log_file_path); } else { - client = std::make_unique<DevToolsHttpClient>(endpoint, factory, - std::move(window_types)); + client = std::make_unique<DevToolsHttpClient>( + endpoint, factory, socket_factory, std::move(device_metrics), + std::move(window_types), capabilities->page_load_strategy); } const base::TimeTicks initial = base::TimeTicks::Now(); @@ -377,8 +387,8 @@ std::unique_ptr<DevToolsHttpClient> devtools_http_client; bool retry = true; status = WaitForDevToolsAndCheckVersion( - DevToolsEndpoint(capabilities.debugger_address), factory, &capabilities, - 60, &devtools_http_client, &retry, ChromeType::Remote); + DevToolsEndpoint(capabilities.debugger_address), factory, socket_factory, + &capabilities, 60, &devtools_http_client, &retry, ChromeType::Remote); if (status.IsError()) { return Status( kUnknownError, @@ -399,16 +409,9 @@ << status.message(); } - std::unique_ptr<DeviceMetrics> device_metrics; - if (capabilities.device_metrics) { - device_metrics = - std::make_unique<DeviceMetrics>(*capabilities.device_metrics); - } - *chrome = std::make_unique<ChromeRemoteImpl>( std::move(devtools_http_client), std::move(devtools_websocket_client), - std::move(devtools_event_listeners), std::move(device_metrics), - socket_factory, capabilities.page_load_strategy); + std::move(devtools_event_listeners), capabilities.page_load_strategy); return Status(kOk); } @@ -589,8 +592,9 @@ std::ostringstream oss; oss << command.GetProgram(); status = WaitForDevToolsAndCheckVersion( - DevToolsEndpoint(devtools_port), factory, &capabilities, 1, - &devtools_http_client, &retry, ChromeType::Desktop, oss.str()); + DevToolsEndpoint(devtools_port), factory, socket_factory, + &capabilities, 1, &devtools_http_client, &retry, ChromeType::Desktop, + oss.str()); if (!retry) { break; } @@ -664,18 +668,11 @@ << status.message(); } - std::unique_ptr<DeviceMetrics> device_metrics; - if (capabilities.device_metrics) { - device_metrics = - std::make_unique<DeviceMetrics>(*capabilities.device_metrics); - } - std::unique_ptr<ChromeDesktopImpl> chrome_desktop = std::make_unique<ChromeDesktopImpl>( std::move(devtools_http_client), std::move(devtools_websocket_client), - std::move(devtools_event_listeners), std::move(device_metrics), - socket_factory, capabilities.page_load_strategy, std::move(process), - command, &user_data_dir_temp_dir, &extension_dir, + std::move(devtools_event_listeners), capabilities.page_load_strategy, + std::move(process), command, &user_data_dir_temp_dir, &extension_dir, capabilities.network_emulation_enabled); if (!capabilities.extension_load_timeout.is_zero()) { for (size_t i = 0; i < extension_bg_pages.size(); ++i) { @@ -740,8 +737,8 @@ std::unique_ptr<DevToolsHttpClient> devtools_http_client; bool retry = true; status = WaitForDevToolsAndCheckVersion( - DevToolsEndpoint(devtools_port), factory, &capabilities, 60, - &devtools_http_client, &retry, ChromeType::Android); + DevToolsEndpoint(devtools_port), factory, socket_factory, &capabilities, + 60, &devtools_http_client, &retry, ChromeType::Android); if (status.IsError()) { device->TearDown(); return status; @@ -758,16 +755,10 @@ << status.message(); } - std::unique_ptr<DeviceMetrics> device_metrics; - if (capabilities.device_metrics) { - device_metrics = - std::make_unique<DeviceMetrics>(*capabilities.device_metrics); - } - *chrome = std::make_unique<ChromeAndroidImpl>( std::move(devtools_http_client), std::move(devtools_websocket_client), - std::move(devtools_event_listeners), std::move(device_metrics), - socket_factory, capabilities.page_load_strategy, std::move(device)); + std::move(devtools_event_listeners), capabilities.page_load_strategy, + std::move(device)); return Status(kOk); } @@ -801,8 +792,8 @@ std::unique_ptr<DevToolsHttpClient> devtools_http_client; bool retry = true; status = WaitForDevToolsAndCheckVersion( - DevToolsEndpoint(0), factory, &capabilities, 1, &devtools_http_client, - &retry, ChromeType::Replay); + DevToolsEndpoint(0), factory, socket_factory, &capabilities, 1, + &devtools_http_client, &retry, ChromeType::Replay); if (status.IsError()) return status; std::unique_ptr<DevToolsClient> devtools_websocket_client; @@ -815,19 +806,11 @@ LOG(WARNING) << "Browser-wide DevTools client failed to connect: " << status.message(); } - - std::unique_ptr<DeviceMetrics> device_metrics; - if (capabilities.device_metrics) { - device_metrics = - std::make_unique<DeviceMetrics>(*capabilities.device_metrics); - } - base::Process dummy_process; std::unique_ptr<ChromeDesktopImpl> chrome_impl = std::make_unique<ChromeReplayImpl>( std::move(devtools_http_client), std::move(devtools_websocket_client), - std::move(devtools_event_listeners), std::move(device_metrics), - socket_factory, capabilities.page_load_strategy, + std::move(devtools_event_listeners), capabilities.page_load_strategy, std::move(dummy_process), command, &user_data_dir_temp_dir, &extension_dir, capabilities.network_emulation_enabled);
diff --git a/chrome/test/chromedriver/log_replay/chrome_replay_impl.cc b/chrome/test/chromedriver/log_replay/chrome_replay_impl.cc index 2d59b28d..009ae6c 100644 --- a/chrome/test/chromedriver/log_replay/chrome_replay_impl.cc +++ b/chrome/test/chromedriver/log_replay/chrome_replay_impl.cc
@@ -3,7 +3,6 @@ // found in the LICENSE file. #include "chrome/test/chromedriver/log_replay/chrome_replay_impl.h" -#include "chrome/test/chromedriver/chrome/device_metrics.h" #include "chrome/test/chromedriver/chrome/devtools_client.h" #include "chrome/test/chromedriver/chrome/devtools_event_listener.h" #include "chrome/test/chromedriver/chrome/devtools_http_client.h" @@ -14,8 +13,6 @@ std::unique_ptr<DevToolsClient> websocket_client, std::vector<std::unique_ptr<DevToolsEventListener>> devtools_event_listeners, - std::unique_ptr<DeviceMetrics> device_metrics, - SyncWebSocketFactory socket_factory, std::string page_load_strategy, base::Process process, const base::CommandLine& command, @@ -25,8 +22,6 @@ : ChromeDesktopImpl(std::move(http_client), std::move(websocket_client), std::move(devtools_event_listeners), - std::move(device_metrics), - std::move(socket_factory), page_load_strategy, std::move(process), command,
diff --git a/chrome/test/chromedriver/log_replay/chrome_replay_impl.h b/chrome/test/chromedriver/log_replay/chrome_replay_impl.h index 087b4578..ab7e5cb0 100644 --- a/chrome/test/chromedriver/log_replay/chrome_replay_impl.h +++ b/chrome/test/chromedriver/log_replay/chrome_replay_impl.h
@@ -4,14 +4,11 @@ #ifndef CHROME_TEST_CHROMEDRIVER_LOG_REPLAY_CHROME_REPLAY_IMPL_H_ #define CHROME_TEST_CHROMEDRIVER_LOG_REPLAY_CHROME_REPLAY_IMPL_H_ -#include <memory> #include "chrome/test/chromedriver/chrome/chrome_desktop_impl.h" -#include "chrome/test/chromedriver/chrome/device_metrics.h" class DevToolsClient; class DevToolsHttpClient; class Status; -struct DeviceMetrics; // Same as ChromeDesktopImpl except that it completely ignores the existence // of the |process| passed into the constructor. This allows running Chrome @@ -23,8 +20,6 @@ std::unique_ptr<DevToolsClient> websocket_client, std::vector<std::unique_ptr<DevToolsEventListener>> devtools_event_listeners, - std::unique_ptr<DeviceMetrics> device_metrics, - SyncWebSocketFactory socket_factory, std::string page_load_strategy, base::Process process, const base::CommandLine& command,
diff --git a/chrome/test/chromedriver/log_replay/replay_http_client.cc b/chrome/test/chromedriver/log_replay/replay_http_client.cc index 3437c48..46718fc 100644 --- a/chrome/test/chromedriver/log_replay/replay_http_client.cc +++ b/chrome/test/chromedriver/log_replay/replay_http_client.cc
@@ -5,6 +5,7 @@ #include <utility> +#include "chrome/test/chromedriver/chrome/device_metrics.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" #include "url/gurl.h" @@ -21,9 +22,17 @@ ReplayHttpClient::ReplayHttpClient( const DevToolsEndpoint& endpoint, network::mojom::URLLoaderFactory* factory, + const SyncWebSocketFactory& socket_factory, + std::unique_ptr<DeviceMetrics> device_metrics, std::unique_ptr<std::set<WebViewInfo::Type>> window_types, + std::string page_load_strategy, const base::FilePath& log_path) - : DevToolsHttpClient(endpoint, factory, std::move(window_types)), + : DevToolsHttpClient(endpoint, + factory, + socket_factory, + std::move(device_metrics), + std::move(window_types), + page_load_strategy), log_reader_(log_path) {} ReplayHttpClient::~ReplayHttpClient() {}
diff --git a/chrome/test/chromedriver/log_replay/replay_http_client.h b/chrome/test/chromedriver/log_replay/replay_http_client.h index 9f114acc..b714f7d9 100644 --- a/chrome/test/chromedriver/log_replay/replay_http_client.h +++ b/chrome/test/chromedriver/log_replay/replay_http_client.h
@@ -29,7 +29,10 @@ // Initializes a DevToolsLogReader with the given log file. ReplayHttpClient(const DevToolsEndpoint& endpoint, network::mojom::URLLoaderFactory* factory, + const SyncWebSocketFactory& socket_factory, + std::unique_ptr<DeviceMetrics> device_metrics, std::unique_ptr<std::set<WebViewInfo::Type>> window_types, + std::string page_load_strategy, const base::FilePath& log_file); ~ReplayHttpClient() override;
diff --git a/chrome/test/data/webui/chromeos/os_feedback_ui/search_page_test.js b/chrome/test/data/webui/chromeos/os_feedback_ui/search_page_test.js index b6e6504..40d2031 100644 --- a/chrome/test/data/webui/chromeos/os_feedback_ui/search_page_test.js +++ b/chrome/test/data/webui/chromeos/os_feedback_ui/search_page_test.js
@@ -101,8 +101,12 @@ await initializePage(); textAreaElement = page.shadowRoot.querySelector('#descriptionText'); assertTrue(!!textAreaElement); - // Verify the textarea is empty. + // Verify the textarea is empty and hint is showing. assertEquals('', textAreaElement.value); + assertEquals( + 'Share your feedback or describe your issue. ' + + 'If possible, include steps to reproduce your issue.', + textAreaElement.placeholder); // Enter three chars. textAreaElement.value = 'abc';
diff --git a/chrome/updater/app/server/win/com_classes_legacy_unittest.cc b/chrome/updater/app/server/win/com_classes_legacy_unittest.cc index 8fe31a79..c9262af 100644 --- a/chrome/updater/app/server/win/com_classes_legacy_unittest.cc +++ b/chrome/updater/app/server/win/com_classes_legacy_unittest.cc
@@ -208,6 +208,13 @@ } } + std::wstring GetCommandLine(int key, const std::wstring& exe_name) { + base::FilePath programfiles_path; + EXPECT_TRUE(base::PathService::Get(key, &programfiles_path)); + return base::CommandLine(programfiles_path.Append(exe_name)) + .GetCommandLineString(); + } + base::CommandLine test_process_command_line_; base::FilePath temp_directory_; }; @@ -228,48 +235,43 @@ absl::nullopt); } -TEST_F(LegacyAppCommandWebImplTest, NoArguments) { - EXPECT_EQ(FormatCommandLine(L"\"C:\\Program Files (x86)\\process.exe\"", {}) - .value(), - L"\"C:\\Program Files (x86)\\process.exe\""); - EXPECT_EQ(FormatCommandLine(L"\"C:\\Program Files (x86)\\process.exe\"", {}) - .value(), - L"\"C:\\Program Files (x86)\\process.exe\""); +TEST_F(LegacyAppCommandWebImplTest, ProgramFilesPaths) { + for (const int key : {base::DIR_PROGRAM_FILES, base::DIR_PROGRAM_FILESX86, + base::DIR_PROGRAM_FILES6432}) { + const std::wstring process_command_line = + GetCommandLine(key, L"process.exe"); + EXPECT_EQ(FormatCommandLine(process_command_line, {}).value(), + process_command_line); + } } TEST_F(LegacyAppCommandWebImplTest, UnformattedParameters) { std::wstring process_name; std::wstring arguments; + const std::wstring process_command_line = + GetCommandLine(base::DIR_PROGRAM_FILES, L"process.exe"); + + EXPECT_EQ(FormatCommandLine(process_command_line + L" abc=1", {}).value(), + process_command_line + L" abc=1"); EXPECT_EQ( - FormatCommandLine(L"\"C:\\Program Files (x86)\\process.exe\" abc=1", {}) - .value(), - L"\"C:\\Program Files (x86)\\process.exe\" abc=1"); - EXPECT_EQ(FormatCommandLine( - L"\"C:\\Program Files (x86)\\process.exe\" abc=1 xyz=2", {}) + FormatCommandLine(process_command_line + L" abc=1 xyz=2", {}).value(), + process_command_line + L" abc=1 xyz=2"); + EXPECT_EQ(FormatCommandLine(process_command_line + L" abc=1 xyz=2 q ", {}) .value(), - L"\"C:\\Program Files (x86)\\process.exe\" abc=1 xyz=2"); + process_command_line + L" abc=1 xyz=2 q"); EXPECT_EQ( - FormatCommandLine( - L"\"C:\\Program Files (x86)\\process.exe\" abc=1 xyz=2 q ", {}) - .value(), - L"\"C:\\Program Files (x86)\\process.exe\" abc=1 xyz=2 q"); - EXPECT_EQ(FormatCommandLine( - L"\"C:\\Program Files (x86)\\process.exe\" \"abc = 1\"", {}) - .value(), - L"\"C:\\Program Files (x86)\\process.exe\" \"abc = 1\""); - EXPECT_EQ(FormatCommandLine( - L"\"C:\\Program Files (x86)\\process.exe\" abc\" = \"1", {}) - .value(), - L"\"C:\\Program Files (x86)\\process.exe\" \"abc = 1\""); + FormatCommandLine(process_command_line + L" \"abc = 1\"", {}).value(), + process_command_line + L" \"abc = 1\""); + EXPECT_EQ( + FormatCommandLine(process_command_line + L" abc\" = \"1", {}).value(), + process_command_line + L" \"abc = 1\""); EXPECT_EQ( - FormatCommandLine(L"\"c:\\Program Files\\process.exe\" \"abc = 1\"", {}) - .value(), - L"\"c:\\Program Files\\process.exe\" \"abc = 1\""); + FormatCommandLine(process_command_line + L" \"abc = 1\"", {}).value(), + process_command_line + L" \"abc = 1\""); EXPECT_EQ( - FormatCommandLine(L"\"c:\\Program Files\\process.exe\" abc\" = \"1", {}) - .value(), - L"\"c:\\Program Files\\process.exe\" \"abc = 1\""); + FormatCommandLine(process_command_line + L" abc\" = \"1", {}).value(), + process_command_line + L" \"abc = 1\""); } TEST_F(LegacyAppCommandWebImplTest, SimpleParameters) { @@ -277,25 +279,26 @@ parameters.push_back(L"p1"); parameters.push_back(L"p2"); parameters.push_back(L"p3"); + const std::wstring process_command_line = + GetCommandLine(base::DIR_PROGRAM_FILES, L"process.exe"); - EXPECT_EQ(FormatCommandLine( - L"\"C:\\Program Files (x86)\\process.exe\" abc=%1", parameters) - .value(), - L"\"C:\\Program Files (x86)\\process.exe\" abc=p1"); - EXPECT_EQ(FormatCommandLine( - L"\"C:\\Program Files (x86)\\process.exe\" abc=%1 %3 %2=x", - parameters) - .value(), - L"\"C:\\Program Files (x86)\\process.exe\" abc=p1 p3 p2=x"); + EXPECT_EQ( + FormatCommandLine(process_command_line + L" abc=%1", parameters).value(), + process_command_line + L" abc=p1"); + EXPECT_EQ( + FormatCommandLine(process_command_line + L" abc=%1 %3 %2=x", parameters) + .value(), + process_command_line + L" abc=p1 p3 p2=x"); - EXPECT_EQ(FormatCommandLine(L"\"C:\\Program Files (x86)\\process.exe\" %4", - parameters), + EXPECT_EQ(FormatCommandLine(process_command_line + L" %4", parameters), absl::nullopt); } TEST_F(LegacyAppCommandWebImplTest, SimpleParametersNoFormatParameters) { EXPECT_EQ( - FormatCommandLine(L"\"C:\\Program Files (x86)\\process.exe\" abc=%1", {}), + FormatCommandLine( + GetCommandLine(base::DIR_PROGRAM_FILES, L"process.exe") + L" abc=%1", + {}), absl::nullopt); } @@ -308,15 +311,15 @@ {L"%%%1", L"%p1"}, {L"abc%%def%%", L"abc%def%"}, {L"%12", L"p12"}, {L"%1%2", L"p1p2"}, }; + const std::wstring process_command_line = + GetCommandLine(base::DIR_PROGRAM_FILES, L"process.exe"); for (const auto& test_case : test_cases) { EXPECT_EQ(FormatCommandLine( - base::StrCat({L"\"C:\\Program Files (x86)\\process.exe\" ", - test_case.input}), + base::StrCat({process_command_line, L" ", test_case.input}), {L"p1", L"p2", L"p3"}) .value(), - base::StrCat({L"\"C:\\Program Files (x86)\\process.exe\" ", - test_case.output})); + base::StrCat({process_command_line, L" ", test_case.output})); } } @@ -330,13 +333,14 @@ L"placeholder %4 is > size of input substitutions", L"%1 is ok, but %8 or %9 is not ok", }; + const std::wstring process_command_line = + GetCommandLine(base::DIR_PROGRAM_FILES, L"process.exe"); for (const wchar_t* test_case : test_cases) { - EXPECT_EQ(FormatCommandLine( - base::StrCat({L"\"C:\\Program Files (x86)\\process.exe\" ", - test_case}), - {L"p1", L"p2", L"p3"}), - absl::nullopt); + EXPECT_EQ( + FormatCommandLine(base::StrCat({process_command_line, L" ", test_case}), + {L"p1", L"p2", L"p3"}), + absl::nullopt); } } @@ -370,15 +374,15 @@ // leading space. {L" abcdef", L"\" abcdef\""}, }; + const std::wstring process_command_line = + GetCommandLine(base::DIR_PROGRAM_FILES, L"process.exe"); for (const auto& test_case : test_cases) { std::wstring command_line = - FormatCommandLine(L"\"C:\\Program Files (x86)\\process.exe\" %1", - {test_case.input}) + FormatCommandLine(process_command_line + L" %1", {test_case.input}) .value(); EXPECT_EQ(command_line, - base::StrCat({L"\"C:\\Program Files (x86)\\process.exe\" ", - test_case.output})); + base::StrCat({process_command_line, L" ", test_case.output})); // The formatted output is now sent through ::CommandLineToArgvW to verify // that it produces the original input.
diff --git a/chromecast/bindings/BUILD.gn b/chromecast/bindings/BUILD.gn index cd898f9..7187c51c 100644 --- a/chromecast/bindings/BUILD.gn +++ b/chromecast/bindings/BUILD.gn
@@ -42,7 +42,7 @@ ] public_deps = [ ":bindings_manager", - "//fuchsia/runners/cast/fidl", + "//fuchsia_web/runners/cast/fidl", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mem", ] deps = [
diff --git a/chromecast/bindings/DEPS b/chromecast/bindings/DEPS index 4ad31ef..956e08a 100644 --- a/chromecast/bindings/DEPS +++ b/chromecast/bindings/DEPS
@@ -13,6 +13,6 @@ specific_include_rules = { "bindings_manager_fuchsia\..*": [ - "+fuchsia/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h", + "+fuchsia_web/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h", ], }
diff --git a/chromecast/bindings/bindings_manager_fuchsia.h b/chromecast/bindings/bindings_manager_fuchsia.h index 926e67f..7e73fd6 100644 --- a/chromecast/bindings/bindings_manager_fuchsia.h +++ b/chromecast/bindings/bindings_manager_fuchsia.h
@@ -12,7 +12,7 @@ #include <string> #include "chromecast/bindings/bindings_manager.h" -#include "fuchsia/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" +#include "fuchsia_web/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" namespace chromecast { namespace bindings {
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 17a87f1..7e58f0a 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -3347,6 +3347,9 @@ <message name="IDS_FEEDBACK_TOOL_FEEDBACK_HELP_LINK_LABEL" translateable="false" desc="The text used for the link that navigates to the feedback help webpage."> Tips on writing feedback </message> + <message name="IDS_FEEDBACK_TOOL_DESCRIPTION_HINT" translateable="false" desc="Label for the hint in description textarea"> + Share your feedback or describe your issue. If possible, include steps to reproduce your issue. + </message> <!-- End of Feedback Tool --> </messages> </release>
diff --git a/chromeos/services/assistant/public/cpp/assistant_prefs.cc b/chromeos/services/assistant/public/cpp/assistant_prefs.cc index 9ddd07d3..b98c555 100644 --- a/chromeos/services/assistant/public/cpp/assistant_prefs.cc +++ b/chromeos/services/assistant/public/cpp/assistant_prefs.cc
@@ -25,6 +25,11 @@ // VoiceInteractionContextEnabled administrator policy. const char kAssistantContextEnabled[] = "settings.voice_interaction.context.enabled"; +// A preference that indicates that the user has already triggered metalayer +// mode while it is deprecated and been shown a toast that the what's on my +// screen feature has been deprecated. +const char kAssistantDeprecateStylusToast[] = + "settings.assistant.deprecate_stylus_toast"; // A preference that indicates the Assistant has been disabled by domain policy. // If true, the Assistant will always been disabled and user cannot enable it. // This preference should only be changed in browser. @@ -64,6 +69,7 @@ registry->RegisterIntegerPref(kAssistantConsentStatus, ConsentStatus::kUnknown); registry->RegisterBooleanPref(kAssistantContextEnabled, false); + registry->RegisterBooleanPref(kAssistantDeprecateStylusToast, false); registry->RegisterBooleanPref(kAssistantDisabledByPolicy, false); registry->RegisterBooleanPref(kAssistantEnabled, false); registry->RegisterBooleanPref(kAssistantHotwordAlwaysOn, false);
diff --git a/chromeos/services/assistant/public/cpp/assistant_prefs.h b/chromeos/services/assistant/public/cpp/assistant_prefs.h index 99f130dd..873250a4 100644 --- a/chromeos/services/assistant/public/cpp/assistant_prefs.h +++ b/chromeos/services/assistant/public/cpp/assistant_prefs.h
@@ -52,6 +52,8 @@ COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) extern const char kAssistantContextEnabled[]; COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) +extern const char kAssistantDeprecateStylusToast[]; +COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) extern const char kAssistantDisabledByPolicy[]; COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) extern const char kAssistantEnabled[];
diff --git a/chromeos/services/libassistant/settings_controller.cc b/chromeos/services/libassistant/settings_controller.cc index 42b91e2b..442b8c1 100644 --- a/chromeos/services/libassistant/settings_controller.cc +++ b/chromeos/services/libassistant/settings_controller.cc
@@ -231,6 +231,7 @@ void SettingsController::SetLocale(const std::string& value) { locale_ = LocaleOrDefault(value); + UpdateLocaleOverride(locale_); UpdateInternalOptions(locale_, spoken_feedback_enabled_, dark_mode_enabled_); UpdateDeviceSettings(locale_, hotword_enabled_); } @@ -298,9 +299,6 @@ if (!assistant_client_) return; - if (locale.has_value()) - assistant_client_->SetLocaleOverride(locale.value()); - if (locale.has_value() && spoken_feedback_enabled.has_value() && dark_mode_enabled.has_value()) { assistant_client_->SetDeviceAttributes(dark_mode_enabled.value()); @@ -309,6 +307,17 @@ } } +void SettingsController::UpdateLocaleOverride( + const absl::optional<std::string>& locale) { + if (!assistant_client_) + return; + + if (!locale.has_value()) + return; + + assistant_client_->SetLocaleOverride(locale.value()); +} + void SettingsController::UpdateDeviceSettings( const absl::optional<std::string>& locale, absl::optional<bool> hotword_enabled) { @@ -329,7 +338,10 @@ // Libassistant to be fully ready. UpdateAuthenticationTokens(authentication_tokens_); UpdateInternalOptions(locale_, spoken_feedback_enabled_, dark_mode_enabled_); - UpdateListeningEnabled(listening_enabled_); + if (!chromeos::assistant::features::IsLibAssistantV2Enabled()) { + UpdateLocaleOverride(locale_); + UpdateListeningEnabled(listening_enabled_); + } } void SettingsController::OnAssistantClientRunning( @@ -338,6 +350,10 @@ std::make_unique<DeviceSettingsUpdater>(this, assistant_client); UpdateDeviceSettings(locale_, hotword_enabled_); + if (chromeos::assistant::features::IsLibAssistantV2Enabled()) { + UpdateLocaleOverride(locale_); + UpdateListeningEnabled(listening_enabled_); + } } void SettingsController::OnDestroyingAssistantClient(
diff --git a/chromeos/services/libassistant/settings_controller.h b/chromeos/services/libassistant/settings_controller.h index f4871241..3c63090 100644 --- a/chromeos/services/libassistant/settings_controller.h +++ b/chromeos/services/libassistant/settings_controller.h
@@ -57,6 +57,7 @@ void UpdateInternalOptions(const absl::optional<std::string>& locale, absl::optional<bool> spoken_feedback_enabled, absl::optional<bool> dark_mode_enabled); + void UpdateLocaleOverride(const absl::optional<std::string>& locale); void UpdateDeviceSettings(const absl::optional<std::string>& locale, absl::optional<bool> hotword_enabled);
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index 05713ac..41504cf 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -289,6 +289,10 @@ "payments/payments_requests/get_details_for_enrollment_request.h", "payments/payments_requests/get_unmask_details_request.cc", "payments/payments_requests/get_unmask_details_request.h", + "payments/payments_requests/get_upload_details_request.cc", + "payments/payments_requests/get_upload_details_request.h", + "payments/payments_requests/migrate_cards_request.cc", + "payments/payments_requests/migrate_cards_request.h", "payments/payments_requests/opt_change_request.cc", "payments/payments_requests/opt_change_request.h", "payments/payments_requests/payments_request.cc", @@ -299,6 +303,8 @@ "payments/payments_requests/unmask_card_request.h", "payments/payments_requests/update_virtual_card_enrollment_request.cc", "payments/payments_requests/update_virtual_card_enrollment_request.h", + "payments/payments_requests/upload_card_request.cc", + "payments/payments_requests/upload_card_request.h", "payments/payments_service_url.cc", "payments/payments_service_url.h", "payments/payments_util.cc",
diff --git a/components/autofill/core/browser/payments/payments_client.cc b/components/autofill/core/browser/payments/payments_client.cc index 892f83ff..aa8c507 100644 --- a/components/autofill/core/browser/payments/payments_client.cc +++ b/components/autofill/core/browser/payments/payments_client.cc
@@ -13,13 +13,9 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/json/json_reader.h" -#include "base/json/json_writer.h" -#include "base/strings/escape.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" -#include "base/strings/string_util.h" #include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "build/build_config.h" #include "components/autofill/core/browser/autofill_experiments.h" @@ -30,14 +26,16 @@ #include "components/autofill/core/browser/payments/local_card_migration_manager.h" #include "components/autofill/core/browser/payments/payments_requests/get_details_for_enrollment_request.h" #include "components/autofill/core/browser/payments/payments_requests/get_unmask_details_request.h" +#include "components/autofill/core/browser/payments/payments_requests/get_upload_details_request.h" +#include "components/autofill/core/browser/payments/payments_requests/migrate_cards_request.h" #include "components/autofill/core/browser/payments/payments_requests/opt_change_request.h" #include "components/autofill/core/browser/payments/payments_requests/payments_request.h" #include "components/autofill/core/browser/payments/payments_requests/select_challenge_option_request.h" #include "components/autofill/core/browser/payments/payments_requests/unmask_card_request.h" #include "components/autofill/core/browser/payments/payments_requests/update_virtual_card_enrollment_request.h" +#include "components/autofill/core/browser/payments/payments_requests/upload_card_request.h" #include "components/autofill/core/browser/payments/payments_service_url.h" #include "components/autofill/core/common/autofill_features.h" -#include "components/autofill/core/common/autofill_payments_features.h" #include "components/signin/public/identity_manager/identity_manager.h" #include "components/signin/public/identity_manager/primary_account_access_token_fetcher.h" #include "components/signin/public/identity_manager/scope_set.h" @@ -54,25 +52,6 @@ namespace { -const char kGetUploadDetailsRequestPath[] = - "payments/apis/chromepaymentsservice/getdetailsforsavecard"; - -const char kUploadCardRequestPath[] = - "payments/apis-secure/chromepaymentsservice/savecard" - "?s7e_suffix=chromewallet"; -const char kUploadCardRequestFormat[] = - "requestContentType=application/json; charset=utf-8&request=%s" - "&s7e_1_pan=%s&s7e_13_cvc=%s"; -const char kUploadCardRequestFormatWithoutCvc[] = - "requestContentType=application/json; charset=utf-8&request=%s" - "&s7e_1_pan=%s"; - -const char kMigrateCardsRequestPath[] = - "payments/apis-secure/chromepaymentsservice/migratecards" - "?s7e_suffix=chromewallet"; -const char kMigrateCardsRequestFormat[] = - "requestContentType=application/json; charset=utf-8&request=%s"; - const char kTokenFetchId[] = "wallet_client"; const char kPaymentsOAuth2Scope[] = "https://www.googleapis.com/auth/wallet.chrome"; @@ -95,587 +74,6 @@ return GetBaseSecureUrl().Resolve(path); } -void SetStringIfNotEmpty(const AutofillDataModel& profile, - const ServerFieldType& type, - const std::string& app_locale, - const std::string& path, - base::Value& dictionary) { - const std::u16string value = profile.GetInfo(AutofillType(type), app_locale); - if (!value.empty()) - dictionary.SetKey(path, base::Value(value)); -} - -void AppendStringIfNotEmpty(const AutofillProfile& profile, - const ServerFieldType& type, - const std::string& app_locale, - base::Value& list) { - const std::u16string value = profile.GetInfo(type, app_locale); - if (!value.empty()) - list.Append(value); -} - -// Returns a dictionary with the structure expected by Payments RPCs, containing -// each of the fields in |profile|, formatted according to |app_locale|. If -// |include_non_location_data| is false, the name and phone number in |profile| -// are not included. -base::Value BuildAddressDictionary(const AutofillProfile& profile, - const std::string& app_locale, - bool include_non_location_data) { - base::Value postal_address(base::Value::Type::DICTIONARY); - - if (include_non_location_data) { - SetStringIfNotEmpty(profile, NAME_FULL, app_locale, - PaymentsClient::kRecipientName, postal_address); - } - - base::Value address_lines(base::Value::Type::LIST); - AppendStringIfNotEmpty(profile, ADDRESS_HOME_LINE1, app_locale, - address_lines); - AppendStringIfNotEmpty(profile, ADDRESS_HOME_LINE2, app_locale, - address_lines); - AppendStringIfNotEmpty(profile, ADDRESS_HOME_LINE3, app_locale, - address_lines); - if (!address_lines.GetListDeprecated().empty()) - postal_address.SetKey("address_line", std::move(address_lines)); - - SetStringIfNotEmpty(profile, ADDRESS_HOME_CITY, app_locale, "locality_name", - postal_address); - SetStringIfNotEmpty(profile, ADDRESS_HOME_STATE, app_locale, - "administrative_area_name", postal_address); - SetStringIfNotEmpty(profile, ADDRESS_HOME_ZIP, app_locale, - "postal_code_number", postal_address); - - // Use GetRawInfo to get a country code instead of the country name: - const std::u16string country_code = profile.GetRawInfo(ADDRESS_HOME_COUNTRY); - if (!country_code.empty()) - postal_address.SetKey("country_name_code", base::Value(country_code)); - - base::Value address(base::Value::Type::DICTIONARY); - address.SetKey("postal_address", std::move(postal_address)); - - if (include_non_location_data) { - SetStringIfNotEmpty(profile, PHONE_HOME_WHOLE_NUMBER, app_locale, - PaymentsClient::kPhoneNumber, address); - } - - return address; -} - -// Returns a dictionary of the credit card with the structure expected by -// Payments RPCs, containing expiration month, expiration year and cardholder -// name (if any) fields in |credit_card|, formatted according to |app_locale|. -// |pan_field_name| is the field name for the encrypted pan. We use each credit -// card's guid as the unique id. -base::Value BuildCreditCardDictionary(const CreditCard& credit_card, - const std::string& app_locale, - const std::string& pan_field_name) { - base::Value card(base::Value::Type::DICTIONARY); - card.SetKey("unique_id", base::Value(credit_card.guid())); - - const std::u16string exp_month = - credit_card.GetInfo(AutofillType(CREDIT_CARD_EXP_MONTH), app_locale); - const std::u16string exp_year = credit_card.GetInfo( - AutofillType(CREDIT_CARD_EXP_4_DIGIT_YEAR), app_locale); - int value = 0; - if (base::StringToInt(exp_month, &value)) - card.SetKey("expiration_month", base::Value(value)); - if (base::StringToInt(exp_year, &value)) - card.SetKey("expiration_year", base::Value(value)); - SetStringIfNotEmpty(credit_card, CREDIT_CARD_NAME_FULL, app_locale, - "cardholder_name", card); - - if (credit_card.HasNonEmptyValidNickname()) - card.SetKey("nickname", base::Value(credit_card.nickname())); - - card.SetKey("encrypted_pan", base::Value("__param:" + pan_field_name)); - return card; -} - -// Populates the list of active experiments that affect either the data sent in -// payments RPCs or whether the RPCs are sent or not. -void SetActiveExperiments(const std::vector<const char*>& active_experiments, - base::Value& request_dict) { - if (active_experiments.empty()) - return; - - base::Value active_chrome_experiments(base::Value::Type::LIST); - for (const char* it : active_experiments) - active_chrome_experiments.Append(it); - - request_dict.SetKey("active_chrome_experiments", - std::move(active_chrome_experiments)); -} - -// TODO(crbug.com/1249665): Move requests to separate files. -class GetUploadDetailsRequest : public PaymentsRequest { - public: - GetUploadDetailsRequest( - const std::vector<AutofillProfile>& addresses, - const int detected_values, - const std::vector<const char*>& active_experiments, - const bool full_sync_enabled, - const std::string& app_locale, - base::OnceCallback<void(AutofillClient::PaymentsRpcResult, - const std::u16string&, - std::unique_ptr<base::Value>, - std::vector<std::pair<int, int>>)> callback, - const int billable_service_number, - const int64_t billing_customer_number, - PaymentsClient::UploadCardSource upload_card_source) - : addresses_(addresses), - detected_values_(detected_values), - active_experiments_(active_experiments), - full_sync_enabled_(full_sync_enabled), - app_locale_(app_locale), - callback_(std::move(callback)), - billable_service_number_(billable_service_number), - upload_card_source_(upload_card_source), - billing_customer_number_(billing_customer_number) {} - - GetUploadDetailsRequest(const GetUploadDetailsRequest&) = delete; - GetUploadDetailsRequest& operator=(const GetUploadDetailsRequest&) = delete; - - ~GetUploadDetailsRequest() override = default; - - std::string GetRequestUrlPath() override { - return kGetUploadDetailsRequestPath; - } - - std::string GetRequestContentType() override { return "application/json"; } - - std::string GetRequestContent() override { - base::Value request_dict(base::Value::Type::DICTIONARY); - base::Value context(base::Value::Type::DICTIONARY); - context.SetKey("language_code", base::Value(app_locale_)); - context.SetKey("billable_service", base::Value(billable_service_number_)); - if (base::FeatureList::IsEnabled( - features::kAutofillEnableSendingBcnInGetUploadDetails) && - billing_customer_number_ != 0) { - context.SetKey("customer_context", - BuildCustomerContextDictionary(billing_customer_number_)); - } - request_dict.SetKey("context", std::move(context)); - - base::Value chrome_user_context(base::Value::Type::DICTIONARY); - chrome_user_context.SetKey("full_sync_enabled", - base::Value(full_sync_enabled_)); - request_dict.SetKey("chrome_user_context", std::move(chrome_user_context)); - - base::Value addresses(base::Value::Type::LIST); - for (const AutofillProfile& profile : addresses_) { - // These addresses are used by Payments to (1) accurately determine the - // user's country in order to show the correct legal documents and (2) to - // verify that the addresses are valid for their purposes so that we don't - // offer save in a case where it would definitely fail (e.g. P.O. boxes if - // min address is not possible). The final parameter directs - // BuildAddressDictionary to omit names and phone numbers, which aren't - // useful for these purposes. - addresses.Append(BuildAddressDictionary(profile, app_locale_, false)); - } - request_dict.SetKey("address", std::move(addresses)); - - // It's possible we may not have found name/address/CVC in the checkout - // flow. The detected_values_ bitmask tells Payments what *was* found, and - // Payments will decide if the provided data is enough to offer upload save. - request_dict.SetKey("detected_values", base::Value(detected_values_)); - - SetActiveExperiments(active_experiments_, request_dict); - - switch (upload_card_source_) { - case PaymentsClient::UploadCardSource::UNKNOWN_UPLOAD_CARD_SOURCE: - request_dict.SetKey("upload_card_source", - base::Value("UNKNOWN_UPLOAD_CARD_SOURCE")); - break; - case PaymentsClient::UploadCardSource::UPSTREAM_CHECKOUT_FLOW: - request_dict.SetKey("upload_card_source", - base::Value("UPSTREAM_CHECKOUT_FLOW")); - break; - case PaymentsClient::UploadCardSource::UPSTREAM_SETTINGS_PAGE: - request_dict.SetKey("upload_card_source", - base::Value("UPSTREAM_SETTINGS_PAGE")); - break; - case PaymentsClient::UploadCardSource::UPSTREAM_CARD_OCR: - request_dict.SetKey("upload_card_source", - base::Value("UPSTREAM_CARD_OCR")); - break; - case PaymentsClient::UploadCardSource::LOCAL_CARD_MIGRATION_CHECKOUT_FLOW: - request_dict.SetKey("upload_card_source", - base::Value("LOCAL_CARD_MIGRATION_CHECKOUT_FLOW")); - break; - case PaymentsClient::UploadCardSource::LOCAL_CARD_MIGRATION_SETTINGS_PAGE: - request_dict.SetKey("upload_card_source", - base::Value("LOCAL_CARD_MIGRATION_SETTINGS_PAGE")); - break; - default: - NOTREACHED(); - } - - std::string request_content; - base::JSONWriter::Write(request_dict, &request_content); - VLOG(3) << "getdetailsforsavecard request body: " << request_content; - return request_content; - } - - void ParseResponse(const base::Value& response) override { - const auto* context_token = response.FindStringKey("context_token"); - context_token_ = - context_token ? base::UTF8ToUTF16(*context_token) : std::u16string(); - - const base::Value* dictionary_value = - response.FindKeyOfType("legal_message", base::Value::Type::DICTIONARY); - if (dictionary_value) - legal_message_ = std::make_unique<base::Value>(dictionary_value->Clone()); - - const auto* supported_card_bin_ranges_string = - response.FindStringKey("supported_card_bin_ranges_string"); - supported_card_bin_ranges_ = ParseSupportedCardBinRangesString( - supported_card_bin_ranges_string ? *supported_card_bin_ranges_string - : base::EmptyString()); - } - - bool IsResponseComplete() override { - return !context_token_.empty() && legal_message_; - } - - void RespondToDelegate(AutofillClient::PaymentsRpcResult result) override { - std::move(callback_).Run(result, context_token_, std::move(legal_message_), - supported_card_bin_ranges_); - } - - private: - // Helper for ParseResponse(). Input format should be :"1234,30000-55555,765", - // where ranges are separated by commas and items separated with a dash means - // the start and ends of the range. Items without a dash have the same start - // and end (ex. 1234-1234) - std::vector<std::pair<int, int>> ParseSupportedCardBinRangesString( - const std::string& supported_card_bin_ranges_string) { - std::vector<std::pair<int, int>> supported_card_bin_ranges; - std::vector<std::string> range_strings = - base::SplitString(supported_card_bin_ranges_string, ",", - base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - - for (std::string& range_string : range_strings) { - std::vector<std::string> range = base::SplitString( - range_string, "-", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - DCHECK(range.size() <= 2); - int start; - base::StringToInt(range[0], &start); - if (range.size() == 1) { - supported_card_bin_ranges.emplace_back(start, start); - } else { - int end; - base::StringToInt(range[1], &end); - DCHECK_LE(start, end); - supported_card_bin_ranges.emplace_back(start, end); - } - } - return supported_card_bin_ranges; - } - - const std::vector<AutofillProfile> addresses_; - const int detected_values_; - const std::vector<const char*> active_experiments_; - const bool full_sync_enabled_; - std::string app_locale_; - base::OnceCallback<void(AutofillClient::PaymentsRpcResult, - const std::u16string&, - std::unique_ptr<base::Value>, - std::vector<std::pair<int, int>>)> - callback_; - std::u16string context_token_; - std::unique_ptr<base::Value> legal_message_; - std::vector<std::pair<int, int>> supported_card_bin_ranges_; - const int billable_service_number_; - PaymentsClient::UploadCardSource upload_card_source_; - const int64_t billing_customer_number_; -}; - -class UploadCardRequest : public PaymentsRequest { - public: - UploadCardRequest( - const PaymentsClient::UploadRequestDetails& request_details, - const bool full_sync_enabled, - base::OnceCallback<void(AutofillClient::PaymentsRpcResult, - const PaymentsClient::UploadCardResponseDetails&)> - callback) - : request_details_(request_details), - full_sync_enabled_(full_sync_enabled), - callback_(std::move(callback)) {} - - UploadCardRequest(const UploadCardRequest&) = delete; - UploadCardRequest& operator=(const UploadCardRequest&) = delete; - - ~UploadCardRequest() override = default; - - std::string GetRequestUrlPath() override { return kUploadCardRequestPath; } - - std::string GetRequestContentType() override { - return "application/x-www-form-urlencoded"; - } - - std::string GetRequestContent() override { - base::Value request_dict(base::Value::Type::DICTIONARY); - request_dict.SetKey("encrypted_pan", base::Value("__param:s7e_1_pan")); - if (!request_details_.cvc.empty()) - request_dict.SetKey("encrypted_cvc", base::Value("__param:s7e_13_cvc")); - request_dict.SetKey("risk_data_encoded", - BuildRiskDictionary(request_details_.risk_data)); - - const std::string& app_locale = request_details_.app_locale; - base::Value context(base::Value::Type::DICTIONARY); - context.SetKey("language_code", base::Value(app_locale)); - context.SetKey("billable_service", - base::Value(kUploadCardBillableServiceNumber)); - if (request_details_.billing_customer_number != 0) { - context.SetKey("customer_context", - BuildCustomerContextDictionary( - request_details_.billing_customer_number)); - } - request_dict.SetKey("context", std::move(context)); - - base::Value chrome_user_context(base::Value::Type::DICTIONARY); - chrome_user_context.SetKey("full_sync_enabled", - base::Value(full_sync_enabled_)); - request_dict.SetKey("chrome_user_context", std::move(chrome_user_context)); - - SetStringIfNotEmpty(request_details_.card, CREDIT_CARD_NAME_FULL, - app_locale, "cardholder_name", request_dict); - - base::Value addresses(base::Value::Type::LIST); - for (const AutofillProfile& profile : request_details_.profiles) { - addresses.Append(BuildAddressDictionary(profile, app_locale, true)); - } - request_dict.SetKey("address", std::move(addresses)); - - request_dict.SetKey("context_token", - base::Value(request_details_.context_token)); - - int value = 0; - const std::u16string exp_month = request_details_.card.GetInfo( - AutofillType(CREDIT_CARD_EXP_MONTH), app_locale); - const std::u16string exp_year = request_details_.card.GetInfo( - AutofillType(CREDIT_CARD_EXP_4_DIGIT_YEAR), app_locale); - if (base::StringToInt(exp_month, &value)) - request_dict.SetKey("expiration_month", base::Value(value)); - if (base::StringToInt(exp_year, &value)) - request_dict.SetKey("expiration_year", base::Value(value)); - - if (request_details_.card.HasNonEmptyValidNickname()) { - request_dict.SetKey("nickname", - base::Value(request_details_.card.nickname())); - } - - SetActiveExperiments(request_details_.active_experiments, request_dict); - - const std::u16string pan = request_details_.card.GetInfo( - AutofillType(CREDIT_CARD_NUMBER), app_locale); - std::string json_request; - base::JSONWriter::Write(request_dict, &json_request); - std::string request_content; - if (request_details_.cvc.empty()) { - request_content = base::StringPrintf( - kUploadCardRequestFormatWithoutCvc, - base::EscapeUrlEncodedData(json_request, true).c_str(), - base::EscapeUrlEncodedData(base::UTF16ToASCII(pan), true).c_str()); - } else { - request_content = base::StringPrintf( - kUploadCardRequestFormat, - base::EscapeUrlEncodedData(json_request, true).c_str(), - base::EscapeUrlEncodedData(base::UTF16ToASCII(pan), true).c_str(), - base::EscapeUrlEncodedData(base::UTF16ToASCII(request_details_.cvc), - true) - .c_str()); - } - VLOG(3) << "savecard request body: " << request_content; - return request_content; - } - - void ParseResponse(const base::Value& response) override { - const std::string* credit_card_id = - response.FindStringKey("credit_card_id"); - upload_card_response_details_.server_id = - credit_card_id ? *credit_card_id : std::string(); - - const std::string* response_instrument_id = - response.FindStringKey("instrument_id"); - if (response_instrument_id) { - int64_t instrument_id; - if (base::StringToInt64(base::StringPiece(*response_instrument_id), - &instrument_id)) { - upload_card_response_details_.instrument_id = instrument_id; - } - } - - const auto* virtual_card_metadata = response.FindKeyOfType( - "virtual_card_metadata", base::Value::Type::DICTIONARY); - if (virtual_card_metadata) { - const std::string* virtual_card_enrollment_status = - virtual_card_metadata->FindStringKey("status"); - if (virtual_card_enrollment_status) { - if (*virtual_card_enrollment_status == "ENROLLED") { - upload_card_response_details_.virtual_card_enrollment_state = - CreditCard::VirtualCardEnrollmentState::ENROLLED; - } else if (*virtual_card_enrollment_status == "ENROLLMENT_ELIGIBLE") { - upload_card_response_details_.virtual_card_enrollment_state = - CreditCard::VirtualCardEnrollmentState::UNENROLLED_AND_ELIGIBLE; - } else { - upload_card_response_details_.virtual_card_enrollment_state = - CreditCard::VirtualCardEnrollmentState:: - UNENROLLED_AND_NOT_ELIGIBLE; - } - } - } - - const std::string* card_art_url = response.FindStringKey("card_art_url"); - upload_card_response_details_.card_art_url = - card_art_url ? GURL(*card_art_url) : GURL(); - } - - bool IsResponseComplete() override { return true; } - - void RespondToDelegate(AutofillClient::PaymentsRpcResult result) override { - std::move(callback_).Run(result, upload_card_response_details_); - } - - private: - const PaymentsClient::UploadRequestDetails request_details_; - const bool full_sync_enabled_; - base::OnceCallback<void(AutofillClient::PaymentsRpcResult, - const PaymentsClient::UploadCardResponseDetails&)> - callback_; - PaymentsClient::UploadCardResponseDetails upload_card_response_details_; -}; - -class MigrateCardsRequest : public PaymentsRequest { - public: - MigrateCardsRequest( - const PaymentsClient::MigrationRequestDetails& request_details, - const std::vector<MigratableCreditCard>& migratable_credit_cards, - const bool full_sync_enabled, - MigrateCardsCallback callback) - : request_details_(request_details), - migratable_credit_cards_(migratable_credit_cards), - full_sync_enabled_(full_sync_enabled), - callback_(std::move(callback)) {} - - MigrateCardsRequest(const MigrateCardsRequest&) = delete; - MigrateCardsRequest& operator=(const MigrateCardsRequest&) = delete; - - ~MigrateCardsRequest() override = default; - - std::string GetRequestUrlPath() override { return kMigrateCardsRequestPath; } - - std::string GetRequestContentType() override { - return "application/x-www-form-urlencoded"; - } - - std::string GetRequestContent() override { - base::Value request_dict(base::Value::Type::DICTIONARY); - - request_dict.SetKey("risk_data_encoded", - BuildRiskDictionary(request_details_.risk_data)); - - const std::string& app_locale = request_details_.app_locale; - base::Value context(base::Value::Type::DICTIONARY); - context.SetKey("language_code", base::Value(app_locale)); - context.SetKey("billable_service", - base::Value(kMigrateCardsBillableServiceNumber)); - if (request_details_.billing_customer_number != 0) { - context.SetKey("customer_context", - BuildCustomerContextDictionary( - request_details_.billing_customer_number)); - } - request_dict.SetKey("context", std::move(context)); - - base::Value chrome_user_context(base::Value::Type::DICTIONARY); - chrome_user_context.SetKey("full_sync_enabled", - base::Value(full_sync_enabled_)); - request_dict.SetKey("chrome_user_context", std::move(chrome_user_context)); - - request_dict.SetKey("context_token", - base::Value(request_details_.context_token)); - - std::string all_pans_data = std::string(); - base::Value migrate_cards(base::Value::Type::LIST); - for (size_t index = 0; index < migratable_credit_cards_.size(); ++index) { - std::string pan_field_name = GetPanFieldName(index); - // Generate credit card dictionary. - migrate_cards.Append(BuildCreditCardDictionary( - migratable_credit_cards_[index].credit_card(), app_locale, - pan_field_name)); - // Append pan data to the |all_pans_data|. - all_pans_data += - GetAppendPan(migratable_credit_cards_[index].credit_card(), - app_locale, pan_field_name); - } - request_dict.SetKey("local_card", std::move(migrate_cards)); - - std::string json_request; - base::JSONWriter::Write(request_dict, &json_request); - std::string request_content = base::StringPrintf( - kMigrateCardsRequestFormat, - base::EscapeUrlEncodedData(json_request, true).c_str()); - request_content += all_pans_data; - return request_content; - } - - void ParseResponse(const base::Value& response) override { - const auto* found_list = - response.FindKeyOfType("save_result", base::Value::Type::LIST); - if (!found_list) - return; - - save_result_ = - std::make_unique<std::unordered_map<std::string, std::string>>(); - for (const base::Value& result : found_list->GetListDeprecated()) { - if (result.is_dict()) { - const std::string* unique_id = result.FindStringKey("unique_id"); - const std::string* status = result.FindStringKey("status"); - save_result_->insert( - std::make_pair(unique_id ? *unique_id : std::string(), - status ? *status : std::string())); - } - } - - const std::string* display_text = - response.FindStringKey("value_prop_display_text"); - display_text_ = display_text ? *display_text : std::string(); - } - - bool IsResponseComplete() override { - return !display_text_.empty() && save_result_; - } - - void RespondToDelegate(AutofillClient::PaymentsRpcResult result) override { - std::move(callback_).Run(result, std::move(save_result_), display_text_); - } - - private: - // Return the pan field name for the encrypted pan based on the |index|. - std::string GetPanFieldName(const size_t& index) { - return "s7e_1_pan" + std::to_string(index); - } - - // Return the formatted pan to append to the end of the request. - std::string GetAppendPan(const CreditCard& credit_card, - const std::string& app_locale, - const std::string& pan_field_name) { - const std::u16string pan = - credit_card.GetInfo(AutofillType(CREDIT_CARD_NUMBER), app_locale); - std::string pan_str = - base::EscapeUrlEncodedData(base::UTF16ToASCII(pan), true).c_str(); - std::string append_pan = "&" + pan_field_name + "=" + pan_str; - return append_pan; - } - - const PaymentsClient::MigrationRequestDetails request_details_; - const std::vector<MigratableCreditCard>& migratable_credit_cards_; - const bool full_sync_enabled_; - MigrateCardsCallback callback_; - std::unique_ptr<std::unordered_map<std::string, std::string>> save_result_; - std::string display_text_; -}; - } // namespace const char PaymentsClient::kRecipientName[] = "recipient_name";
diff --git a/components/autofill/core/browser/payments/payments_requests/get_upload_details_request.cc b/components/autofill/core/browser/payments/payments_requests/get_upload_details_request.cc new file mode 100644 index 0000000..99c0651 --- /dev/null +++ b/components/autofill/core/browser/payments/payments_requests/get_upload_details_request.cc
@@ -0,0 +1,179 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill/core/browser/payments/payments_requests/get_upload_details_request.h" + +#include <string> + +#include "base/json/json_writer.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" + +namespace autofill::payments { + +namespace { +const char kGetUploadDetailsRequestPath[] = + "payments/apis/chromepaymentsservice/getdetailsforsavecard"; +} // namespace + +GetUploadDetailsRequest::GetUploadDetailsRequest( + const std::vector<AutofillProfile>& addresses, + const int detected_values, + const std::vector<const char*>& active_experiments, + const bool full_sync_enabled, + const std::string& app_locale, + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const std::u16string&, + std::unique_ptr<base::Value>, + std::vector<std::pair<int, int>>)> callback, + const int billable_service_number, + const int64_t billing_customer_number, + PaymentsClient::UploadCardSource upload_card_source) + : addresses_(addresses), + detected_values_(detected_values), + active_experiments_(active_experiments), + full_sync_enabled_(full_sync_enabled), + app_locale_(app_locale), + callback_(std::move(callback)), + billable_service_number_(billable_service_number), + upload_card_source_(upload_card_source), + billing_customer_number_(billing_customer_number) {} + +GetUploadDetailsRequest::~GetUploadDetailsRequest() = default; + +std::string GetUploadDetailsRequest::GetRequestUrlPath() { + return kGetUploadDetailsRequestPath; +} + +std::string GetUploadDetailsRequest::GetRequestContentType() { + return "application/json"; +} + +std::string GetUploadDetailsRequest::GetRequestContent() { + base::Value request_dict(base::Value::Type::DICTIONARY); + base::Value context(base::Value::Type::DICTIONARY); + context.SetKey("language_code", base::Value(app_locale_)); + context.SetKey("billable_service", base::Value(billable_service_number_)); + if (base::FeatureList::IsEnabled( + features::kAutofillEnableSendingBcnInGetUploadDetails) && + billing_customer_number_ != 0) { + context.SetKey("customer_context", + BuildCustomerContextDictionary(billing_customer_number_)); + } + request_dict.SetKey("context", std::move(context)); + + base::Value chrome_user_context(base::Value::Type::DICTIONARY); + chrome_user_context.SetKey("full_sync_enabled", + base::Value(full_sync_enabled_)); + request_dict.SetKey("chrome_user_context", std::move(chrome_user_context)); + + base::Value addresses(base::Value::Type::LIST); + for (const AutofillProfile& profile : addresses_) { + // These addresses are used by Payments to (1) accurately determine the + // user's country in order to show the correct legal documents and (2) to + // verify that the addresses are valid for their purposes so that we don't + // offer save in a case where it would definitely fail (e.g. P.O. boxes if + // min address is not possible). The final parameter directs + // BuildAddressDictionary to omit names and phone numbers, which aren't + // useful for these purposes. + addresses.Append(BuildAddressDictionary(profile, app_locale_, false)); + } + request_dict.SetKey("address", std::move(addresses)); + + // It's possible we may not have found name/address/CVC in the checkout + // flow. The detected_values_ bitmask tells Payments what *was* found, and + // Payments will decide if the provided data is enough to offer upload save. + request_dict.SetKey("detected_values", base::Value(detected_values_)); + + SetActiveExperiments(active_experiments_, request_dict); + + switch (upload_card_source_) { + case PaymentsClient::UploadCardSource::UNKNOWN_UPLOAD_CARD_SOURCE: + request_dict.SetKey("upload_card_source", + base::Value("UNKNOWN_UPLOAD_CARD_SOURCE")); + break; + case PaymentsClient::UploadCardSource::UPSTREAM_CHECKOUT_FLOW: + request_dict.SetKey("upload_card_source", + base::Value("UPSTREAM_CHECKOUT_FLOW")); + break; + case PaymentsClient::UploadCardSource::UPSTREAM_SETTINGS_PAGE: + request_dict.SetKey("upload_card_source", + base::Value("UPSTREAM_SETTINGS_PAGE")); + break; + case PaymentsClient::UploadCardSource::UPSTREAM_CARD_OCR: + request_dict.SetKey("upload_card_source", + base::Value("UPSTREAM_CARD_OCR")); + break; + case PaymentsClient::UploadCardSource::LOCAL_CARD_MIGRATION_CHECKOUT_FLOW: + request_dict.SetKey("upload_card_source", + base::Value("LOCAL_CARD_MIGRATION_CHECKOUT_FLOW")); + break; + case PaymentsClient::UploadCardSource::LOCAL_CARD_MIGRATION_SETTINGS_PAGE: + request_dict.SetKey("upload_card_source", + base::Value("LOCAL_CARD_MIGRATION_SETTINGS_PAGE")); + break; + default: + NOTREACHED(); + } + + std::string request_content; + base::JSONWriter::Write(request_dict, &request_content); + VLOG(3) << "getdetailsforsavecard request body: " << request_content; + return request_content; +} + +void GetUploadDetailsRequest::ParseResponse(const base::Value& response) { + const auto* context_token = response.FindStringKey("context_token"); + context_token_ = + context_token ? base::UTF8ToUTF16(*context_token) : std::u16string(); + + const base::Value* dictionary_value = + response.FindKeyOfType("legal_message", base::Value::Type::DICTIONARY); + if (dictionary_value) + legal_message_ = std::make_unique<base::Value>(dictionary_value->Clone()); + + const auto* supported_card_bin_ranges_string = + response.FindStringKey("supported_card_bin_ranges_string"); + supported_card_bin_ranges_ = ParseSupportedCardBinRangesString( + supported_card_bin_ranges_string ? *supported_card_bin_ranges_string + : base::EmptyString()); +} + +bool GetUploadDetailsRequest::IsResponseComplete() { + return !context_token_.empty() && legal_message_; +} + +void GetUploadDetailsRequest::RespondToDelegate( + AutofillClient::PaymentsRpcResult result) { + std::move(callback_).Run(result, context_token_, std::move(legal_message_), + supported_card_bin_ranges_); +} + +std::vector<std::pair<int, int>> +GetUploadDetailsRequest::ParseSupportedCardBinRangesString( + const std::string& supported_card_bin_ranges_string) { + std::vector<std::pair<int, int>> supported_card_bin_ranges; + std::vector<std::string> range_strings = + base::SplitString(supported_card_bin_ranges_string, ",", + base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + + for (std::string& range_string : range_strings) { + std::vector<std::string> range = base::SplitString( + range_string, "-", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + DCHECK(range.size() <= 2); + int start; + base::StringToInt(range[0], &start); + if (range.size() == 1) { + supported_card_bin_ranges.emplace_back(start, start); + } else { + int end; + base::StringToInt(range[1], &end); + DCHECK_LE(start, end); + supported_card_bin_ranges.emplace_back(start, end); + } + } + return supported_card_bin_ranges; +} + +} // namespace autofill::payments
diff --git a/components/autofill/core/browser/payments/payments_requests/get_upload_details_request.h b/components/autofill/core/browser/payments/payments_requests/get_upload_details_request.h new file mode 100644 index 0000000..673728df --- /dev/null +++ b/components/autofill/core/browser/payments/payments_requests/get_upload_details_request.h
@@ -0,0 +1,76 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_REQUESTS_GET_UPLOAD_DETAILS_REQUEST_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_REQUESTS_GET_UPLOAD_DETAILS_REQUEST_H_ + +#include <string> + +#include "base/callback.h" +#include "components/autofill/core/browser/autofill_client.h" +#include "components/autofill/core/browser/payments/payments_client.h" +#include "components/autofill/core/browser/payments/payments_requests/payments_request.h" + +namespace base { +class Value; +} // namespace base + +namespace autofill::payments { + +class GetUploadDetailsRequest : public PaymentsRequest { + public: + GetUploadDetailsRequest( + const std::vector<AutofillProfile>& addresses, + const int detected_values, + const std::vector<const char*>& active_experiments, + const bool full_sync_enabled, + const std::string& app_locale, + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const std::u16string&, + std::unique_ptr<base::Value>, + std::vector<std::pair<int, int>>)> callback, + const int billable_service_number, + const int64_t billing_customer_number, + PaymentsClient::UploadCardSource upload_card_source); + GetUploadDetailsRequest(const GetUploadDetailsRequest&) = delete; + GetUploadDetailsRequest& operator=(const GetUploadDetailsRequest&) = delete; + ~GetUploadDetailsRequest() override; + + // PaymentsRequest: + std::string GetRequestUrlPath() override; + std::string GetRequestContentType() override; + std::string GetRequestContent() override; + void ParseResponse(const base::Value& response) override; + bool IsResponseComplete() override; + void RespondToDelegate(AutofillClient::PaymentsRpcResult result) override; + + private: + // Helper for ParseResponse(). Input format should be :"1234,30000-55555,765", + // where ranges are separated by commas and items separated with a dash means + // the start and ends of the range. Items without a dash have the same start + // and end (ex. 1234-1234) + std::vector<std::pair<int, int>> ParseSupportedCardBinRangesString( + const std::string& supported_card_bin_ranges_string); + + const std::vector<AutofillProfile> addresses_; + const int detected_values_; + const std::vector<const char*> active_experiments_; + const bool full_sync_enabled_; + std::string app_locale_; + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const std::u16string&, + std::unique_ptr<base::Value>, + std::vector<std::pair<int, int>>)> + callback_; + std::u16string context_token_; + std::unique_ptr<base::Value> legal_message_; + std::vector<std::pair<int, int>> supported_card_bin_ranges_; + const int billable_service_number_; + PaymentsClient::UploadCardSource upload_card_source_; + const int64_t billing_customer_number_; +}; + +} // namespace autofill::payments + +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_REQUESTS_GET_UPLOAD_DETAILS_REQUEST_H_
diff --git a/components/autofill/core/browser/payments/payments_requests/migrate_cards_request.cc b/components/autofill/core/browser/payments/payments_requests/migrate_cards_request.cc new file mode 100644 index 0000000..f1365c48 --- /dev/null +++ b/components/autofill/core/browser/payments/payments_requests/migrate_cards_request.cc
@@ -0,0 +1,141 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill/core/browser/payments/payments_requests/migrate_cards_request.h" + +#include <string> + +#include "base/json/json_writer.h" +#include "base/strings/escape.h" +#include "base/strings/utf_string_conversions.h" +#include "components/autofill/core/browser/payments/local_card_migration_manager.h" + +namespace autofill::payments { + +namespace { +const char kMigrateCardsRequestPath[] = + "payments/apis-secure/chromepaymentsservice/migratecards" + "?s7e_suffix=chromewallet"; +const char kMigrateCardsRequestFormat[] = + "requestContentType=application/json; charset=utf-8&request=%s"; +} // namespace + +MigrateCardsRequest::MigrateCardsRequest( + const PaymentsClient::MigrationRequestDetails& request_details, + const std::vector<MigratableCreditCard>& migratable_credit_cards, + const bool full_sync_enabled, + MigrateCardsCallback callback) + : request_details_(request_details), + migratable_credit_cards_(migratable_credit_cards), + full_sync_enabled_(full_sync_enabled), + callback_(std::move(callback)) {} + +MigrateCardsRequest::~MigrateCardsRequest() = default; + +std::string MigrateCardsRequest::GetRequestUrlPath() { + return kMigrateCardsRequestPath; +} + +std::string MigrateCardsRequest::GetRequestContentType() { + return "application/x-www-form-urlencoded"; +} + +std::string MigrateCardsRequest::GetRequestContent() { + base::Value request_dict(base::Value::Type::DICTIONARY); + + request_dict.SetKey("risk_data_encoded", + BuildRiskDictionary(request_details_.risk_data)); + + const std::string& app_locale = request_details_.app_locale; + base::Value context(base::Value::Type::DICTIONARY); + context.SetKey("language_code", base::Value(app_locale)); + context.SetKey("billable_service", + base::Value(kMigrateCardsBillableServiceNumber)); + if (request_details_.billing_customer_number != 0) { + context.SetKey("customer_context", + BuildCustomerContextDictionary( + request_details_.billing_customer_number)); + } + request_dict.SetKey("context", std::move(context)); + + base::Value chrome_user_context(base::Value::Type::DICTIONARY); + chrome_user_context.SetKey("full_sync_enabled", + base::Value(full_sync_enabled_)); + request_dict.SetKey("chrome_user_context", std::move(chrome_user_context)); + + request_dict.SetKey("context_token", + base::Value(request_details_.context_token)); + + std::string all_pans_data = std::string(); + base::Value migrate_cards(base::Value::Type::LIST); + for (size_t index = 0; index < migratable_credit_cards_.size(); ++index) { + std::string pan_field_name = GetPanFieldName(index); + // Generate credit card dictionary. + migrate_cards.Append( + BuildCreditCardDictionary(migratable_credit_cards_[index].credit_card(), + app_locale, pan_field_name)); + // Append pan data to the |all_pans_data|. + all_pans_data += GetAppendPan(migratable_credit_cards_[index].credit_card(), + app_locale, pan_field_name); + } + request_dict.SetKey("local_card", std::move(migrate_cards)); + + std::string json_request; + base::JSONWriter::Write(request_dict, &json_request); + std::string request_content = base::StringPrintf( + kMigrateCardsRequestFormat, + base::EscapeUrlEncodedData(json_request, true).c_str()); + request_content += all_pans_data; + return request_content; +} + +void MigrateCardsRequest::ParseResponse(const base::Value& response) { + const auto* found_list = + response.FindKeyOfType("save_result", base::Value::Type::LIST); + if (!found_list) + return; + + save_result_ = + std::make_unique<std::unordered_map<std::string, std::string>>(); + for (const base::Value& result : found_list->GetListDeprecated()) { + if (result.is_dict()) { + const std::string* unique_id = result.FindStringKey("unique_id"); + const std::string* status = result.FindStringKey("status"); + save_result_->insert( + std::make_pair(unique_id ? *unique_id : std::string(), + status ? *status : std::string())); + } + } + + const std::string* display_text = + response.FindStringKey("value_prop_display_text"); + display_text_ = display_text ? *display_text : std::string(); +} + +bool MigrateCardsRequest::IsResponseComplete() { + return !display_text_.empty() && save_result_; +} + +void MigrateCardsRequest::RespondToDelegate( + AutofillClient::PaymentsRpcResult result) { + std::move(callback_).Run(result, std::move(save_result_), display_text_); +} + +std::string MigrateCardsRequest::GetPanFieldName(const size_t& index) { + return "s7e_1_pan" + base::NumberToString(index); +} + +std::string MigrateCardsRequest::GetAppendPan( + const CreditCard& credit_card, + const std::string& app_locale, + const std::string& pan_field_name) { + const std::u16string pan = + credit_card.GetInfo(AutofillType(CREDIT_CARD_NUMBER), app_locale); + std::string pan_str = + base::EscapeUrlEncodedData(base::UTF16ToASCII(pan), true).c_str(); + std::string append_pan = "&" + pan_field_name + "=" + pan_str; + return append_pan; +} + +} // namespace autofill::payments
diff --git a/components/autofill/core/browser/payments/payments_requests/migrate_cards_request.h b/components/autofill/core/browser/payments/payments_requests/migrate_cards_request.h new file mode 100644 index 0000000..6784422 --- /dev/null +++ b/components/autofill/core/browser/payments/payments_requests/migrate_cards_request.h
@@ -0,0 +1,59 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_REQUESTS_MIGRATE_CARDS_REQUEST_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_REQUESTS_MIGRATE_CARDS_REQUEST_H_ + +#include <string> + +#include "base/callback.h" +#include "components/autofill/core/browser/autofill_client.h" +#include "components/autofill/core/browser/payments/payments_client.h" +#include "components/autofill/core/browser/payments/payments_requests/payments_request.h" + +namespace base { +class Value; +} // namespace base + +namespace autofill::payments { + +class MigrateCardsRequest : public PaymentsRequest { + public: + MigrateCardsRequest( + const PaymentsClient::MigrationRequestDetails& request_details, + const std::vector<MigratableCreditCard>& migratable_credit_cards, + const bool full_sync_enabled, + MigrateCardsCallback callback); + MigrateCardsRequest(const MigrateCardsRequest&) = delete; + MigrateCardsRequest& operator=(const MigrateCardsRequest&) = delete; + ~MigrateCardsRequest() override; + + // PaymentsRequest: + std::string GetRequestUrlPath() override; + std::string GetRequestContentType() override; + std::string GetRequestContent() override; + void ParseResponse(const base::Value& response) override; + bool IsResponseComplete() override; + void RespondToDelegate(AutofillClient::PaymentsRpcResult result) override; + + private: + // Return the pan field name for the encrypted pan based on the |index|. + std::string GetPanFieldName(const size_t& index); + + // Return the formatted pan to append to the end of the request. + std::string GetAppendPan(const CreditCard& credit_card, + const std::string& app_locale, + const std::string& pan_field_name); + + const PaymentsClient::MigrationRequestDetails request_details_; + const std::vector<MigratableCreditCard>& migratable_credit_cards_; + const bool full_sync_enabled_; + MigrateCardsCallback callback_; + std::unique_ptr<std::unordered_map<std::string, std::string>> save_result_; + std::string display_text_; +}; + +} // namespace autofill::payments + +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_REQUESTS_MIGRATE_CARDS_REQUEST_H_
diff --git a/components/autofill/core/browser/payments/payments_requests/payments_request.cc b/components/autofill/core/browser/payments/payments_requests/payments_request.cc index 0de08f93..b6c85788 100644 --- a/components/autofill/core/browser/payments/payments_requests/payments_request.cc +++ b/components/autofill/core/browser/payments/payments_requests/payments_request.cc
@@ -7,9 +7,9 @@ #include "base/strings/string_number_conversions.h" #include "base/values.h" #include "build/build_config.h" +#include "components/autofill/core/browser/payments/payments_client.h" -namespace autofill { -namespace payments { +namespace autofill::payments { PaymentsRequest::~PaymentsRequest() = default; @@ -41,5 +41,107 @@ return customer_context; } -} // namespace payments -} // namespace autofill +void PaymentsRequest::SetActiveExperiments( + const std::vector<const char*>& active_experiments, + base::Value& request_dict) { + if (active_experiments.empty()) + return; + + base::Value active_chrome_experiments(base::Value::Type::LIST); + for (const char* it : active_experiments) + active_chrome_experiments.Append(it); + + request_dict.SetKey("active_chrome_experiments", + std::move(active_chrome_experiments)); +} + +base::Value PaymentsRequest::BuildAddressDictionary( + const AutofillProfile& profile, + const std::string& app_locale, + bool include_non_location_data) { + base::Value postal_address(base::Value::Type::DICTIONARY); + + if (include_non_location_data) { + SetStringIfNotEmpty(profile, NAME_FULL, app_locale, + PaymentsClient::kRecipientName, postal_address); + } + + base::Value address_lines(base::Value::Type::LIST); + AppendStringIfNotEmpty(profile, ADDRESS_HOME_LINE1, app_locale, + address_lines); + AppendStringIfNotEmpty(profile, ADDRESS_HOME_LINE2, app_locale, + address_lines); + AppendStringIfNotEmpty(profile, ADDRESS_HOME_LINE3, app_locale, + address_lines); + if (!address_lines.GetListDeprecated().empty()) + postal_address.SetKey("address_line", std::move(address_lines)); + + SetStringIfNotEmpty(profile, ADDRESS_HOME_CITY, app_locale, "locality_name", + postal_address); + SetStringIfNotEmpty(profile, ADDRESS_HOME_STATE, app_locale, + "administrative_area_name", postal_address); + SetStringIfNotEmpty(profile, ADDRESS_HOME_ZIP, app_locale, + "postal_code_number", postal_address); + + // Use GetRawInfo to get a country code instead of the country name: + const std::u16string country_code = profile.GetRawInfo(ADDRESS_HOME_COUNTRY); + if (!country_code.empty()) + postal_address.SetKey("country_name_code", base::Value(country_code)); + + base::Value address(base::Value::Type::DICTIONARY); + address.SetKey("postal_address", std::move(postal_address)); + + if (include_non_location_data) { + SetStringIfNotEmpty(profile, PHONE_HOME_WHOLE_NUMBER, app_locale, + PaymentsClient::kPhoneNumber, address); + } + + return address; +} + +base::Value PaymentsRequest::BuildCreditCardDictionary( + const CreditCard& credit_card, + const std::string& app_locale, + const std::string& pan_field_name) { + base::Value card(base::Value::Type::DICTIONARY); + card.SetKey("unique_id", base::Value(credit_card.guid())); + + const std::u16string exp_month = + credit_card.GetInfo(AutofillType(CREDIT_CARD_EXP_MONTH), app_locale); + const std::u16string exp_year = credit_card.GetInfo( + AutofillType(CREDIT_CARD_EXP_4_DIGIT_YEAR), app_locale); + int value = 0; + if (base::StringToInt(exp_month, &value)) + card.SetKey("expiration_month", base::Value(value)); + if (base::StringToInt(exp_year, &value)) + card.SetKey("expiration_year", base::Value(value)); + SetStringIfNotEmpty(credit_card, CREDIT_CARD_NAME_FULL, app_locale, + "cardholder_name", card); + + if (credit_card.HasNonEmptyValidNickname()) + card.SetKey("nickname", base::Value(credit_card.nickname())); + + card.SetKey("encrypted_pan", base::Value("__param:" + pan_field_name)); + return card; +} + +void PaymentsRequest::AppendStringIfNotEmpty(const AutofillProfile& profile, + const ServerFieldType& type, + const std::string& app_locale, + base::Value& list) { + const std::u16string value = profile.GetInfo(type, app_locale); + if (!value.empty()) + list.Append(value); +} + +void PaymentsRequest::SetStringIfNotEmpty(const AutofillDataModel& profile, + const ServerFieldType& type, + const std::string& app_locale, + const std::string& path, + base::Value& dictionary) { + const std::u16string value = profile.GetInfo(AutofillType(type), app_locale); + if (!value.empty()) + dictionary.SetKey(path, base::Value(value)); +} + +} // namespace autofill::payments
diff --git a/components/autofill/core/browser/payments/payments_requests/payments_request.h b/components/autofill/core/browser/payments/payments_requests/payments_request.h index be88bca..dd2f017 100644 --- a/components/autofill/core/browser/payments/payments_requests/payments_request.h +++ b/components/autofill/core/browser/payments/payments_requests/payments_request.h
@@ -8,13 +8,15 @@ #include <string> #include "components/autofill/core/browser/autofill_client.h" +#include "components/autofill/core/browser/data_model/autofill_profile.h" +#include "components/autofill/core/browser/data_model/credit_card.h" +#include "components/autofill/core/common/autofill_payments_features.h" namespace base { class Value; } -namespace autofill { -namespace payments { +namespace autofill::payments { // Shared class for the various Payments request types. class PaymentsRequest { @@ -47,9 +49,42 @@ // Shared helper function to build the customer context sent in the request. base::Value BuildCustomerContextDictionary(int64_t external_customer_id); + + // Shared helper function that populates the list of active experiments that + // affect either the data sent in payments RPCs or whether the RPCs are sent + // or not. + void SetActiveExperiments(const std::vector<const char*>& active_experiments, + base::Value& request_dict); + + // Shared helper functoin that returns a dictionary with the structure + // expected by Payments RPCs, containing each of the fields in |profile|, + // formatted according to |app_locale|. If |include_non_location_data| is + // false, the name and phone number in |profile| are not included. + base::Value BuildAddressDictionary(const AutofillProfile& profile, + const std::string& app_locale, + bool include_non_location_data); + + // Shared helper function that returns a dictionary of the credit card with + // the structure expected by Payments RPCs, containing expiration month, + // expiration year and cardholder name (if any) fields in |credit_card|, + // formatted according to |app_locale|. |pan_field_name| is the field name for + // the encrypted pan. We use each credit card's guid as the unique id. + base::Value BuildCreditCardDictionary(const CreditCard& credit_card, + const std::string& app_locale, + const std::string& pan_field_name); + + // Shared helper functions for string operations. + void AppendStringIfNotEmpty(const AutofillProfile& profile, + const ServerFieldType& type, + const std::string& app_locale, + base::Value& list); + void SetStringIfNotEmpty(const AutofillDataModel& profile, + const ServerFieldType& type, + const std::string& app_locale, + const std::string& path, + base::Value& dictionary); }; -} // namespace payments -} // namespace autofill +} // namespace autofill::payments #endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_REQUESTS_PAYMENTS_REQUEST_H_
diff --git a/components/autofill/core/browser/payments/payments_requests/upload_card_request.cc b/components/autofill/core/browser/payments/payments_requests/upload_card_request.cc new file mode 100644 index 0000000..dfe4928 --- /dev/null +++ b/components/autofill/core/browser/payments/payments_requests/upload_card_request.cc
@@ -0,0 +1,172 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill/core/browser/payments/payments_requests/upload_card_request.h" + +#include <string> + +#include "base/json/json_writer.h" +#include "base/strings/escape.h" +#include "base/strings/utf_string_conversions.h" + +namespace autofill::payments { + +namespace { +const char kUploadCardRequestPath[] = + "payments/apis-secure/chromepaymentsservice/savecard" + "?s7e_suffix=chromewallet"; +const char kUploadCardRequestFormat[] = + "requestContentType=application/json; charset=utf-8&request=%s" + "&s7e_1_pan=%s&s7e_13_cvc=%s"; +const char kUploadCardRequestFormatWithoutCvc[] = + "requestContentType=application/json; charset=utf-8&request=%s" + "&s7e_1_pan=%s"; +} // namespace + +UploadCardRequest::UploadCardRequest( + const PaymentsClient::UploadRequestDetails& request_details, + const bool full_sync_enabled, + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const PaymentsClient::UploadCardResponseDetails&)> + callback) + : request_details_(request_details), + full_sync_enabled_(full_sync_enabled), + callback_(std::move(callback)) {} + +UploadCardRequest::~UploadCardRequest() = default; + +std::string UploadCardRequest::GetRequestUrlPath() { + return kUploadCardRequestPath; +} + +std::string UploadCardRequest::GetRequestContentType() { + return "application/x-www-form-urlencoded"; +} + +std::string UploadCardRequest::GetRequestContent() { + base::Value request_dict(base::Value::Type::DICTIONARY); + request_dict.SetKey("encrypted_pan", base::Value("__param:s7e_1_pan")); + if (!request_details_.cvc.empty()) + request_dict.SetKey("encrypted_cvc", base::Value("__param:s7e_13_cvc")); + request_dict.SetKey("risk_data_encoded", + BuildRiskDictionary(request_details_.risk_data)); + + const std::string& app_locale = request_details_.app_locale; + base::Value context(base::Value::Type::DICTIONARY); + context.SetKey("language_code", base::Value(app_locale)); + context.SetKey("billable_service", + base::Value(kUploadCardBillableServiceNumber)); + if (request_details_.billing_customer_number != 0) { + context.SetKey("customer_context", + BuildCustomerContextDictionary( + request_details_.billing_customer_number)); + } + request_dict.SetKey("context", std::move(context)); + + base::Value chrome_user_context(base::Value::Type::DICTIONARY); + chrome_user_context.SetKey("full_sync_enabled", + base::Value(full_sync_enabled_)); + request_dict.SetKey("chrome_user_context", std::move(chrome_user_context)); + + SetStringIfNotEmpty(request_details_.card, CREDIT_CARD_NAME_FULL, app_locale, + "cardholder_name", request_dict); + + base::Value addresses(base::Value::Type::LIST); + for (const AutofillProfile& profile : request_details_.profiles) { + addresses.Append(BuildAddressDictionary(profile, app_locale, true)); + } + request_dict.SetKey("address", std::move(addresses)); + + request_dict.SetKey("context_token", + base::Value(request_details_.context_token)); + + int value = 0; + const std::u16string exp_month = request_details_.card.GetInfo( + AutofillType(CREDIT_CARD_EXP_MONTH), app_locale); + const std::u16string exp_year = request_details_.card.GetInfo( + AutofillType(CREDIT_CARD_EXP_4_DIGIT_YEAR), app_locale); + if (base::StringToInt(exp_month, &value)) + request_dict.SetKey("expiration_month", base::Value(value)); + if (base::StringToInt(exp_year, &value)) + request_dict.SetKey("expiration_year", base::Value(value)); + + if (request_details_.card.HasNonEmptyValidNickname()) { + request_dict.SetKey("nickname", + base::Value(request_details_.card.nickname())); + } + + SetActiveExperiments(request_details_.active_experiments, request_dict); + + const std::u16string pan = request_details_.card.GetInfo( + AutofillType(CREDIT_CARD_NUMBER), app_locale); + std::string json_request; + base::JSONWriter::Write(request_dict, &json_request); + std::string request_content; + if (request_details_.cvc.empty()) { + request_content = base::StringPrintf( + kUploadCardRequestFormatWithoutCvc, + base::EscapeUrlEncodedData(json_request, true).c_str(), + base::EscapeUrlEncodedData(base::UTF16ToASCII(pan), true).c_str()); + } else { + request_content = base::StringPrintf( + kUploadCardRequestFormat, + base::EscapeUrlEncodedData(json_request, true).c_str(), + base::EscapeUrlEncodedData(base::UTF16ToASCII(pan), true).c_str(), + base::EscapeUrlEncodedData(base::UTF16ToASCII(request_details_.cvc), + true) + .c_str()); + } + VLOG(3) << "savecard request body: " << request_content; + return request_content; +} + +void UploadCardRequest::ParseResponse(const base::Value& response) { + const std::string* credit_card_id = response.FindStringKey("credit_card_id"); + upload_card_response_details_.server_id = + credit_card_id ? *credit_card_id : std::string(); + + const std::string* response_instrument_id = + response.FindStringKey("instrument_id"); + if (response_instrument_id) { + int64_t instrument_id; + if (base::StringToInt64(base::StringPiece(*response_instrument_id), + &instrument_id)) { + upload_card_response_details_.instrument_id = instrument_id; + } + } + + const auto* virtual_card_metadata = response.FindKeyOfType( + "virtual_card_metadata", base::Value::Type::DICTIONARY); + if (virtual_card_metadata) { + const std::string* virtual_card_enrollment_status = + virtual_card_metadata->FindStringKey("status"); + if (virtual_card_enrollment_status) { + if (*virtual_card_enrollment_status == "ENROLLED") { + upload_card_response_details_.virtual_card_enrollment_state = + CreditCard::VirtualCardEnrollmentState::ENROLLED; + } else if (*virtual_card_enrollment_status == "ENROLLMENT_ELIGIBLE") { + upload_card_response_details_.virtual_card_enrollment_state = + CreditCard::VirtualCardEnrollmentState::UNENROLLED_AND_ELIGIBLE; + } else { + upload_card_response_details_.virtual_card_enrollment_state = + CreditCard::VirtualCardEnrollmentState::UNENROLLED_AND_NOT_ELIGIBLE; + } + } + } + + const std::string* card_art_url = response.FindStringKey("card_art_url"); + upload_card_response_details_.card_art_url = + card_art_url ? GURL(*card_art_url) : GURL(); +} + +bool UploadCardRequest::IsResponseComplete() { + return true; +} + +void UploadCardRequest::RespondToDelegate( + AutofillClient::PaymentsRpcResult result) { + std::move(callback_).Run(result, upload_card_response_details_); +} + +} // namespace autofill::payments
diff --git a/components/autofill/core/browser/payments/payments_requests/upload_card_request.h b/components/autofill/core/browser/payments/payments_requests/upload_card_request.h new file mode 100644 index 0000000..80b0f86 --- /dev/null +++ b/components/autofill/core/browser/payments/payments_requests/upload_card_request.h
@@ -0,0 +1,52 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_REQUESTS_UPLOAD_CARD_REQUEST_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_REQUESTS_UPLOAD_CARD_REQUEST_H_ + +#include <string> + +#include "base/callback.h" +#include "components/autofill/core/browser/autofill_client.h" +#include "components/autofill/core/browser/payments/payments_client.h" +#include "components/autofill/core/browser/payments/payments_requests/payments_request.h" + +namespace base { +class Value; +} // namespace base + +namespace autofill::payments { + +class UploadCardRequest : public PaymentsRequest { + public: + UploadCardRequest( + const PaymentsClient::UploadRequestDetails& request_details, + const bool full_sync_enabled, + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const PaymentsClient::UploadCardResponseDetails&)> + callback); + UploadCardRequest(const UploadCardRequest&) = delete; + UploadCardRequest& operator=(const UploadCardRequest&) = delete; + ~UploadCardRequest() override; + + // PaymentsRequest: + std::string GetRequestUrlPath() override; + std::string GetRequestContentType() override; + std::string GetRequestContent() override; + void ParseResponse(const base::Value& response) override; + bool IsResponseComplete() override; + void RespondToDelegate(AutofillClient::PaymentsRpcResult result) override; + + private: + const PaymentsClient::UploadRequestDetails request_details_; + const bool full_sync_enabled_; + base::OnceCallback<void(AutofillClient::PaymentsRpcResult, + const PaymentsClient::UploadCardResponseDetails&)> + callback_; + PaymentsClient::UploadCardResponseDetails upload_card_response_details_; +}; + +} // namespace autofill::payments + +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_REQUESTS_UPLOAD_CARD_REQUEST_H_
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc index 2d72a55f..4c58970 100644 --- a/components/autofill/core/common/autofill_features.cc +++ b/components/autofill/core/common/autofill_features.cc
@@ -331,7 +331,7 @@ // shown. This is to prevent double clicks accidentally accepting suggestions. // TODO(crbug/1279268): Remove once launched. const base::Feature kAutofillIgnoreEarlyClicksOnPopup{ - "AutofillIgnoreEarlyClicksOnPopup", base::FEATURE_DISABLED_BY_DEFAULT}; + "AutofillIgnoreEarlyClicksOnPopup", base::FEATURE_ENABLED_BY_DEFAULT}; // The duration for which clicks on the just-shown Autofill popup should be // ignored if AutofillIgnoreEarlyClicksOnPopup is enabled. @@ -340,7 +340,7 @@ const base::FeatureParam<base::TimeDelta> kAutofillIgnoreEarlyClicksOnPopupDuration{ &kAutofillIgnoreEarlyClicksOnPopup, "duration", - base::Milliseconds(500)}; + base::Milliseconds(250)}; // When enabled, only changed values are highlighted in preview mode. // TODO(crbug/1248585): Remove when launched.
diff --git a/components/autofill/core/common/form_data.h b/components/autofill/core/common/form_data.h index 1f65bc4c..4574e89 100644 --- a/components/autofill/core/common/form_data.h +++ b/components/autofill/core/common/form_data.h
@@ -173,7 +173,6 @@ // The name attribute of the form. std::u16string name_attribute; - // NOTE: update IdentityComparator when adding new a member. // NOTE: update SameFormAs() if needed when adding new a member. // NOTE: update SimilarFormAs() if needed when adding new a member. // NOTE: update DynamicallySameFormAs() if needed when adding new a member.
diff --git a/components/autofill/core/common/form_field_data.cc b/components/autofill/core/common/form_field_data.cc index abe5b86..2cacc08 100644 --- a/components/autofill/core/common/form_field_data.cc +++ b/components/autofill/core/common/form_field_data.cc
@@ -268,12 +268,6 @@ return DynamicIdentityTuple(*this) == DynamicIdentityTuple(field); } -bool FormFieldData::IdentityComparator::operator()( - const FormFieldData& a, - const FormFieldData& b) const { - return IdentityTuple(a) < IdentityTuple(b); -} - bool FormFieldData::IsTextInputElement() const { return form_control_type == "text" || form_control_type == "password" || form_control_type == "search" || form_control_type == "tel" ||
diff --git a/components/autofill/core/common/form_field_data.h b/components/autofill/core/common/form_field_data.h index ba879c2..86cf599f 100644 --- a/components/autofill/core/common/form_field_data.h +++ b/components/autofill/core/common/form_field_data.h
@@ -70,13 +70,6 @@ using RoleAttribute = mojom::FormFieldData_RoleAttribute; using LabelSource = mojom::FormFieldData_LabelSource; - // TODO(crbug/1211834): This comparator is deprecated. - // Less-than relation for STL containers. Compares only members needed to - // uniquely identify a field. - struct IdentityComparator { - bool operator()(const FormFieldData& a, const FormFieldData& b) const; - }; - // Returns true if all members of fields |a| and |b| are identical. static bool DeepEqual(const FormFieldData& a, const FormFieldData& b); @@ -149,7 +142,6 @@ #define EXPECT_EQ_UNIQUE_ID(expected, actual) #endif - // NOTE: update IdentityComparator when adding new a member. // NOTE: update SameFieldAs() if needed when adding new a member. // NOTE: update SimilarFieldAs() if needed when adding new a member. // NOTE: update DynamicallySameFieldAs() if needed when adding new a member.
diff --git a/components/certificate_transparency/data/log_list.json b/components/certificate_transparency/data/log_list.json index d86f90d..4c0f2a7 100644 --- a/components/certificate_transparency/data/log_list.json +++ b/components/certificate_transparency/data/log_list.json
@@ -1,6 +1,6 @@ { - "version": "9.30", - "log_list_timestamp": "2022-06-01T12:54:29Z", + "version": "9.31", + "log_list_timestamp": "2022-06-02T12:54:07Z", "operators": [ { "name": "Google",
diff --git a/components/desks_storage/core/local_desk_data_manager.cc b/components/desks_storage/core/local_desk_data_manager.cc index 7db7914..3b48f62 100644 --- a/components/desks_storage/core/local_desk_data_manager.cc +++ b/components/desks_storage/core/local_desk_data_manager.cc
@@ -142,14 +142,19 @@ user_data_dir_path.AppendASCII(kSavedDeskDirectoryName)), account_id_(account_id), cache_status_(CacheStatus::kNotInitialized) { - // Load the cache. - task_runner_->PostTask( - FROM_HERE, base::BindOnce(&LocalDeskDataManager::EnsureCacheIsLoaded, - base::Unretained(this))); // Populate `saved_desks_list_` with all the desk types. for (const auto& desk_type : kDeskTypes) { saved_desks_list_[desk_type]; } + auto entries = std::make_unique< + std::map<base::GUID, std::unique_ptr<ash::DeskTemplate>>>(); + // Load the cache. + task_runner_->PostTaskAndReply( + FROM_HERE, + base::BindOnce(&LocalDeskDataManager::EnsureCacheIsLoaded, + base::Unretained(this), entries.get()), + base::BindOnce(&LocalDeskDataManager::MoveEntriesIntoCache, + weak_ptr_factory_.GetWeakPtr(), std::move(entries))); } LocalDeskDataManager::~LocalDeskDataManager() = default; @@ -158,31 +163,66 @@ DeskModel::GetAllEntriesCallback callback) { auto status = std::make_unique<DeskModel::GetAllEntriesStatus>(); auto entries = std::make_unique<std::vector<const ash::DeskTemplate*>>(); + if (cache_status_ != CacheStatus::kOk) { + *status = DeskModel::GetAllEntriesStatus::kFailure; + std::move(callback).Run(*status, *entries); + return; + } + for (const auto& it : policy_entries_) + entries->push_back(it.get()); + for (auto& saved_desk : saved_desks_list_) { + for (auto& [uuid, template_entry] : saved_desk.second) { + DCHECK_EQ(uuid, template_entry->uuid()); + entries->push_back(template_entry.get()); + } + } // It's safe to pass base::Unretained(this) since the LocalDeskDataManager is // a long-lived object that should persist during user session. task_runner_->PostTaskAndReply( FROM_HERE, base::BindOnce(&LocalDeskDataManager::GetAllEntriesTask, - base::Unretained(this), status.get(), entries.get()), + base::Unretained(this), status.get()), base::BindOnce(&LocalDeskDataManager::OnGetAllEntries, weak_ptr_factory_.GetWeakPtr(), std::move(status), std::move(entries), std::move(callback))); } void LocalDeskDataManager::GetEntryByUUID( - const std::string& uuid, + const std::string& uuid_str, DeskModel::GetEntryByUuidCallback callback) { auto status = std::make_unique<DeskModel::GetEntryByUuidStatus>(); auto entry_ptr = std::make_unique<ash::DeskTemplate*>(); + + if (cache_status_ != LocalDeskDataManager::CacheStatus::kOk) { + *status = DeskModel::GetEntryByUuidStatus::kFailure; + std::move(callback).Run(*status, nullptr); + return; + } + + const base::GUID uuid = base::GUID::ParseCaseInsensitive(uuid_str); + if (!uuid.is_valid()) { + *status = DeskModel::GetEntryByUuidStatus::kInvalidUuid; + } + const ash::DeskTemplateType desk_type = GetDeskTypeOfUuid(uuid); + + const auto cache_entry = saved_desks_list_[desk_type].find(uuid); + + if (cache_entry != saved_desks_list_[desk_type].end()) { + *status = DeskModel::GetEntryByUuidStatus::kOk; + *entry_ptr = cache_entry->second.get(); + } else { + *status = DeskModel::GetEntryByUuidStatus::kNotFound; + } + task_runner_->PostTaskAndReply( FROM_HERE, base::BindOnce(&LocalDeskDataManager::GetEntryByUuidTask, - base::Unretained(this), uuid, status.get(), - entry_ptr.get()), + base::Unretained(this), uuid_str, status.get()), base::BindOnce(&LocalDeskDataManager::OnGetEntryByUuid, - weak_ptr_factory_.GetWeakPtr(), uuid, std::move(status), - std::move(entry_ptr), std::move(callback))); + weak_ptr_factory_.GetWeakPtr(), uuid_str, + std::move(status), std::move(entry_ptr), + std::move(callback))); } void LocalDeskDataManager::AddOrUpdateEntry( @@ -235,6 +275,18 @@ std::unique_ptr<ash::DeskTemplate> deserialize_entry = desk_template_conversion::ParseDeskTemplateFromSource( template_base_value, new_entry->source()); + bool is_update = + std::find_if( + saved_desks_list_[desk_type].begin(), + saved_desks_list_[desk_type].end(), + [&uuid](const std::pair<const base::GUID, + std::unique_ptr<ash::DeskTemplate>>& entry) { + return entry.first == uuid; + }) != saved_desks_list_[desk_type].end(); + std::unique_ptr<ash::DeskTemplate> old_entry = nullptr; + if (is_update) + old_entry = saved_desks_list_[desk_type][uuid]->Clone(); + saved_desks_list_[desk_type][uuid] = std::move(deserialize_entry); task_runner_->PostTaskAndReply( @@ -244,34 +296,73 @@ std::move(template_base_value)), base::BindOnce(&LocalDeskDataManager::OnAddOrUpdateEntry, weak_ptr_factory_.GetWeakPtr(), std::move(status), - std::move(callback))); + std::move(callback), is_update, desk_type, uuid, + std::move(old_entry))); } void LocalDeskDataManager::DeleteEntry( const std::string& uuid_str, DeskModel::DeleteEntryCallback callback) { auto status = std::make_unique<DeskModel::DeleteEntryStatus>(); + if (cache_status_ != CacheStatus::kOk) { + *status = DeskModel::DeleteEntryStatus::kFailure; + std::move(callback).Run(*status); + return; + } + const base::GUID uuid = base::GUID::ParseCaseInsensitive(uuid_str); + if (!uuid.is_valid()) { + // There does not exist an entry with invalid UUID. + // Therefore the deletion request is vicariously successful. + *status = DeskModel::DeleteEntryStatus::kOk; + std::move(callback).Run(*status); + return; + } + const ash::DeskTemplateType desk_type = GetDeskTypeOfUuid(uuid); + // `entry` is used to keep track of the deleted entry in case we need to + // rollback the deletion if the file operation fails to delete it. + auto entry = std::make_unique< + std::map<base::GUID, std::unique_ptr<ash::DeskTemplate>>>(); + (*entry)[uuid] = std::move(saved_desks_list_[desk_type][uuid]); + saved_desks_list_[desk_type].erase(uuid); task_runner_->PostTaskAndReply( FROM_HERE, base::BindOnce(&LocalDeskDataManager::DeleteEntryTask, base::Unretained(this), uuid_str, status.get()), base::BindOnce(&LocalDeskDataManager::OnDeleteEntry, weak_ptr_factory_.GetWeakPtr(), std::move(status), - std::move(callback))); + std::move(entry), std::move(callback))); } void LocalDeskDataManager::DeleteAllEntries( DeskModel::DeleteEntryCallback callback) { auto status = std::make_unique<DeskModel::DeleteEntryStatus>(); + if (cache_status_ != CacheStatus::kOk) { + *status = DeskModel::DeleteEntryStatus::kFailure; + std::move(callback).Run(*status); + return; + } + // `entries` is used to keep track of any desk template entry that failed to + // be deleted by the file system. This is used to rollback the deletion of + // those fail to delete files. + auto entries = std::make_unique< + std::map<base::GUID, std::unique_ptr<ash::DeskTemplate>>>(); + + // Deletes all desk templates and save and recall desks. + for (auto& saved_desk : saved_desks_list_) { + for (auto& [uuid, template_entry] : saved_desk.second) { + (*entries)[uuid] = std::move(template_entry); + } + saved_desk.second.clear(); + } task_runner_->PostTaskAndReply( FROM_HERE, base::BindOnce(&LocalDeskDataManager::DeleteAllEntriesTask, - base::Unretained(this), status.get()), + base::Unretained(this), status.get(), entries.get()), base::BindOnce(&LocalDeskDataManager::OnDeleteEntry, weak_ptr_factory_.GetWeakPtr(), std::move(status), - std::move(callback))); + std::move(entries), std::move(callback))); } // TODO(crbug.com/1320805): Remove this function once both desk models support @@ -336,7 +427,8 @@ g_exclude_save_and_recall_desk_in_max_entry_count = exclude; } -void LocalDeskDataManager::EnsureCacheIsLoaded() { +void LocalDeskDataManager::EnsureCacheIsLoaded( + std::map<base::GUID, std::unique_ptr<ash::DeskTemplate>>* entries_ptr) { // Cache is already loaded. Do nothing. if (cache_status_ == CacheStatus::kOk) return; @@ -351,25 +443,39 @@ return; } - ReadFilesIntoCache(); + // Set dir_reader to read from the `local_saved_desk_path_` directory. + // check to make sure there is a `local_saved_desk_path_` directory. If not + // create it. + bool dir_create_success = base::CreateDirectory(local_saved_desk_path_); + base::DirReaderPosix dir_reader( + local_saved_desk_path_.AsUTF8Unsafe().c_str()); + + if (!dir_create_success || !dir_reader.IsValid()) { + // Failed to find or create the `local_saved_desk_path_` directory path. + // This local storage cannot load any entry of `type` from disk. + cache_status_ = CacheStatus::kInvalidPath; + return; + } + + while (dir_reader.Next()) { + if (!IsValidTemplateFileName(dir_reader.name())) { + continue; + } + + std::unique_ptr<ash::DeskTemplate> entry = + ReadFileToTemplate(local_saved_desk_path_.Append(dir_reader.name())); + if (entry) { + (*entries_ptr)[entry->uuid()] = std::move(entry); + } + } + + cache_status_ = CacheStatus::kOk; } void LocalDeskDataManager::GetAllEntriesTask( - DeskModel::GetAllEntriesStatus* out_status_ptr, - std::vector<const ash::DeskTemplate*>* out_entries_ptr) { - EnsureCacheIsLoaded(); + DeskModel::GetAllEntriesStatus* out_status_ptr) { if (cache_status_ == CacheStatus::kInvalidPath) { *out_status_ptr = DeskModel::GetAllEntriesStatus::kFailure; - return; - } - for (const auto& it : policy_entries_) - out_entries_ptr->push_back(it.get()); - - for (auto& saved_desk : saved_desks_list_) { - for (auto& [uuid, template_entry] : saved_desk.second) { - DCHECK_EQ(uuid, template_entry->uuid()); - out_entries_ptr->push_back(template_entry.get()); - } } if (cache_status_ == CacheStatus::kOk) { *out_status_ptr = DeskModel::GetAllEntriesStatus::kOk; @@ -387,10 +493,7 @@ void LocalDeskDataManager::GetEntryByUuidTask( const std::string& uuid_str, - DeskModel::GetEntryByUuidStatus* out_status_ptr, - ash::DeskTemplate** out_entry_ptr_ptr) { - EnsureCacheIsLoaded(); - + DeskModel::GetEntryByUuidStatus* out_status_ptr) { if (cache_status_ == LocalDeskDataManager::CacheStatus::kInvalidPath) { *out_status_ptr = DeskModel::GetEntryByUuidStatus::kFailure; return; @@ -401,17 +504,6 @@ *out_status_ptr = DeskModel::GetEntryByUuidStatus::kInvalidUuid; return; } - - const ash::DeskTemplateType desk_type = GetDeskTypeOfUuid(uuid); - - const auto cache_entry = saved_desks_list_[desk_type].find(uuid); - - if (cache_entry != saved_desks_list_[desk_type].end()) { - *out_status_ptr = DeskModel::GetEntryByUuidStatus::kOk; - *out_entry_ptr_ptr = cache_entry->second.get(); - } else { - *out_status_ptr = DeskModel::GetEntryByUuidStatus::kNotFound; - } } void LocalDeskDataManager::OnGetEntryByUuid( @@ -438,7 +530,6 @@ const base::GUID uuid, DeskModel::AddOrUpdateEntryStatus* out_status_ptr, base::Value entry_base_value) { - EnsureCacheIsLoaded(); const base::FilePath fully_qualified_path = GetFullyQualifiedPath(local_saved_desk_path_, uuid.AsLowercaseString()); if (WriteTemplateFile(fully_qualified_path, std::move(entry_base_value))) { @@ -450,28 +541,25 @@ void LocalDeskDataManager::OnAddOrUpdateEntry( std::unique_ptr<DeskModel::AddOrUpdateEntryStatus> status_ptr, - DeskModel::AddOrUpdateEntryCallback callback) { + DeskModel::AddOrUpdateEntryCallback callback, + bool is_update, + ash::DeskTemplateType desk_type, + const base::GUID uuid, + std::unique_ptr<ash::DeskTemplate> entry) { + // Rollback the template addition to the cache if there's a failure. + if (*status_ptr == DeskModel::AddOrUpdateEntryStatus::kFailure) { + if (is_update) { + saved_desks_list_[desk_type][uuid] = std::move(entry); + } else { + saved_desks_list_[desk_type].erase(uuid); + } + } std::move(callback).Run(*status_ptr); } void LocalDeskDataManager::DeleteEntryTask( const std::string& uuid_str, DeskModel::DeleteEntryStatus* out_status_ptr) { - EnsureCacheIsLoaded(); - if (cache_status_ == CacheStatus::kInvalidPath) { - *out_status_ptr = DeskModel::DeleteEntryStatus::kFailure; - return; - } - const base::GUID uuid = base::GUID::ParseCaseInsensitive(uuid_str); - if (!uuid.is_valid()) { - // There does not exist an entry with invalid UUID. - // Therefore the deletion request is vicariously successful. - *out_status_ptr = DeskModel::DeleteEntryStatus::kOk; - return; - } - const ash::DeskTemplateType desk_type = GetDeskTypeOfUuid(uuid); - saved_desks_list_[desk_type].erase(uuid); - const base::FilePath fully_qualified_path = GetFullyQualifiedPath(local_saved_desk_path_, uuid_str); base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, @@ -484,24 +572,14 @@ } void LocalDeskDataManager::DeleteAllEntriesTask( - DeskModel::DeleteEntryStatus* out_status_ptr) { - EnsureCacheIsLoaded(); - if (cache_status_ == CacheStatus::kInvalidPath) { - *out_status_ptr = DeskModel::DeleteEntryStatus::kFailure; - return; - } - // Deletes all desk templates and save and recall desks. - for (auto& saved_desk : saved_desks_list_) { - saved_desk.second.clear(); - } + DeskModel::DeleteEntryStatus* out_status_ptr, + std::map<base::GUID, std::unique_ptr<ash::DeskTemplate>>* out_entries_ptr) { base::DirReaderPosix dir_reader( local_saved_desk_path_.AsUTF8Unsafe().c_str()); - if (!dir_reader.IsValid()) { *out_status_ptr = DeskModel::DeleteEntryStatus::kFailure; return; } - DeskModel::DeleteEntryStatus overall_delete_successes = DeskModel::DeleteEntryStatus::kOk; @@ -513,16 +591,32 @@ local_saved_desk_path_.Append(dir_reader.name())); base::ScopedBlockingCall scoped_blocking_call( FROM_HERE, base::BlockingType::MAY_BLOCK); + // Keep a copy of the entry in memory. If the delete fails, get the uuid of + // the failed deleted entry so it can be rolled back later. + std::unique_ptr<ash::DeskTemplate> entry = + ReadFileToTemplate(fully_qualified_path); bool delete_success = base::DeleteFile(fully_qualified_path); - if (!delete_success) + if (!delete_success) { overall_delete_successes = DeskModel::DeleteEntryStatus::kFailure; + } else { + // File deleted successfully, remove the backup of the deleted file. + if (entry) { + (*out_entries_ptr).erase(entry->uuid()); + } + } } *out_status_ptr = overall_delete_successes; } void LocalDeskDataManager::OnDeleteEntry( std::unique_ptr<DeskModel::DeleteEntryStatus> status_ptr, + std::unique_ptr<std::map<base::GUID, std::unique_ptr<ash::DeskTemplate>>> + entries_ptr, DeskModel::DeleteEntryCallback callback) { + // Rollback deletes from the cache for the failed file deletes. + if (*status_ptr == DeskModel::DeleteEntryStatus::kFailure) { + MoveEntriesIntoCache(std::move(entries_ptr)); + } std::move(callback).Run(*status_ptr); } @@ -555,37 +649,15 @@ return ash::DeskTemplateType::kTemplate; } -void LocalDeskDataManager::ReadFilesIntoCache() { - // Set dir_reader to read from the `local_saved_desk_path_` directory. - // check to make sure there is a `local_saved_desk_path_` directory. If not - // create it. - base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, - base::BlockingType::MAY_BLOCK); - bool dir_create_success = base::CreateDirectory(local_saved_desk_path_); - base::DirReaderPosix dir_reader( - local_saved_desk_path_.AsUTF8Unsafe().c_str()); - - if (!dir_create_success || !dir_reader.IsValid()) { - // Failed to find or create the `local_saved_desk_path_` directory path. - // This local storage cannot load any entry of `type` from disk. - cache_status_ = CacheStatus::kInvalidPath; - return; - } - - while (dir_reader.Next()) { - if (!IsValidTemplateFileName(dir_reader.name())) { - continue; - } - - std::unique_ptr<ash::DeskTemplate> entry = - ReadFileToTemplate(local_saved_desk_path_.Append(dir_reader.name())); - if (entry) { - const base::GUID uuid = entry->uuid(); - saved_desks_list_[entry->type()][uuid] = std::move(entry); +void LocalDeskDataManager::MoveEntriesIntoCache( + std::unique_ptr<std::map<base::GUID, std::unique_ptr<ash::DeskTemplate>>> + entries_ptr) { + for (auto& [uuid, template_entry] : *entries_ptr) { + if (template_entry) { + saved_desks_list_[template_entry->type()][uuid] = + std::move(template_entry); } } - - cache_status_ = CacheStatus::kOk; } } // namespace desks_storage
diff --git a/components/desks_storage/core/local_desk_data_manager.h b/components/desks_storage/core/local_desk_data_manager.h index ffecc57..64b7b3f 100644 --- a/components/desks_storage/core/local_desk_data_manager.h +++ b/components/desks_storage/core/local_desk_data_manager.h
@@ -54,7 +54,7 @@ // DeskModel: void GetAllEntries(GetAllEntriesCallback callback) override; - void GetEntryByUUID(const std::string& uuid, + void GetEntryByUUID(const std::string& uuid_str, GetEntryByUuidCallback callback) override; void AddOrUpdateEntry(std::unique_ptr<ash::DeskTemplate> new_entry, AddOrUpdateEntryCallback callback) override; @@ -81,22 +81,15 @@ // Loads templates from `local_saved_desk_path_` into the // `saved_desks_list_`, based on the template's desk type, if the cache is not // loaded yet. - void EnsureCacheIsLoaded(); + void EnsureCacheIsLoaded( + std::map<base::GUID, std::unique_ptr<ash::DeskTemplate>>* entries_ptr); - // Gets all entries from user's `local_saved_desk_path_` - void GetAllEntriesTask(DeskModel::GetAllEntriesStatus* status_ptr, - std::vector<const ash::DeskTemplate*>* entries_ptr); - - // Wrapper method to call GetAllEntriesCallback. - void OnGetAllEntries( - std::unique_ptr<DeskModel::GetAllEntriesStatus> status_ptr, - std::unique_ptr<std::vector<const ash::DeskTemplate*>> entries_ptr, - DeskModel::GetAllEntriesCallback callback); + // Gets all entries from user's `local_saved_desk_path_`. + void GetAllEntriesTask(DeskModel::GetAllEntriesStatus* status_ptr); // Get a specific entry by `uuid_str`. void GetEntryByUuidTask(const std::string& uuid_str, - DeskModel::GetEntryByUuidStatus* status_ptr, - ash::DeskTemplate** entry_ptr_ptr); + DeskModel::GetEntryByUuidStatus* status_ptr); // Wrapper method to call GetEntryByUuidCallback. void OnGetEntryByUuid( @@ -105,6 +98,12 @@ std::unique_ptr<ash::DeskTemplate*> entry_ptr_ptr, DeskModel::GetEntryByUuidCallback callback); + // Wrapper method to call GetAllEntriesCallback. + void OnGetAllEntries( + std::unique_ptr<DeskModel::GetAllEntriesStatus> status_ptr, + std::unique_ptr<std::vector<const ash::DeskTemplate*>> entries_ptr, + DeskModel::GetAllEntriesCallback callback); + // Add or update an entry by `new_entry`'s UUID. void AddOrUpdateEntryTask(const base::GUID uuid, DeskModel::AddOrUpdateEntryStatus* status_ptr, @@ -113,7 +112,11 @@ // Wrapper method to call AddOrUpdateEntryCallback. void OnAddOrUpdateEntry( std::unique_ptr<DeskModel::AddOrUpdateEntryStatus> status_ptr, - DeskModel::AddOrUpdateEntryCallback callback); + DeskModel::AddOrUpdateEntryCallback callback, + bool is_update, + ash::DeskTemplateType desk_type, + const base::GUID uuid, + std::unique_ptr<ash::DeskTemplate> entry); // Remove entry with `uuid_str`. If the entry with `uuid_str` does not // exist, then the deletion is considered a success. @@ -121,11 +124,16 @@ DeskModel::DeleteEntryStatus* status_ptr); // Delete all entries. - void DeleteAllEntriesTask(DeskModel::DeleteEntryStatus* status_ptr); + void DeleteAllEntriesTask( + DeskModel::DeleteEntryStatus* status_ptr, + std::map<base::GUID, std::unique_ptr<ash::DeskTemplate>>* entries_ptr); // Wrapper method to call DeleteEntryCallback. - void OnDeleteEntry(std::unique_ptr<DeskModel::DeleteEntryStatus> status_ptr, - DeskModel::DeleteEntryCallback callback); + void OnDeleteEntry( + std::unique_ptr<DeskModel::DeleteEntryStatus> status_ptr, + std::unique_ptr<std::map<base::GUID, std::unique_ptr<ash::DeskTemplate>>> + entries_ptr, + DeskModel::DeleteEntryCallback callback); // Returns true if the storage model has an entry of desk type `type` with the // file name `name`. @@ -135,8 +143,10 @@ // Returns the desk type of the `uuid`. ash::DeskTemplateType GetDeskTypeOfUuid(const base::GUID uuid) const; - // Read template files into their appropriate caches. - void ReadFilesIntoCache(); + // Wrapper method to load the read files into the `saved_desks_list_` cache. + void MoveEntriesIntoCache( + std::unique_ptr<std::map<base::GUID, std::unique_ptr<ash::DeskTemplate>>> + entries_ptr); // Task runner used to schedule tasks on the IO thread. scoped_refptr<base::SequencedTaskRunner> task_runner_;
diff --git a/components/desks_storage/core/local_desks_data_manager_unittests.cc b/components/desks_storage/core/local_desks_data_manager_unittests.cc index 82be6b2..cef3707b 100644 --- a/components/desks_storage/core/local_desks_data_manager_unittests.cc +++ b/components/desks_storage/core/local_desks_data_manager_unittests.cc
@@ -112,6 +112,11 @@ EXPECT_EQ(status, DeskModel::AddOrUpdateEntryStatus::kOk); } +// Verifies that the status passed into it is kFailure +void VerifyEntryAddedFailure(DeskModel::AddOrUpdateEntryStatus status) { + EXPECT_EQ(status, DeskModel::AddOrUpdateEntryStatus::kFailure); +} + void VerifyEntryAddedErrorHitMaximumLimit( DeskModel::AddOrUpdateEntryStatus status) { EXPECT_EQ(status, DeskModel::AddOrUpdateEntryStatus::kHitMaximumLimit); @@ -585,6 +590,7 @@ GetEntryByUuidReturnsFailureIfDeskManagerHasInvalidPath) { data_manager_ = std::make_unique<LocalDeskDataManager>(kInvalidFilePath, account_id_); + task_environment_.RunUntilIdle(); base::RunLoop loop; data_manager_->GetEntryByUUID( @@ -624,14 +630,12 @@ data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_one_), base::BindOnce(&VerifyEntryAddedCorrectly)); - base::RunLoop loop; - data_manager_->DeleteEntry( kTestUuid1, base::BindLambdaForTesting([&](DeskModel::DeleteEntryStatus status) { EXPECT_EQ(status, DeskModel::DeleteEntryStatus::kOk); })); - + base::RunLoop loop; data_manager_->GetAllEntries(base::BindLambdaForTesting( [&](DeskModel::GetAllEntriesStatus status, const std::vector<const ash::DeskTemplate*>& entries) { @@ -639,7 +643,6 @@ EXPECT_EQ(entries.size(), 0ul); loop.Quit(); })); - loop.Run(); } @@ -659,6 +662,7 @@ base::BindLambdaForTesting([&](DeskModel::DeleteEntryStatus status) { EXPECT_EQ(status, DeskModel::DeleteEntryStatus::kOk); })); + task_environment_.RunUntilIdle(); data_manager_->GetAllEntries(base::BindLambdaForTesting( [&](DeskModel::GetAllEntriesStatus status, @@ -863,4 +867,109 @@ EXPECT_EQ(data_manager_->GetSaveAndRecallDeskEntryCount(), 6ul); } +TEST_F(LocalDeskDataManagerTest, RollbackUpdateTemplatesOnFileWriteFailure) { + // Add two user templates. + for (std::size_t index = 0u; index < 2u; ++index) { + data_manager_->AddOrUpdateEntry( + MakeTestDeskTemplate(index, ash::DeskTemplateType::kTemplate), + base::BindOnce(&VerifyEntryAddedCorrectly)); + } + + EXPECT_EQ(data_manager_->GetEntryCount(), 2ul); + EXPECT_EQ(data_manager_->GetDeskTemplateEntryCount(), 2ul); + task_environment_.RunUntilIdle(); + + base::SetPosixFilePermissions(temp_dir_.GetPath(), + base::FILE_PERMISSION_READ_BY_USER); + data_manager_->AddOrUpdateEntry( + MakeTestDeskTemplate(1ul, ash::DeskTemplateType::kTemplate), + base::BindOnce(&VerifyEntryAddedFailure)); + + VerifyAllEntries(2ul, + "Updated one desk template failed to write to file system"); + + base::SetPosixFilePermissions(temp_dir_.GetPath(), + base::FILE_PERMISSION_READ_BY_USER | + base::FILE_PERMISSION_WRITE_BY_USER | + base::FILE_PERMISSION_EXECUTE_BY_USER); +} + +TEST_F(LocalDeskDataManagerTest, RollbackAddTemplatesOnFileWriteFailure) { + // Add two user templates. + for (std::size_t index = 0u; index < 2u; ++index) { + data_manager_->AddOrUpdateEntry( + MakeTestDeskTemplate(index, ash::DeskTemplateType::kTemplate), + base::BindOnce(&VerifyEntryAddedCorrectly)); + } + + EXPECT_EQ(data_manager_->GetEntryCount(), 2ul); + EXPECT_EQ(data_manager_->GetDeskTemplateEntryCount(), 2ul); + task_environment_.RunUntilIdle(); + + base::SetPosixFilePermissions(temp_dir_.GetPath(), + base::FILE_PERMISSION_READ_BY_USER); + data_manager_->AddOrUpdateEntry( + MakeTestDeskTemplate(3ul, ash::DeskTemplateType::kTemplate), + base::BindOnce(&VerifyEntryAddedFailure)); + task_environment_.RunUntilIdle(); + + VerifyAllEntries(2ul, "Add one desk template failed to write to file system"); + + base::SetPosixFilePermissions(temp_dir_.GetPath(), + base::FILE_PERMISSION_READ_BY_USER | + base::FILE_PERMISSION_WRITE_BY_USER | + base::FILE_PERMISSION_EXECUTE_BY_USER); +} + +TEST_F(LocalDeskDataManagerTest, RollbackDeleteTemplatesOnFileDeleteFailure) { + data_manager_->AddOrUpdateEntry(std::move(sample_desk_template_one_), + base::BindOnce(&VerifyEntryAddedCorrectly)); + EXPECT_EQ(data_manager_->GetEntryCount(), 1ul); + EXPECT_EQ(data_manager_->GetDeskTemplateEntryCount(), 1ul); + task_environment_.RunUntilIdle(); + base::SetPosixFilePermissions(temp_dir_.GetPath(), + base::FILE_PERMISSION_READ_BY_USER); + data_manager_->DeleteEntry( + kTestUuid1, + base::BindLambdaForTesting([&](DeskModel::DeleteEntryStatus status) { + EXPECT_EQ(status, DeskModel::DeleteEntryStatus::kFailure); + })); + task_environment_.RunUntilIdle(); + + VerifyAllEntries(1ul, "Delete desk template failed to delete on file system"); + + base::SetPosixFilePermissions(temp_dir_.GetPath(), + base::FILE_PERMISSION_READ_BY_USER | + base::FILE_PERMISSION_WRITE_BY_USER | + base::FILE_PERMISSION_EXECUTE_BY_USER); +} + +TEST_F(LocalDeskDataManagerTest, + RollbackDeleteAllTemplatesOnFileDeleteFailure) { + // Add four user templates. + for (std::size_t index = 0u; index < 4u; ++index) { + data_manager_->AddOrUpdateEntry( + MakeTestDeskTemplate(index, ash::DeskTemplateType::kTemplate), + base::BindOnce(&VerifyEntryAddedCorrectly)); + } + EXPECT_EQ(data_manager_->GetEntryCount(), 4ul); + EXPECT_EQ(data_manager_->GetDeskTemplateEntryCount(), 4ul); + task_environment_.RunUntilIdle(); + base::SetPosixFilePermissions(temp_dir_.GetPath(), + base::FILE_PERMISSION_READ_BY_USER); + data_manager_->DeleteAllEntries( + base::BindLambdaForTesting([&](DeskModel::DeleteEntryStatus status) { + EXPECT_EQ(status, DeskModel::DeleteEntryStatus::kFailure); + })); + task_environment_.RunUntilIdle(); + + VerifyAllEntries(4ul, + "Delete all desk template failed to delete on file system"); + + base::SetPosixFilePermissions(temp_dir_.GetPath(), + base::FILE_PERMISSION_READ_BY_USER | + base::FILE_PERMISSION_WRITE_BY_USER | + base::FILE_PERMISSION_EXECUTE_BY_USER); +} + } // namespace desks_storage
diff --git a/components/device_signals/core/common/win/BUILD.gn b/components/device_signals/core/common/win/BUILD.gn index 022f4b8..89ed223 100644 --- a/components/device_signals/core/common/win/BUILD.gn +++ b/components/device_signals/core/common/win/BUILD.gn
@@ -4,13 +4,18 @@ static_library("win") { public = [ + "win_types.h", "wmi_client.h", "wmi_client_impl.h", + "wsc_client.h", + "wsc_client_impl.h", ] sources = [ "wmi_client.cc", "wmi_client_impl.cc", + "wsc_client.cc", + "wsc_client_impl.cc", ] public_deps = [ @@ -35,7 +40,10 @@ source_set("unit_tests") { testonly = true - sources = [ "wmi_client_impl_unittest.cc" ] + sources = [ + "wmi_client_impl_unittest.cc", + "wsc_client_impl_unittest.cc", + ] deps = [ ":test_support",
diff --git a/components/device_signals/core/common/win/com_fakes.cc b/components/device_signals/core/common/win/com_fakes.cc index e1d9edb..b9c74e9a 100644 --- a/components/device_signals/core/common/win/com_fakes.cc +++ b/components/device_signals/core/common/win/com_fakes.cc
@@ -19,7 +19,26 @@ return ::InterlockedDecrement(&ref_count_); \ } -IMPL_IUNKOWN_NOQI_WITH_REF(FakeWbemClassObject) +#define IMPL_IDISPATCH(cls) \ + IMPL_IUNKOWN_NOQI_WITH_REF(cls) \ + IFACEMETHODIMP cls::GetTypeInfoCount(UINT* pctinfo) { return E_NOTIMPL; } \ + IFACEMETHODIMP cls::GetTypeInfo(UINT iTInfo, LCID lcid, \ + ITypeInfo** ppTInfo) { \ + return E_NOTIMPL; \ + } \ + IFACEMETHODIMP cls::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, \ + UINT cNames, LCID lcid, \ + DISPID* rgDispId) { \ + return E_NOTIMPL; \ + } \ + IFACEMETHODIMP cls::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, \ + WORD wFlags, DISPPARAMS* pDispParams, \ + VARIANT* pVarResult, EXCEPINFO* pExcepInfo, \ + UINT* puArgErr) { \ + return E_NOTIMPL; \ + } + +// FakeEnumWbemClassObject FakeEnumWbemClassObject::FakeEnumWbemClassObject() = default; @@ -74,6 +93,8 @@ IMPL_IUNKOWN_NOQI_WITH_REF(FakeEnumWbemClassObject) +// FakeWbemClassObject + FakeWbemClassObject::FakeWbemClassObject() = default; FakeWbemClassObject::FakeWbemClassObject(FakeWbemClassObject&&) = default; FakeWbemClassObject& FakeWbemClassObject::operator=(FakeWbemClassObject&&) = @@ -221,4 +242,128 @@ return E_NOTIMPL; } +IMPL_IUNKOWN_NOQI_WITH_REF(FakeWbemClassObject) + +// FakeWscProduct + +FakeWscProduct::FakeWscProduct() = default; + +FakeWscProduct::FakeWscProduct(const wchar_t* name, + const wchar_t* id, + WSC_SECURITY_PRODUCT_STATE state) + : name_(name), id_(id), state_(state) {} + +FakeWscProduct::FakeWscProduct(FakeWscProduct&& other) + : failed_step_(other.failed_step_), state_(other.state_) { + name_.Reset(other.name_.Release()); + id_.Reset(other.id_.Release()); +} + +FakeWscProduct& FakeWscProduct::operator=(FakeWscProduct&& other) { + failed_step_ = other.failed_step_; + state_ = other.state_; + name_.Reset(other.name_.Release()); + id_.Reset(other.id_.Release()); + return *this; +} + +FakeWscProduct::~FakeWscProduct() = default; + +HRESULT FakeWscProduct::get_ProductName(BSTR* pVal) { + if (ShouldFail(FailureStep::kProductName)) { + return E_FAIL; + } + + *pVal = name_.Get(); + return S_OK; +} + +HRESULT FakeWscProduct::get_ProductGuid(BSTR* pVal) { + if (ShouldFail(FailureStep::kProductId)) { + return E_FAIL; + } + + *pVal = id_.Get(); + return S_OK; +} + +HRESULT FakeWscProduct::get_ProductState(WSC_SECURITY_PRODUCT_STATE* pVal) { + if (ShouldFail(FailureStep::kProductState)) { + return E_FAIL; + } + + *pVal = state_; + return S_OK; +} + +HRESULT FakeWscProduct::get_ProductStateTimestamp(BSTR* pVal) { + return E_NOTIMPL; +} + +HRESULT FakeWscProduct::get_RemediationPath(BSTR* pVal) { + return E_NOTIMPL; +} + +HRESULT FakeWscProduct::get_SignatureStatus( + WSC_SECURITY_SIGNATURE_STATUS* pVal) { + return E_NOTIMPL; +} + +HRESULT FakeWscProduct::get_ProductIsDefault(BOOL* pVal) { + return E_NOTIMPL; +} + +bool FakeWscProduct::ShouldFail(FakeWscProduct::FailureStep step) { + return failed_step_.has_value() && failed_step_.value() == step; +} + +IMPL_IDISPATCH(FakeWscProduct) + +// FakeWSCProductList + +FakeWSCProductList::FakeWSCProductList() = default; + +FakeWSCProductList::~FakeWSCProductList() = default; + +HRESULT FakeWSCProductList::get_Count(LONG* pVal) { + if (ShouldFail(FailureStep::kGetCount)) { + return E_FAIL; + } + + *pVal = products_.size(); + return S_OK; +} + +HRESULT FakeWSCProductList::get_Item(ULONG index, IWscProduct** pVal) { + if (ShouldFail(FailureStep::kGetItem)) { + return E_FAIL; + } + + if (index < 0 || index >= products_.size()) { + return E_FAIL; + } + + *pVal = products_[index]; + + return S_OK; +} + +HRESULT FakeWSCProductList::Initialize(ULONG provider) { + if (ShouldFail(FailureStep::kInitialize)) { + return E_FAIL; + } + + // Initialize can only be called once. + DCHECK(!provider_.has_value()); + + provider_ = provider; + return S_OK; +} + +bool FakeWSCProductList::ShouldFail(FakeWSCProductList::FailureStep step) { + return failed_step_.has_value() && failed_step_.value() == step; +} + +IMPL_IDISPATCH(FakeWSCProductList) + } // namespace device_signals
diff --git a/components/device_signals/core/common/win/com_fakes.h b/components/device_signals/core/common/win/com_fakes.h index ba4c1ef..06fc731 100644 --- a/components/device_signals/core/common/win/com_fakes.h +++ b/components/device_signals/core/common/win/com_fakes.h
@@ -6,6 +6,7 @@ #define COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_WIN_COM_FAKES_H_ #include <atlcomcli.h> +#include <iwscapi.h> #include <wbemidl.h> #include <iterator> #include <map> @@ -24,6 +25,18 @@ ULONG STDMETHODCALLTYPE Release(void) override; \ ULONG ref_count_ = 1; +#define DECLARE_IDISPATCH() \ + DECLARE_IUNKOWN_NOQI_WITH_REF() \ + IFACEMETHODIMP GetTypeInfoCount(UINT* pctinfo) override; \ + IFACEMETHODIMP GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) \ + override; \ + IFACEMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, \ + LCID lcid, DISPID* rgDispId) override; \ + IFACEMETHODIMP Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, \ + WORD wFlags, DISPPARAMS* pDispParams, \ + VARIANT* pVarResult, EXCEPINFO* pExcepInfo, \ + UINT* puArgErr) override; + class FakeEnumWbemClassObject : public IEnumWbemClassObject { public: FakeEnumWbemClassObject(); @@ -133,6 +146,89 @@ std::map<std::wstring, base::win::ScopedVariant> map_; }; +class FakeWscProduct : public IWscProduct { + public: + FakeWscProduct(); + FakeWscProduct(const wchar_t* name, + const wchar_t* id, + WSC_SECURITY_PRODUCT_STATE state); + + FakeWscProduct(const FakeWscProduct& copy) = delete; + FakeWscProduct& operator=(const FakeWscProduct&) = delete; + FakeWscProduct(FakeWscProduct&&); + FakeWscProduct& operator=(FakeWscProduct&&); + + virtual ~FakeWscProduct(); + + enum class FailureStep { + kProductName = 0, + kProductId = 1, + kProductState = 2, + }; + + // IWscProduct: + IFACEMETHODIMP get_ProductName(BSTR* pVal) override; + IFACEMETHODIMP get_ProductGuid(BSTR* pVal) override; + IFACEMETHODIMP get_ProductState(WSC_SECURITY_PRODUCT_STATE* pVal) override; + + // Can be used to force a failure to happen in one of the functions + // represented by `step`. + void set_failed_step(FailureStep step) { failed_step_ = step; } + + private: + // IWscProduct: + DECLARE_IDISPATCH() + IFACEMETHODIMP get_ProductStateTimestamp(BSTR* pVal) override; + IFACEMETHODIMP get_RemediationPath(BSTR* pVal) override; + IFACEMETHODIMP get_SignatureStatus( + WSC_SECURITY_SIGNATURE_STATUS* pVal) override; + IFACEMETHODIMP get_ProductIsDefault(BOOL* pVal) override; + + bool ShouldFail(FailureStep step); + + absl::optional<FailureStep> failed_step_; + + base::win::ScopedBstr name_; + base::win::ScopedBstr id_; + WSC_SECURITY_PRODUCT_STATE state_; +}; + +class FakeWSCProductList : public IWSCProductList { + public: + FakeWSCProductList(); + + virtual ~FakeWSCProductList(); + + enum class FailureStep { + kInitialize = 0, + kGetCount = 1, + kGetItem = 2, + }; + + void Add(IWscProduct* product) { products_.push_back(product); } + // IWSCProductList: + IFACEMETHODIMP get_Count(LONG* pVal) override; + IFACEMETHODIMP get_Item(ULONG index, IWscProduct** pVal) override; + IFACEMETHODIMP Initialize(ULONG provider) override; + + // Can be used to force a failure to happen in one of the functions + // represented by `step`. + void set_failed_step(FailureStep step) { failed_step_ = step; } + + const absl::optional<ULONG>& provider() { return provider_; } + + private: + // IWSCProductList: + DECLARE_IDISPATCH() + + bool ShouldFail(FailureStep step); + + absl::optional<FailureStep> failed_step_; + + absl::optional<ULONG> provider_; + std::vector<IWscProduct*> products_; +}; + } // namespace device_signals #endif // COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_WIN_COM_FAKES_H_
diff --git a/components/device_signals/core/common/win/win_types.h b/components/device_signals/core/common/win/win_types.h new file mode 100644 index 0000000..2b40f68 --- /dev/null +++ b/components/device_signals/core/common/win/win_types.h
@@ -0,0 +1,39 @@ +// Copyright (c) 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_WIN_WIN_TYPES_H_ +#define COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_WIN_WIN_TYPES_H_ + +#include <string> + +namespace device_signals { + +// Various states in which an AntiVirus software can be. +enum class AvProductState { kOn, kOff, kSnoozed, kExpired }; + +// Metadata about an installed AntiVirus software product. +// Can be retrieve via WSC on Windows 8 and above, and below properties are +// collected via this interface: +// https://docs.microsoft.com/en-us/windows/win32/api/iwscapi/nn-iwscapi-iwscproduct +struct AvProduct { + std::string display_name; + AvProductState state; + + // Although not present on the documentation, IWscProduct exposes a + // `get_ProductGuid` function to retrieve an GUID representing an Antivirus + // software. + std::string product_id; +}; + +// Metadata about an installed Hotfix update. +struct InstalledHotfix { + // In WMI, this value represents the `HotFixID` property from entries in + // "Win32_QuickFixEngineering". They have a format looking like `KB123123`. + // https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-quickfixengineering + std::string hotfix_id; +}; + +} // namespace device_signals + +#endif // COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_WIN_WIN_TYPES_H_
diff --git a/components/device_signals/core/common/win/wmi_client.h b/components/device_signals/core/common/win/wmi_client.h index a46ebe0..6215633c 100644 --- a/components/device_signals/core/common/win/wmi_client.h +++ b/components/device_signals/core/common/win/wmi_client.h
@@ -9,6 +9,7 @@ #include <vector> #include "base/win/wmi.h" +#include "components/device_signals/core/common/win/win_types.h" #include "third_party/abseil-cpp/absl/types/optional.h" // WMI interfaces are available on Windows Vista and above, and are officially @@ -22,14 +23,6 @@ kMaxValue = kFailedToGetName }; -// Metadata about an installed Hotfix update. -struct InstalledHotfix { - // In WMI, this value represents the `HotFixID` property from entries in - // "Win32_QuickFixEngineering". They have a format looking like `KB123123`. - // https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-quickfixengineering - std::string hotfix_id; -}; - // Response object for calls to retrieve information about installed hotfix // updates. struct WmiHotfixesResponse {
diff --git a/components/device_signals/core/common/win/wmi_client_impl_unittest.cc b/components/device_signals/core/common/win/wmi_client_impl_unittest.cc index d8c67f3..cd83f1f 100644 --- a/components/device_signals/core/common/win/wmi_client_impl_unittest.cc +++ b/components/device_signals/core/common/win/wmi_client_impl_unittest.cc
@@ -17,6 +17,7 @@ #include "base/test/task_environment.h" #include "base/win/wmi.h" #include "components/device_signals/core/common/win/com_fakes.h" +#include "components/device_signals/core/common/win/win_types.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/components/device_signals/core/common/win/wsc_client.cc b/components/device_signals/core/common/win/wsc_client.cc new file mode 100644 index 0000000..4b44c20 --- /dev/null +++ b/components/device_signals/core/common/win/wsc_client.cc
@@ -0,0 +1,15 @@ +// Copyright (c) 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/device_signals/core/common/win/wsc_client.h" + +namespace device_signals { + +WscAvProductsResponse::WscAvProductsResponse() = default; +WscAvProductsResponse::~WscAvProductsResponse() = default; + +WscAvProductsResponse::WscAvProductsResponse( + const WscAvProductsResponse& other) = default; + +} // namespace device_signals
diff --git a/components/device_signals/core/common/win/wsc_client.h b/components/device_signals/core/common/win/wsc_client.h new file mode 100644 index 0000000..089808e --- /dev/null +++ b/components/device_signals/core/common/win/wsc_client.h
@@ -0,0 +1,59 @@ +// Copyright (c) 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_WIN_WSC_CLIENT_H_ +#define COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_WIN_WSC_CLIENT_H_ + +#include <string> +#include <vector> + +#include "components/device_signals/core/common/win/win_types.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +// WSC interfaces are available on Windows 8 and above. More information at: +// https://docs.microsoft.com/en-us/windows/win32/api/iwscapi/ +namespace device_signals { + +enum class WscQueryError { + kFailedToCreateInstance = 0, + kFailedToInitializeProductList = 1, + kFailedToGetProductCount = 2, +}; + +// Errors that can occur when calling WSC, or parsing response values. +enum class WscParsingError { + kFailedToGetItem = 0, + kFailedToGetState = 1, + kStateInvalid = 2, + kFailedToGetName = 3, + kFailedToGetId = 4, + kMaxValue = kFailedToGetId +}; + +// Response object for calls to retrieve information about installed AntiVirus +// software. +struct WscAvProductsResponse { + WscAvProductsResponse(); + ~WscAvProductsResponse(); + + WscAvProductsResponse(const WscAvProductsResponse& other); + + std::vector<AvProduct> av_products; + absl::optional<WscQueryError> query_error; + std::vector<WscParsingError> parsing_errors; +}; + +// Interface for a client instance used to get information from Windows Security +// Center. +class WscClient { + public: + virtual ~WscClient() = default; + + // Will retrieve information about installed AntiVirus software. + virtual WscAvProductsResponse GetAntiVirusProducts() = 0; +}; + +} // namespace device_signals + +#endif // COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_WIN_WSC_CLIENT_H_
diff --git a/components/device_signals/core/common/win/wsc_client_impl.cc b/components/device_signals/core/common/win/wsc_client_impl.cc new file mode 100644 index 0000000..fae2aed1 --- /dev/null +++ b/components/device_signals/core/common/win/wsc_client_impl.cc
@@ -0,0 +1,125 @@ +// Copyright (c) 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/device_signals/core/common/win/wsc_client_impl.h" + +#include <iwscapi.h> +#include <windows.h> +#include <wrl/client.h> +#include <wscapi.h> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/check.h" +#include "base/metrics/histogram_functions.h" +#include "base/strings/sys_string_conversions.h" +#include "base/threading/scoped_blocking_call.h" +#include "base/win/com_init_util.h" +#include "base/win/scoped_bstr.h" +#include "base/win/scoped_variant.h" +#include "base/win/windows_version.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +using Microsoft::WRL::ComPtr; + +namespace device_signals { + +namespace { + +AvProductState ConvertState(WSC_SECURITY_PRODUCT_STATE state) { + switch (state) { + case WSC_SECURITY_PRODUCT_STATE_ON: + return AvProductState::kOn; + case WSC_SECURITY_PRODUCT_STATE_OFF: + return AvProductState::kOff; + case WSC_SECURITY_PRODUCT_STATE_SNOOZED: + return AvProductState::kSnoozed; + case WSC_SECURITY_PRODUCT_STATE_EXPIRED: + return AvProductState::kExpired; + } +} + +HRESULT CreateProductList(IWSCProductList** product_list) { + return ::CoCreateInstance(__uuidof(WSCProductList), nullptr, + CLSCTX_INPROC_SERVER, IID_PPV_ARGS(product_list)); +} + +} // namespace + +WscClientImpl::WscClientImpl() + : create_callback_(base::BindRepeating(CreateProductList)) {} + +WscClientImpl::WscClientImpl(CreateProductListCallback create_callback) + : create_callback_(std::move(create_callback)) {} + +WscClientImpl::~WscClientImpl() = default; + +WscAvProductsResponse WscClientImpl::GetAntiVirusProducts() { + base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, + base::BlockingType::MAY_BLOCK); + WscAvProductsResponse response; + + ComPtr<IWSCProductList> product_list; + HRESULT hr = create_callback_.Run(&product_list); + if (FAILED(hr)) { + response.query_error = WscQueryError::kFailedToCreateInstance; + return response; + } + + hr = product_list->Initialize(WSC_SECURITY_PROVIDER_ANTIVIRUS); + if (FAILED(hr)) { + response.query_error = WscQueryError::kFailedToInitializeProductList; + return response; + } + + LONG product_count; + hr = product_list->get_Count(&product_count); + if (FAILED(hr)) { + response.query_error = WscQueryError::kFailedToGetProductCount; + return response; + } + + for (LONG i = 0; i < product_count; i++) { + ComPtr<IWscProduct> product; + hr = product_list->get_Item(i, &product); + if (FAILED(hr)) { + response.parsing_errors.push_back(WscParsingError::kFailedToGetItem); + continue; + } + + AvProduct av_product; + WSC_SECURITY_PRODUCT_STATE product_state; + hr = product->get_ProductState(&product_state); + if (FAILED(hr)) { + response.parsing_errors.push_back(WscParsingError::kFailedToGetState); + continue; + } + + av_product.state = ConvertState(product_state); + + base::win::ScopedBstr product_name; + hr = product->get_ProductName(product_name.Receive()); + if (FAILED(hr)) { + response.parsing_errors.push_back(WscParsingError::kFailedToGetName); + continue; + } + av_product.display_name = base::SysWideToUTF8( + std::wstring(product_name.Get(), product_name.Length())); + + base::win::ScopedBstr product_id; + hr = product->get_ProductGuid(product_id.Receive()); + if (FAILED(hr)) { + response.parsing_errors.push_back(WscParsingError::kFailedToGetId); + continue; + } + av_product.product_id = base::SysWideToUTF8( + std::wstring(product_id.Get(), product_id.Length())); + + response.av_products.push_back(std::move(av_product)); + } + + return response; +} + +} // namespace device_signals
diff --git a/components/device_signals/core/common/win/wsc_client_impl.h b/components/device_signals/core/common/win/wsc_client_impl.h new file mode 100644 index 0000000..e17df9d3 --- /dev/null +++ b/components/device_signals/core/common/win/wsc_client_impl.h
@@ -0,0 +1,39 @@ +// Copyright (c) 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_WIN_WSC_CLIENT_IMPL_H_ +#define COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_WIN_WSC_CLIENT_IMPL_H_ + +#include <iwscapi.h> + +#include "base/callback.h" +#include "components/device_signals/core/common/win/wsc_client.h" + +namespace device_signals { + +class WscClientImpl : public WscClient { + public: + using CreateProductListCallback = + base::RepeatingCallback<HRESULT(IWSCProductList**)>; + + WscClientImpl(); + + ~WscClientImpl() override; + + // WscClient: + WscAvProductsResponse GetAntiVirusProducts() override; + + private: + friend class WscClientImplTest; + + // Constructor taking in a `create_callback` which can be used to mock + // creating the product list COM object. + explicit WscClientImpl(CreateProductListCallback create_callback); + + CreateProductListCallback create_callback_; +}; + +} // namespace device_signals + +#endif // COMPONENTS_DEVICE_SIGNALS_CORE_COMMON_WIN_WSC_CLIENT_IMPL_H_
diff --git a/components/device_signals/core/common/win/wsc_client_impl_unittest.cc b/components/device_signals/core/common/win/wsc_client_impl_unittest.cc new file mode 100644 index 0000000..e922328 --- /dev/null +++ b/components/device_signals/core/common/win/wsc_client_impl_unittest.cc
@@ -0,0 +1,251 @@ +// Copyright (c) 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/device_signals/core/common/win/wsc_client_impl.h" + +#include <iwscapi.h> +#include <windows.h> +#include <wrl/client.h> +#include <wscapi.h> +#include <memory> +#include <vector> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/strings/sys_string_conversions.h" +#include "base/test/task_environment.h" +#include "base/win/windows_version.h" +#include "components/device_signals/core/common/win/com_fakes.h" +#include "components/device_signals/core/common/win/win_types.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +using Microsoft::WRL::ComPtr; + +namespace device_signals { + +struct AvTestData { + const wchar_t* name; + const wchar_t* id; + WSC_SECURITY_PRODUCT_STATE state; + AvProductState expected_state; +}; + +class WscClientImplTest : public testing::Test { + protected: + WscClientImplTest() + : wsc_client_(base::BindRepeating(&WscClientImplTest::CreateProductList, + base::Unretained(this))) {} + + HRESULT CreateProductList(IWSCProductList** product_list) { + if (fail_list_creation_) { + return E_FAIL; + } + + *product_list = &product_list_; + return S_OK; + } + + void ExpectAvInitialized() { + EXPECT_TRUE(product_list_.provider().has_value()); + EXPECT_EQ(product_list_.provider().value(), + WSC_SECURITY_PROVIDER_ANTIVIRUS); + } + + bool fail_list_creation_ = false; + + FakeWSCProductList product_list_; + WscClientImpl wsc_client_; +}; + +// Tests how the client handles all different product states when parsing +// products received from the list. +TEST_F(WscClientImplTest, GetAntiVirusProducts_AllStates) { + std::vector<AvTestData> test_data; + test_data.push_back({L"first name", L"first product id", + WSC_SECURITY_PRODUCT_STATE_ON, AvProductState::kOn}); + test_data.push_back({L"second name", L"second product id", + WSC_SECURITY_PRODUCT_STATE_OFF, AvProductState::kOff}); + test_data.push_back({L"third name", L"third product id", + WSC_SECURITY_PRODUCT_STATE_SNOOZED, + AvProductState::kSnoozed}); + test_data.push_back({L"fourth name", L"fourth product id", + WSC_SECURITY_PRODUCT_STATE_EXPIRED, + AvProductState::kExpired}); + + // Used to keep products from going out of scope. + std::vector<FakeWscProduct> products; + + for (const auto& data : test_data) { + products.emplace_back(data.name, data.id, data.state); + } + + for (auto& product : products) { + product_list_.Add(&product); + } + + auto response = wsc_client_.GetAntiVirusProducts(); + + ExpectAvInitialized(); + EXPECT_EQ(response.query_error, absl::nullopt); + + EXPECT_EQ(response.parsing_errors.size(), 0U); + + ASSERT_EQ(response.av_products.size(), test_data.size()); + ASSERT_GT(response.av_products.size(), 0U); + + for (size_t i = 0; i < test_data.size(); i++) { + EXPECT_EQ(response.av_products[i].display_name, + base::SysWideToUTF8(test_data[i].name)); + EXPECT_EQ(response.av_products[i].product_id, + base::SysWideToUTF8(test_data[i].id)); + EXPECT_EQ(response.av_products[i].state, test_data[i].expected_state); + } +} + +// Tests how the client reacts to a failure occurring when trying to create a +// product list instance. +TEST_F(WscClientImplTest, GetAntiVirusProducts_FailedCreate) { + fail_list_creation_ = true; + + auto response = wsc_client_.GetAntiVirusProducts(); + + EXPECT_EQ(response.av_products.size(), 0U); + EXPECT_EQ(response.parsing_errors.size(), 0U); + + ASSERT_TRUE(response.query_error.has_value()); + EXPECT_EQ(response.query_error.value(), + WscQueryError::kFailedToCreateInstance); +} + +// Tests how the client reacts to a failure occurring when trying to initialize +// a product list instance. +TEST_F(WscClientImplTest, GetAntiVirusProducts_FailedInitialize) { + product_list_.set_failed_step(FakeWSCProductList::FailureStep::kInitialize); + + auto response = wsc_client_.GetAntiVirusProducts(); + + EXPECT_EQ(response.av_products.size(), 0U); + EXPECT_EQ(response.parsing_errors.size(), 0U); + + ASSERT_TRUE(response.query_error.has_value()); + EXPECT_EQ(response.query_error.value(), + WscQueryError::kFailedToInitializeProductList); +} + +// Tests how the client reacts to a failure occurring when trying to get a +// product count from a product list. +TEST_F(WscClientImplTest, GetAntiVirusProducts_FailedGetProductCount) { + product_list_.set_failed_step(FakeWSCProductList::FailureStep::kGetCount); + + auto response = wsc_client_.GetAntiVirusProducts(); + + ExpectAvInitialized(); + EXPECT_EQ(response.av_products.size(), 0U); + EXPECT_EQ(response.parsing_errors.size(), 0U); + + ASSERT_TRUE(response.query_error.has_value()); + EXPECT_EQ(response.query_error.value(), + WscQueryError::kFailedToGetProductCount); +} + +// Tests how the client reacts to a failure occurring when trying to get an item +// from a product list. +TEST_F(WscClientImplTest, GetAntiVirusProducts_FailedGetItem) { + product_list_.set_failed_step(FakeWSCProductList::FailureStep::kGetItem); + + auto* name1 = L"first name"; + auto* id1 = L"first product id"; + FakeWscProduct on_product(name1, id1, WSC_SECURITY_PRODUCT_STATE_ON); + product_list_.Add(&on_product); + + auto response = wsc_client_.GetAntiVirusProducts(); + + ExpectAvInitialized(); + EXPECT_EQ(response.av_products.size(), 0U); + EXPECT_FALSE(response.query_error.has_value()); + + ASSERT_EQ(response.parsing_errors.size(), 1U); + EXPECT_EQ(response.parsing_errors[0], WscParsingError::kFailedToGetItem); +} + +// Tests how the client reacts to a failure occurring when facing product +// parsing errors. +TEST_F(WscClientImplTest, GetAntiVirusProducts_ProductErrors) { + // Valid product. + auto* name1 = L"first name"; + auto* id1 = L"first product id"; + FakeWscProduct on_product(name1, id1, WSC_SECURITY_PRODUCT_STATE_ON); + + // Product missing a state. + auto* name2 = L"second name"; + auto* id2 = L"second product id"; + FakeWscProduct stateless_product(name2, id2, WSC_SECURITY_PRODUCT_STATE_OFF); + stateless_product.set_failed_step(FakeWscProduct::FailureStep::kProductState); + + // Product missing a name. + auto* name3 = L"third name"; + auto* id3 = L"third product id"; + FakeWscProduct nameless_product(name3, id3, + WSC_SECURITY_PRODUCT_STATE_SNOOZED); + nameless_product.set_failed_step(FakeWscProduct::FailureStep::kProductName); + + // Product missing a name. + auto* name4 = L"fourth name"; + auto* id4 = L"fourth product id"; + FakeWscProduct id_less_product(name4, id4, + WSC_SECURITY_PRODUCT_STATE_SNOOZED); + id_less_product.set_failed_step(FakeWscProduct::FailureStep::kProductId); + + product_list_.Add(&on_product); + product_list_.Add(&stateless_product); + product_list_.Add(&nameless_product); + product_list_.Add(&id_less_product); + + auto response = wsc_client_.GetAntiVirusProducts(); + + ExpectAvInitialized(); + EXPECT_FALSE(response.query_error.has_value()); + + ASSERT_EQ(response.av_products.size(), 1U); + EXPECT_EQ(response.av_products[0].display_name, base::SysWideToUTF8(name1)); + EXPECT_EQ(response.av_products[0].product_id, base::SysWideToUTF8(id1)); + EXPECT_EQ(response.av_products[0].state, AvProductState::kOn); + + ASSERT_EQ(response.parsing_errors.size(), 3U); + EXPECT_EQ(response.parsing_errors[0], WscParsingError::kFailedToGetState); + EXPECT_EQ(response.parsing_errors[1], WscParsingError::kFailedToGetName); + EXPECT_EQ(response.parsing_errors[2], WscParsingError::kFailedToGetId); +} + +// Smoke/sanity test to verify that Defender's instance GUID does not change +// over time. This test actually calls WSC. +TEST(RealWscClientImplTest, SmokeWsc_GetAntiVirusProducts) { + // That part of the display name is not translated when getting it from WSC, + // so it can be used quite simply. + constexpr char kPartialDefenderName[] = "Microsoft Defender"; + + constexpr char kDefenderProductGuid[] = + "{D68DDC3A-831F-4fae-9E44-DA132C1ACF46}"; + + // WSC is only supported on Win8+ (and not server). + base::win::OSInfo* os_info = base::win::OSInfo::GetInstance(); + if (os_info->version_type() == base::win::SUITE_SERVER || + os_info->version() < base::win::Version::WIN8) { + return; + } + + WscClientImpl wsc_client; + auto response = wsc_client.GetAntiVirusProducts(); + + for (const auto& av_product : response.av_products) { + if (av_product.display_name.find(kPartialDefenderName) != + std::string::npos) { + EXPECT_EQ(av_product.product_id, kDefenderProductGuid); + } + } +} + +} // namespace device_signals
diff --git a/components/discardable_memory/client/client_discardable_shared_memory_manager.cc b/components/discardable_memory/client/client_discardable_shared_memory_manager.cc index 571ff78f..87299ea 100644 --- a/components/discardable_memory/client/client_discardable_shared_memory_manager.cc +++ b/components/discardable_memory/client/client_discardable_shared_memory_manager.cc
@@ -29,6 +29,9 @@ namespace discardable_memory { namespace { +const base::Feature kShorterPeriodicPurge{"ShorterPeriodicPurge", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Global atomic to generate unique discardable shared memory IDs. base::AtomicSequenceNumber g_next_discardable_shared_memory_id; @@ -420,8 +423,13 @@ // recover the memory without adverse latency effects. // TODO(crbug.com/1123679): Determine if |kMinAgeForScheduledPurge| and the // constant from |ScheduledPurge| need to be tuned. - PurgeUnlockedMemory( - ClientDiscardableSharedMemoryManager::kMinAgeForScheduledPurge); + if (base::FeatureList::IsEnabled(kShorterPeriodicPurge)) { + PurgeUnlockedMemory( + ClientDiscardableSharedMemoryManager::kMinAgeForScheduledPurge / 2); + } else { + PurgeUnlockedMemory( + ClientDiscardableSharedMemoryManager::kMinAgeForScheduledPurge); + } bool should_schedule = false; {
diff --git a/components/discardable_memory/client/client_discardable_shared_memory_manager.h b/components/discardable_memory/client/client_discardable_shared_memory_manager.h index 055c8f66..b22f65a 100644 --- a/components/discardable_memory/client/client_discardable_shared_memory_manager.h +++ b/components/discardable_memory/client/client_discardable_shared_memory_manager.h
@@ -78,6 +78,8 @@ bytes_allocated_limit_for_testing_ = limit; } + // Anything younger than |kMinAgeForScheduledPurge| is not discarded when we + // do our periodic purge. static constexpr base::TimeDelta kMinAgeForScheduledPurge = base::Minutes(5); // The expected cost of purging should be very small (< 1ms), so it can be
diff --git a/components/embedder_support/android/metrics/android_metrics_service_client.cc b/components/embedder_support/android/metrics/android_metrics_service_client.cc index ad3eca7..0fef2d04d 100644 --- a/components/embedder_support/android/metrics/android_metrics_service_client.cc +++ b/components/embedder_support/android/metrics/android_metrics_service_client.cc
@@ -324,6 +324,7 @@ pref_service_, /* metrics_reporting_enabled */ false)); OnMetricsNotStarted(); pref_service_->ClearPref(prefs::kMetricsClientID); + pref_service_->ClearPref(prefs::kMetricsProvisionalClientID); } }
diff --git a/components/embedder_support/pref_names.cc b/components/embedder_support/pref_names.cc index e0b70f2e..c2a04d0 100644 --- a/components/embedder_support/pref_names.cc +++ b/components/embedder_support/pref_names.cc
@@ -15,4 +15,8 @@ const char kForceMajorVersionToMinorPosition[] = "force_major_version_to_minor_position_in_user_agent"; +// Enum indicating if the user agent reduction feature should be forced enabled +// or disabled. Defaults to blink::features::kReduceUserAgentMinorVersion trial. +const char kReduceUserAgentMinorVersion[] = "user_agent_reduction"; + } // namespace embedder_support
diff --git a/components/embedder_support/pref_names.h b/components/embedder_support/pref_names.h index 1cfd57dc..806ed3c 100644 --- a/components/embedder_support/pref_names.h +++ b/components/embedder_support/pref_names.h
@@ -12,6 +12,7 @@ extern const char kAlternateErrorPagesEnabled[]; extern const char kForceMajorVersionToMinorPosition[]; +extern const char kReduceUserAgentMinorVersion[]; } // namespace embedder_support
diff --git a/components/embedder_support/user_agent_utils.cc b/components/embedder_support/user_agent_utils.cc index 7f9f64b..b8764e5 100644 --- a/components/embedder_support/user_agent_utils.cc +++ b/components/embedder_support/user_agent_utils.cc
@@ -173,6 +173,18 @@ force_major_to_minor == ForceMajorVersionToMinorPosition::kForceEnabled); } +// Returns true if the user agent reduction should be forced (or prevented). +// TODO(crbug.com/1330890): Remove this method along with policy. +bool ShouldReduceUserAgentMinorVersion( + UserAgentReductionEnterprisePolicyState user_agent_reduction) { + return ((user_agent_reduction != + UserAgentReductionEnterprisePolicyState::kForceDisabled && + base::FeatureList::IsEnabled( + blink::features::kReduceUserAgentMinorVersion)) || + user_agent_reduction == + UserAgentReductionEnterprisePolicyState::kForceEnabled); +} + const std::string& GetMajorInMinorVersionNumber() { static const base::NoDestructor<std::string> version_number([] { base::Version version(version_info::GetVersionNumber()); @@ -330,18 +342,17 @@ } // namespace std::string GetProductAndVersion( - ForceMajorVersionToMinorPosition force_major_to_minor) { + ForceMajorVersionToMinorPosition force_major_to_minor, + UserAgentReductionEnterprisePolicyState user_agent_reduction) { if (ShouldForceMajorVersionToMinorPosition(force_major_to_minor)) { // Force major version to 99 and major version to minor version position. - if (base::FeatureList::IsEnabled( - blink::features::kReduceUserAgentMinorVersion)) { + if (ShouldReduceUserAgentMinorVersion(user_agent_reduction)) { return "Chrome/" + GetReducedMajorInMinorVersionNumber(); } else { return "Chrome/" + GetMajorInMinorVersionNumber(); } } else { - if (base::FeatureList::IsEnabled( - blink::features::kReduceUserAgentMinorVersion)) { + if (ShouldReduceUserAgentMinorVersion(user_agent_reduction)) { return version_info::GetProductNameAndVersionForReducedUserAgent( blink::features::kUserAgentFrozenBuildVersion.Get().data()); } else { @@ -351,7 +362,8 @@ } std::string GetUserAgent( - ForceMajorVersionToMinorPosition force_major_to_minor) { + ForceMajorVersionToMinorPosition force_major_to_minor, + UserAgentReductionEnterprisePolicyState user_agent_reduction) { base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); if (command_line->HasSwitch(kUserAgent)) { std::string ua = command_line->GetSwitchValueASCII(kUserAgent); @@ -366,7 +378,7 @@ if (base::FeatureList::IsEnabled(blink::features::kReduceUserAgent)) return GetReducedUserAgent(force_major_to_minor); - return GetFullUserAgent(force_major_to_minor); + return GetFullUserAgent(force_major_to_minor, user_agent_reduction); } std::string GetReducedUserAgent( @@ -378,8 +390,10 @@ } std::string GetFullUserAgent( - ForceMajorVersionToMinorPosition force_major_to_minor) { - std::string product = GetProductAndVersion(force_major_to_minor); + ForceMajorVersionToMinorPosition force_major_to_minor, + UserAgentReductionEnterprisePolicyState user_agent_reduction) { + std::string product = + GetProductAndVersion(force_major_to_minor, user_agent_reduction); #if BUILDFLAG(IS_ANDROID) if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kUseMobileUserAgent)) @@ -615,4 +629,19 @@ } } +embedder_support::UserAgentReductionEnterprisePolicyState +GetUserAgentReductionFromPrefs(const PrefService* pref_service) { + if (!pref_service->HasPrefPath(kReduceUserAgentMinorVersion)) + return UserAgentReductionEnterprisePolicyState::kDefault; + switch (pref_service->GetInteger(kReduceUserAgentMinorVersion)) { + case 1: + return UserAgentReductionEnterprisePolicyState::kForceDisabled; + case 2: + return UserAgentReductionEnterprisePolicyState::kForceEnabled; + case 0: + default: + return UserAgentReductionEnterprisePolicyState::kDefault; + } +} + } // namespace embedder_support
diff --git a/components/embedder_support/user_agent_utils.h b/components/embedder_support/user_agent_utils.h index a345622..bf6db619 100644 --- a/components/embedder_support/user_agent_utils.h +++ b/components/embedder_support/user_agent_utils.h
@@ -29,6 +29,13 @@ kForceEnabled = 2, }; +// TODO(crbug.com/1330890): Remove this enum along with policy. +enum class UserAgentReductionEnterprisePolicyState { + kDefault = 0, + kForceDisabled = 1, + kForceEnabled = 2, +}; + struct UserAgentOptions { bool force_major_version_100 = false; ForceMajorVersionToMinorPosition force_major_to_minor = @@ -43,13 +50,17 @@ // TODO(crbug.com/1291612): modify to accept an optional PrefService*. std::string GetProductAndVersion( ForceMajorVersionToMinorPosition force_major_to_minor = - ForceMajorVersionToMinorPosition::kDefault); + ForceMajorVersionToMinorPosition::kDefault, + UserAgentReductionEnterprisePolicyState user_agent_reduction = + UserAgentReductionEnterprisePolicyState::kDefault); // Returns the user agent string for Chrome. // TODO(crbug.com/1291612): modify to accept an optional PrefService*. std::string GetFullUserAgent( ForceMajorVersionToMinorPosition force_major_to_minor = - ForceMajorVersionToMinorPosition::kDefault); + ForceMajorVersionToMinorPosition::kDefault, + UserAgentReductionEnterprisePolicyState user_agent_reduction = + UserAgentReductionEnterprisePolicyState::kDefault); // Returns the reduced user agent string for Chrome. // TODO(crbug.com/1291612): modify to accept an optional PrefService*. @@ -60,8 +71,11 @@ // Returns the full or "reduced" user agent string, depending on the // UserAgentReduction enterprise policy and blink::features::kReduceUserAgent // TODO(crbug.com/1291612): modify to accept an optional PrefService*. -std::string GetUserAgent(ForceMajorVersionToMinorPosition force_major_to_minor = - ForceMajorVersionToMinorPosition::kDefault); +std::string GetUserAgent( + ForceMajorVersionToMinorPosition force_major_to_minor = + ForceMajorVersionToMinorPosition::kDefault, + UserAgentReductionEnterprisePolicyState user_agent_reduction = + UserAgentReductionEnterprisePolicyState::kDefault); // Returns UserAgentMetadata per the default policy. // This override is currently used in fuchsia, where the enterprise policy @@ -114,6 +128,12 @@ embedder_support::ForceMajorVersionToMinorPosition GetMajorToMinorFromPrefs( const PrefService* pref_service); +// Returns the UserAgentReductionEnterprisePolicyState enum value corresponding +// to the provided integer policy value for UserAgentReduction. +// TODO(crbug.com/1330890): Remove this function with policy. +embedder_support::UserAgentReductionEnterprisePolicyState +GetUserAgentReductionFromPrefs(const PrefService* pref_service); + } // namespace embedder_support #endif // COMPONENTS_EMBEDDER_SUPPORT_USER_AGENT_UTILS_H_
diff --git a/components/embedder_support/user_agent_utils_unittest.cc b/components/embedder_support/user_agent_utils_unittest.cc index d9a50f7..af497d7 100644 --- a/components/embedder_support/user_agent_utils_unittest.cc +++ b/components/embedder_support/user_agent_utils_unittest.cc
@@ -997,38 +997,68 @@ } TEST_F(UserAgentUtilsTest, GetProductAndVersion) { + std::string product; + std::string major_version; + std::string minor_version; + std::string build_version; + std::string patch_version; + + // (1) Features: UserAgentReduction and MajorVersionInMinor disabled. base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitWithFeatures( /*enabled_features=*/{}, /*disabled_features=*/{ blink::features::kForceMajorVersionInMinorPositionInUserAgent, blink::features::kReduceUserAgentMinorVersion}); - std::string product = GetProductAndVersion(); - std::string major_version; - std::string minor_version; + // (1a) Policies: UserAgentReduction and MajorVersionInMinor default. + product = + GetProductAndVersion(ForceMajorVersionToMinorPosition::kDefault, + UserAgentReductionEnterprisePolicyState::kDefault); EXPECT_TRUE(re2::RE2::FullMatch(product, kChromeProductVersionRegex, - &major_version, &minor_version)); + &major_version, &minor_version, + &build_version, &patch_version)); EXPECT_EQ(major_version, version_info::GetMajorVersionNumber()); EXPECT_EQ(minor_version, "0"); + EXPECT_NE(build_version, "0"); + EXPECT_EQ(patch_version, "0"); - // Ensure policy is respected if ForceMajorToMinor is force enabled - product = - GetProductAndVersion(ForceMajorVersionToMinorPosition::kForceEnabled); + // (1b) Policies: UserAgentReduction and MajorVersionInMinor force enabled. + product = GetProductAndVersion( + ForceMajorVersionToMinorPosition::kForceEnabled, + UserAgentReductionEnterprisePolicyState::kForceEnabled); EXPECT_TRUE(re2::RE2::FullMatch(product, kChromeProductVersionRegex, - &major_version, &minor_version)); + &major_version, &minor_version, + &build_version, &patch_version)); EXPECT_EQ(major_version, "99"); EXPECT_EQ(minor_version, version_info::GetMajorVersionNumber()); + EXPECT_EQ(build_version, "0"); + EXPECT_EQ(patch_version, "0"); - // Ensure the build version FeatureParam is used when set. + // (1c) Policies:: UserAgentReduction and MajorVersionInMinor force disabled. + product = GetProductAndVersion( + ForceMajorVersionToMinorPosition::kForceDisabled, + UserAgentReductionEnterprisePolicyState::kForceDisabled); + EXPECT_TRUE(re2::RE2::FullMatch(product, kChromeProductVersionRegex, + &major_version, &minor_version, + &build_version, &patch_version)); + EXPECT_EQ(major_version, version_info::GetMajorVersionNumber()); + EXPECT_EQ(minor_version, "0"); + EXPECT_NE(build_version, "0"); + EXPECT_EQ(patch_version, "0"); + + // (2) Features: UserAgentReduction enabled with version and + // MajorVersionInMinor disabled. scoped_feature_list.Reset(); scoped_feature_list.InitWithFeaturesAndParameters( /*enabled_features=*/{{blink::features::kReduceUserAgentMinorVersion, {{{"build_version", "5555"}}}}}, /*disabled_features=*/{ blink::features::kForceMajorVersionInMinorPositionInUserAgent}); - product = GetProductAndVersion(); - std::string build_version; - std::string patch_version; + + // (2a) Policies: UserAgentReduction and MajorVersionInMinor default. + product = + GetProductAndVersion(ForceMajorVersionToMinorPosition::kDefault, + UserAgentReductionEnterprisePolicyState::kDefault); EXPECT_TRUE(re2::RE2::FullMatch(product, kChromeProductVersionRegex, &major_version, &minor_version, &build_version, &patch_version)); @@ -1037,36 +1067,84 @@ EXPECT_EQ(build_version, "5555"); EXPECT_EQ(patch_version, "0"); - // Ensure policy is respected if ForcemajorToMinor is force disabled, even if - // the respective Blink feature is enabled. + // (2b) Policies: UserAgentReduction and MajorVersionInMinor force enabled. + product = GetProductAndVersion( + ForceMajorVersionToMinorPosition::kForceEnabled, + UserAgentReductionEnterprisePolicyState::kForceEnabled); + EXPECT_TRUE(re2::RE2::FullMatch(product, kChromeProductVersionRegex, + &major_version, &minor_version, + &build_version, &patch_version)); + EXPECT_EQ(major_version, "99"); + EXPECT_EQ(minor_version, version_info::GetMajorVersionNumber()); + EXPECT_EQ(build_version, "0"); + EXPECT_EQ(patch_version, "0"); + + // (2c) Policies:: UserAgentReduction and MajorVersionInMinor force disabled. + product = GetProductAndVersion( + ForceMajorVersionToMinorPosition::kForceDisabled, + UserAgentReductionEnterprisePolicyState::kForceDisabled); + EXPECT_TRUE(re2::RE2::FullMatch(product, kChromeProductVersionRegex, + &major_version, &minor_version, + &build_version, &patch_version)); + EXPECT_EQ(major_version, version_info::GetMajorVersionNumber()); + EXPECT_EQ(minor_version, "0"); + EXPECT_NE(build_version, "5555"); + EXPECT_EQ(patch_version, "0"); + + // (3) Features: UserAgentReduction disabled and MajorVersionInMinor enabled. scoped_feature_list.Reset(); scoped_feature_list.InitWithFeatures( /*enabled_features=*/{blink::features:: kForceMajorVersionInMinorPositionInUserAgent}, /*disabled_features=*/{blink::features::kReduceUserAgentMinorVersion}); - product = - GetProductAndVersion(ForceMajorVersionToMinorPosition::kForceDisabled); - EXPECT_TRUE(re2::RE2::FullMatch(product, kChromeProductVersionRegex, - &major_version, &minor_version, - &build_version)); - EXPECT_EQ(major_version, version_info::GetMajorVersionNumber()); - EXPECT_EQ(minor_version, "0"); - EXPECT_NE(build_version, "9999"); - product = GetProductAndVersion(); + // (3a) Policies: UserAgentReduction and MajorVersionInMinor default. + product = + GetProductAndVersion(ForceMajorVersionToMinorPosition::kDefault, + UserAgentReductionEnterprisePolicyState::kDefault); EXPECT_TRUE(re2::RE2::FullMatch(product, kChromeProductVersionRegex, &major_version, &minor_version, - &build_version)); + &build_version, &patch_version)); EXPECT_EQ(major_version, "99"); EXPECT_EQ(minor_version, version_info::GetMajorVersionNumber()); EXPECT_NE(build_version, "0"); + EXPECT_EQ(patch_version, "0"); + // (3b) Policies: UserAgentReduction and MajorVersionInMinor force enabled. + product = GetProductAndVersion( + ForceMajorVersionToMinorPosition::kForceEnabled, + UserAgentReductionEnterprisePolicyState::kForceEnabled); + EXPECT_TRUE(re2::RE2::FullMatch(product, kChromeProductVersionRegex, + &major_version, &minor_version, + &build_version, &patch_version)); + EXPECT_EQ(major_version, "99"); + EXPECT_EQ(minor_version, version_info::GetMajorVersionNumber()); + EXPECT_EQ(build_version, "0"); + EXPECT_EQ(patch_version, "0"); + + // (3c) Policies:: UserAgentReduction and MajorVersionInMinor force disabled. + product = GetProductAndVersion( + ForceMajorVersionToMinorPosition::kForceDisabled, + UserAgentReductionEnterprisePolicyState::kForceDisabled); + EXPECT_TRUE(re2::RE2::FullMatch(product, kChromeProductVersionRegex, + &major_version, &minor_version, + &build_version, &patch_version)); + EXPECT_EQ(major_version, version_info::GetMajorVersionNumber()); + EXPECT_EQ(minor_version, "0"); + EXPECT_NE(build_version, "0"); + EXPECT_EQ(patch_version, "0"); + + // (4) Features: UserAgentReduction enabled and MajorVersionInMinor disabled. scoped_feature_list.Reset(); scoped_feature_list.InitWithFeatures( /*enabled_features=*/{blink::features::kReduceUserAgentMinorVersion}, /*disabled_features=*/{ blink::features::kForceMajorVersionInMinorPositionInUserAgent}); - product = GetProductAndVersion(); + + // (4a) Policies: UserAgentReduction and MajorVersionInMinor default. + product = + GetProductAndVersion(ForceMajorVersionToMinorPosition::kDefault, + UserAgentReductionEnterprisePolicyState::kDefault); EXPECT_TRUE(re2::RE2::FullMatch(product, kChromeProductVersionRegex, &major_version, &minor_version, &build_version, &patch_version)); @@ -1075,13 +1153,10 @@ EXPECT_EQ(build_version, "0"); EXPECT_EQ(patch_version, "0"); - scoped_feature_list.Reset(); - scoped_feature_list.InitWithFeatures( - /*enabled_features=*/{blink::features::kReduceUserAgentMinorVersion, - blink::features:: - kForceMajorVersionInMinorPositionInUserAgent}, - /*disabled_features=*/{}); - product = GetProductAndVersion(); + // (4b) Policies: UserAgentReduction and MajorVersionInMinor force enabled. + product = GetProductAndVersion( + ForceMajorVersionToMinorPosition::kForceEnabled, + UserAgentReductionEnterprisePolicyState::kForceEnabled); EXPECT_TRUE(re2::RE2::FullMatch(product, kChromeProductVersionRegex, &major_version, &minor_version, &build_version, &patch_version)); @@ -1089,6 +1164,62 @@ EXPECT_EQ(minor_version, version_info::GetMajorVersionNumber()); EXPECT_EQ(build_version, "0"); EXPECT_EQ(patch_version, "0"); + + // (4c) Policies:: UserAgentReduction and MajorVersionInMinor force disabled. + product = GetProductAndVersion( + ForceMajorVersionToMinorPosition::kForceDisabled, + UserAgentReductionEnterprisePolicyState::kForceDisabled); + EXPECT_TRUE(re2::RE2::FullMatch(product, kChromeProductVersionRegex, + &major_version, &minor_version, + &build_version, &patch_version)); + EXPECT_EQ(major_version, version_info::GetMajorVersionNumber()); + EXPECT_EQ(minor_version, "0"); + EXPECT_NE(build_version, "0"); + EXPECT_EQ(patch_version, "0"); + + // (5) Features: UserAgentReduction and MajorVersionInMinor enabled. + scoped_feature_list.Reset(); + scoped_feature_list.InitWithFeatures( + /*enabled_features=*/{blink::features::kReduceUserAgentMinorVersion, + blink::features:: + kForceMajorVersionInMinorPositionInUserAgent}, + /*disabled_features=*/{}); + + // (5a) Policies: UserAgentReduction and MajorVersionInMinor default. + product = + GetProductAndVersion(ForceMajorVersionToMinorPosition::kDefault, + UserAgentReductionEnterprisePolicyState::kDefault); + EXPECT_TRUE(re2::RE2::FullMatch(product, kChromeProductVersionRegex, + &major_version, &minor_version, + &build_version, &patch_version)); + EXPECT_EQ(major_version, "99"); + EXPECT_EQ(minor_version, version_info::GetMajorVersionNumber()); + EXPECT_EQ(build_version, "0"); + EXPECT_EQ(patch_version, "0"); + + // (5b) Policies: UserAgentReduction and MajorVersionInMinor force enabled. + product = GetProductAndVersion( + ForceMajorVersionToMinorPosition::kForceEnabled, + UserAgentReductionEnterprisePolicyState::kForceEnabled); + EXPECT_TRUE(re2::RE2::FullMatch(product, kChromeProductVersionRegex, + &major_version, &minor_version, + &build_version, &patch_version)); + EXPECT_EQ(major_version, "99"); + EXPECT_EQ(minor_version, version_info::GetMajorVersionNumber()); + EXPECT_EQ(build_version, "0"); + EXPECT_EQ(patch_version, "0"); + + // (5c) Policies:: UserAgentReduction and MajorVersionInMinor force disabled. + product = GetProductAndVersion( + ForceMajorVersionToMinorPosition::kForceDisabled, + UserAgentReductionEnterprisePolicyState::kForceDisabled); + EXPECT_TRUE(re2::RE2::FullMatch(product, kChromeProductVersionRegex, + &major_version, &minor_version, + &build_version, &patch_version)); + EXPECT_EQ(major_version, version_info::GetMajorVersionNumber()); + EXPECT_EQ(minor_version, "0"); + EXPECT_NE(build_version, "0"); + EXPECT_EQ(patch_version, "0"); } TEST_F(UserAgentUtilsTest, GetUserAgent) {
diff --git a/components/fuchsia_component_support/BUILD.gn b/components/fuchsia_component_support/BUILD.gn index 21afde6..f007975 100644 --- a/components/fuchsia_component_support/BUILD.gn +++ b/components/fuchsia_component_support/BUILD.gn
@@ -13,7 +13,7 @@ ":unit_tests", "//chromecast/internal/*", "//fuchsia/engine/*", - "//fuchsia/runners/*", + "//fuchsia_web/runners/*", ] public = [ "config_reader.h",
diff --git a/components/gcm_driver/crypto/encryption_header_parsers.cc b/components/gcm_driver/crypto/encryption_header_parsers.cc index b70dc527..a695f354 100644 --- a/components/gcm_driver/crypto/encryption_header_parsers.cc +++ b/components/gcm_driver/crypto/encryption_header_parsers.cc
@@ -83,16 +83,16 @@ const base::StringPiece name = name_value_pairs.name_piece(); const base::StringPiece value = name_value_pairs.value_piece(); - if (base::LowerCaseEqualsASCII(name, "keyid")) { + if (base::EqualsCaseInsensitiveASCII(name, "keyid")) { if (found_keyid) return false; keyid_.assign(value.data(), value.size()); found_keyid = true; - } else if (base::LowerCaseEqualsASCII(name, "salt")) { + } else if (base::EqualsCaseInsensitiveASCII(name, "salt")) { if (found_salt || !ValueToDecodedString(value, &salt_)) return false; found_salt = true; - } else if (base::LowerCaseEqualsASCII(name, "rs")) { + } else if (base::EqualsCaseInsensitiveASCII(name, "rs")) { if (found_rs || !RecordSizeToInt(value, &rs_)) return false; found_rs = true; @@ -132,16 +132,16 @@ const base::StringPiece name = name_value_pairs.name_piece(); const base::StringPiece value = name_value_pairs.value_piece(); - if (base::LowerCaseEqualsASCII(name, "keyid")) { + if (base::EqualsCaseInsensitiveASCII(name, "keyid")) { if (found_keyid) return false; keyid_.assign(value.data(), value.size()); found_keyid = true; - } else if (base::LowerCaseEqualsASCII(name, "aesgcm128")) { + } else if (base::EqualsCaseInsensitiveASCII(name, "aesgcm128")) { if (found_aesgcm128 || !ValueToDecodedString(value, &aesgcm128_)) return false; found_aesgcm128 = true; - } else if (base::LowerCaseEqualsASCII(name, "dh")) { + } else if (base::EqualsCaseInsensitiveASCII(name, "dh")) { if (found_dh || !ValueToDecodedString(value, &dh_)) return false; found_dh = true;
diff --git a/components/history_clusters/core/config.h b/components/history_clusters/core/config.h index 9ed8b632..b360353 100644 --- a/components/history_clusters/core/config.h +++ b/components/history_clusters/core/config.h
@@ -74,7 +74,10 @@ bool omnibox_action = false; // If enabled, allows the Omnibox Action chip to also appear on URLs. This - // does nothing if `omnibox_action` is disabled. + // does nothing if `omnibox_action` is disabled. Note, that if you turn this + // flag to true, you almost certainly will want to set + // `omnibox_action_on_navigation_intents` to true as well, as otherwise your + // desired action chips on URLs will almost certainly all be suppressed. bool omnibox_action_on_urls = false; // If enabled, allows the Omnibox Action chip to appear on URLs from noisy @@ -85,7 +88,7 @@ // user is intending to perform a navigation. This does not affect which // suggestions are allowed to display the chip. Does nothing if // `omnibox_action` is disabled. - bool omnibox_action_on_navigation_intents = true; + bool omnibox_action_on_navigation_intents = false; // If `omnibox_action_on_navigation_intents` is enabled, this threshold // helps determine when the user is intending to perform a navigation. @@ -93,7 +96,7 @@ // If enabled, allows the Omnibox Action chip to appear when the suggestions // contain pedals. Does nothing if `omnibox_action` is disabled. - bool omnibox_action_with_pedals = true; + bool omnibox_action_with_pedals = false; // If enabled, adds the keywords of aliases for detected entity names to a // cluster.
diff --git a/components/metrics/metrics_pref_names.cc b/components/metrics/metrics_pref_names.cc index d7be87e..b5e39cb 100644 --- a/components/metrics/metrics_pref_names.cc +++ b/components/metrics/metrics_pref_names.cc
@@ -12,6 +12,18 @@ // Note: the 'uninstall_metrics' name is a legacy name and doesn't mean much. const char kInstallDate[] = "uninstall_metrics.installation_date2"; +// A provisional metrics client GUID used for field trial group assignments +// before metrics reporting consent is known (i.e., during first run). This GUID +// is never reported directly. However, if the user enables UMA, this +// provisional client GUID becomes the metrics client GUID (see +// |kMetricsClientID|), and this pref is cleared. In that case, the GUID may +// be reported. +// Note: This GUID is stored in prefs because it is possible that the user +// closes Chrome during the FRE. We re-use this GUID in subsequent FRE runs +// until metrics reporting consent is truly known. +const char kMetricsProvisionalClientID[] = + "user_experience_metrics.provisional_client_id"; + // The metrics client GUID. // Note: The name client_id2 is a result of creating // new prefs to do a one-time reset of the previous values.
diff --git a/components/metrics/metrics_pref_names.h b/components/metrics/metrics_pref_names.h index 20eb93c4..ec9bbe74 100644 --- a/components/metrics/metrics_pref_names.h +++ b/components/metrics/metrics_pref_names.h
@@ -20,6 +20,7 @@ extern const char kMetricsInitialLogsMetadata[]; extern const char kMetricsLowEntropySource[]; extern const char kMetricsOldLowEntropySource[]; +extern const char kMetricsProvisionalClientID[]; extern const char kMetricsPseudoLowEntropySource[]; extern const char kMetricsMachineId[]; extern const char kMetricsOngoingLogs[];
diff --git a/components/metrics/metrics_state_manager.cc b/components/metrics/metrics_state_manager.cc index b73db9f..6bbfe4b 100644 --- a/components/metrics/metrics_state_manager.cc +++ b/components/metrics/metrics_state_manager.cc
@@ -28,6 +28,7 @@ #include "base/strings/stringprintf.h" #include "base/threading/thread_restrictions.h" #include "base/time/time.h" +#include "build/branding_buildflags.h" #include "build/build_config.h" #include "components/metrics/cloned_install_detector.h" #include "components/metrics/enabled_state_provider.h" @@ -226,6 +227,9 @@ // static bool MetricsStateManager::instance_exists_ = false; +// static +bool MetricsStateManager::enable_provisional_client_id_for_testing_ = false; + MetricsStateManager::MetricsStateManager( PrefService* local_state, EnabledStateProvider* enabled_state_provider, @@ -283,33 +287,26 @@ #endif // BUILDFLAG(IS_ANDROID) } -#if !BUILDFLAG(IS_WIN) - if (is_first_run) { - // If this is a first run (no install date) and there's no client id, then - // generate a provisional client id now. This id will be used for field - // trial randomization on first run and will be promoted to become the - // client id if UMA is enabled during this session, via the logic in - // ForceClientIdCreation(). - // - // Note: We don't do this on Windows because on Windows, there's no UMA - // checkbox on first run and instead it comes from the install page. So if - // UMA is not enabled at this point, it's unlikely it will be enabled in - // the same session since that requires the user to manually do that via - // settings page after they unchecked it on the download page. - // - // Note: Windows first run is covered by browser tests - // FirstRunMasterPrefsVariationsSeedTest.PRE_SecondRun and - // FirstRunMasterPrefsVariationsSeedTest.SecondRun. If the platform ifdef - // for this logic changes, the tests should be updated as well. - if (client_id_.empty()) - provisional_client_id_ = base::GenerateGUID(); + // Generate and store a provisional client ID if necessary. This ID will be + // used for field trial randomization on first run (and possibly in future + // runs if the user closes Chrome during the FRE) and will be promoted to + // become the client ID if UMA is enabled during this session, via the logic + // in ForceClientIdCreation(). If UMA is disabled (refused), we discard it. + // + // Note: This means that if a provisional client ID is used for this session, + // and the user disables (refuses) UMA, then starting from the next run, the + // field trial randomization (group assignment) will be different. + if (ShouldGenerateProvisionalClientId(is_first_run)) { + local_state_->SetString(prefs::kMetricsProvisionalClientID, + base::GenerateGUID()); } -#endif // !BUILDFLAG(IS_WIN) // The |initial_client_id_| should only be set if UMA is enabled or there's a // provisional client id. initial_client_id_ = - (client_id_.empty() ? provisional_client_id_ : client_id_); + (client_id_.empty() + ? local_state_->GetString(prefs::kMetricsProvisionalClientID) + : client_id_); DCHECK(!instance_exists_); instance_exists_ = true; } @@ -501,7 +498,9 @@ // so generate a new one. If there's a provisional client id (e.g. UMA // was enabled as part of first run), promote that to the client id, // otherwise (e.g. UMA enabled in a future session), generate a new one. - if (provisional_client_id_.empty()) { + std::string provisional_client_id = + local_state_->GetString(prefs::kMetricsProvisionalClientID); + if (provisional_client_id.empty()) { client_id_ = base::GenerateGUID(); base::UmaHistogramEnumeration("UMA.ClientIdSource", ClientIdSource::kClientIdNew); @@ -511,8 +510,8 @@ previous_client_id); #endif // BUILDFLAG(IS_CHROMEOS_ASH) } else { - client_id_ = provisional_client_id_; - provisional_client_id_.clear(); + client_id_ = provisional_client_id; + local_state_->ClearPref(prefs::kMetricsProvisionalClientID); base::UmaHistogramEnumeration("UMA.ClientIdSource", ClientIdSource::kClientIdFromProvisionalId); #if BUILDFLAG(IS_CHROMEOS_ASH) @@ -593,6 +592,8 @@ // static void MetricsStateManager::RegisterPrefs(PrefRegistrySimple* registry) { + registry->RegisterStringPref(prefs::kMetricsProvisionalClientID, + std::string()); registry->RegisterStringPref(prefs::kMetricsClientID, std::string()); registry->RegisterInt64Pref(prefs::kMetricsReportingEnabledTimestamp, 0); registry->RegisterInt64Pref(prefs::kInstallDate, 0); @@ -672,6 +673,55 @@ store_client_info_.Run(ClientInfo()); } +bool MetricsStateManager::ShouldGenerateProvisionalClientId(bool is_first_run) { +#if BUILDFLAG(IS_WIN) + // We do not want to generate a provisional client ID on Windows because + // there's no UMA checkbox on first run. Instead it comes from the install + // page. So if UMA is not enabled at this point, it's unlikely it will be + // enabled in the same session since that requires the user to manually do + // that via settings page after they unchecked it on the download page. + // + // Note: Windows first run is covered by browser tests + // FirstRunMasterPrefsVariationsSeedTest.PRE_SecondRun and + // FirstRunMasterPrefsVariationsSeedTest.SecondRun. If the platform ifdef + // for this logic changes, the tests should be updated as well. + return false; +#else + // We should only generate a provisional client ID on the first run. If for + // some reason there is already a client ID, we do not generate one either. + // This can happen if metrics reporting is managed by a policy. + if (!is_first_run || !client_id_.empty()) + return false; + + // Return false if |kMetricsReportingEnabled| is managed by a policy. For + // example, if metrics reporting is disabled by a policy, then + // |kMetricsReportingEnabled| will always be set to false, so there is no + // reason to generate a provisional client ID. If metrics reporting is enabled + // by a policy, then the default value of |kMetricsReportingEnabled| will be + // true, and so a client ID will have already been generated (we would have + // returned false already because of the previous check). + if (local_state_->IsManagedPreference(prefs::kMetricsReportingEnabled)) + return false; + + // If this is a non-Google-Chrome-branded build, we do not want to generate a + // provisional client ID because metrics reporting is not enabled on those + // builds. This would be problematic because we store the provisional client + // ID in the Local State, and clear it when either 1) we enable UMA (the + // provisional client ID becomes the client ID), or 2) we disable UMA. Since + // in non-Google-Chrome-branded builds we never actually go through the code + // paths to either enable or disable UMA, the pref storing the provisional + // client ID would never be cleared. However, for test consistency between + // the different builds, we do not return false here if + // |enable_provisional_client_id_for_testing_| is set to true. + if (!BUILDFLAG(GOOGLE_CHROME_BRANDING) && + !enable_provisional_client_id_for_testing_) { + return false; + } + + return true; +#endif // BUILDFLAG(IS_WIN) +} + #if BUILDFLAG(IS_CHROMEOS_ASH) void MetricsStateManager::LogClientIdChanged( metrics::structured::NeutrinoDevicesLocation location,
diff --git a/components/metrics/metrics_state_manager.h b/components/metrics/metrics_state_manager.h index 27128fc..513efe4 100644 --- a/components/metrics/metrics_state_manager.h +++ b/components/metrics/metrics_state_manager.h
@@ -215,7 +215,7 @@ FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest, ProvisionalClientId_PromotedToClientId); FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest, - ProvisionalClientId_NotPersisted); + ProvisionalClientId_PersistedAcrossFirstRuns); FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest, ResetBackup); FRIEND_TEST_ALL_PREFIXES(MetricsStateManagerTest, ResetMetricsIDs); @@ -284,7 +284,7 @@ // Returns the high entropy source for this client, which is composed of a // client ID and the low entropy source. This is intended to be unique for // each install. UMA must be enabled (and |client_id_| must be set) or - // |provisional_client_id_| must be set before calling this. + // |kMetricsProvisionalClientID| must be set before calling this. std::string GetHighEntropySource(); // Returns the old low entropy source for this client. @@ -309,6 +309,8 @@ // pref is true. void ResetMetricsIDsIfNecessary(); + bool ShouldGenerateProvisionalClientId(bool is_first_run); + #if BUILDFLAG(IS_CHROMEOS_ASH) // Log to structured metrics when the client id is changed. void LogClientIdChanged(metrics::structured::NeutrinoDevicesLocation location, @@ -341,14 +343,6 @@ // The identifier that's sent to the server with the log reports. std::string client_id_; - // A provisional client id that's generated at start up before we know whether - // metrics consent has been received from the client. This id becomes the - // |client_id_| if consent is given within the same session, or is cleared - // otherwise. Does not control transmission of UMA metrics, only used for the - // high entropy source used for field trial randomization so that field - // trials don't toggle state between first and second run. - std::string provisional_client_id_; - // The client id that was used do field trial randomization. This field should // only be changed when we need to do group assignment. |initial_client_id| // should left blank iff a client id was not used to do field trial @@ -384,6 +378,10 @@ // used only during startup. On Android WebLayer, Android WebView, and iOS, // the visibility is unknown at this point in startup. const StartupVisibility startup_visibility_; + + // Force enables the creation of a provisional client ID on first run even if + // this is not a Chrome-branded build. Used for testing. + static bool enable_provisional_client_id_for_testing_; }; } // namespace metrics
diff --git a/components/metrics/metrics_state_manager_unittest.cc b/components/metrics/metrics_state_manager_unittest.cc index caab1380..1c7efc1 100644 --- a/components/metrics/metrics_state_manager_unittest.cc +++ b/components/metrics/metrics_state_manager_unittest.cc
@@ -322,15 +322,21 @@ #if !BUILDFLAG(IS_WIN) TEST_F(MetricsStateManagerTest, ProvisionalClientId_PromotedToClientId) { + // Force enable the creation of a provisional client ID on first run for + // consistency between Chromium and Chrome builds. + MetricsStateManager::enable_provisional_client_id_for_testing_ = true; + std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager()); // Verify that there was a provisional client id created. - std::string provisional_client_id = state_manager->provisional_client_id_; + std::string provisional_client_id = + prefs_.GetString(prefs::kMetricsProvisionalClientID); VerifyClientId(provisional_client_id); // No client id should have been stored. EXPECT_TRUE(prefs_.FindPreference(prefs::kMetricsClientID)->IsDefaultValue()); int low_entropy_source = state_manager->GetLowEntropySource(); - // The default entropy provider should be the high entropy one. + // The default entropy provider should be the high entropy one since we a + // the provisional client ID. state_manager->CreateDefaultEntropyProvider(); EXPECT_EQ(state_manager->entropy_source_returned(), MetricsStateManager::ENTROPY_SOURCE_HIGH); @@ -342,45 +348,53 @@ std::string client_id = state_manager->client_id(); EXPECT_EQ(provisional_client_id, client_id); EXPECT_EQ(prefs_.GetString(prefs::kMetricsClientID), client_id); - EXPECT_TRUE(state_manager->provisional_client_id_.empty()); + EXPECT_TRUE(prefs_.FindPreference(prefs::kMetricsProvisionalClientID) + ->IsDefaultValue()); + EXPECT_TRUE(prefs_.GetString(prefs::kMetricsProvisionalClientID).empty()); EXPECT_EQ(state_manager->GetLowEntropySource(), low_entropy_source); EXPECT_EQ(client_info_load_count_, 1); } -TEST_F(MetricsStateManagerTest, ProvisionalClientId_NotPersisted) { - std::string provisional_client_id; - int low_entropy_source; +TEST_F(MetricsStateManagerTest, ProvisionalClientId_PersistedAcrossFirstRuns) { + // Force enable the creation of a provisional client ID on first run for + // consistency between Chromium and Chrome builds. + MetricsStateManager::enable_provisional_client_id_for_testing_ = true; - // First run, with a provisional client id. + std::string provisional_client_id; + + // Simulate a first run, and verify that a provisional client id is generated. + // We also do not enable nor disable UMA in order to simulate exiting during + // the first run flow. { std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager()); // Verify that there was a provisional client id created. - std::string provisional_client_id = state_manager->provisional_client_id_; + provisional_client_id = + prefs_.GetString(prefs::kMetricsProvisionalClientID); VerifyClientId(provisional_client_id); // No client id should have been stored. EXPECT_TRUE( prefs_.FindPreference(prefs::kMetricsClientID)->IsDefaultValue()); - low_entropy_source = state_manager->GetLowEntropySource(); - // The default entropy provider should be the high entropy one. + // The default entropy provider should be the high entropy one since we a + // the provisional client ID. state_manager->CreateDefaultEntropyProvider(); EXPECT_EQ(state_manager->entropy_source_returned(), MetricsStateManager::ENTROPY_SOURCE_HIGH); } - // Now, simulate a second run, such that UMA was not turned on during the - // first run. This should not result in any client id existing nor any - // provisional client id. + // Now, simulate a second run, and verify that the provisional client ID is + // the same. { std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager()); - EXPECT_TRUE(state_manager->provisional_client_id_.empty()); - EXPECT_TRUE(state_manager->client_id().empty()); - EXPECT_EQ(state_manager->GetLowEntropySource(), low_entropy_source); - EXPECT_TRUE( - prefs_.FindPreference(prefs::kMetricsClientID)->IsDefaultValue()); - // The default entropy provider should be the low entropy one. + // Verify that the same provisional client ID as the first run is used. + EXPECT_EQ(provisional_client_id, + prefs_.GetString(prefs::kMetricsProvisionalClientID)); + // There still should not be any stored client ID. + EXPECT_TRUE(prefs_.FindPreference(prefs::kMetricsClientID)); + // The default entropy provider should be the high entropy one since we a + // the provisional client ID. state_manager->CreateDefaultEntropyProvider(); EXPECT_EQ(state_manager->entropy_source_returned(), - MetricsStateManager::ENTROPY_SOURCE_LOW); + MetricsStateManager::ENTROPY_SOURCE_HIGH); } } #endif // !BUILDFLAG(IS_WIN)
diff --git a/components/metrics/unsent_log_store.cc b/components/metrics/unsent_log_store.cc index 6b0ce7ce..1db3af5 100644 --- a/components/metrics/unsent_log_store.cc +++ b/components/metrics/unsent_log_store.cc
@@ -290,10 +290,12 @@ std::vector<std::unique_ptr<LogInfo>> trimmed_list; size_t bytes_used = 0; - // The distance of the staged log from the end of the list of logs. Usually - // this is 0 (end of list). We mark so we can correct adjust the - // staged_log_index after log trimming. - size_t staged_index_distance = 0; + // The distance of the staged log from the end of the list of logs, which is + // usually 0 (end of list). This is used in case there is currently a staged + // log, which may or may not get trimmed. We want to keep track of the new + // position of the staged log after trimming so that we can update + // |staged_log_index_|. + absl::optional<size_t> staged_index_distance; // Reverse order, so newest ones are prioritized. for (int i = list_.size() - 1; i >= 0; --i) { @@ -330,8 +332,14 @@ // We may need to adjust the staged index since the number of logs may be // reduced. However, we want to make sure not to change the index if there is // no log staged. - if (staged_log_index_ != -1) { - staged_log_index_ = list_.size() - 1 - staged_index_distance; + if (staged_index_distance.has_value()) { + staged_log_index_ = list_.size() - 1 - staged_index_distance.value(); + } else { + // Set |staged_log_index_| to -1. It might already be -1. E.g., at the time + // we are trimming logs, there was no staged log. However, it is also + // possible that we trimmed away the staged log, so we need to update the + // index to -1. + staged_log_index_ = -1; } }
diff --git a/components/metrics/unsent_log_store_unittest.cc b/components/metrics/unsent_log_store_unittest.cc index c79ce10..be2888e5 100644 --- a/components/metrics/unsent_log_store_unittest.cc +++ b/components/metrics/unsent_log_store_unittest.cc
@@ -296,6 +296,44 @@ result_unsent_log_store.ExpectNextLog(target_log); } +// Store a set of logs over the length limit, and over the minimum number of +// bytes. The first log will be a staged log that should be trimmed away. This +// should make the log store not have a staged log anymore. +TEST_F(UnsentLogStoreTest, TrimStagedLog) { + TestUnsentLogStore unsent_log_store(&prefs_, kLogByteLimit); + + // Make each log byte count the limit. + size_t log_size = kLogByteLimit; + + // Create a target log that will be the staged log that we want to trim away. + std::string target_log = "First that should be trimmed"; + target_log += GenerateLogWithMinCompressedSize(log_size); + LogMetadata log_metadata; + unsent_log_store.StoreLog(target_log, log_metadata); + unsent_log_store.StageNextLog(); + EXPECT_TRUE(unsent_log_store.has_staged_log()); + + // Add |kLogCountLimit| additional logs. + std::string log_data = GenerateLogWithMinCompressedSize(log_size); + for (size_t i = 0; i < kLogCountLimit; ++i) { + unsent_log_store.StoreLog(log_data, log_metadata); + } + + EXPECT_EQ(kLogCountLimit + 1, unsent_log_store.size()); + unsent_log_store.TrimAndPersistUnsentLogs(); + + // Verify that the first log (the staged one) was trimmed away, and that the + // log store does not consider to have any staged log anymore. The other logs + // are not trimmed because the most recent logs are prioritized and we trim + // until we have |kLogCountLimit| logs. + EXPECT_EQ(kLogCountLimit, unsent_log_store.size()); + EXPECT_FALSE(unsent_log_store.has_staged_log()); + // Verify that all of the logs in the log store are not the |target_log|. + while (unsent_log_store.size() > 0) { + unsent_log_store.ExpectNextLog(log_data); + } +} + // Check that the store/stage/discard functions work as expected. TEST_F(UnsentLogStoreTest, Staging) { TestUnsentLogStore unsent_log_store(&prefs_, kLogByteLimit);
diff --git a/components/password_manager/core/browser/ui/credential_ui_entry.cc b/components/password_manager/core/browser/ui/credential_ui_entry.cc index b0b19fb..4b08a2ca 100644 --- a/components/password_manager/core/browser/ui/credential_ui_entry.cc +++ b/components/password_manager/core/browser/ui/credential_ui_entry.cc
@@ -8,8 +8,6 @@ namespace password_manager { -CredentialUIEntry::CredentialUIEntry() = default; - CredentialUIEntry::CredentialUIEntry(const PasswordForm& form) : signon_realm(form.signon_realm), url(form.url),
diff --git a/components/password_manager/core/browser/ui/credential_ui_entry.h b/components/password_manager/core/browser/ui/credential_ui_entry.h index a5bd721..da72546 100644 --- a/components/password_manager/core/browser/ui/credential_ui_entry.h +++ b/components/password_manager/core/browser/ui/credential_ui_entry.h
@@ -20,7 +20,6 @@ // construction from PasswordForm for convenience. A single entry might // correspond to multiple PasswordForms. struct CredentialUIEntry { - CredentialUIEntry(); explicit CredentialUIEntry(const PasswordForm& form); CredentialUIEntry(const CredentialUIEntry& other); CredentialUIEntry(CredentialUIEntry&& other);
diff --git a/components/password_manager/core/browser/ui/insecure_credentials_manager.cc b/components/password_manager/core/browser/ui/insecure_credentials_manager.cc index 9540153..d7d4ae02 100644 --- a/components/password_manager/core/browser/ui/insecure_credentials_manager.cc +++ b/components/password_manager/core/browser/ui/insecure_credentials_manager.cc
@@ -285,30 +285,22 @@ if (it == credentials_to_forms_.end()) return false; - // Mute all matching compromised credentials from the store. - // For a match, all insecureity types saved in the store are muted. - // Return whether any credentials were muted. const auto& saved_passwords = it->second.forms; - bool muted = false; - for (const PasswordForm& saved_password : saved_passwords) { - PasswordForm form_to_update = saved_password; - bool form_changed = false; - for (const auto& password_issue : saved_password.password_issues) { - if (!password_issue.second.is_muted.value() && - SupportsMuteOperation(password_issue.first)) { - form_to_update.password_issues.insert_or_assign( - password_issue.first, - InsecurityMetadata(password_issue.second.create_time, - IsMuted(true))); - form_changed = true; - } - } - if (form_changed) { - GetStoreFor(saved_password).UpdateLogin(form_to_update); - muted = true; + DCHECK(!saved_passwords.empty()); + + return MuteCredential(CredentialUIEntry(saved_passwords[0])); +} + +bool InsecureCredentialsManager::MuteCredential( + const CredentialUIEntry& credential) { + CredentialUIEntry updated_credential = credential; + for (auto& password_issue : updated_credential.password_issues) { + if (!password_issue.second.is_muted.value() && + SupportsMuteOperation(password_issue.first)) { + password_issue.second.is_muted = IsMuted(true); } } - return muted; + return presenter_->EditSavedCredentials(updated_credential); } bool InsecureCredentialsManager::UnmuteCredential( @@ -317,31 +309,22 @@ if (it == credentials_to_forms_.end()) return false; - // Unmute all matching compromised credentials from the store. - // For a match, all insecureity types saved in the store are unmuted. - // Return whether any credentials were unmuted. const auto& saved_passwords = it->second.forms; - bool unmuted = false; + DCHECK(!saved_passwords.empty()); - for (const PasswordForm& saved_password : saved_passwords) { - PasswordForm form_to_update = saved_password; - bool form_changed = false; - for (const auto& password_issue : saved_password.password_issues) { - if (password_issue.second.is_muted.value() && - SupportsMuteOperation(password_issue.first)) { - form_to_update.password_issues.insert_or_assign( - password_issue.first, - InsecurityMetadata(password_issue.second.create_time, - IsMuted(false))); - form_changed = true; - } - } - if (form_changed) { - GetStoreFor(saved_password).UpdateLogin(form_to_update); - unmuted = true; + return UnmuteCredential(CredentialUIEntry(saved_passwords[0])); +} + +bool InsecureCredentialsManager::UnmuteCredential( + const CredentialUIEntry& credential) { + CredentialUIEntry updated_credential = credential; + for (auto& password_issue : updated_credential.password_issues) { + if (password_issue.second.is_muted.value() && + SupportsMuteOperation(password_issue.first)) { + password_issue.second.is_muted = IsMuted(false); } } - return unmuted; + return presenter_->EditSavedCredentials(updated_credential); } bool InsecureCredentialsManager::UpdateCredential(
diff --git a/components/password_manager/core/browser/ui/insecure_credentials_manager.h b/components/password_manager/core/browser/ui/insecure_credentials_manager.h index 905c3d8..20cf5eb 100644 --- a/components/password_manager/core/browser/ui/insecure_credentials_manager.h +++ b/components/password_manager/core/browser/ui/insecure_credentials_manager.h
@@ -189,11 +189,15 @@ // Attempts to mute |credential| from the password store. // Returns whether the mute succeeded. + // TODO(crbug.com/1330549): Use CredentialUIEntry only. bool MuteCredential(const CredentialView& credential); + bool MuteCredential(const CredentialUIEntry& credential); // Attempts to unmute |credential| from the password store. // Returns whether the unmute succeeded. + // TODO(crbug.com/1330549): Use CredentialUIEntry only. bool UnmuteCredential(const CredentialView& credential); + bool UnmuteCredential(const CredentialUIEntry& credential); // Returns a vector of currently insecure credentials. // TODO(crbug.com/1330549): Use CredentialUIEntry only.
diff --git a/components/password_manager/core/browser/ui/insecure_credentials_manager_unittest.cc b/components/password_manager/core/browser/ui/insecure_credentials_manager_unittest.cc index 8778292..ddbabe54 100644 --- a/components/password_manager/core/browser/ui/insecure_credentials_manager_unittest.cc +++ b/components/password_manager/core/browser/ui/insecure_credentials_manager_unittest.cc
@@ -705,14 +705,16 @@ store().AddLogin(password); RunUntilIdle(); - CredentialWithPassword expected = MakeCompromisedCredential(password); + ASSERT_THAT(provider().GetInsecureCredentialEntries(), + ElementsAre(CredentialUIEntry(password))); - EXPECT_THAT(provider().GetInsecureCredentials(), ElementsAre(expected)); - EXPECT_FALSE(provider().GetInsecureCredentials()[0].is_muted); - - EXPECT_TRUE(provider().MuteCredential(expected)); + EXPECT_TRUE(provider().MuteCredential(CredentialUIEntry(password))); RunUntilIdle(); - EXPECT_TRUE(provider().GetInsecureCredentials()[0].is_muted); + + EXPECT_TRUE(provider() + .GetInsecureCredentialEntries()[0] + .password_issues.at(InsecureType::kLeaked) + .is_muted.value()); EXPECT_TRUE(store() .stored_passwords() .at(kExampleCom) @@ -730,15 +732,15 @@ store().AddLogin(password); RunUntilIdle(); - CredentialWithPassword expected = MakeCompromisedCredential( - password, InsecureCredentialTypeFlags::kCredentialLeaked, true); + ASSERT_THAT(provider().GetInsecureCredentialEntries(), + ElementsAre(CredentialUIEntry(password))); - EXPECT_THAT(provider().GetInsecureCredentials(), ElementsAre(expected)); - EXPECT_TRUE(provider().GetInsecureCredentials()[0].is_muted); - - EXPECT_TRUE(provider().UnmuteCredential(expected)); + EXPECT_TRUE(provider().UnmuteCredential(CredentialUIEntry(password))); RunUntilIdle(); - EXPECT_FALSE(provider().GetInsecureCredentials()[0].is_muted); + EXPECT_FALSE(provider() + .GetInsecureCredentialEntries()[0] + .password_issues.at(InsecureType::kLeaked) + .is_muted.value()); EXPECT_FALSE(store() .stored_passwords() .at(kExampleCom) @@ -757,15 +759,15 @@ store().AddLogin(password); RunUntilIdle(); - CredentialWithPassword expected = MakeCompromisedCredential( - password, InsecureCredentialTypeFlags::kCredentialLeaked, false); + ASSERT_THAT(provider().GetInsecureCredentialEntries(), + ElementsAre(CredentialUIEntry(password))); - EXPECT_THAT(provider().GetInsecureCredentials(), ElementsAre(expected)); - EXPECT_FALSE(provider().GetInsecureCredentials()[0].is_muted); - - EXPECT_FALSE(provider().UnmuteCredential(expected)); + EXPECT_FALSE(provider().UnmuteCredential(CredentialUIEntry(password))); RunUntilIdle(); - EXPECT_FALSE(provider().GetInsecureCredentials()[0].is_muted); + EXPECT_FALSE(provider() + .GetInsecureCredentialEntries()[0] + .password_issues.at(InsecureType::kLeaked) + .is_muted.value()); EXPECT_FALSE(store() .stored_passwords() .at(kExampleCom) @@ -787,19 +789,19 @@ store().AddLogin(password); RunUntilIdle(); - CredentialWithPassword expected = MakeCompromisedCredential( - password, - InsecureCredentialTypeFlags::kCredentialLeaked | - InsecureCredentialTypeFlags::kCredentialPhished, - true); + ASSERT_THAT(provider().GetInsecureCredentialEntries(), + ElementsAre(CredentialUIEntry(password))); - EXPECT_THAT(provider().GetInsecureCredentials(), ElementsAre(expected)); - - EXPECT_TRUE(provider().GetInsecureCredentials()[0].is_muted); - - EXPECT_TRUE(provider().UnmuteCredential(expected)); + EXPECT_TRUE(provider().UnmuteCredential(CredentialUIEntry(password))); RunUntilIdle(); - EXPECT_FALSE(provider().GetInsecureCredentials()[0].is_muted); + EXPECT_FALSE(provider() + .GetInsecureCredentialEntries()[0] + .password_issues.at(InsecureType::kLeaked) + .is_muted.value()); + EXPECT_FALSE(provider() + .GetInsecureCredentialEntries()[0] + .password_issues.at(InsecureType::kPhished) + .is_muted.value()); EXPECT_FALSE(store() .stored_passwords() .at(kExampleCom) @@ -831,22 +833,17 @@ store().AddLogin(password); RunUntilIdle(); - CredentialWithPassword expected = MakeCompromisedCredential( - password, - InsecureCredentialTypeFlags::kCredentialLeaked | - InsecureCredentialTypeFlags::kCredentialPhished | - InsecureCredentialTypeFlags::kReusedCredential | - InsecureCredentialTypeFlags::kWeakCredential, - true); + ASSERT_THAT(provider().GetInsecureCredentialEntries(), + ElementsAre(CredentialUIEntry(password))); - EXPECT_THAT(provider().GetInsecureCredentials(), ElementsAre(expected)); - - EXPECT_TRUE(provider().GetInsecureCredentials()[0].is_muted); - - EXPECT_TRUE(provider().UnmuteCredential(expected)); + EXPECT_TRUE(provider().UnmuteCredential(CredentialUIEntry(password))); RunUntilIdle(); - EXPECT_FALSE(provider().GetInsecureCredentials()[0].is_muted); + PasswordForm expected = password; + expected.password_issues[InsecureType::kLeaked].is_muted = IsMuted(false); + expected.password_issues[InsecureType::kPhished].is_muted = IsMuted(false); + EXPECT_THAT(provider().GetInsecureCredentialEntries(), + ElementsAre(CredentialUIEntry(expected))); EXPECT_FALSE(store() .stored_passwords() .at(kExampleCom) @@ -882,15 +879,13 @@ store().AddLogin(password); RunUntilIdle(); - CredentialWithPassword expected = MakeCompromisedCredential( - password, InsecureCredentialTypeFlags::kCredentialLeaked, true); + ASSERT_THAT(provider().GetInsecureCredentialEntries(), + ElementsAre(CredentialUIEntry(password))); - EXPECT_THAT(provider().GetInsecureCredentials(), ElementsAre(expected)); - EXPECT_TRUE(provider().GetInsecureCredentials()[0].is_muted); - - EXPECT_FALSE(provider().MuteCredential(expected)); + EXPECT_FALSE(provider().MuteCredential(CredentialUIEntry(password))); RunUntilIdle(); - EXPECT_TRUE(provider().GetInsecureCredentials()[0].is_muted); + EXPECT_THAT(provider().GetInsecureCredentialEntries(), + ElementsAre(CredentialUIEntry(password))); EXPECT_TRUE(store() .stored_passwords() .at(kExampleCom) @@ -913,19 +908,16 @@ store().AddLogin(password); RunUntilIdle(); - CredentialWithPassword expected = MakeCompromisedCredential( - password, - InsecureCredentialTypeFlags::kCredentialLeaked | - InsecureCredentialTypeFlags::kCredentialPhished, - false); + ASSERT_THAT(provider().GetInsecureCredentialEntries(), + ElementsAre(CredentialUIEntry(password))); - EXPECT_THAT(provider().GetInsecureCredentials(), ElementsAre(expected)); - - EXPECT_FALSE(provider().GetInsecureCredentials()[0].is_muted); - - EXPECT_TRUE(provider().MuteCredential(expected)); + EXPECT_TRUE(provider().MuteCredential(CredentialUIEntry(password))); RunUntilIdle(); - EXPECT_TRUE(provider().GetInsecureCredentials()[0].is_muted); + PasswordForm expected = password; + expected.password_issues[InsecureType::kLeaked].is_muted = IsMuted(true); + expected.password_issues[InsecureType::kPhished].is_muted = IsMuted(true); + EXPECT_THAT(provider().GetInsecureCredentialEntries(), + ElementsAre(CredentialUIEntry(expected))); EXPECT_TRUE(store() .stored_passwords() .at(kExampleCom) @@ -958,23 +950,18 @@ store().AddLogin(password); RunUntilIdle(); - CredentialWithPassword expected = MakeCompromisedCredential( - password, - InsecureCredentialTypeFlags::kCredentialLeaked | - InsecureCredentialTypeFlags::kCredentialPhished | - InsecureCredentialTypeFlags::kWeakCredential | - InsecureCredentialTypeFlags::kReusedCredential, - false); + ASSERT_THAT(provider().GetInsecureCredentialEntries(), + ElementsAre(CredentialUIEntry(password))); - EXPECT_THAT(provider().GetInsecureCredentials(), ElementsAre(expected)); - - EXPECT_FALSE(provider().GetInsecureCredentials()[0].is_muted); - - EXPECT_TRUE(provider().MuteCredential(expected)); + EXPECT_TRUE(provider().MuteCredential(CredentialUIEntry(password))); RunUntilIdle(); - EXPECT_TRUE(provider().GetInsecureCredentials()[0].is_muted); + PasswordForm expected = password; + expected.password_issues[InsecureType::kLeaked].is_muted = IsMuted(true); + expected.password_issues[InsecureType::kPhished].is_muted = IsMuted(true); + EXPECT_THAT(provider().GetInsecureCredentialEntries(), + ElementsAre(CredentialUIEntry(expected))); EXPECT_TRUE(store() .stored_passwords() .at(kExampleCom) @@ -1011,17 +998,13 @@ store().AddLogin(password); RunUntilIdle(); - CredentialWithPassword expected = MakeCompromisedCredential( - password, InsecureCredentialTypeFlags::kWeakCredential, false); + ASSERT_THAT(provider().GetInsecureCredentialEntries(), IsEmpty()); - EXPECT_TRUE(provider().GetInsecureCredentials().empty()); - - EXPECT_FALSE(provider().MuteCredential(expected)); + EXPECT_FALSE(provider().MuteCredential(CredentialUIEntry(password))); RunUntilIdle(); - EXPECT_TRUE(provider().GetInsecureCredentials().empty()); - + EXPECT_THAT(provider().GetInsecureCredentialEntries(), IsEmpty()); EXPECT_FALSE(store() .stored_passwords() .at(kExampleCom) @@ -1040,16 +1023,13 @@ store().AddLogin(password); RunUntilIdle(); - CredentialWithPassword expected = MakeCompromisedCredential( - password, InsecureCredentialTypeFlags::kWeakCredential, false); + ASSERT_THAT(provider().GetInsecureCredentialEntries(), IsEmpty()); - EXPECT_TRUE(provider().GetInsecureCredentials().empty()); - - EXPECT_FALSE(provider().UnmuteCredential(expected)); + EXPECT_FALSE(provider().UnmuteCredential(CredentialUIEntry(password))); RunUntilIdle(); - EXPECT_TRUE(provider().GetInsecureCredentials().empty()); + EXPECT_THAT(provider().GetInsecureCredentialEntries(), IsEmpty()); EXPECT_TRUE(store() .stored_passwords() @@ -1070,17 +1050,13 @@ store().AddLogin(password); RunUntilIdle(); - CredentialWithPassword expected = MakeCompromisedCredential( - password, InsecureCredentialTypeFlags::kReusedCredential, false); + ASSERT_THAT(provider().GetInsecureCredentialEntries(), IsEmpty()); - EXPECT_TRUE(provider().GetInsecureCredentials().empty()); - - EXPECT_FALSE(provider().MuteCredential(expected)); + EXPECT_FALSE(provider().MuteCredential(CredentialUIEntry(password))); RunUntilIdle(); - EXPECT_TRUE(provider().GetInsecureCredentials().empty()); - + EXPECT_THAT(provider().GetInsecureCredentialEntries(), IsEmpty()); EXPECT_FALSE(store() .stored_passwords() .at(kExampleCom) @@ -1099,17 +1075,13 @@ store().AddLogin(password); RunUntilIdle(); - CredentialWithPassword expected = MakeCompromisedCredential( - password, InsecureCredentialTypeFlags::kReusedCredential, false); + ASSERT_THAT(provider().GetInsecureCredentialEntries(), IsEmpty()); - EXPECT_TRUE(provider().GetInsecureCredentials().empty()); - - EXPECT_FALSE(provider().UnmuteCredential(expected)); + EXPECT_FALSE(provider().UnmuteCredential(CredentialUIEntry(password))); RunUntilIdle(); - EXPECT_TRUE(provider().GetInsecureCredentials().empty()); - + EXPECT_THAT(provider().GetInsecureCredentialEntries(), IsEmpty()); EXPECT_TRUE(store() .stored_passwords() .at(kExampleCom)
diff --git a/components/password_manager/core/browser/ui/saved_passwords_presenter.cc b/components/password_manager/core/browser/ui/saved_passwords_presenter.cc index d8da304..ece02a88 100644 --- a/components/password_manager/core/browser/ui/saved_passwords_presenter.cc +++ b/components/password_manager/core/browser/ui/saved_passwords_presenter.cc
@@ -193,10 +193,26 @@ base::ranges::transform(range.first, range.second, std::back_inserter(forms_to_change), [](const auto& pair) { return pair.second; }); + if (forms_to_change.empty()) + return false; + std::u16string new_note = credential.notes.empty() ? u"" : credential.notes[0].value; - return EditSavedPasswords(forms_to_change, credential.username, - credential.password, new_note); + + // TODO(crbug.com/1184691): Merge into a single method. + if (credential.username != forms_to_change[0].username_value || + credential.password != forms_to_change[0].password_value || + credential.notes != forms_to_change[0].notes) { + return EditSavedPasswords(forms_to_change, credential.username, + credential.password, new_note); + } else if (credential.password_issues != forms_to_change[0].password_issues) { + for (auto& old_form : forms_to_change) { + old_form.password_issues = credential.password_issues; + GetStoreFor(old_form).UpdateLogin(old_form); + } + return true; + } + return false; } bool SavedPasswordsPresenter::EditSavedPasswords(
diff --git a/components/performance_manager/features.cc b/components/performance_manager/features.cc index 54e2f96..67ce5ff 100644 --- a/components/performance_manager/features.cc +++ b/components/performance_manager/features.cc
@@ -53,6 +53,9 @@ const base::Feature kHighEfficiencyModeAvailable{ "HighEfficiencyModeAvailable", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kBatterySaverModeAvailable{ + "BatterySaverModeAvailable", base::FEATURE_DISABLED_BY_DEFAULT}; + const base::FeatureParam<base::TimeDelta> kHighEfficiencyModeTimeBeforeDiscard{ &kHighEfficiencyModeAvailable, "time_before_discard", base::Minutes(5)}; #endif
diff --git a/components/performance_manager/public/features.h b/components/performance_manager/public/features.h index c59b8fb..2863748 100644 --- a/components/performance_manager/public/features.h +++ b/components/performance_manager/public/features.h
@@ -61,10 +61,11 @@ // directly from Performance Manager rather than via TabLoader. extern const base::Feature kBackgroundTabLoadingFromPerformanceManager; -// Makes the High-Efficiency Mode available to users. If this is enabled, it -// doesn't mean High-Efficiency Mode is enabled, just that the user has the -// option of toggling it. +// Make the High-Efficiency or Battery Saver Modes available to users. If this +// is enabled, it doesn't mean the specific Mode is enabled, just that the user +// has the option of toggling it. extern const base::Feature kHighEfficiencyModeAvailable; +extern const base::Feature kBatterySaverModeAvailable; // Defines the time in seconds before a background tab is discarded for // High-Efficiency Mode.
diff --git a/components/services/screen_ai/DEPS b/components/services/screen_ai/DEPS index 7a6bb31..30107b9 100644 --- a/components/services/screen_ai/DEPS +++ b/components/services/screen_ai/DEPS
@@ -3,6 +3,7 @@ "+ui/accessibility/ax_enum_util.h", "+ui/accessibility/ax_enums.mojom.h", "+ui/accessibility/ax_node_data.h", + "+ui/accessibility/ax_role_properties.h", "+ui/accessibility/ax_tree_update.h", "+ui/gfx/geometry", ]
diff --git a/components/services/screen_ai/proto/proto_convertor.cc b/components/services/screen_ai/proto/proto_convertor.cc index 5a46c5c..222cdae4 100644 --- a/components/services/screen_ai/proto/proto_convertor.cc +++ b/components/services/screen_ai/proto/proto_convertor.cc
@@ -4,9 +4,19 @@ #include "components/services/screen_ai/proto/proto_convertor.h" -#include <memory> +#include <stdint.h> -#include "base/containers/contains.h" +#include <algorithm> +#include <array> +#include <iterator> +#include <map> +#include <memory> +#include <numeric> +#include <utility> +#include <vector> + +#include "base/check_op.h" +#include "base/notreached.h" #include "components/services/screen_ai/proto/chrome_screen_ai.pb.h" #include "components/services/screen_ai/proto/dimension.pb.h" #include "components/services/screen_ai/proto/view_hierarchy.pb.h" @@ -15,6 +25,7 @@ #include "ui/accessibility/ax_enum_util.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_node_data.h" +#include "ui/accessibility/ax_role_properties.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/geometry/transform.h" @@ -24,38 +35,50 @@ // accepted. // TODO(https://crbug.com/1278249): Add experiment or heuristics to better // adjust this threshold. -const float kScreenAIMinConfidenceThreshold = 0.1; +constexpr float kScreenAIMinConfidenceThreshold = 0.1f; // Returns the next valid ID that can be used for identifying `AXNode`s in the // accessibility tree. ui::AXNodeID GetNextNodeID() { - static int next_node_id = 1; + static ui::AXNodeID next_node_id{1}; return next_node_id++; } -void SerializePredictedType( - const chrome_screen_ai::UIComponent_PredictedType& predicted_type, +// Returns whether the provided `predicted_type` is: +// A) set, and +// B) has a confidence that is above our acceptance threshold. +bool SerializePredictedType( + const chrome_screen_ai::UIComponent::PredictedType& predicted_type, ui::AXNodeData& out_data) { + DCHECK_EQ(out_data.role, ax::mojom::Role::kUnknown); + if (predicted_type.confidence() < 0.0f || + predicted_type.confidence() > 1.0f) { + NOTREACHED() + << "Unrecognized chrome_screen_ai::PredictedType::confidence value: " + << predicted_type.confidence(); + return false; // Confidence is out of bounds. + } + if (predicted_type.confidence() < kScreenAIMinConfidenceThreshold) + return false; switch (predicted_type.type_of_case()) { - case chrome_screen_ai::UIComponent_PredictedType::kEnumType: - // TODO(https://crbug.com/1278249): Add tests to ensure these two types - // match. Add a PRESUBMIT test that compares the proto and enum. - // TODO(accessibility): Why do we even need an enum. Couldn't all - // predicted types be strings? We could easily map from a string to an - // ax::mojom::Role. Then, we won't need to keep the enums synced. + case chrome_screen_ai::UIComponent::PredictedType::kEnumType: + // TODO(https://crbug.com/1278249): We do not actually need an enum. All + // predicted types could be strings. We could easily map from a string to + // an `ax::mojom::Role`. Then, we won't need to keep the enums synced. out_data.role = static_cast<ax::mojom::Role>(predicted_type.enum_type()); break; - case chrome_screen_ai::UIComponent_PredictedType::kStringType: + case chrome_screen_ai::UIComponent::PredictedType::kStringType: out_data.role = ax::mojom::Role::kGenericContainer; out_data.AddStringAttribute(ax::mojom::StringAttribute::kRoleDescription, predicted_type.string_type()); break; - case chrome_screen_ai::UIComponent_PredictedType::TYPE_OF_NOT_SET: - // TODO(accessibility): Why is this a possibility if the member in the - // proto is not marked optional? - NOTREACHED(); - break; + case chrome_screen_ai::UIComponent::PredictedType::TYPE_OF_NOT_SET: + NOTREACHED() << "Malformed proto message: Required field " + "`chrome_screen_ai::UIComponent::PredictedType` not set."; + return false; } + + return true; } void SerializeBoundingBox(const chrome_screen_ai::Rect& bounding_box, @@ -64,6 +87,9 @@ out_data.relative_bounds.bounds = gfx::RectF(bounding_box.x(), bounding_box.y(), bounding_box.width(), bounding_box.height()); + // A negative width or height will result in an empty rect. + if (out_data.relative_bounds.bounds.IsEmpty()) + return; if (container_id != ui::kInvalidAXNodeID) out_data.relative_bounds.offset_container_id = container_id; if (bounding_box.angle()) { @@ -72,21 +98,199 @@ } } -absl::optional<ui::AXNodeData> SerializeUIComponent( - const chrome_screen_ai::UIComponent& ui_component) { - // The score is only used to prune very low confidence detections and we don't - // use it in the accessibility tree. - if (ui_component.predicted_type().confidence() < - kScreenAIMinConfidenceThreshold) { - return absl::nullopt; +void SerializeDirection(const chrome_screen_ai::Orientation& direction, + ui::AXNodeData& out_data) { + if (!chrome_screen_ai::Orientation_IsValid(direction)) { + NOTREACHED() << "Unrecognized chrome_screen_ai::Direction value: " + << direction; + return; } + // TODO(accessibility): Why is writing direction represented using the + // orientation enum whose values are in part non-sensical for use as a writing + // direction? E.g., what does `ORIENTATION_ROTATED_HORIZONTAL` mean? + switch (direction) { + case chrome_screen_ai::Orientation::ORIENTATION_DEFAULT: + case chrome_screen_ai::Orientation::ORIENTATION_HORIZONTAL: + out_data.AddIntAttribute( + ax::mojom::IntAttribute::kTextDirection, + static_cast<int32_t>(ax::mojom::WritingDirection::kLtr)); + break; + case chrome_screen_ai::Orientation::ORIENTATION_VERTICAL: + out_data.AddIntAttribute( + ax::mojom::IntAttribute::kTextDirection, + static_cast<int32_t>(ax::mojom::WritingDirection::kTtb)); + break; + case chrome_screen_ai::Orientation::ORIENTATION_ROTATED_HORIZONTAL: + out_data.AddIntAttribute( + ax::mojom::IntAttribute::kTextDirection, + static_cast<int32_t>(ax::mojom::WritingDirection::kRtl)); + break; + case chrome_screen_ai::Orientation::ORIENTATION_ROTATED_VERTICAL: + out_data.AddIntAttribute( + ax::mojom::IntAttribute::kTextDirection, + static_cast<int32_t>(ax::mojom::WritingDirection::kBtt)); + break; + case google::protobuf::kint32min: + case google::protobuf::kint32max: + // Ordinarily, a default case should have been added to permit future + // additions to `chrome_screen_ai::Orientation`. However, in this + // case, both the screen_ai library and this code should always be in + // sync. + NOTREACHED() << "Unrecognized chrome_screen_ai::Direction value: " + << direction; + break; + } +} - ui::AXNodeData node_data; - node_data.id = GetNextNodeID(); - SerializePredictedType(ui_component.predicted_type(), node_data); - SerializeBoundingBox(ui_component.bounding_box(), - /* container_id */ ui::kInvalidAXNodeID, node_data); - return node_data; +void SerializeContentType(const chrome_screen_ai::ContentType& content_type, + ui::AXNodeData& out_data) { + if (!chrome_screen_ai::ContentType_IsValid(content_type)) { + NOTREACHED() << "Unrecognized chrome_screen_ai::ContentType value: " + << content_type; + return; + } + switch (content_type) { + case chrome_screen_ai::CONTENT_TYPE_PRINTED_TEXT: + case chrome_screen_ai::CONTENT_TYPE_HANDWRITTEN_TEXT: + out_data.role = ax::mojom::Role::kStaticText; + break; + case chrome_screen_ai::CONTENT_TYPE_IMAGE: + out_data.role = ax::mojom::Role::kImage; + break; + case chrome_screen_ai::CONTENT_TYPE_LINE_DRAWING: + out_data.role = ax::mojom::Role::kGraphicsObject; + break; + case chrome_screen_ai::CONTENT_TYPE_SEPARATOR: + out_data.role = ax::mojom::Role::kSplitter; + break; + case chrome_screen_ai::CONTENT_TYPE_UNREADABLE_TEXT: + out_data.role = ax::mojom::Role::kGraphicsObject; + break; + case chrome_screen_ai::CONTENT_TYPE_FORMULA: + case chrome_screen_ai::CONTENT_TYPE_HANDWRITTEN_FORMULA: + // Note that `Role::kMath` indicates that the formula is not represented + // as a subtree of MathML elements in the accessibility tree, but as a raw + // string which may optionally be written in MathML, but could also be + // written in plain text. + out_data.role = ax::mojom::Role::kMath; + break; + case chrome_screen_ai::CONTENT_TYPE_SIGNATURE: + // Signatures may be readable, but even when they are not we could still + // try our best. + // TODO(accessibility): Explore adding a description attribute informing + // the user that this is a signature, e.g. via ARIA Annotations. + out_data.role = ax::mojom::Role::kStaticText; + break; + case chrome_screen_ai::CONTENT_TYPE_UNKNOWN: + // This should be "Role::kPresentational" but it has been erroniously + // removed from the codebase. + // TODO(nektar): Add presentational role back to avoid confusion with the + // meaning of kNone vs. kUnknown. + out_data.role = ax::mojom::Role::kNone; // Presentational. + break; + case google::protobuf::kint32min: + case google::protobuf::kint32max: + // Ordinarily, a default case should have been added to permit future + // additions to `chrome_screen_ai::ContentType`. However, in this + // case, both the screen_ai library and this code should always be in + // sync. + NOTREACHED() << "Unrecognized chrome_screen_ai::ContentType value: " + << content_type; + break; + } +} + +void SerializeWordBox(const chrome_screen_ai::WordBox& word_box, + const size_t index, + ui::AXNodeData& parent_node, + std::vector<ui::AXNodeData>& node_data) { + DCHECK_LT(index, node_data.size()); + DCHECK_NE(parent_node.id, ui::kInvalidAXNodeID); + ui::AXNodeData& word_box_node = node_data[index]; + DCHECK_EQ(word_box_node.role, ax::mojom::Role::kUnknown); + if (word_box.confidence() < 0.0f || word_box.confidence() > 1.0f) { + NOTREACHED() << "Unrecognized chrome_screen_ai::WordBox::confidence value: " + << word_box.confidence(); + return; // Confidence is out of bounds. + } + if (word_box.confidence() < kScreenAIMinConfidenceThreshold) + return; + word_box_node.role = ax::mojom::Role::kInlineTextBox; + word_box_node.id = GetNextNodeID(); + SerializeBoundingBox(word_box.bounding_box(), parent_node.id, word_box_node); + // Since the role is `kInlineTextBox`, NameFrom would automatically and + // correctly be set to `ax::mojom::NameFrom::kContents`. + if (word_box.has_space_after()) { + word_box_node.SetName(word_box.utf8_string() + " "); + } else { + word_box_node.SetName(word_box.utf8_string()); + } + // TODO(nektar): DCHECK that line box's text is equal to the concatenation of + // the text found in all contained word boxes. + // TODO(nektar): Set character bounding box information. + if (word_box.estimate_color_success()) { + word_box_node.AddIntAttribute(ax::mojom::IntAttribute::kBackgroundColor, + word_box.background_rgb_value()); + word_box_node.AddIntAttribute(ax::mojom::IntAttribute::kColor, + word_box.foreground_rgb_value()); + } + SerializeDirection( + static_cast<chrome_screen_ai::Orientation>(word_box.direction()), + word_box_node); + parent_node.child_ids.push_back(word_box_node.id); +} + +void SerializeUIComponent(const chrome_screen_ai::UIComponent& ui_component, + const size_t index, + ui::AXNodeData& parent_node, + std::vector<ui::AXNodeData>& node_data) { + DCHECK_LT(index, node_data.size()); + DCHECK_NE(parent_node.id, ui::kInvalidAXNodeID); + ui::AXNodeData& current_node = node_data[index]; + if (SerializePredictedType(ui_component.predicted_type(), current_node)) + return; + current_node.id = GetNextNodeID(); + SerializeBoundingBox(ui_component.bounding_box(), parent_node.id, + current_node); + parent_node.child_ids.push_back(current_node.id); +} + +void SerializeLineBox(const chrome_screen_ai::LineBox& line_box, + const size_t index, + ui::AXNodeData& parent_node, + std::vector<ui::AXNodeData>& node_data) { + DCHECK_LT(index, node_data.size()); + DCHECK_NE(parent_node.id, ui::kInvalidAXNodeID); + ui::AXNodeData& line_box_node = node_data[index]; + DCHECK_EQ(line_box_node.role, ax::mojom::Role::kUnknown); + if (line_box.confidence() < 0.0f || line_box.confidence() > 1.0f) { + NOTREACHED() << "Unrecognized chrome_screen_ai::LineBox::confidence value: " + << line_box.confidence(); + return; // Confidence is out of bounds. + } + if (line_box.confidence() < kScreenAIMinConfidenceThreshold) + return; + SerializeContentType(line_box.content_type(), line_box_node); + line_box_node.id = GetNextNodeID(); + if (ui::IsText(line_box_node.role)) { + size_t word_node_index = index + 1u; + for (const auto& word : line_box.words()) + SerializeWordBox(word, word_node_index++, line_box_node, node_data); + } + SerializeBoundingBox(line_box.bounding_box(), parent_node.id, line_box_node); + // Since the role is `kStaticText`, NameFrom would automatically and correctly + // be set to `ax::mojom::NameFrom::kContents`. + line_box_node.SetName(line_box.utf8_string()); + if (!line_box.language().empty()) { + // TODO(nektar): Only set language if different from parent node to + // minimize memory usage. + line_box_node.AddStringAttribute(ax::mojom::StringAttribute::kLanguage, + line_box.language()); + } + SerializeDirection( + static_cast<chrome_screen_ai::Orientation>(line_box.direction()), + line_box_node); + parent_node.child_ids.push_back(line_box_node.id); } // Adds the subtree of |nodes[node_index_to_add]| to |nodes_order| with @@ -113,20 +317,92 @@ chrome_screen_ai::VisualAnnotation visual_annotation; if (!visual_annotation.ParseFromString(serialized_proto)) { - VLOG(1) << "Could not parse Screen AI library output."; + NOTREACHED() << "Could not parse Screen AI library output."; return update; } // TODO(https://crbug.com/1278249): Create an AXTreeSource and create the // update using AXTreeSerializer. - for (const auto& ui_component : visual_annotation.ui_component()) { - absl::optional<ui::AXNodeData> node_data = - SerializeUIComponent(ui_component); - if (node_data) - update.nodes.push_back(*node_data); + // Each `UIComponent`, `LineBox`, and `WordBox` will take up one node in the + // accessibility tree, resulting in hundreds of nodes, making it inefficient + // to push_back one node at a time. We pre-allocate the needed nodes making + // node creation an O(n) operation. + const size_t word_count = std::accumulate( + std::begin(visual_annotation.lines()), + std::end(visual_annotation.lines()), 0u, + [](const size_t& count, const chrome_screen_ai::LineBox& line_box) { + return count + line_box.words().size(); + }); + + // Each unique `chrome_screen_ai::LineBox::block_id` creates a new + // paragraph, each paragraph is placed in its correct reading order, + // and each paragraph has a sorted set of line boxes. Line boxes are sorted + // using their `chrome_screen_ai::LineBox::order_within_block` member and they + // are identified by their index in the container of line boxes. Use std::map + // to sort both paragraphs and lines, both operations having an O(n * log(n)) + // complexity. + // TODO(accessibility): Determine reading order based on visual positioning of + // paragraphs, not on their block IDs. + std::map<int32_t, std::map<int32_t, int>> blocks_to_lines_map; + for (int i = 0; i < visual_annotation.lines_size(); ++i) { + const chrome_screen_ai::LineBox& line = visual_annotation.lines(i); + blocks_to_lines_map[line.block_id()].emplace( + std::make_pair(line.order_within_block(), i)); } + size_t rootnodes_count = 0u; + if (!visual_annotation.ui_component().empty()) + ++rootnodes_count; + if (!visual_annotation.lines().empty()) + ++rootnodes_count; + + std::vector<ui::AXNodeData> nodes( + rootnodes_count + visual_annotation.ui_component().size() + + blocks_to_lines_map.size() + visual_annotation.lines().size() + + word_count); + size_t index = 0u; + + if (!visual_annotation.ui_component().empty()) { + ui::AXNodeData& rootnode = nodes[index++]; + rootnode.role = ax::mojom::Role::kDialog; + rootnode.id = GetNextNodeID(); + // TODO(nektar): Set the bounding box of `rootnode` to the bounding box of + // the screen snapshot. + for (const auto& ui_component : visual_annotation.ui_component()) + SerializeUIComponent(ui_component, index++, rootnode, nodes); + } + + if (!visual_annotation.lines().empty()) { + // We assume that OCR is performed on a page-by-page basis. + ui::AXNodeData& page_node = nodes[index++]; + page_node.role = ax::mojom::Role::kRegion; + page_node.id = GetNextNodeID(); + page_node.AddBoolAttribute(ax::mojom::BoolAttribute::kIsPageBreakingObject, + true); + // TODO(nektar): Set the bounding box of `page_node` to the bounding box of + // the captured image. + for (const auto& block_to_lines_pair : blocks_to_lines_map) { + for (const auto& line_sequence_number_to_index_pair : + block_to_lines_pair.second) { + const chrome_screen_ai::LineBox& line_box = + visual_annotation.lines(line_sequence_number_to_index_pair.second); + SerializeLineBox(line_box, index++, page_node, nodes); + index += line_box.words().size(); + } + } + } + + // Filter out invalid / unrecognized / unused nodes from the update. + update.nodes.resize(nodes.size()); + auto end_node_iter = + std::copy_if(std::begin(nodes), std::end(nodes), std::begin(update.nodes), + [](const ui::AXNodeData& node_data) { + return node_data.role != ax::mojom::Role::kUnknown && + node_data.id != ui::kInvalidAXNodeID; + }); + update.nodes.resize(std::distance(std::begin(update.nodes), end_node_iter)); + // TODO(https://crbug.com/1278249): Add UMA metrics to record the number of // annotations, item types, confidence levels, etc. @@ -179,8 +455,7 @@ for (int node_index : nodes_order) { const ui::AXNodeData& node = snapshot.nodes[node_index]; - int ax_node_id = static_cast<int>(node.id); - + const ui::AXNodeID& ax_node_id = node.id; screenai::UiElement* uie = view_hierarchy.add_ui_elements(); screenai::UiElementAttribute* attrib = nullptr;
diff --git a/components/services/screen_ai/proto/proto_convertor_unittest.cc b/components/services/screen_ai/proto/proto_convertor_unittest.cc index 1259763..5af6458 100644 --- a/components/services/screen_ai/proto/proto_convertor_unittest.cc +++ b/components/services/screen_ai/proto/proto_convertor_unittest.cc
@@ -3,6 +3,10 @@ // found in the LICENSE file. #include "components/services/screen_ai/proto/proto_convertor.h" + +#include <string> + +#include "components/services/screen_ai/proto/chrome_screen_ai.pb.h" #include "components/services/screen_ai/proto/view_hierarchy.pb.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/accessibility/ax_node_data.h" @@ -10,14 +14,14 @@ namespace { -const int kMaxChildInTemplate = 3; +constexpr int kMaxChildInTemplate = 3; // A dummy tree node definition. -typedef struct { - int node_id; +struct NodeTemplate { + ui::AXNodeID node_id; int child_count; - int child_ids[kMaxChildInTemplate]; -} NodeTemplate; + ui::AXNodeID child_ids[kMaxChildInTemplate]; +}; ui::AXTreeUpdate CreateAXTreeUpdateFromTemplate(int root_id, NodeTemplate* nodes_template, @@ -49,6 +53,140 @@ using ProtoConvertorTest = testing::Test; +TEST_F(ProtoConvertorTest, ScreenAIVisualAnnotationToAXTreeUpdate) { + chrome_screen_ai::VisualAnnotation annotation; + + { + chrome_screen_ai::UIComponent* component_0 = annotation.add_ui_component(); + chrome_screen_ai::UIComponent::PredictedType* type_0 = + component_0->mutable_predicted_type(); + type_0->set_enum_type(chrome_screen_ai::UIComponent::BUTTON); + type_0->set_confidence(0.8f); + chrome_screen_ai::Rect* box_0 = component_0->mutable_bounding_box(); + box_0->set_x(0); + box_0->set_y(1); + box_0->set_width(2); + box_0->set_height(3); + box_0->set_angle(90.0f); + + chrome_screen_ai::UIComponent* component_1 = annotation.add_ui_component(); + chrome_screen_ai::UIComponent::PredictedType* type_1 = + component_1->mutable_predicted_type(); + type_1->set_string_type("Presentational"); + // If the confidence is low, this component together with all its fields + // should be ignored. + type_1->set_confidence(0.05f); + chrome_screen_ai::Rect* box_1 = component_1->mutable_bounding_box(); + box_1->set_x(0); + box_1->set_y(0); + box_1->set_width(5); + box_1->set_height(5); + + chrome_screen_ai::UIComponent* component_2 = annotation.add_ui_component(); + chrome_screen_ai::UIComponent::PredictedType* type_2 = + component_2->mutable_predicted_type(); + type_2->set_string_type("Signature"); + type_2->set_confidence(0.6f); + chrome_screen_ai::Rect* box_2 = component_2->mutable_bounding_box(); + // `x`, `y`, and `angle` should be defaulted to 0 since they are singular + // proto3 fields, not proto2. + box_2->set_width(5); + box_2->set_height(5); + } + + { + std::string serialized_annotation; + ASSERT_TRUE(annotation.SerializeToString(&serialized_annotation)); + const ui::AXTreeUpdate update = + ScreenAIVisualAnnotationToAXTreeUpdate(serialized_annotation); + + const std::string expected_update( + "id=1 dialog (0, 0)-(0, 0) child_ids=2\n"); + EXPECT_EQ(expected_update, update.ToString()); + } + + { + chrome_screen_ai::LineBox* line_0 = annotation.add_lines(); + + chrome_screen_ai::WordBox* word_0_0 = line_0->add_words(); + chrome_screen_ai::Rect* box_0_0 = word_0_0->mutable_bounding_box(); + box_0_0->set_x(100); + box_0_0->set_y(100); + box_0_0->set_width(250); + box_0_0->set_height(20); + word_0_0->set_utf8_string("Hello"); + word_0_0->set_has_space_after(true); + word_0_0->set_confidence(0.9f); + word_0_0->set_estimate_color_success(true); + word_0_0->set_background_rgb_value(50000); + word_0_0->set_foreground_rgb_value(25000); + + chrome_screen_ai::WordBox* word_0_1 = line_0->add_words(); + chrome_screen_ai::Rect* box_0_1 = word_0_1->mutable_bounding_box(); + box_0_1->set_x(350); + box_0_1->set_y(100); + box_0_1->set_width(250); + box_0_1->set_height(20); + word_0_1->set_utf8_string("world"); + // `word_0_1.has_space_after()` should be defaulted to false. + word_0_1->set_confidence(0.9f); + word_0_1->set_estimate_color_success(true); + word_0_1->set_background_rgb_value(50000); + word_0_1->set_foreground_rgb_value(25000); + + chrome_screen_ai::Rect* box_0 = line_0->mutable_bounding_box(); + box_0->set_x(100); + box_0->set_y(100); + box_0->set_width(500); + box_0->set_height(20); + line_0->set_utf8_string("Hello world"); + line_0->set_confidence(0.9f); + line_0->set_language("en"); + line_0->set_block_id(2); + line_0->set_order_within_block(1); + + chrome_screen_ai::LineBox* line_1 = annotation.add_lines(); + line_1->set_confidence(0.0f); + // Language, and the line as a whole, should be ignored since the + // confidence is zero. + line_1->set_language("en"); + line_1->set_block_id(1); + line_1->set_order_within_block(0); + + chrome_screen_ai::LineBox* line_2 = annotation.add_lines(); + line_2->set_confidence(0.7f); + chrome_screen_ai::Rect* box_2 = line_2->mutable_bounding_box(); + // No bounding box should be created in the AXTree because the height is -5. + box_2->set_width(5); + box_2->set_height(-5); + line_2->set_block_id(2); + line_2->set_order_within_block(0); + } + + { + std::string serialized_annotation; + ASSERT_TRUE(annotation.SerializeToString(&serialized_annotation)); + const ui::AXTreeUpdate update = + ScreenAIVisualAnnotationToAXTreeUpdate(serialized_annotation); + + const std::string expected_update( + "id=3 dialog (0, 0)-(0, 0) child_ids=4\n" + "id=5 region (0, 0)-(0, 0) is_page_breaking_object=true child_ids=6,7\n" + " id=6 staticText (0, 0)-(5, 0) name_from=contents text_direction=ltr " + "name=\n" + " id=7 staticText offset_container_id=5 (100, 100)-(500, 20) " + "name_from=contents text_direction=ltr name=Hello world language=en " + "child_ids=8,9\n" + " id=8 inlineTextBox offset_container_id=7 (100, 100)-(250, 20) " + "name_from=contents background_color=&C350 color=&61A8 " + "text_direction=ltr name=Hello \n" + " id=9 inlineTextBox offset_container_id=7 (350, 100)-(250, 20) " + "name_from=contents background_color=&C350 color=&61A8 " + "text_direction=ltr name=world\n"); + EXPECT_EQ(expected_update, update.ToString()); + } +} + // Tests if the given tree is properly traversed and new ids are assigned. TEST_F(ProtoConvertorTest, PreOrderTreeGeneration) { // Input Tree: @@ -78,7 +216,7 @@ CreateAXTreeUpdateFromTemplate(1, input_tree, nodes_count); std::string serialized_proto = Screen2xSnapshotToViewHierarchy(tree_update); screenai::ViewHierarchy view_hierarchy; - EXPECT_TRUE(view_hierarchy.ParseFromString(serialized_proto)); + ASSERT_TRUE(view_hierarchy.ParseFromString(serialized_proto)); // Verify. EXPECT_EQ(view_hierarchy.ui_elements().size(), nodes_count);
diff --git a/components/signin/public/base/signin_metrics.cc b/components/signin/public/base/signin_metrics.cc index 3965889d..6b14513 100644 --- a/components/signin/public/base/signin_metrics.cc +++ b/components/signin/public/base/signin_metrics.cc
@@ -120,6 +120,10 @@ base::RecordAction(base::UserMetricsAction( "Signin_Signin_FromSigninInterceptFirstRunExperience")); break; + case AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO: + base::RecordAction( + base::UserMetricsAction("Signin_Signin_FromNTPFeedTopPromo")); + break; case AccessPoint::ACCESS_POINT_KALEIDOSCOPE: NOTREACHED() << "Access point " << static_cast<int>(access_point) << " is only used to trigger non-sync sign-in and this" @@ -186,6 +190,10 @@ base::RecordAction(base::UserMetricsAction( "Signin_SigninWithDefault_FromNTPContentSuggestions")); break; + case AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO: + base::RecordAction(base::UserMetricsAction( + "Signin_SigninWithDefault_FromNTPFeedTopPromo")); + break; case AccessPoint::ACCESS_POINT_ENTERPRISE_SIGNOUT_COORDINATOR: case AccessPoint::ACCESS_POINT_START_PAGE: case AccessPoint::ACCESS_POINT_NTP_LINK: @@ -260,6 +268,10 @@ base::RecordAction(base::UserMetricsAction( "Signin_SigninNotDefault_FromNTPContentSuggestions")); break; + case AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO: + base::RecordAction(base::UserMetricsAction( + "Signin_SigninNotDefault_FromNTPFeedTopPromo")); + break; case AccessPoint::ACCESS_POINT_ENTERPRISE_SIGNOUT_COORDINATOR: case AccessPoint::ACCESS_POINT_START_PAGE: case AccessPoint::ACCESS_POINT_NTP_LINK: @@ -338,6 +350,10 @@ "Signin_SigninNewAccountNoExistingAccount_FromNTPContentSuggestions")); // NOLINT(whitespace/line_length) // clang-format on break; + case AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO: + base::RecordAction(base::UserMetricsAction( + "Signin_SigninNewAccountNoExistingAccount_FromNTPFeedTopPromo")); + break; case AccessPoint::ACCESS_POINT_ENTERPRISE_SIGNOUT_COORDINATOR: case AccessPoint::ACCESS_POINT_START_PAGE: case AccessPoint::ACCESS_POINT_NTP_LINK: @@ -419,6 +435,10 @@ base::RecordAction(base::UserMetricsAction( "Signin_SigninNewAccountExistingAccount_FromNTPContentSuggestions")); break; + case AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO: + base::RecordAction(base::UserMetricsAction( + "Signin_SigninNewAccountExistingAccount_FromNTPFeedTopPromo")); + break; case AccessPoint::ACCESS_POINT_ENTERPRISE_SIGNOUT_COORDINATOR: case AccessPoint::ACCESS_POINT_START_PAGE: case AccessPoint::ACCESS_POINT_NTP_LINK: @@ -841,6 +861,10 @@ base::RecordAction( base::UserMetricsAction("Signin_Impression_FromSendTabToSelfPromo")); break; + case AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO: + base::RecordAction( + base::UserMetricsAction("Signin_Impression_FromNTPFeedTopPromo")); + break; case AccessPoint::ACCESS_POINT_ENTERPRISE_SIGNOUT_COORDINATOR: case AccessPoint::ACCESS_POINT_CONTENT_AREA: case AccessPoint::ACCESS_POINT_EXTENSIONS: @@ -948,6 +972,15 @@ "Signin_ImpressionWithNoAccount_FromNTPContentSuggestions")); } break; + case AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO: + if (with_account) { + base::RecordAction(base::UserMetricsAction( + "Signin_ImpressionWithAccount_FromNTPFeedTopPromo")); + } else { + base::RecordAction(base::UserMetricsAction( + "Signin_ImpressionWithNoAccount_FromNTPFeedTopPromo")); + } + break; case AccessPoint::ACCESS_POINT_ENTERPRISE_SIGNOUT_COORDINATOR: case AccessPoint::ACCESS_POINT_START_PAGE: case AccessPoint::ACCESS_POINT_NTP_LINK:
diff --git a/components/signin/public/base/signin_metrics.h b/components/signin/public/base/signin_metrics.h index 300389cf..af14197 100644 --- a/components/signin/public/base/signin_metrics.h +++ b/components/signin/public/base/signin_metrics.h
@@ -182,6 +182,7 @@ ACCESS_POINT_ENTERPRISE_SIGNOUT_COORDINATOR = 34, ACCESS_POINT_SIGNIN_INTERCEPT_FIRST_RUN_EXPERIENCE = 35, ACCESS_POINT_SEND_TAB_TO_SELF_PROMO = 36, + ACCESS_POINT_NTP_FEED_TOP_PROMO = 37, // Add values above this line with a corresponding label to the // "SigninAccessPoint" enum in tools/metrics/histograms/enums.xml ACCESS_POINT_MAX, // This must be last.
diff --git a/components/signin/public/base/signin_metrics_unittest.cc b/components/signin/public/base/signin_metrics_unittest.cc index 7742a5f..33ab44e 100644 --- a/components/signin/public/base/signin_metrics_unittest.cc +++ b/components/signin/public/base/signin_metrics_unittest.cc
@@ -38,7 +38,8 @@ AccessPoint::ACCESS_POINT_RESIGNIN_INFOBAR, AccessPoint::ACCESS_POINT_TAB_SWITCHER, AccessPoint::ACCESS_POINT_MACHINE_LOGON, - AccessPoint::ACCESS_POINT_GOOGLE_SERVICES_SETTINGS}; + AccessPoint::ACCESS_POINT_GOOGLE_SERVICES_SETTINGS, + AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO}; const AccessPoint kAccessPointsThatSupportImpression[] = { AccessPoint::ACCESS_POINT_START_PAGE, @@ -57,7 +58,8 @@ AccessPoint::ACCESS_POINT_AUTOFILL_DROPDOWN, AccessPoint::ACCESS_POINT_NTP_CONTENT_SUGGESTIONS, AccessPoint::ACCESS_POINT_RESIGNIN_INFOBAR, - AccessPoint::ACCESS_POINT_TAB_SWITCHER}; + AccessPoint::ACCESS_POINT_TAB_SWITCHER, + AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO}; const AccessPoint kAccessPointsThatSupportPersonalizedPromos[] = { AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER, @@ -68,7 +70,8 @@ AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN, AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE, AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE, - AccessPoint::ACCESS_POINT_NTP_CONTENT_SUGGESTIONS}; + AccessPoint::ACCESS_POINT_NTP_CONTENT_SUGGESTIONS, + AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO}; class SigninMetricsTest : public ::testing::Test { public: @@ -140,6 +143,8 @@ return "SigninInterceptFirstRunExperience"; case AccessPoint::ACCESS_POINT_SEND_TAB_TO_SELF_PROMO: return "SendTabToSelfPromo"; + case AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO: + return "NTPFeedTopPromo"; case AccessPoint::ACCESS_POINT_MAX: NOTREACHED(); return "";
diff --git a/components/signin/public/base/signin_switches.cc b/components/signin/public/base/signin_switches.cc index 73245fa7..2413900 100644 --- a/components/signin/public/base/signin_switches.cc +++ b/components/signin/public/base/signin_switches.cc
@@ -45,6 +45,12 @@ "ForceDisableExtendedSyncPromos", base::FEATURE_DISABLED_BY_DEFAULT}; #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) +// Decouples signing out from clearing browsing data on Android. Users are +// no longer signed-out when they clear browsing data. Instead they may +// choose to sign out separately by pressing another button. +const base::Feature kEnableCbdSignOut{"EnableCbdSignOut", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Features to trigger the startup sign-in promo at boot. const base::Feature kForceStartupSigninPromo{"ForceStartupSigninPromo", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/signin/public/base/signin_switches.h b/components/signin/public/base/signin_switches.h index e751931..37c8689 100644 --- a/components/signin/public/base/signin_switches.h +++ b/components/signin/public/base/signin_switches.h
@@ -36,6 +36,7 @@ extern const base::Feature kForceDisableExtendedSyncPromos; #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) +extern const base::Feature kEnableCbdSignOut; extern const base::Feature kForceStartupSigninPromo; extern const base::Feature kTangibleSync; #endif
diff --git a/components/viz/host/host_frame_sink_manager.cc b/components/viz/host/host_frame_sink_manager.cc index 1ad1e78b..90429aee 100644 --- a/components/viz/host/host_frame_sink_manager.cc +++ b/components/viz/host/host_frame_sink_manager.cc
@@ -288,6 +288,15 @@ frame_sink_manager_->Throttle(ids, interval); } +void HostFrameSinkManager::StartThrottlingAllFrameSinks( + base::TimeDelta interval) { + frame_sink_manager_->StartThrottlingAllFrameSinks(interval); +} + +void HostFrameSinkManager::StopThrottlingAllFrameSinks() { + frame_sink_manager_->StopThrottlingAllFrameSinks(); +} + void HostFrameSinkManager::AddHitTestRegionObserver( HitTestRegionObserver* observer) { observers_.AddObserver(observer);
diff --git a/components/viz/host/host_frame_sink_manager.h b/components/viz/host/host_frame_sink_manager.h index 5a0d894..44db2fc3 100644 --- a/components/viz/host/host_frame_sink_manager.h +++ b/components/viz/host/host_frame_sink_manager.h
@@ -194,6 +194,8 @@ std::unique_ptr<CopyOutputRequest> request); void Throttle(const std::vector<FrameSinkId>& ids, base::TimeDelta interval); + void StartThrottlingAllFrameSinks(base::TimeDelta interval); + void StopThrottlingAllFrameSinks(); // Add/Remove an observer to receive notifications of when the host receives // new hit test data.
diff --git a/components/viz/service/display/direct_renderer.cc b/components/viz/service/display/direct_renderer.cc index 774d3ae..ce0b2474 100644 --- a/components/viz/service/display/direct_renderer.cc +++ b/components/viz/service/display/direct_renderer.cc
@@ -215,18 +215,6 @@ auto* root_render_pass = render_passes_in_draw_order->back().get(); DCHECK(root_render_pass); - bool overdraw_feedback = debug_settings_->show_overdraw_feedback; - if (overdraw_feedback && !output_surface_->capabilities().supports_stencil) { -#if DCHECK_IS_ON() - DLOG_IF(WARNING, !overdraw_feedback_support_missing_logged_once_) - << "Overdraw feedback enabled on platform without support."; - overdraw_feedback_support_missing_logged_once_ = true; -#endif - overdraw_feedback = false; - } - base::AutoReset<bool> auto_reset_overdraw_feedback(&overdraw_feedback_, - overdraw_feedback); - current_frame_valid_ = true; current_frame_ = DrawingFrame(); current_frame()->render_passes_in_draw_order = render_passes_in_draw_order; @@ -345,7 +333,6 @@ // Only reshape when we know we are going to draw. Otherwise, the reshape // can leave the window at the wrong size if we never draw and the proper // viewport size is never set. - bool use_stencil = overdraw_feedback_; bool needs_full_frame_redraw = false; auto display_transform = output_surface_->GetDisplayTransform(); OutputSurface::ReshapeParams reshape_params; @@ -354,7 +341,6 @@ reshape_params.color_space = frame_color_space; reshape_params.sdr_white_level = CurrentFrameSDRWhiteLevel(); reshape_params.format = frame_buffer_format; - reshape_params.use_stencil = use_stencil; if (next_frame_needs_full_frame_redraw_ || reshape_params != reshape_params_ || display_transform != reshape_display_transform_) { @@ -398,16 +384,6 @@ if (!skip_drawing_root_render_pass) DrawRenderPassAndExecuteCopyRequests(root_render_pass); - // Use a fence to synchronize display of the main fb used by the output - // surface. Note that gpu_fence_id may have the special value 0 ("no fence") - // if fences are not supported. In that case synchronization will happen - // through other means on the service side. - // TODO(afrantzis): Consider using per-overlay fences instead of the one - // associated with the output surface when possible. - if (current_frame()->output_surface_plane) - current_frame()->output_surface_plane->gpu_fence_id = - output_surface_->UpdateGpuFence(); - if (overlay_processor_) overlay_processor_->TakeOverlayCandidates(¤t_frame()->overlay_list); @@ -633,16 +609,8 @@ const bool render_pass_requires_scissor = render_pass_is_clipped || (supports_dc_layers && is_root_render_pass); - const bool has_external_stencil_test = - is_root_render_pass && output_surface_->HasExternalStencilTest(); const bool should_clear_surface = - !has_external_stencil_test && - (!is_root_render_pass || settings_->should_clear_root_render_pass); - - // If |has_external_stencil_test| we can't discard or clear. Make sure we - // don't need to. - DCHECK(!has_external_stencil_test || - !current_frame()->current_render_pass->has_transparent_background); + !is_root_render_pass || settings_->should_clear_root_render_pass; SurfaceInitializationMode mode; if (should_clear_surface && render_pass_requires_scissor) { @@ -713,9 +681,6 @@ render_pass_requires_scissor); FinishDrawingQuadList(); - if (is_root_render_pass && overdraw_feedback_) - FlushOverdrawFeedback(render_pass_scissor_in_draw_space); - if (render_pass->generate_mipmap) GenerateMipmap(); }
diff --git a/components/viz/service/display/direct_renderer.h b/components/viz/service/display/direct_renderer.h index cab2564..27bd75e 100644 --- a/components/viz/service/display/direct_renderer.h +++ b/components/viz/service/display/direct_renderer.h
@@ -264,7 +264,6 @@ virtual void DoDrawQuad(const DrawQuad* quad, const gfx::QuadF* clip_region) = 0; virtual void BeginDrawingFrame() = 0; - virtual void FlushOverdrawFeedback(const gfx::Rect& output_rect) {} virtual void FinishDrawingFrame() = 0; // If a pass contains a single tile draw quad and can be drawn without // a render pass (e.g. applying a filter directly to the tile quad) @@ -316,8 +315,6 @@ bool allow_empty_swap_ = false; // Whether partial swap can be used. bool use_partial_swap_ = false; - // Whether overdraw feedback is enabled and can be used. - bool overdraw_feedback_ = false; // A map from RenderPass id to the single quad present in and replacing the // RenderPass. The DrawQuads are owned by their RenderPasses, which outlive @@ -375,9 +372,7 @@ virtual void DrawDelegatedInkTrail(); bool initialized_ = false; -#if DCHECK_IS_ON() - bool overdraw_feedback_support_missing_logged_once_ = false; -#endif + gfx::Rect last_root_render_pass_scissor_rect_; gfx::Size enlarge_pass_texture_amount_;
diff --git a/components/viz/service/display/null_renderer.h b/components/viz/service/display/null_renderer.h index fa291a47a..99935df3 100644 --- a/components/viz/service/display/null_renderer.h +++ b/components/viz/service/display/null_renderer.h
@@ -45,7 +45,6 @@ void DoDrawQuad(const DrawQuad* quad, const gfx::QuadF* clip_region) override {} void BeginDrawingFrame() override; - void FlushOverdrawFeedback(const gfx::Rect& output_rect) override {} void FinishDrawingFrame() override {} bool FlippedFramebuffer() const override; void EnsureScissorTestEnabled() override {}
diff --git a/components/viz/service/display/output_surface.cc b/components/viz/service/display/output_surface.cc index 6088ff13..9354f7d 100644 --- a/components/viz/service/display/output_surface.cc +++ b/components/viz/service/display/output_surface.cc
@@ -30,14 +30,9 @@ OutputSurface::OutputSurface(Type type) : type_(type) {} -OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider) - : context_provider_(std::move(context_provider)), type_(Type::kOpenGL) { - DCHECK(context_provider_); -} - OutputSurface::OutputSurface( std::unique_ptr<SoftwareOutputDevice> software_device) - : software_device_(std::move(software_device)), type_(Type::kSoftware) { + : type_(Type::kSoftware), software_device_(std::move(software_device)) { DCHECK(software_device_); }
diff --git a/components/viz/service/display/output_surface.h b/components/viz/service/display/output_surface.h index f43dd23..4ec62b3 100644 --- a/components/viz/service/display/output_surface.h +++ b/components/viz/service/display/output_surface.h
@@ -12,7 +12,6 @@ #include "base/memory/ref_counted.h" #include "base/threading/thread_checker.h" #include "components/viz/common/display/update_vsync_parameters_callback.h" -#include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/gpu/gpu_vsync_callback.h" #include "components/viz/common/resources/resource_format.h" #include "components/viz/common/resources/returned_resource.h" @@ -26,6 +25,7 @@ #include "mojo/public/cpp/bindings/pending_receiver.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/skia/include/core/SkM44.h" +#include "ui/gfx/buffer_types.h" #include "ui/gfx/color_space.h" #include "ui/gfx/overlay_transform.h" #include "ui/gfx/surface_origin.h" @@ -77,10 +77,6 @@ bool uses_default_gl_framebuffer = true; // Where (0,0) is on this OutputSurface. gfx::SurfaceOrigin output_surface_origin = gfx::SurfaceOrigin::kBottomLeft; - // Whether this OutputSurface supports stencil operations or not. - // Note: HasExternalStencilTest() must return false when an output surface - // has been configured for stencil usage. - bool supports_stencil = false; // Whether this OutputSurface supports post sub buffer or not. bool supports_post_sub_buffer = false; // Whether this OutputSurface supports commit overlay planes. @@ -145,8 +141,6 @@ // Constructor for skia-based compositing. explicit OutputSurface(Type type); - // Constructor for GL-based compositing. - explicit OutputSurface(scoped_refptr<ContextProvider> context_provider); // Constructor for software compositing. explicit OutputSurface(std::unique_ptr<SoftwareOutputDevice> software_device); @@ -158,11 +152,9 @@ const Capabilities& capabilities() const { return capabilities_; } Type type() const { return type_; } - // Obtain the 3d context or the software device associated with this output - // surface. Either of these may return a null pointer, but not both. - // In the event of a lost context, the entire output surface should be - // recreated. - ContextProvider* context_provider() const { return context_provider_.get(); } + // Obtain the software device associated with this output surface. This will + // return non-null for a software output surface and null for skia output + // surface. SoftwareOutputDevice* software_device() const { return software_device_.get(); } @@ -183,10 +175,6 @@ virtual void EnsureBackbuffer() = 0; virtual void DiscardBackbuffer() = 0; - // Bind the default framebuffer for drawing to, only valid for GL backed - // OutputSurfaces. - virtual void BindFramebuffer() = 0; - // Marks that the given rectangle will be drawn to on the default, bound // framebuffer. The contents of the framebuffer are undefined after this // command and must be filled in completely before a swap happens. Drawing @@ -204,9 +192,6 @@ // Returns true if a main image overlay plane should be scheduled. virtual bool IsDisplayedAsOverlayPlane() const = 0; - // Get the texture for the main image's overlay. - virtual unsigned GetOverlayTextureId() const = 0; - // Returns the |mailbox| corresponding to the main image's overlay. virtual gpu::Mailbox GetOverlayMailbox() const; @@ -217,14 +202,12 @@ gfx::ColorSpace color_space; float sdr_white_level = gfx::ColorSpace::kDefaultSDRWhiteLevel; gfx::BufferFormat format = gfx::BufferFormat::RGBX_8888; - bool use_stencil = false; bool operator==(const ReshapeParams& other) const { return size == other.size && device_scale_factor == other.device_scale_factor && color_space == other.color_space && - sdr_white_level == other.sdr_white_level && - format == other.format && use_stencil == other.use_stencil; + sdr_white_level == other.sdr_white_level; } bool operator!=(const ReshapeParams& other) const { return !(*this == other); @@ -232,13 +215,6 @@ }; virtual void Reshape(const ReshapeParams& params) = 0; - virtual bool HasExternalStencilTest() const = 0; - virtual void ApplyExternalStencil() = 0; - - // Gives the GL internal format that should be used for calling CopyTexImage2D - // when the framebuffer is bound via BindFramebuffer(). - virtual uint32_t GetFramebufferCopyTextureFormat() = 0; - // Swaps the current backbuffer to the screen. For successful swaps, the // implementation must call OutputSurfaceClient::DidReceiveSwapBuffersAck() // after returning from this method in order to unblock the next frame. @@ -254,14 +230,6 @@ // TODO(dcastagna): Consider making the following pure virtual. virtual gfx::Rect GetCurrentFramebufferDamage() const; - // Updates the GpuFence associated with this surface. The id of a newly - // created GpuFence is returned, or if an error occurs, or fences are not - // supported, the special id of 0 (meaning "no fence") is returned. In all - // cases, any previously associated fence is destroyed. The returned fence id - // corresponds to the GL id used by the CHROMIUM_gpu_fence GL extension and - // can be passed directly to any related extension functions. - virtual unsigned UpdateGpuFence() = 0; - // Sets callback to receive updated vsync parameters after SwapBuffers() if // supported. virtual void SetUpdateVSyncParametersCallback( @@ -320,11 +288,10 @@ protected: struct OutputSurface::Capabilities capabilities_; - scoped_refptr<ContextProvider> context_provider_; - std::unique_ptr<SoftwareOutputDevice> software_device_; private: const Type type_; + std::unique_ptr<SoftwareOutputDevice> software_device_; SkM44 color_matrix_; };
diff --git a/components/viz/service/display/overlay_processor_interface.h b/components/viz/service/display/overlay_processor_interface.h index 22cb824..2d4c5ff 100644 --- a/components/viz/service/display/overlay_processor_interface.h +++ b/components/viz/service/display/overlay_processor_interface.h
@@ -33,6 +33,10 @@ class DisplayResourceProvider; } +namespace gpu { +class SharedImageInterface; +} + namespace viz { struct DebugRendererSettings; class OutputSurface; @@ -95,9 +99,6 @@ // Opacity of the overlay independent of buffer alpha. When rendered: // src-alpha = |opacity| * buffer-component-alpha. float opacity; - // TODO(weiliangc): Should be replaced by SharedImage mailbox. - // Gpu fence to wait for before overlay is ready for display. - unsigned gpu_fence_id; // Mailbox corresponding to the buffer backing the primary plane. gpu::Mailbox mailbox; // Hints for overlay prioritization.
diff --git a/components/viz/service/display/skia_output_surface.h b/components/viz/service/display/skia_output_surface.h index 7b8bec2..2378966 100644 --- a/components/viz/service/display/skia_output_surface.h +++ b/components/viz/service/display/skia_output_surface.h
@@ -33,6 +33,10 @@ class ColorSpace; } // namespace gfx +namespace gpu { +class SharedImageInterface; +} + namespace viz { class OverlayCandidate;
diff --git a/components/viz/service/display/skia_readback_pixeltest.cc b/components/viz/service/display/skia_readback_pixeltest.cc index 86516244..dd1c51d 100644 --- a/components/viz/service/display/skia_readback_pixeltest.cc +++ b/components/viz/service/display/skia_readback_pixeltest.cc
@@ -21,6 +21,7 @@ #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/frame_sinks/copy_output_result.h" #include "components/viz/common/frame_sinks/copy_output_util.h" +#include "components/viz/common/gpu/context_provider.h" #include "components/viz/service/display_embedder/skia_output_surface_impl.h" #include "components/viz/service/gl/gpu_service_impl.h" #include "components/viz/test/gl_scaler_test_util.h"
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index dec5b55..fbd06e7 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -929,8 +929,6 @@ } void SkiaRenderer::BindFramebufferToOutputSurface() { - DCHECK(!output_surface_->HasExternalStencilTest()); - root_canvas_ = skia_output_surface_->BeginPaintCurrentFrame(); current_canvas_ = root_canvas_; current_surface_ = root_surface_.get();
diff --git a/components/viz/service/display/software_renderer.cc b/components/viz/service/display/software_renderer.cc index f018b200..a088937 100644 --- a/components/viz/service/display/software_renderer.cc +++ b/components/viz/service/display/software_renderer.cc
@@ -134,7 +134,6 @@ } void SoftwareRenderer::BindFramebufferToOutputSurface() { - DCHECK(!output_surface_->HasExternalStencilTest()); DCHECK(!root_canvas_); current_framebuffer_canvas_.reset();
diff --git a/components/viz/service/display_embedder/output_surface_unified.cc b/components/viz/service/display_embedder/output_surface_unified.cc index f01790c..a5c52de 100644 --- a/components/viz/service/display_embedder/output_surface_unified.cc +++ b/components/viz/service/display_embedder/output_surface_unified.cc
@@ -29,22 +29,6 @@ return false; } -unsigned OutputSurfaceUnified::GetOverlayTextureId() const { - return 0; -} - -bool OutputSurfaceUnified::HasExternalStencilTest() const { - return false; -} - -uint32_t OutputSurfaceUnified::GetFramebufferCopyTextureFormat() { - return 0; -} - -unsigned OutputSurfaceUnified::UpdateGpuFence() { - return 0; -} - gfx::OverlayTransform OutputSurfaceUnified::GetDisplayTransform() { return gfx::OVERLAY_TRANSFORM_NONE; }
diff --git a/components/viz/service/display_embedder/output_surface_unified.h b/components/viz/service/display_embedder/output_surface_unified.h index 31d8e86..8d9d4deb 100644 --- a/components/viz/service/display_embedder/output_surface_unified.h +++ b/components/viz/service/display_embedder/output_surface_unified.h
@@ -34,15 +34,9 @@ void BindToClient(OutputSurfaceClient* client) override {} void EnsureBackbuffer() override {} void DiscardBackbuffer() override {} - void BindFramebuffer() override {} void Reshape(const ReshapeParams& params) override {} void SwapBuffers(OutputSurfaceFrame frame) override; bool IsDisplayedAsOverlayPlane() const override; - unsigned GetOverlayTextureId() const override; - bool HasExternalStencilTest() const override; - void ApplyExternalStencil() override {} - uint32_t GetFramebufferCopyTextureFormat() override; - unsigned UpdateGpuFence() override; void SetUpdateVSyncParametersCallback( UpdateVSyncParametersCallback callback) override {} void SetDisplayTransformHint(gfx::OverlayTransform transform) override {}
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc index 94627867..a037c08 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -234,10 +234,6 @@ client_ = client; } -void SkiaOutputSurfaceImpl::BindFramebuffer() { - // TODO(penghuang): remove this method when GLRenderer is removed. -} - void SkiaOutputSurfaceImpl::SetDrawRectangle(const gfx::Rect& draw_rectangle) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(capabilities().supports_dc_layers); @@ -1176,40 +1172,15 @@ return GrBackendFormat(); } -uint32_t SkiaOutputSurfaceImpl::GetFramebufferCopyTextureFormat() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - - return GL_RGB; -} - bool SkiaOutputSurfaceImpl::IsDisplayedAsOverlayPlane() const { return is_displayed_as_overlay_; } -unsigned SkiaOutputSurfaceImpl::GetOverlayTextureId() const { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - return 0; -} - gpu::Mailbox SkiaOutputSurfaceImpl::GetOverlayMailbox() const { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); return last_swapped_mailbox_; } -bool SkiaOutputSurfaceImpl::HasExternalStencilTest() const { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - - return false; -} - -void SkiaOutputSurfaceImpl::ApplyExternalStencil() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); -} - -unsigned SkiaOutputSurfaceImpl::UpdateGpuFence() { - return 0; -} - void SkiaOutputSurfaceImpl::SetNeedsSwapSizeNotifications( bool needs_swap_size_notifications) { needs_swap_size_notifications_ = needs_swap_size_notifications;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.h b/components/viz/service/display_embedder/skia_output_surface_impl.h index cf65c04b..c78d40b 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl.h
@@ -76,7 +76,6 @@ // OutputSurface implementation: gpu::SurfaceHandle GetSurfaceHandle() const override; void BindToClient(OutputSurfaceClient* client) override; - void BindFramebuffer() override; void SetDrawRectangle(const gfx::Rect& draw_rectangle) override; void SetEnableDCLayers(bool enable) override; void EnsureBackbuffer() override; @@ -89,13 +88,8 @@ void SetDisplayTransformHint(gfx::OverlayTransform transform) override; gfx::OverlayTransform GetDisplayTransform() override; void SwapBuffers(OutputSurfaceFrame frame) override; - uint32_t GetFramebufferCopyTextureFormat() override; bool IsDisplayedAsOverlayPlane() const override; - unsigned GetOverlayTextureId() const override; gpu::Mailbox GetOverlayMailbox() const override; - bool HasExternalStencilTest() const override; - void ApplyExternalStencil() override; - unsigned UpdateGpuFence() override; void SetNeedsSwapSizeNotifications( bool needs_swap_size_notifications) override; base::ScopedClosureRunner GetCacheBackBufferCb() override;
diff --git a/components/viz/service/display_embedder/software_output_surface.cc b/components/viz/service/display_embedder/software_output_surface.cc index 77bf3580..0fe3318e 100644 --- a/components/viz/service/display_embedder/software_output_surface.cc +++ b/components/viz/service/display_embedder/software_output_surface.cc
@@ -24,12 +24,12 @@ namespace viz { SoftwareOutputSurface::SoftwareOutputSurface( - std::unique_ptr<SoftwareOutputDevice> software_device) - : OutputSurface(std::move(software_device)) { + std::unique_ptr<SoftwareOutputDevice> device) + : OutputSurface(std::move(device)) { capabilities_.pending_swap_params.max_pending_swaps = - software_device_->MaxFramesPending(); + software_device()->MaxFramesPending(); capabilities_.resize_based_on_root_surface = - software_device_->SupportsOverridePlatformSize(); + software_device()->SupportsOverridePlatformSize(); } SoftwareOutputSurface::~SoftwareOutputSurface() = default; @@ -48,11 +48,6 @@ software_device()->DiscardBackbuffer(); } -void SoftwareOutputSurface::BindFramebuffer() { - // Not used for software surfaces. - NOTREACHED(); -} - void SoftwareOutputSurface::Reshape(const ReshapeParams& params) { software_device()->Resize(params.size, params.device_scale_factor); } @@ -85,22 +80,6 @@ return false; } -unsigned SoftwareOutputSurface::GetOverlayTextureId() const { - return 0; -} - -bool SoftwareOutputSurface::HasExternalStencilTest() const { - return false; -} - -void SoftwareOutputSurface::ApplyExternalStencil() {} - -uint32_t SoftwareOutputSurface::GetFramebufferCopyTextureFormat() { - // Not used for software surfaces. - NOTREACHED(); - return 0; -} - void SoftwareOutputSurface::SwapBuffersCallback(base::TimeTicks swap_time, const gfx::Size& pixel_size) { latency_tracker_.OnGpuSwapBuffersCompleted( @@ -130,10 +109,6 @@ update_vsync_parameters_callback_.Run(timebase, interval); } -unsigned SoftwareOutputSurface::UpdateGpuFence() { - return 0; -} - void SoftwareOutputSurface::SetUpdateVSyncParametersCallback( UpdateVSyncParametersCallback callback) { update_vsync_parameters_callback_ = std::move(callback);
diff --git a/components/viz/service/display_embedder/software_output_surface.h b/components/viz/service/display_embedder/software_output_surface.h index 26af7321a..a712789 100644 --- a/components/viz/service/display_embedder/software_output_surface.h +++ b/components/viz/service/display_embedder/software_output_surface.h
@@ -38,15 +38,9 @@ void BindToClient(OutputSurfaceClient* client) override; void EnsureBackbuffer() override; void DiscardBackbuffer() override; - void BindFramebuffer() override; void Reshape(const ReshapeParams& params) override; void SwapBuffers(OutputSurfaceFrame frame) override; bool IsDisplayedAsOverlayPlane() const override; - unsigned GetOverlayTextureId() const override; - bool HasExternalStencilTest() const override; - void ApplyExternalStencil() override; - uint32_t GetFramebufferCopyTextureFormat() override; - unsigned UpdateGpuFence() override; void SetUpdateVSyncParametersCallback( UpdateVSyncParametersCallback callback) override; void SetDisplayTransformHint(gfx::OverlayTransform transform) override {}
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc index dad49bc..083f266 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
@@ -416,6 +416,11 @@ for (auto& observer : observer_list_) observer.OnCreatedCompositorFrameSink(frame_sink_id, support->is_root()); + + if (global_throttle_interval_) { + UpdateThrottlingRecursively(frame_sink_id, + global_throttle_interval_.value()); + } } void FrameSinkManagerImpl::UnregisterCompositorFrameSinkSupport( @@ -735,16 +740,41 @@ UpdateThrottling(); } +void FrameSinkManagerImpl::StartThrottlingAllFrameSinks( + base::TimeDelta interval) { + global_throttle_interval_ = interval; + UpdateThrottling(); +} + +void FrameSinkManagerImpl::StopThrottlingAllFrameSinks() { + global_throttle_interval_ = absl::nullopt; + UpdateThrottling(); +} + void FrameSinkManagerImpl::UpdateThrottling() { // Clear previous throttling effect on all frame sinks. for (auto& support_map_item : support_map_) { support_map_item.second->ThrottleBeginFrame(base::TimeDelta()); } - if (throttle_interval_.is_zero()) + if (throttle_interval_.is_zero() && + (!global_throttle_interval_ || + global_throttle_interval_.value().is_zero())) return; - for (const auto& id : frame_sink_ids_to_throttle_) { - UpdateThrottlingRecursively(id, throttle_interval_); + if (global_throttle_interval_) { + for (const auto& support : support_map_) { + support.second->ThrottleBeginFrame(global_throttle_interval_.value()); + } + } + + // If the per-frame sink throttle interval is more aggressive than the global + // throttling interval, apply it to those frame sinks effectively always + // throttling a frame sink as much as possible. + if (!global_throttle_interval_ || + throttle_interval_ > global_throttle_interval_) { + for (const auto& id : frame_sink_ids_to_throttle_) { + UpdateThrottlingRecursively(id, throttle_interval_); + } } // Clear throttling on frame sinks currently being captured. for (const auto& id : captured_frame_sink_ids_) {
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.h b/components/viz/service/frame_sinks/frame_sink_manager_impl.h index d736d6b..7c7c279 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.h +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.h
@@ -153,6 +153,8 @@ const DebugRendererSettings& debug_settings) override; void Throttle(const std::vector<FrameSinkId>& ids, base::TimeDelta interval) override; + void StartThrottlingAllFrameSinks(base::TimeDelta interval) override; + void StopThrottlingAllFrameSinks() override; void DestroyFrameSinkBundle(const FrameSinkBundleId& id); @@ -395,9 +397,16 @@ // Ids of the frame sinks that have been requested to throttle. std::vector<FrameSinkId> frame_sink_ids_to_throttle_; - // The throttling interval which defines how often BeginFrames are sent. + // The throttling interval which defines how often BeginFrames are sent for + // frame sinks in `frame_sink_ids_to_throttle_`, if + // `global_throttle_interval_` is unset or if this interval is longer than + // `global_throttle_interval_`. base::TimeDelta throttle_interval_ = BeginFrameArgs::DefaultInterval(); + // If present, the throttling interval which defines the upper bound of how + // often BeginFrames are sent for all current and future frame sinks. + absl::optional<base::TimeDelta> global_throttle_interval_ = absl::nullopt; + base::flat_map<uint32_t, base::ScopedClosureRunner> cached_back_buffers_; THREAD_CHECKER(thread_checker_);
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc b/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc index c49494e9..8f8ba7e 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc +++ b/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc
@@ -33,6 +33,8 @@ constexpr FrameSinkId kFrameSinkIdB(3, 1); constexpr FrameSinkId kFrameSinkIdC(4, 1); constexpr FrameSinkId kFrameSinkIdD(5, 1); +constexpr FrameSinkId kFrameSinkIdE(6, 1); +constexpr FrameSinkId kFrameSinkIdF(7, 1); // Holds the four interface objects needed to create a RootCompositorFrameSink. struct RootCompositorFrameSinkData { @@ -472,6 +474,86 @@ client_d->frame_sink_id()); } +TEST_F(FrameSinkManagerTest, GlobalThrottle) { + // root -> A -> B + // -> C -> D + auto root = CreateCompositorFrameSinkSupport(kFrameSinkIdRoot); + auto client_a = CreateCompositorFrameSinkSupport(kFrameSinkIdA); + auto client_b = CreateCompositorFrameSinkSupport(kFrameSinkIdB); + auto client_c = CreateCompositorFrameSinkSupport(kFrameSinkIdC); + auto client_d = CreateCompositorFrameSinkSupport(kFrameSinkIdD); + + // Set up the hierarchy. + manager_.RegisterFrameSinkHierarchy(root->frame_sink_id(), + client_a->frame_sink_id()); + manager_.RegisterFrameSinkHierarchy(client_a->frame_sink_id(), + client_b->frame_sink_id()); + manager_.RegisterFrameSinkHierarchy(root->frame_sink_id(), + client_c->frame_sink_id()); + manager_.RegisterFrameSinkHierarchy(client_c->frame_sink_id(), + client_d->frame_sink_id()); + + constexpr base::TimeDelta global_interval = base::Hertz(30); + constexpr base::TimeDelta interval = base::Hertz(20); + + std::vector<FrameSinkId> ids{kFrameSinkIdRoot, kFrameSinkIdA, kFrameSinkIdB, + kFrameSinkIdC, kFrameSinkIdD}; + + // By default, a CompositorFrameSinkSupport shouldn't have its + // |begin_frame_interval| set. + VerifyThrottling(base::TimeDelta(), ids); + + // Starting global throttling should throttle the entire hierarchy. + manager_.StartThrottlingAllFrameSinks(global_interval); + VerifyThrottling(global_interval, ids); + + // Throttling more aggressively on top of global throttling should further + // throttle the specified frame sink hierarchy, but preserve global throttling + // on the unaffected framesinks. + manager_.Throttle({kFrameSinkIdC}, interval); + VerifyThrottling(global_interval, + {kFrameSinkIdRoot, kFrameSinkIdA, kFrameSinkIdB}); + VerifyThrottling(interval, {kFrameSinkIdC, kFrameSinkIdD}); + + // Attempting to per-sink throttle to an interval shorter than the global + // throttling should still throttle all frame sinks to the global interval. + manager_.Throttle({kFrameSinkIdA}, base::Hertz(40)); + VerifyThrottling(global_interval, ids); + + // Add a new branch to the hierarchy. These new frame sinks should be globally + // throttled immediately. root -> A -> B + // -> C -> D + // -> E -> F + auto client_e = CreateCompositorFrameSinkSupport(kFrameSinkIdE); + auto client_f = CreateCompositorFrameSinkSupport(kFrameSinkIdF); + manager_.RegisterFrameSinkHierarchy(root->frame_sink_id(), + client_e->frame_sink_id()); + manager_.RegisterFrameSinkHierarchy(client_e->frame_sink_id(), + client_f->frame_sink_id()); + VerifyThrottling( + global_interval, + {kFrameSinkIdRoot, kFrameSinkIdA, kFrameSinkIdB, kFrameSinkIdC, + kFrameSinkIdD, kFrameSinkIdE, kFrameSinkIdF}); + + // Disabling global throttling should revert back to only the up-to-date + // per-frame sink throttling. + manager_.StopThrottlingAllFrameSinks(); + VerifyThrottling(base::Hertz(40), {kFrameSinkIdA, kFrameSinkIdB}); + + manager_.UnregisterFrameSinkHierarchy(root->frame_sink_id(), + client_a->frame_sink_id()); + manager_.UnregisterFrameSinkHierarchy(client_a->frame_sink_id(), + client_b->frame_sink_id()); + manager_.UnregisterFrameSinkHierarchy(root->frame_sink_id(), + client_c->frame_sink_id()); + manager_.UnregisterFrameSinkHierarchy(client_c->frame_sink_id(), + client_d->frame_sink_id()); + manager_.UnregisterFrameSinkHierarchy(root->frame_sink_id(), + client_e->frame_sink_id()); + manager_.UnregisterFrameSinkHierarchy(client_e->frame_sink_id(), + client_f->frame_sink_id()); +} + // Verifies if a frame sink is being captured, it should not be throttled. TEST_F(FrameSinkManagerTest, NoThrottleOnFrameSinksBeingCaptured) { // root -> A -> B -> C
diff --git a/components/viz/test/fake_output_surface.cc b/components/viz/test/fake_output_surface.cc index 7430827..7c605e8d 100644 --- a/components/viz/test/fake_output_surface.cc +++ b/components/viz/test/fake_output_surface.cc
@@ -47,8 +47,6 @@ client_->DidReceivePresentationFeedback({now, base::TimeDelta(), 0}); } -void FakeSoftwareOutputSurface::BindFramebuffer() {} - void FakeSoftwareOutputSurface::SetDrawRectangle(const gfx::Rect& rect) { NOTREACHED(); } @@ -57,32 +55,16 @@ NOTREACHED(); } -uint32_t FakeSoftwareOutputSurface::GetFramebufferCopyTextureFormat() { - return GL_RGB; -} - void FakeSoftwareOutputSurface::BindToClient(OutputSurfaceClient* client) { DCHECK(client); DCHECK(!client_); client_ = client; } -bool FakeSoftwareOutputSurface::HasExternalStencilTest() const { - return false; -} - bool FakeSoftwareOutputSurface::IsDisplayedAsOverlayPlane() const { return false; } -unsigned FakeSoftwareOutputSurface::GetOverlayTextureId() const { - return 0; -} - -unsigned FakeSoftwareOutputSurface::UpdateGpuFence() { - return 0; -} - void FakeSoftwareOutputSurface::SetUpdateVSyncParametersCallback( UpdateVSyncParametersCallback callback) {}
diff --git a/components/viz/test/fake_output_surface.h b/components/viz/test/fake_output_surface.h index 71d40d5..c1f6fd0e 100644 --- a/components/viz/test/fake_output_surface.h +++ b/components/viz/test/fake_output_surface.h
@@ -37,17 +37,11 @@ void BindToClient(OutputSurfaceClient* client) override; void EnsureBackbuffer() override {} void DiscardBackbuffer() override {} - void BindFramebuffer() override; void SetDrawRectangle(const gfx::Rect& rect) override; void SetEnableDCLayers(bool enabled) override; void Reshape(const ReshapeParams& params) override; void SwapBuffers(OutputSurfaceFrame frame) override; - uint32_t GetFramebufferCopyTextureFormat() override; - bool HasExternalStencilTest() const override; - void ApplyExternalStencil() override {} bool IsDisplayedAsOverlayPlane() const override; - unsigned GetOverlayTextureId() const override; - unsigned UpdateGpuFence() override; void SetUpdateVSyncParametersCallback( UpdateVSyncParametersCallback callback) override; void SetDisplayTransformHint(gfx::OverlayTransform transform) override;
diff --git a/components/viz/test/fake_skia_output_surface.cc b/components/viz/test/fake_skia_output_surface.cc index 15ce84b0..8c07fb66 100644 --- a/components/viz/test/fake_skia_output_surface.cc +++ b/components/viz/test/fake_skia_output_surface.cc
@@ -56,10 +56,6 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); } -void FakeSkiaOutputSurface::BindFramebuffer() { - // TODO(penghuang): remove this method when GLRenderer is removed. -} - void FakeSkiaOutputSurface::Reshape(const ReshapeParams& params) { auto& sk_surface = sk_surfaces_[AggregatedRenderPassId{0}]; SkColorType color_type = kRGBA_8888_SkColorType; @@ -87,34 +83,10 @@ NOTIMPLEMENTED(); } -uint32_t FakeSkiaOutputSurface::GetFramebufferCopyTextureFormat() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - return GL_RGB; -} - bool FakeSkiaOutputSurface::IsDisplayedAsOverlayPlane() const { return false; } -unsigned FakeSkiaOutputSurface::GetOverlayTextureId() const { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - return 0; -} - -bool FakeSkiaOutputSurface::HasExternalStencilTest() const { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - return false; -} - -void FakeSkiaOutputSurface::ApplyExternalStencil() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); -} - -unsigned FakeSkiaOutputSurface::UpdateGpuFence() { - NOTIMPLEMENTED(); - return 0; -} - void FakeSkiaOutputSurface::SetNeedsSwapSizeNotifications( bool needs_swap_size_notifications) { NOTIMPLEMENTED();
diff --git a/components/viz/test/fake_skia_output_surface.h b/components/viz/test/fake_skia_output_surface.h index cbbc88c0..e9893a0 100644 --- a/components/viz/test/fake_skia_output_surface.h +++ b/components/viz/test/fake_skia_output_surface.h
@@ -44,18 +44,12 @@ void BindToClient(OutputSurfaceClient* client) override; void EnsureBackbuffer() override; void DiscardBackbuffer() override; - void BindFramebuffer() override; void Reshape(const ReshapeParams& params) override; void SwapBuffers(OutputSurfaceFrame frame) override; void ScheduleOutputSurfaceAsOverlay( OverlayProcessorInterface::OutputSurfaceOverlayPlane output_surface_plane) override; - uint32_t GetFramebufferCopyTextureFormat() override; bool IsDisplayedAsOverlayPlane() const override; - unsigned GetOverlayTextureId() const override; - bool HasExternalStencilTest() const override; - void ApplyExternalStencil() override; - unsigned UpdateGpuFence() override; void SetNeedsSwapSizeNotifications( bool needs_swap_size_notifications) override; void SetUpdateVSyncParametersCallback(
diff --git a/components/viz/test/test_frame_sink_manager.h b/components/viz/test/test_frame_sink_manager.h index 310dedd1..55cd4d3b 100644 --- a/components/viz/test/test_frame_sink_manager.h +++ b/components/viz/test/test_frame_sink_manager.h
@@ -73,6 +73,8 @@ const DebugRendererSettings& debug_settings) override {} void Throttle(const std::vector<FrameSinkId>& ids, base::TimeDelta interval) override {} + void StartThrottlingAllFrameSinks(base::TimeDelta interval) override {} + void StopThrottlingAllFrameSinks() override {} mojo::Receiver<mojom::FrameSinkManager> receiver_{this}; mojo::Remote<mojom::FrameSinkManagerClient> client_;
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index e9983d94..3444ee0 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1345,6 +1345,7 @@ "payments/respond_with_callback.cc", "payments/respond_with_callback.h", "per_web_ui_browser_interface_broker.cc", + "performance_manager/frame_rate_throttling.cc", "permissions/permission_controller_impl.cc", "permissions/permission_controller_impl.h", "permissions/permission_service_context.cc", @@ -1910,10 +1911,14 @@ "sms/webotp_service.h", "speculation_rules/prefetch/prefetch_container.cc", "speculation_rules/prefetch/prefetch_container.h", + "speculation_rules/prefetch/prefetch_cookie_listener.cc", + "speculation_rules/prefetch/prefetch_cookie_listener.h", "speculation_rules/prefetch/prefetch_document_manager.cc", "speculation_rules/prefetch/prefetch_document_manager.h", "speculation_rules/prefetch/prefetch_features.cc", "speculation_rules/prefetch/prefetch_features.h", + "speculation_rules/prefetch/prefetch_from_string_url_loader.cc", + "speculation_rules/prefetch/prefetch_from_string_url_loader.h", "speculation_rules/prefetch/prefetch_network_context.cc", "speculation_rules/prefetch/prefetch_network_context.h", "speculation_rules/prefetch/prefetch_network_context_client.cc", @@ -1927,6 +1932,8 @@ "speculation_rules/prefetch/prefetch_status.h", "speculation_rules/prefetch/prefetch_type.cc", "speculation_rules/prefetch/prefetch_type.h", + "speculation_rules/prefetch/prefetch_url_loader_interceptor.cc", + "speculation_rules/prefetch/prefetch_url_loader_interceptor.h", "speculation_rules/prefetch/prefetched_mainframe_response_container.cc", "speculation_rules/prefetch/prefetched_mainframe_response_container.h", "speculation_rules/speculation_host_impl.cc",
diff --git a/content/browser/accessibility/dump_accessibility_browsertest_base.cc b/content/browser/accessibility/dump_accessibility_browsertest_base.cc index 289243b..f2d0c64 100644 --- a/content/browser/accessibility/dump_accessibility_browsertest_base.cc +++ b/content/browser/accessibility/dump_accessibility_browsertest_base.cc
@@ -311,7 +311,7 @@ if (!expected_file.empty()) { expected_lines = test_helper_.LoadExpectationFile(expected_file); } -#if BUILDFLAG(IS_WIN) +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_FUCHSIA) else { LOG(INFO) << "No expectation file present, ignoring test on this " "platform.";
diff --git a/content/browser/aggregation_service/README.md b/content/browser/aggregation_service/README.md index 42b7cae5..2ebcd52e 100644 --- a/content/browser/aggregation_service/README.md +++ b/content/browser/aggregation_service/README.md
@@ -1,6 +1,6 @@ # Aggregation service -This directory contains the implementation of the client-side logic for the [Aggregation service](https://github.com/WICG/conversion-measurement-api/blob/main/AGGREGATE.md#data-processing-through-the-aggregation-service) proposed for the [Attribution Reporting API](https://github.com/WICG/conversion-measurement-api). +This directory contains the implementation of the client-side logic for the [Aggregation service](https://github.com/WICG/attribution-reporting-api/blob/main/AGGREGATE.md#data-processing-through-a-secure-aggregation-service) proposed for the [Attribution Reporting API](https://github.com/WICG/attribution-reporting-api). ## Command-line tool A command-line tool that generates aggregatable reports for testing is available. Please see //tools/aggregation_service's [README](../../../tools/aggregation_service/README.md) for more detail
diff --git a/content/browser/aggregation_service/aggregatable_report.h b/content/browser/aggregation_service/aggregatable_report.h index 8d1037f..7b21d486 100644 --- a/content/browser/aggregation_service/aggregatable_report.h +++ b/content/browser/aggregation_service/aggregatable_report.h
@@ -41,11 +41,11 @@ enum class AggregationMode { // Uses a server-side Trusted Execution Environment (TEE) to process the // encrypted payloads, see - // https://github.com/WICG/conversion-measurement-api/blob/main/AGGREGATION_SERVICE_TEE.md. + // https://github.com/WICG/attribution-reporting-api/blob/main/AGGREGATION_SERVICE_TEE.md. kTeeBased, // Implements a protocol similar to poplar VDAF in the PPM Framework, see - // https://github.com/WICG/conversion-measurement-api/blob/main/AGGREGATE.md#choosing-among-aggregation-services. + // https://github.com/WICG/attribution-reporting-api/blob/main/AGGREGATE.md#choosing-among-aggregation-services. kExperimentalPoplar, kDefault = kTeeBased,
diff --git a/content/browser/aggregation_service/aggregatable_report_sender.cc b/content/browser/aggregation_service/aggregatable_report_sender.cc index d9a3e1a0..bc5fd51 100644 --- a/content/browser/aggregation_service/aggregatable_report_sender.cc +++ b/content/browser/aggregation_service/aggregatable_report_sender.cc
@@ -92,7 +92,7 @@ "Sends the aggregatable report to reporting endpoint requested by " "APIs that rely on private, secure aggregation (e.g. Attribution " "Reporting API, see " - "https://github.com/WICG/conversion-measurement-api)." + "https://github.com/WICG/attribution-reporting-api)." trigger: "When an aggregatable report has become eligible for reporting." data:
diff --git a/content/browser/aggregation_service/aggregation_service_network_fetcher_impl.cc b/content/browser/aggregation_service/aggregation_service_network_fetcher_impl.cc index 967f147..71d4f6b 100644 --- a/content/browser/aggregation_service/aggregation_service_network_fetcher_impl.cc +++ b/content/browser/aggregation_service/aggregation_service_network_fetcher_impl.cc
@@ -93,7 +93,7 @@ description: "Downloads public keys for helper servers requested by APIs that " "rely on private, secure aggregation (e.g. Attribution Reporting " - "API, see https://github.com/WICG/conversion-measurement-api). " + "API, see https://github.com/WICG/attribution-reporting-api). " "Keys are requested prior to aggregate reports being sent and are " "used to encrypt payloads for the helper servers." trigger:
diff --git a/content/browser/aggregation_service/payload_encryption.md b/content/browser/aggregation_service/payload_encryption.md index 178cbed9..29a10ed 100644 --- a/content/browser/aggregation_service/payload_encryption.md +++ b/content/browser/aggregation_service/payload_encryption.md
@@ -3,7 +3,7 @@ Here, we briefly describe the precise details of payload encryption for aggregatable reports used in the aggregation service. The format of the payload itself is provided in the -[explainer](https://github.com/WICG/conversion-measurement-api/blob/3d0a541c708391d73905afafa155d6753c8565af/AGGREGATE.md#encrypted-payload)[^1], +[explainer](https://github.com/WICG/attribution-reporting-api/blob/3d0a541c708391d73905afafa155d6753c8565af/AGGREGATE.md#encrypted-payload)[^1], but some of these details aren’t. Note that these details are subject to change, but reflect the current API offered by `aggregation_service/`. @@ -20,7 +20,7 @@ The unencrypted payload is first generated as a [CBOR](https://cbor.io/) map with the format described in the -[explainer](https://github.com/WICG/conversion-measurement-api/blob/3d0a541c708391d73905afafa155d6753c8565af/AGGREGATE.md#encrypted-payload)[^1]. +[explainer](https://github.com/WICG/attribution-reporting-api/blob/3d0a541c708391d73905afafa155d6753c8565af/AGGREGATE.md#encrypted-payload)[^1]. This map is serialized to binary and used as the plaintext input. ### Associated data @@ -56,7 +56,7 @@ The public key is a 32-byte (256-bit) bytestring. The browser downloads public keys from the aggregation service according to the process described in the -[explainer](https://github.com/WICG/conversion-measurement-api/blob/3d0a541c708391d73905afafa155d6753c8565af/AGGREGATE.md#encrypted-payload)[^1] +[explainer](https://github.com/WICG/attribution-reporting-api/blob/3d0a541c708391d73905afafa155d6753c8565af/AGGREGATE.md#encrypted-payload)[^1] and picks one uniformly at random (if multiple are specified). Note that this key must be base64 decoded by the client. The browser provides the matching `id` of the key used to encrypt the payload as `key_id`. @@ -91,7 +91,7 @@ [^1]: Note that these links point to a specific commit of the explainer that reflects what is currently implemented as of the latest update to this file. The - [up-to-date explainer](https://github.com/WICG/conversion-measurement-api/blob/main/AGGREGATE.md#encrypted-payload) + [up-to-date explainer](https://github.com/WICG/attribution-reporting-api/blob/main/AGGREGATE.md#encrypted-payload) may have recent changes that have not yet been implemented. [^2]: This ensures that ciphertexts for one API cannot be accepted for a
diff --git a/content/browser/android/navigation_handle_proxy.cc b/content/browser/android/navigation_handle_proxy.cc index 51d08b50..9cf52b07 100644 --- a/content/browser/android/navigation_handle_proxy.cc +++ b/content/browser/android/navigation_handle_proxy.cc
@@ -60,9 +60,12 @@ ? cpp_navigation_handle_->GetURL() : cpp_navigation_handle_->GetBaseURLForDataURL(); - bool is_fragment_navigation = cpp_navigation_handle_->IsSameDocument(); + bool is_primary_main_frame_fragment_navigation = + cpp_navigation_handle_->IsInPrimaryMainFrame() && + cpp_navigation_handle_->IsSameDocument(); - if (cpp_navigation_handle_->HasCommitted()) { + if (is_primary_main_frame_fragment_navigation && + cpp_navigation_handle_->HasCommitted()) { // See http://crbug.com/251330 for why it's determined this way. GURL::Replacements replacements; replacements.ClearRef(); @@ -70,7 +73,7 @@ cpp_navigation_handle_->GetURL().ReplaceComponents(replacements) == cpp_navigation_handle_->GetPreviousMainFrameURL().ReplaceComponents( replacements); - is_fragment_navigation &= urls_same_ignoring_fragment; + is_primary_main_frame_fragment_navigation = urls_same_ignoring_fragment; } bool is_valid_search_form_url = @@ -81,7 +84,8 @@ Java_NavigationHandle_didFinish( env, java_navigation_handle_, url::GURLAndroid::FromNativeGURL(env, gurl), cpp_navigation_handle_->IsErrorPage(), - cpp_navigation_handle_->HasCommitted(), is_fragment_navigation, + cpp_navigation_handle_->HasCommitted(), + is_primary_main_frame_fragment_navigation, cpp_navigation_handle_->IsDownload(), is_valid_search_form_url, cpp_navigation_handle_->GetPageTransition(), cpp_navigation_handle_->GetNetErrorCode(),
diff --git a/content/browser/attribution_reporting/attribution_src_browsertest.cc b/content/browser/attribution_reporting/attribution_src_browsertest.cc index 5abe21d..b05a6d03 100644 --- a/content/browser/attribution_reporting/attribution_src_browsertest.cc +++ b/content/browser/attribution_reporting/attribution_src_browsertest.cc
@@ -604,8 +604,21 @@ EXPECT_TRUE(request->headers.find("Referer") == request->headers.end()); } -IN_PROC_BROWSER_TEST_F(AttributionSrcBrowserTest, - AttributionSrcImg_TriggerRegistered) { +class AttributionSrcBasicTriggerBrowserTest + : public AttributionSrcBrowserTest, + public ::testing::WithParamInterface< + std::pair<std::string, std::string>> {}; + +INSTANTIATE_TEST_SUITE_P( + All, + AttributionSrcBasicTriggerBrowserTest, + ::testing::Values( + std::make_pair("attributionsrcimg", "createAttributionSrcImg($1)"), + std::make_pair("fetch", "window.fetch($1, {mode:'no-cors'})")), + [](const auto& info) { return info.param.first; }); // test name generator + +IN_PROC_BROWSER_TEST_P(AttributionSrcBasicTriggerBrowserTest, + TriggerRegistered) { GURL page_url = https_server()->GetURL("b.test", "/page_with_impression_creator.html"); EXPECT_TRUE(NavigateToURL(web_contents(), page_url)); @@ -622,8 +635,8 @@ GURL register_url = https_server()->GetURL("c.test", "/register_trigger_headers.html"); - EXPECT_TRUE(ExecJs(web_contents(), - JsReplace("createAttributionSrcImg($1);", register_url))); + const std::string& js_template = GetParam().second; + EXPECT_TRUE(ExecJs(web_contents(), JsReplace(js_template, register_url))); if (!data_host) loop.Run(); data_host->WaitForTriggerData(/*num_trigger_data=*/1);
diff --git a/content/browser/blob_storage/chrome_blob_storage_context.cc b/content/browser/blob_storage/chrome_blob_storage_context.cc index 7dead742..1beba57f 100644 --- a/content/browser/blob_storage/chrome_blob_storage_context.cc +++ b/content/browser/blob_storage/chrome_blob_storage_context.cc
@@ -13,7 +13,6 @@ #include "base/files/file_enumerator.h" #include "base/files/file_util.h" #include "base/guid.h" -#include "base/metrics/histogram_macros.h" #include "base/supports_user_data.h" #include "base/task/single_thread_task_runner.h" #include "base/task/task_runner.h" @@ -54,16 +53,12 @@ } base::FileEnumerator enumerator(blob_storage_parent, false /* recursive */, base::FileEnumerator::DIRECTORIES); - bool success = true; - bool cleanup_needed = false; + for (FilePath name = enumerator.Next(); !name.empty(); name = enumerator.Next()) { - cleanup_needed = true; if (current_run_dir.empty() || name != current_run_dir) - success &= base::DeletePathRecursively(name); + base::DeletePathRecursively(name); } - if (cleanup_needed) - UMA_HISTOGRAM_BOOLEAN("Storage.Blob.CleanupSuccess", success); } class BlobHandleImpl : public BlobHandle {
diff --git a/content/browser/devtools/devtools_url_loader_interceptor.cc b/content/browser/devtools/devtools_url_loader_interceptor.cc index cd09ef2..5fe42f0 100644 --- a/content/browser/devtools/devtools_url_loader_interceptor.cc +++ b/content/browser/devtools/devtools_url_loader_interceptor.cc
@@ -1171,7 +1171,7 @@ while (headers.EnumerateHeader(&iter, name, &cookie_line)) { std::unique_ptr<net::CanonicalCookie> cookie = net::CanonicalCookie::Create( create_loader_params_->request.url, cookie_line, now, server_time, - net::CookiePartitionKey::Todo()); + absl::nullopt); if (cookie) cookies.emplace_back(std::move(cookie)); }
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index 46fec2cf..cd8ed02 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -38,6 +38,7 @@ #include "content/browser/service_worker/service_worker_container_host.h" #include "content/browser/service_worker/service_worker_main_resource_handle.h" #include "content/browser/service_worker/service_worker_main_resource_loader_interceptor.h" +#include "content/browser/speculation_rules/prefetch/prefetch_url_loader_interceptor.h" #include "content/browser/storage_partition_impl.h" #include "content/browser/url_loader_factory_getter.h" #include "content/browser/web_package/prefetched_signed_exchange_cache.h" @@ -474,6 +475,14 @@ std::move(accept_langs))); } + // Set up an interceptor for prefetch. + std::unique_ptr<PrefetchURLLoaderInterceptor> prefetch_interceptor = + content::PrefetchURLLoaderInterceptor::MaybeCreateInterceptor( + frame_tree_node_id_); + if (prefetch_interceptor) { + interceptors_.push_back(std::move(prefetch_interceptor)); + } + // See if embedders want to add interceptors. std::vector<std::unique_ptr<URLLoaderRequestInterceptor>> browser_interceptors =
diff --git a/content/browser/performance_manager/frame_rate_throttling.cc b/content/browser/performance_manager/frame_rate_throttling.cc new file mode 100644 index 0000000..c47c0eb7 --- /dev/null +++ b/content/browser/performance_manager/frame_rate_throttling.cc
@@ -0,0 +1,23 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/public/browser/frame_rate_throttling.h" + +#include "components/viz/host/host_frame_sink_manager.h" +#include "content/browser/compositor/surface_utils.h" +#include "content/public/browser/browser_thread.h" + +namespace content { + +CONTENT_EXPORT void StartThrottlingAllFrameSinks(base::TimeDelta interval) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + GetHostFrameSinkManager()->StartThrottlingAllFrameSinks(interval); +} + +CONTENT_EXPORT void StopThrottlingAllFrameSinks() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + GetHostFrameSinkManager()->StopThrottlingAllFrameSinks(); +} + +} // namespace content
diff --git a/content/browser/renderer_host/navigator.cc b/content/browser/renderer_host/navigator.cc index ccf890a5..0588899 100644 --- a/content/browser/renderer_host/navigator.cc +++ b/content/browser/renderer_host/navigator.cc
@@ -1306,6 +1306,10 @@ navigation_data_->commit_navigation_sent_) { base::TimeTicks unload_start = params.unload_start.value(); base::TimeTicks unload_end = params.unload_end.value(); + // Note: we expect `commit_navigation_end` to be later than `unload_end`. + // `unload_end` is recorded when the unload handlers finish running, which + // happens prior to the navigation committing and recording + // `commit_navigation_end` in this same-process case. base::TimeTicks commit_navigation_end = params.commit_navigation_end.value(); @@ -1316,7 +1320,7 @@ blink::LocalTimeTicks::FromTimeTicks(first_before_unload_start_time), blink::LocalTimeTicks::FromTimeTicks(base::TimeTicks::Now()), blink::RemoteTimeTicks::FromTimeTicks(unload_start), - blink::RemoteTimeTicks::FromTimeTicks(unload_end)); + blink::RemoteTimeTicks::FromTimeTicks(commit_navigation_end)); blink::LocalTimeTicks converted_unload_start = converter.ToLocalTimeTicks( blink::RemoteTimeTicks::FromTimeTicks(unload_start)); blink::LocalTimeTicks converted_unload_end = converter.ToLocalTimeTicks(
diff --git a/content/browser/speculation_rules/prefetch/prefetch_container.cc b/content/browser/speculation_rules/prefetch/prefetch_container.cc index 5b1b8dc..3920e5e 100644 --- a/content/browser/speculation_rules/prefetch/prefetch_container.cc +++ b/content/browser/speculation_rules/prefetch/prefetch_container.cc
@@ -6,6 +6,9 @@ #include <memory> +#include "base/callback.h" +#include "base/time/time.h" +#include "content/browser/speculation_rules/prefetch/prefetch_cookie_listener.h" #include "content/browser/speculation_rules/prefetch/prefetch_document_manager.h" #include "content/browser/speculation_rules/prefetch/prefetch_network_context.h" #include "content/browser/speculation_rules/prefetch/prefetch_service.h" @@ -14,6 +17,7 @@ #include "content/browser/speculation_rules/prefetch/prefetched_mainframe_response_container.h" #include "content/public/browser/global_routing_id.h" #include "services/network/public/cpp/simple_url_loader.h" +#include "services/network/public/mojom/cookie_manager.mojom.h" #include "url/gurl.h" namespace content { @@ -48,6 +52,58 @@ return prefetch_document_manager_.get(); } +void PrefetchContainer::RegisterCookieListener( + network::mojom::CookieManager* cookie_manager) { + cookie_listener_ = + PrefetchCookieListener::MakeAndRegister(url_, cookie_manager); +} + +void PrefetchContainer::StopCookieListener() { + if (cookie_listener_) + cookie_listener_->StopListening(); +} + +bool PrefetchContainer::HaveDefaultContextCookiesChanged() const { + if (cookie_listener_) + return cookie_listener_->HaveCookiesChanged(); + return false; +} + +bool PrefetchContainer::IsIsolatedCookieCopyInProgress() const { + switch (cookie_copy_status_) { + case CookieCopyStatus::kNotStarted: + case CookieCopyStatus::kCompleted: + return false; + case CookieCopyStatus::kInProgress: + return true; + } +} + +void PrefetchContainer::OnIsolatedCookieCopyStart() { + DCHECK(!IsIsolatedCookieCopyInProgress()); + + // We don't want the cookie listener for this URL to get the changes from the + // copy. + StopCookieListener(); + + cookie_copy_status_ = CookieCopyStatus::kInProgress; +} + +void PrefetchContainer::OnIsolatedCookieCopyComplete() { + DCHECK(IsIsolatedCookieCopyInProgress()); + + cookie_copy_status_ = CookieCopyStatus::kCompleted; + + if (on_cookie_copy_complete_callback_) + std::move(on_cookie_copy_complete_callback_).Run(); +} + +void PrefetchContainer::SetOnCookieCopyCompleteCallback( + base::OnceClosure callback) { + DCHECK(IsIsolatedCookieCopyInProgress()); + on_cookie_copy_complete_callback_ = std::move(callback); +} + void PrefetchContainer::TakeURLLoader( std::unique_ptr<network::SimpleURLLoader> loader) { DCHECK(!loader_); @@ -59,17 +115,25 @@ loader_.reset(); } -bool PrefetchContainer::HasPrefetchedResponse() const { - return prefetched_response_ != nullptr; +bool PrefetchContainer::HasValidPrefetchedResponse( + base::TimeDelta cacheable_duration) const { + return prefetched_response_ != nullptr && + prefetch_received_time_.has_value() && + base::TimeTicks::Now() < + prefetch_received_time_.value() + cacheable_duration; } void PrefetchContainer::TakePrefetchedResponse( std::unique_ptr<PrefetchedMainframeResponseContainer> prefetched_response) { + DCHECK(!prefetched_response_); + DCHECK(!is_decoy_); + prefetch_received_time_ = base::TimeTicks::Now(); prefetched_response_ = std::move(prefetched_response); } std::unique_ptr<PrefetchedMainframeResponseContainer> PrefetchContainer::ReleasePrefetchedResponse() { + prefetch_received_time_.reset(); return std::move(prefetched_response_); }
diff --git a/content/browser/speculation_rules/prefetch/prefetch_container.h b/content/browser/speculation_rules/prefetch/prefetch_container.h index 511b7ec..d4e3e7f 100644 --- a/content/browser/speculation_rules/prefetch/prefetch_container.h +++ b/content/browser/speculation_rules/prefetch/prefetch_container.h
@@ -7,7 +7,9 @@ #include <utility> +#include "base/callback.h" #include "base/memory/weak_ptr.h" +#include "base/time/time.h" #include "content/browser/speculation_rules/prefetch/prefetch_status.h" #include "content/browser/speculation_rules/prefetch/prefetch_type.h" #include "content/common/content_export.h" @@ -17,13 +19,17 @@ namespace network { class SimpleURLLoader; +namespace mojom { +class CookieManager; +} // namespace mojom } // namespace network namespace content { -class PrefetchService; +class PrefetchCookieListener; class PrefetchDocumentManager; class PrefetchNetworkContext; +class PrefetchService; class PrefetchedMainframeResponseContainer; // This class contains the state for a request to prefetch a specific URL. @@ -73,6 +79,22 @@ void SetIsDecoy(bool is_decoy) { is_decoy_ = is_decoy; } bool IsDecoy() const { return is_decoy_; } + // After the initial eligiblity check for |url_|, a + // |PrefetchCookieListener| listens for any changes to the cookies + // associated with |url_|. If these cookies change, then no prefetched + // resources will be served. + void RegisterCookieListener(network::mojom::CookieManager* cookie_manager); + void StopCookieListener(); + bool HaveDefaultContextCookiesChanged() const; + + // Before a prefetch can be served, any cookies added to the isolated network + // context must be copied over to the default network context. These functions + // are used to check and update the status of this process. + bool IsIsolatedCookieCopyInProgress() const; + void OnIsolatedCookieCopyStart(); + void OnIsolatedCookieCopyComplete(); + void SetOnCookieCopyCompleteCallback(base::OnceClosure callback); + // The network context used to make network requests for this prefetch. PrefetchNetworkContext* GetOrCreateNetworkContext( PrefetchService* prefetch_service); @@ -87,7 +109,7 @@ PrefetchDocumentManager* GetPrefetchDocumentManager() const; // Whether or not |this| has a prefetched response. - bool HasPrefetchedResponse() const; + bool HasValidPrefetchedResponse(base::TimeDelta cacheable_duration) const; // |this| takes ownership of the given |prefetched_response|. void TakePrefetchedResponse( @@ -125,6 +147,10 @@ // any prefetched resources will not be served. bool is_decoy_ = false; + // This tracks whether the cookies associated with |url_| have changed at some + // point after the initial eligibility check. + std::unique_ptr<PrefetchCookieListener> cookie_listener_; + // The network context used to prefetch |url_|. std::unique_ptr<PrefetchNetworkContext> network_context_; @@ -134,6 +160,23 @@ // The prefetched response for |url_|. std::unique_ptr<PrefetchedMainframeResponseContainer> prefetched_response_; + // The time at which |prefetched_response_| was received. This is used to + // determine whether or not |prefetched_response_| is stale. + absl::optional<base::TimeTicks> prefetch_received_time_; + + // The different possible states of the cookie copy process. + enum class CookieCopyStatus { + kNotStarted, + kInProgress, + kCompleted, + }; + + // The current state of the cookie copy process for this prefetch. + CookieCopyStatus cookie_copy_status_ = CookieCopyStatus::kNotStarted; + + // A callback that runs once |cookie_copy_status_| is set to |kCompleted|. + base::OnceClosure on_cookie_copy_complete_callback_; + base::WeakPtrFactory<PrefetchContainer> weak_method_factory_{this}; };
diff --git a/content/browser/speculation_rules/prefetch/prefetch_container_unittest.cc b/content/browser/speculation_rules/prefetch/prefetch_container_unittest.cc index 4898fc6..7eeff2e 100644 --- a/content/browser/speculation_rules/prefetch/prefetch_container_unittest.cc +++ b/content/browser/speculation_rules/prefetch/prefetch_container_unittest.cc
@@ -6,13 +6,76 @@ #include "content/browser/speculation_rules/prefetch/prefetch_status.h" #include "content/browser/speculation_rules/prefetch/prefetch_type.h" +#include "content/browser/speculation_rules/prefetch/prefetched_mainframe_response_container.h" +#include "content/public/browser/browser_context.h" #include "content/public/browser/global_routing_id.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/test/test_renderer_host.h" +#include "net/base/isolation_info.h" +#include "services/network/public/mojom/cookie_manager.mojom.h" +#include "services/network/public/mojom/network_context.mojom.h" +#include "services/network/public/mojom/url_response_head.mojom.h" #include "testing/gtest/include/gtest/gtest.h" namespace content { namespace { -class PrefetchContainerTest : public ::testing::Test {}; +class PrefetchContainerTest : public RenderViewHostTestHarness { + public: + PrefetchContainerTest() + : RenderViewHostTestHarness( + base::test::TaskEnvironment::TimeSource::MOCK_TIME) {} + + void SetUp() override { + RenderViewHostTestHarness::SetUp(); + + browser_context() + ->GetDefaultStoragePartition() + ->GetNetworkContext() + ->GetCookieManager(cookie_manager_.BindNewPipeAndPassReceiver()); + } + + network::mojom::CookieManager* cookie_manager() { + return cookie_manager_.get(); + } + + bool SetCookie(const GURL& url, const std::string& value) { + std::unique_ptr<net::CanonicalCookie> cookie(net::CanonicalCookie::Create( + url, value, base::Time::Now(), /*server_time=*/absl::nullopt, + /*cookie_partition_key=*/absl::nullopt)); + + EXPECT_TRUE(cookie.get()); + + bool result = false; + base::RunLoop run_loop; + + net::CookieOptions options; + options.set_include_httponly(); + options.set_same_site_cookie_context( + net::CookieOptions::SameSiteCookieContext::MakeInclusive()); + + cookie_manager_->SetCanonicalCookie( + *cookie.get(), url, options, + base::BindOnce( + [](bool* result, base::RunLoop* run_loop, + net::CookieAccessResult set_cookie_access_result) { + *result = set_cookie_access_result.status.IsInclude(); + run_loop->Quit(); + }, + &result, &run_loop)); + + // This will run until the cookie is set. + run_loop.Run(); + + // This will run until the cookie listener is updated. + base::RunLoop().RunUntilIdle(); + + return result; + } + + private: + mojo::Remote<network::mojom::CookieManager> cookie_manager_; +}; TEST_F(PrefetchContainerTest, CreatePrefetchContainer) { PrefetchContainer prefetch_container( @@ -62,5 +125,71 @@ EXPECT_TRUE(prefetch_container.IsDecoy()); } +TEST_F(PrefetchContainerTest, ValidResponse) { + PrefetchContainer prefetch_container( + GlobalRenderFrameHostId(1234, 5678), GURL("https://test.com"), + PrefetchType(/*use_isolated_network_context=*/true, + /*use_prefetch_proxy=*/true), + nullptr); + + prefetch_container.TakePrefetchedResponse( + std::make_unique<PrefetchedMainframeResponseContainer>( + net::IsolationInfo(), network::mojom::URLResponseHead::New(), + std::make_unique<std::string>("test body"))); + + task_environment()->FastForwardBy(base::Minutes(2)); + + EXPECT_FALSE(prefetch_container.HasValidPrefetchedResponse(base::Minutes(1))); + EXPECT_TRUE(prefetch_container.HasValidPrefetchedResponse(base::Minutes(3))); +} + +TEST_F(PrefetchContainerTest, CookieListener) { + PrefetchContainer prefetch_container( + GlobalRenderFrameHostId(1234, 5678), GURL("https://test.com"), + PrefetchType(/*use_isolated_network_context=*/true, + /*use_prefetch_proxy=*/true), + nullptr); + + EXPECT_FALSE(prefetch_container.HaveDefaultContextCookiesChanged()); + + prefetch_container.RegisterCookieListener(cookie_manager()); + + EXPECT_FALSE(prefetch_container.HaveDefaultContextCookiesChanged()); + + ASSERT_TRUE(SetCookie(GURL("https://test.com"), "test-cookie")); + + EXPECT_TRUE(prefetch_container.HaveDefaultContextCookiesChanged()); +} + +TEST_F(PrefetchContainerTest, CookieCopy) { + PrefetchContainer prefetch_container( + GlobalRenderFrameHostId(1234, 5678), GURL("https://test.com"), + PrefetchType(/*use_isolated_network_context=*/true, + /*use_prefetch_proxy=*/true), + nullptr); + prefetch_container.RegisterCookieListener(cookie_manager()); + + EXPECT_FALSE(prefetch_container.IsIsolatedCookieCopyInProgress()); + + prefetch_container.OnIsolatedCookieCopyStart(); + + EXPECT_TRUE(prefetch_container.IsIsolatedCookieCopyInProgress()); + + // Once the cookie copy process has started, we should stop the cookie + // listener. + ASSERT_TRUE(SetCookie(GURL("https://test.com"), "test-cookie")); + EXPECT_FALSE(prefetch_container.HaveDefaultContextCookiesChanged()); + + bool callback_called = false; + prefetch_container.SetOnCookieCopyCompleteCallback( + base::BindOnce([](bool* callback_called) { *callback_called = true; }, + &callback_called)); + + prefetch_container.OnIsolatedCookieCopyComplete(); + + EXPECT_FALSE(prefetch_container.IsIsolatedCookieCopyInProgress()); + EXPECT_TRUE(callback_called); +} + } // namespace } // namespace content
diff --git a/content/browser/speculation_rules/prefetch/prefetch_cookie_listener.cc b/content/browser/speculation_rules/prefetch/prefetch_cookie_listener.cc new file mode 100644 index 0000000..6bbf3ff3 --- /dev/null +++ b/content/browser/speculation_rules/prefetch/prefetch_cookie_listener.cc
@@ -0,0 +1,51 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/speculation_rules/prefetch/prefetch_cookie_listener.h" + +#include <memory> + +#include "base/check.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "services/network/public/mojom/cookie_manager.mojom.h" +#include "url/gurl.h" + +namespace content { + +std::unique_ptr<PrefetchCookieListener> PrefetchCookieListener::MakeAndRegister( + const GURL& url, + network::mojom::CookieManager* cookie_manager) { + DCHECK(cookie_manager); + + std::unique_ptr<PrefetchCookieListener> cookie_listener = + std::make_unique<PrefetchCookieListener>(url); + + // |cookie_listener| will get updates whenever host cookies for |url| or + // domain cookies that match |url| are changed. + cookie_manager->AddCookieChangeListener( + url, absl::nullopt, + cookie_listener->cookie_listener_receiver_.BindNewPipeAndPassRemote()); + + return cookie_listener; +} + +PrefetchCookieListener::PrefetchCookieListener(const GURL& url) : url_(url) {} + +PrefetchCookieListener::~PrefetchCookieListener() = default; + +void PrefetchCookieListener::StopListening() { + cookie_listener_receiver_.reset(); +} + +void PrefetchCookieListener::OnCookieChange( + const net::CookieChangeInfo& change) { + DCHECK(url_.DomainIs(change.cookie.DomainWithoutDot())); + have_cookies_changed_ = true; + + // Once we record one change to the cookies associated with |url_|, we don't + // care about any subsequent changes. + StopListening(); +} + +} // namespace content \ No newline at end of file
diff --git a/content/browser/speculation_rules/prefetch/prefetch_cookie_listener.h b/content/browser/speculation_rules/prefetch/prefetch_cookie_listener.h new file mode 100644 index 0000000..f96d52a --- /dev/null +++ b/content/browser/speculation_rules/prefetch/prefetch_cookie_listener.h
@@ -0,0 +1,57 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_SPECULATION_RULES_PREFETCH_PREFETCH_COOKIE_LISTENER_H_ +#define CONTENT_BROWSER_SPECULATION_RULES_PREFETCH_PREFETCH_COOKIE_LISTENER_H_ + +#include <memory> + +#include "content/common/content_export.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "services/network/public/mojom/cookie_manager.mojom.h" +#include "url/gurl.h" + +namespace content { + +// Listens for changes to the cookies for a specific URL. This includes both +// host and domain cookies. Keeps track of whether the cookies have changed or +// remained the same since the object is created until StopListening() is +// called. +class CONTENT_EXPORT PrefetchCookieListener + : public network::mojom::CookieChangeListener { + public: + static std::unique_ptr<PrefetchCookieListener> MakeAndRegister( + const GURL& url, + network::mojom::CookieManager* cookie_manager); + + explicit PrefetchCookieListener(const GURL& url); + ~PrefetchCookieListener() override; + + PrefetchCookieListener(const PrefetchCookieListener&) = delete; + PrefetchCookieListener& operator=(const PrefetchCookieListener&) = delete; + + // Causes the Cookie Listener to stop listening to cookie changes to |url_|. + // After this is called the value of |have_cookies_changed_| will no longer + // change. + void StopListening(); + + // Gets whether the cookies of |url_| have changed between the creation of the + // object and either the first time |StopListening| is called or now (if + // |StopListening| has never been called). + bool HaveCookiesChanged() const { return have_cookies_changed_; } + + private: + // network::mojom::CookieChangeListener + void OnCookieChange(const net::CookieChangeInfo& change) override; + + bool have_cookies_changed_ = false; + GURL url_; + + mojo::Receiver<network::mojom::CookieChangeListener> + cookie_listener_receiver_{this}; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_SPECULATION_RULES_PREFETCH_PREFETCH_COOKIE_LISTENER_H_
diff --git a/content/browser/speculation_rules/prefetch/prefetch_cookie_listener_unittest.cc b/content/browser/speculation_rules/prefetch/prefetch_cookie_listener_unittest.cc new file mode 100644 index 0000000..2e93bbc --- /dev/null +++ b/content/browser/speculation_rules/prefetch/prefetch_cookie_listener_unittest.cc
@@ -0,0 +1,202 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/speculation_rules/prefetch/prefetch_cookie_listener.h" + +#include <memory> + +#include "content/public/browser/browser_context.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/test/test_renderer_host.h" +#include "services/network/public/mojom/cookie_manager.mojom.h" +#include "services/network/public/mojom/network_context.mojom.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace content { +namespace { + +class PrefetchCookieListenerTest : public RenderViewHostTestHarness { + public: + void SetUp() override { + RenderViewHostTestHarness::SetUp(); + + browser_context() + ->GetDefaultStoragePartition() + ->GetNetworkContext() + ->GetCookieManager(cookie_manager_.BindNewPipeAndPassReceiver()); + } + + std::unique_ptr<PrefetchCookieListener> MakeCookieListener(const GURL& url) { + std::unique_ptr<PrefetchCookieListener> cookie_listener = + PrefetchCookieListener::MakeAndRegister(url, cookie_manager_.get()); + DCHECK(cookie_listener); + return cookie_listener; + } + + // Creates a host cookie for the given url, and then adds it to the default + // partition using |cookie_manager_|. + bool SetHostCookie(const GURL& url, const std::string& value) { + std::unique_ptr<net::CanonicalCookie> cookie(net::CanonicalCookie::Create( + url, value, base::Time::Now(), /*server_time=*/absl::nullopt, + /*cookie_partition_key=*/absl::nullopt)); + EXPECT_TRUE(cookie.get()); + EXPECT_TRUE(cookie->IsHostCookie()); + + return SetCookie(*cookie.get(), url); + } + + // Creates a domain cookie for the given url, and then adds it to the default + // partition using |cookie_manager_|. + bool SetDomainCookie(const GURL& url, + const std::string& name, + const std::string& value, + const std::string& domain) { + net::CookieInclusionStatus status; + std::unique_ptr<net::CanonicalCookie> cookie( + net::CanonicalCookie::CreateSanitizedCookie( + url, name, value, domain, /*path=*/"", base::Time::Now(), + base::Time::Now() + base::Hours(1), base::Time::Now(), + /*secure=*/true, /*http_only=*/false, + net::CookieSameSite::NO_RESTRICTION, net::COOKIE_PRIORITY_DEFAULT, + /*same_party=*/false, /*partition_key=*/absl::nullopt, &status)); + EXPECT_TRUE(cookie.get()); + EXPECT_TRUE(cookie->IsDomainCookie()); + EXPECT_TRUE(status.IsInclude()); + + return SetCookie(*cookie.get(), url); + } + + private: + bool SetCookie(const net::CanonicalCookie& cookie, const GURL& url) { + bool result = false; + base::RunLoop run_loop; + + net::CookieOptions options; + options.set_include_httponly(); + options.set_same_site_cookie_context( + net::CookieOptions::SameSiteCookieContext::MakeInclusive()); + + cookie_manager_->SetCanonicalCookie( + cookie, url, options, + base::BindOnce( + [](bool* result, base::RunLoop* run_loop, + net::CookieAccessResult set_cookie_access_result) { + *result = set_cookie_access_result.status.IsInclude(); + run_loop->Quit(); + }, + &result, &run_loop)); + + // This will run until the cookie is set. + run_loop.Run(); + + // This will run until the cookie listener is updated. + base::RunLoop().RunUntilIdle(); + + return result; + } + + mojo::Remote<network::mojom::CookieManager> cookie_manager_; +}; + +TEST_F(PrefetchCookieListenerTest, NoCookiesChanged) { + std::unique_ptr<PrefetchCookieListener> cookie_listener = + MakeCookieListener(GURL("https://www.example.com/")); + + EXPECT_FALSE(cookie_listener->HaveCookiesChanged()); +} + +TEST_F(PrefetchCookieListenerTest, ChangedHostCookiesForSameURL) { + std::unique_ptr<PrefetchCookieListener> cookie_listener = + MakeCookieListener(GURL("https://www.example.com/")); + + ASSERT_TRUE(SetHostCookie(GURL("https://www.example.com/"), "test-cookie")); + + EXPECT_TRUE(cookie_listener->HaveCookiesChanged()); +} + +TEST_F(PrefetchCookieListenerTest, ChangedHostCookiesForOtherURL) { + std::unique_ptr<PrefetchCookieListener> cookie_listener = + MakeCookieListener(GURL("https://www.example.com/")); + + ASSERT_TRUE(SetHostCookie(GURL("https://www.other.com/"), "test-cookie")); + + EXPECT_FALSE(cookie_listener->HaveCookiesChanged()); +} + +TEST_F(PrefetchCookieListenerTest, ChangedHostCookiesForGeneralDomain) { + std::unique_ptr<PrefetchCookieListener> cookie_listener = + MakeCookieListener(GURL("https://specificdomain.generaldomain.com/")); + + ASSERT_TRUE(SetHostCookie(GURL("https://generaldomain.com/"), "test-cookie")); + + EXPECT_FALSE(cookie_listener->HaveCookiesChanged()); +} + +TEST_F(PrefetchCookieListenerTest, ChangedHostCookiesForSubomain) { + std::unique_ptr<PrefetchCookieListener> cookie_listener = + MakeCookieListener(GURL("https://specificdomain.generaldomain.com/")); + + ASSERT_TRUE(SetHostCookie( + GURL("https://veryspecificdomain.specificdomain.generaldomain.com/"), + "test-cookie")); + + EXPECT_FALSE(cookie_listener->HaveCookiesChanged()); +} + +TEST_F(PrefetchCookieListenerTest, ChangedDomainCookiesForSameURL) { + std::unique_ptr<PrefetchCookieListener> cookie_listener = + MakeCookieListener(GURL("https://www.example.com/")); + + ASSERT_TRUE(SetDomainCookie(GURL("https://www.example.com/"), "test", + "cookie", "www.example.com")); + + EXPECT_TRUE(cookie_listener->HaveCookiesChanged()); +} + +TEST_F(PrefetchCookieListenerTest, ChangedDomainCookiesForOtherURL) { + std::unique_ptr<PrefetchCookieListener> cookie_listener = + MakeCookieListener(GURL("https://www.example.com/")); + + ASSERT_TRUE(SetDomainCookie(GURL("https://www.other.com/"), "test", "cookie", + "www.other.com")); + + EXPECT_FALSE(cookie_listener->HaveCookiesChanged()); +} + +TEST_F(PrefetchCookieListenerTest, ChangedDomainCookiesForGeneralDomain) { + std::unique_ptr<PrefetchCookieListener> cookie_listener = + MakeCookieListener(GURL("https://specificdomain.generaldomain.com/")); + + ASSERT_TRUE(SetDomainCookie(GURL("https://generaldomain.com/"), "test", + "cookie", "generaldomain.com")); + + EXPECT_TRUE(cookie_listener->HaveCookiesChanged()); +} + +TEST_F(PrefetchCookieListenerTest, ChangedDomainCookiesForSubomain) { + std::unique_ptr<PrefetchCookieListener> cookie_listener = + MakeCookieListener(GURL("https://specificdomain.generaldomain.com/")); + + ASSERT_TRUE(SetDomainCookie( + GURL("https://veryspecificdomain.specificdomain.generaldomain.com/"), + "test", "cookie", "veryspecificdomain.specificdomain.generaldomain.com")); + + EXPECT_FALSE(cookie_listener->HaveCookiesChanged()); +} + +TEST_F(PrefetchCookieListenerTest, StopListening) { + std::unique_ptr<PrefetchCookieListener> cookie_listener = + MakeCookieListener(GURL("https://www.example.com/")); + + cookie_listener->StopListening(); + + ASSERT_TRUE(SetHostCookie(GURL("https://www.example.com"), "test-cookie")); + + // Since the cookies were changed after |StopListening| was called, the + // listener shouldn't update. + EXPECT_FALSE(cookie_listener->HaveCookiesChanged()); +} + +} // namespace +} // namespace content
diff --git a/content/browser/speculation_rules/prefetch/prefetch_document_manager.cc b/content/browser/speculation_rules/prefetch/prefetch_document_manager.cc index ec1585f6..cddc358 100644 --- a/content/browser/speculation_rules/prefetch/prefetch_document_manager.cc +++ b/content/browser/speculation_rules/prefetch/prefetch_document_manager.cc
@@ -11,7 +11,10 @@ #include "content/browser/speculation_rules/prefetch/prefetch_container.h" #include "content/browser/speculation_rules/prefetch/prefetch_service.h" #include "content/public/browser/browser_context.h" +#include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_observer.h" #include "url/origin.h" namespace content { @@ -21,10 +24,33 @@ } // namespace PrefetchDocumentManager::PrefetchDocumentManager(RenderFrameHost* rfh) - : DocumentUserData(rfh) {} + : DocumentUserData(rfh), + WebContentsObserver(WebContents::FromRenderFrameHost(rfh)) {} PrefetchDocumentManager::~PrefetchDocumentManager() = default; +void PrefetchDocumentManager::DidStartNavigation( + NavigationHandle* navigation_handle) { + // Ignore navigations for a different RenderFrameHost. + if (render_frame_host().GetGlobalId() != + navigation_handle->GetPreviousRenderFrameHostId()) + return; + + // Ignores any same document navigations since we can't use prefetches to + // speed them up. + if (navigation_handle->IsSameDocument()) + return; + + // Get the prefetch for the URL being navigated to. If there is no prefetch + // for that URL, then stop. + auto prefetch_iter = all_prefetches_.find(navigation_handle->GetURL()); + if (prefetch_iter == all_prefetches_.end()) + return; + + // Inform |PrefetchService| of the navigation to the prefetch. + GetPrefetchService()->PrepareToServe(prefetch_iter->second); +} + void PrefetchDocumentManager::ProcessCandidates( std::vector<blink::mojom::SpeculationCandidatePtr>& candidates) { // Filter out candidates that can be handled by |PrefetchService| and @@ -89,19 +115,9 @@ weak_method_factory_.GetWeakPtr()); all_prefetches_[url] = owned_prefetches_[url]->GetWeakPtr(); - if (g_prefetch_service_for_testing) { - g_prefetch_service_for_testing->PrefetchUrl( - owned_prefetches_[url]->GetWeakPtr()); - return; - } - // Send a reference of the new |PrefetchContainer| to |PrefetchService| to // start the prefetch process. - DCHECK(BrowserContextImpl::From(render_frame_host().GetBrowserContext()) - ->GetPrefetchService()); - BrowserContextImpl::From(render_frame_host().GetBrowserContext()) - ->GetPrefetchService() - ->PrefetchUrl(owned_prefetches_[url]->GetWeakPtr()); + GetPrefetchService()->PrefetchUrl(owned_prefetches_[url]->GetWeakPtr()); // TODO(https://crbug.com/1299059): Track metrics about the prefetches. } @@ -121,6 +137,17 @@ g_prefetch_service_for_testing = prefetch_service; } +PrefetchService* PrefetchDocumentManager::GetPrefetchService() const { + if (g_prefetch_service_for_testing) { + return g_prefetch_service_for_testing; + } + + DCHECK(BrowserContextImpl::From(render_frame_host().GetBrowserContext()) + ->GetPrefetchService()); + return BrowserContextImpl::From(render_frame_host().GetBrowserContext()) + ->GetPrefetchService(); +} + DOCUMENT_USER_DATA_KEY_IMPL(PrefetchDocumentManager); } // namespace content
diff --git a/content/browser/speculation_rules/prefetch/prefetch_document_manager.h b/content/browser/speculation_rules/prefetch/prefetch_document_manager.h index 7d5d162..344fb16 100644 --- a/content/browser/speculation_rules/prefetch/prefetch_document_manager.h +++ b/content/browser/speculation_rules/prefetch/prefetch_document_manager.h
@@ -13,18 +13,21 @@ #include "content/browser/speculation_rules/prefetch/prefetch_type.h" #include "content/common/content_export.h" #include "content/public/browser/document_user_data.h" +#include "content/public/browser/web_contents_observer.h" #include "third_party/blink/public/mojom/speculation_rules/speculation_rules.mojom.h" #include "url/gurl.h" namespace content { +class NavigationHandle; class PrefetchContainer; class PrefetchService; // Manages the state of and tracks metrics about prefetches for a single page // load. class CONTENT_EXPORT PrefetchDocumentManager - : public DocumentUserData<PrefetchDocumentManager> { + : public DocumentUserData<PrefetchDocumentManager>, + public WebContentsObserver { public: ~PrefetchDocumentManager() override; @@ -32,6 +35,9 @@ const PrefetchDocumentManager operator=(const PrefetchDocumentManager&) = delete; + // WebContentsObserver. + void DidStartNavigation(NavigationHandle* navigation_handle) override; + // Processes the given speculation candidates to see if they can be // prefetched. Any candidates that can be prefetched are removed from // |candidates|, and a prefetch for the URL of the candidate is started. @@ -52,6 +58,9 @@ explicit PrefetchDocumentManager(RenderFrameHost* rfh); friend DocumentUserData; + // Helper function to get the |PrefetchService| associated with |this|. + PrefetchService* GetPrefetchService() const; + // This map holds references to all |PrefetchContainer| associated with // |this|, regardless of ownership. std::map<GURL, base::WeakPtr<PrefetchContainer>> all_prefetches_;
diff --git a/content/browser/speculation_rules/prefetch/prefetch_from_string_url_loader.cc b/content/browser/speculation_rules/prefetch/prefetch_from_string_url_loader.cc new file mode 100644 index 0000000..b7f02911 --- /dev/null +++ b/content/browser/speculation_rules/prefetch/prefetch_from_string_url_loader.cc
@@ -0,0 +1,162 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/speculation_rules/prefetch/prefetch_from_string_url_loader.h" + +#include <memory> + +#include "base/bind.h" +#include "base/check_op.h" +#include "base/memory/weak_ptr.h" +#include "base/notreached.h" +#include "content/browser/speculation_rules/prefetch/prefetched_mainframe_response_container.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "mojo/public/cpp/system/data_pipe.h" +#include "mojo/public/cpp/system/simple_watcher.h" +#include "net/base/io_buffer.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/mojom/url_loader.mojom.h" +#include "services/network/public/mojom/url_response_head.mojom.h" + +namespace content { + +PrefetchFromStringURLLoader::PrefetchFromStringURLLoader( + std::unique_ptr<PrefetchedMainframeResponseContainer> response, + const network::ResourceRequest& tentative_resource_request) + : head_(response->ReleaseHead()), + body_buffer_( + base::MakeRefCounted<net::StringIOBuffer>(response->ReleaseBody())), + bytes_of_raw_data_to_transfer_(body_buffer_->size()) {} + +PrefetchFromStringURLLoader::~PrefetchFromStringURLLoader() = default; + +void PrefetchFromStringURLLoader::FollowRedirect( + const std::vector<std::string>& removed_headers, + const net::HttpRequestHeaders& modified_headers, + const net::HttpRequestHeaders& modified_cors_exempt_headers, + const absl::optional<GURL>& new_url) { + NOTREACHED(); +} + +void PrefetchFromStringURLLoader::SetPriority(net::RequestPriority priority, + int32_t intra_priority_value) { + // Ignore: this class doesn't have a concept of priority. +} + +void PrefetchFromStringURLLoader::PauseReadingBodyFromNet() { + // Ignore: this class doesn't read from network. +} + +void PrefetchFromStringURLLoader::ResumeReadingBodyFromNet() { + // Ignore: this class doesn't read from network. +} + +void PrefetchFromStringURLLoader::TransferRawData() { + while (true) { + DCHECK_GE(bytes_of_raw_data_to_transfer_, write_position_); + uint32_t write_size = + static_cast<uint32_t>(bytes_of_raw_data_to_transfer_ - write_position_); + if (write_size == 0) { + Finish(net::OK); + return; + } + + MojoResult result = + producer_handle_->WriteData(body_buffer_->data() + write_position_, + &write_size, MOJO_WRITE_DATA_FLAG_NONE); + if (result == MOJO_RESULT_SHOULD_WAIT) { + handle_watcher_->ArmOrNotify(); + return; + } + + if (result != MOJO_RESULT_OK) { + Finish(net::ERR_FAILED); + return; + } + + // |write_position_| should only be updated when the mojo pipe has + // successfully been written to. + write_position_ += write_size; + } +} + +PrefetchFromStringURLLoader::RequestHandler +PrefetchFromStringURLLoader::ServingResponseHandler() { + return base::BindOnce(&PrefetchFromStringURLLoader::BindAndStart, + weak_ptr_factory_.GetWeakPtr()); +} + +void PrefetchFromStringURLLoader::BindAndStart( + const network::ResourceRequest& request, + mojo::PendingReceiver<network::mojom::URLLoader> receiver, + mojo::PendingRemote<network::mojom::URLLoaderClient> client) { + DCHECK(!receiver_.is_bound()); + receiver_.Bind(std::move(receiver)); + receiver_.set_disconnect_handler( + base::BindOnce(&PrefetchFromStringURLLoader::OnMojoDisconnect, + weak_ptr_factory_.GetWeakPtr())); + client_.Bind(std::move(client)); + + mojo::ScopedDataPipeProducerHandle producer_handle; + mojo::ScopedDataPipeConsumerHandle consumer_handle; + MojoResult rv = + mojo::CreateDataPipe(nullptr, producer_handle, consumer_handle); + + if (rv != MOJO_RESULT_OK) { + Finish(net::ERR_FAILED); + return; + } + + client_->OnReceiveResponse(std::move(head_), std::move(consumer_handle)); + + producer_handle_ = std::move(producer_handle); + + handle_watcher_ = std::make_unique<mojo::SimpleWatcher>( + FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL, + base::SequencedTaskRunnerHandle::Get()); + handle_watcher_->Watch( + producer_handle_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, + MOJO_WATCH_CONDITION_SATISFIED, + base::BindRepeating(&PrefetchFromStringURLLoader::OnHandleReady, + weak_ptr_factory_.GetWeakPtr())); + + TransferRawData(); +} + +void PrefetchFromStringURLLoader::OnHandleReady( + MojoResult result, + const mojo::HandleSignalsState& state) { + if (result != MOJO_RESULT_OK) { + Finish(net::ERR_FAILED); + return; + } + TransferRawData(); +} + +void PrefetchFromStringURLLoader::Finish(int error) { + client_->OnComplete(network::URLLoaderCompletionStatus(error)); + handle_watcher_.reset(); + producer_handle_.reset(); + client_.reset(); + receiver_.reset(); + weak_ptr_factory_.InvalidateWeakPtrs(); + MaybeDeleteSelf(); +} + +void PrefetchFromStringURLLoader::OnMojoDisconnect() { + receiver_.reset(); + client_.reset(); + MaybeDeleteSelf(); +} + +void PrefetchFromStringURLLoader::MaybeDeleteSelf() { + if (!receiver_.is_bound() && !client_.is_bound()) { + delete this; + } +} + +} // namespace content
diff --git a/content/browser/speculation_rules/prefetch/prefetch_from_string_url_loader.h b/content/browser/speculation_rules/prefetch/prefetch_from_string_url_loader.h new file mode 100644 index 0000000..871cdd11 --- /dev/null +++ b/content/browser/speculation_rules/prefetch/prefetch_from_string_url_loader.h
@@ -0,0 +1,107 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_SPECULATION_RULES_PREFETCH_PREFETCH_FROM_STRING_URL_LOADER_H_ +#define CONTENT_BROWSER_SPECULATION_RULES_PREFETCH_PREFETCH_FROM_STRING_URL_LOADER_H_ + +#include <memory> + +#include "base/memory/weak_ptr.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "mojo/public/cpp/system/data_pipe.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/mojom/url_loader.mojom.h" +#include "services/network/public/mojom/url_response_head.mojom.h" + +namespace mojo { +class SimpleWatcher; +} + +namespace net { +class StringIOBuffer; +} + +namespace content { + +class PrefetchedMainframeResponseContainer; + +class PrefetchFromStringURLLoader : public network::mojom::URLLoader { + public: + PrefetchFromStringURLLoader( + std::unique_ptr<PrefetchedMainframeResponseContainer> prefetched_response, + const network::ResourceRequest& tenative_resource_request); + ~PrefetchFromStringURLLoader() override; + + PrefetchFromStringURLLoader(const PrefetchFromStringURLLoader&) = delete; + PrefetchFromStringURLLoader& operator=(const PrefetchFromStringURLLoader&) = + delete; + + using RequestHandler = base::OnceCallback<void( + const network::ResourceRequest& resource_request, + mojo::PendingReceiver<network::mojom::URLLoader> url_loader_receiver, + mojo::PendingRemote<network::mojom::URLLoaderClient> client)>; + + // Called when the response should be served to the user. Returns a handler. + RequestHandler ServingResponseHandler(); + + private: + // network::mojom::URLLoader + void FollowRedirect( + const std::vector<std::string>& removed_headers, + const net::HttpRequestHeaders& modified_headers, + const net::HttpRequestHeaders& modified_cors_exempt_headers, + const absl::optional<GURL>& new_url) override; + void SetPriority(net::RequestPriority priority, + int32_t intra_priority_value) override; + void PauseReadingBodyFromNet() override; + void ResumeReadingBodyFromNet() override; + + // Binds |this| to the mojo handlers and starts the network request using + // |request|. After this method is called, |this| manages its own lifetime. + void BindAndStart( + const network::ResourceRequest& request, + mojo::PendingReceiver<network::mojom::URLLoader> url_loader_receiver, + mojo::PendingRemote<network::mojom::URLLoaderClient> forwarding_client); + + // Called when the mojo handle's state changes, either by being ready for more + // data or an error. + void OnHandleReady(MojoResult result, const mojo::HandleSignalsState& state); + + // Finishes the request with the given net error. + void Finish(int error); + + // Sends data on the mojo pipe. + void TransferRawData(); + + // Unbinds and deletes |this|. + void OnMojoDisconnect(); + + // Deletes |this| if it is not bound to the mojo pipes. + void MaybeDeleteSelf(); + + // The response that will be sent to mojo. + network::mojom::URLResponseHeadPtr head_; + scoped_refptr<net::StringIOBuffer> body_buffer_; + + // Keeps track of the position of the data transfer. + int write_position_ = 0; + + // The length of |body_buffer_|. + const int bytes_of_raw_data_to_transfer_ = 0; + + // Mojo plumbing. + mojo::Receiver<network::mojom::URLLoader> receiver_{this}; + mojo::Remote<network::mojom::URLLoaderClient> client_; + mojo::ScopedDataPipeProducerHandle producer_handle_; + std::unique_ptr<mojo::SimpleWatcher> handle_watcher_; + + base::WeakPtrFactory<PrefetchFromStringURLLoader> weak_ptr_factory_{this}; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_SPECULATION_RULES_PREFETCH_PREFETCH_FROM_STRING_URL_LOADER_H_ \ No newline at end of file
diff --git a/content/browser/speculation_rules/prefetch/prefetch_params.cc b/content/browser/speculation_rules/prefetch/prefetch_params.cc index 8ce44725..d440fca 100644 --- a/content/browser/speculation_rules/prefetch/prefetch_params.cc +++ b/content/browser/speculation_rules/prefetch/prefetch_params.cc
@@ -115,4 +115,9 @@ features::kPrefetchUseContentRefactor, "html_only", false); } +base::TimeDelta PrefetchCacheableDuration() { + return base::Seconds(base::GetFieldTrialParamByFeatureAsInt( + features::kPrefetchUseContentRefactor, "cacheable_duration", 300)); +} + } // namespace content
diff --git a/content/browser/speculation_rules/prefetch/prefetch_params.h b/content/browser/speculation_rules/prefetch/prefetch_params.h index bbcc681..0e8ad75 100644 --- a/content/browser/speculation_rules/prefetch/prefetch_params.h +++ b/content/browser/speculation_rules/prefetch/prefetch_params.h
@@ -59,6 +59,9 @@ // If this is false, there is no MIME type restriction. bool PrefetchServiceHTMLOnly(); +// The maximum time a prefetched response is servable. +CONTENT_EXPORT base::TimeDelta PrefetchCacheableDuration(); + } // namespace content #endif // CONTENT_BROWSER_SPECULATION_RULES_PREFETCH_PREFETCH_PARAMS_H_
diff --git a/content/browser/speculation_rules/prefetch/prefetch_service.cc b/content/browser/speculation_rules/prefetch/prefetch_service.cc index edf30d0..55506e8 100644 --- a/content/browser/speculation_rules/prefetch/prefetch_service.cc +++ b/content/browser/speculation_rules/prefetch/prefetch_service.cc
@@ -7,6 +7,7 @@ #include <memory> #include <utility> +#include "base/barrier_closure.h" #include "base/feature_list.h" #include "base/location.h" #include "base/memory/weak_ptr.h" @@ -33,6 +34,7 @@ #include "net/base/load_flags.h" #include "net/base/url_util.h" #include "net/cookies/canonical_cookie.h" +#include "net/cookies/cookie_partition_key_collection.h" #include "net/cookies/site_for_cookies.h" #include "net/http/http_status_code.h" #include "net/http/http_util.h" @@ -147,6 +149,17 @@ return end - start; } +void RecordPrefetchProxyPrefetchMainframeCookiesToCopy( + size_t cookie_list_size) { + UMA_HISTOGRAM_COUNTS_100("PrefetchProxy.Prefetch.Mainframe.CookiesToCopy", + cookie_list_size); +} + +void CookieSetHelper(base::RepeatingClosure closure, + net::CookieAccessResult access_result) { + closure.Run(); +} + } // namespace // static @@ -370,6 +383,17 @@ prefetch_queue_.push_back(prefetch_container); Prefetch(); + + // Registers a cookie listener for this prefetch if it is using an isolated + // network context. If the cookies in the default partition associated with + // this URL change after this point, then the prefetched resources should not + // be served. + if (prefetch_container->GetPrefetchType() + .IsIsolatedNetworkContextRequired()) { + prefetch_container->RegisterCookieListener( + browser_context_->GetDefaultStoragePartition() + ->GetCookieManagerForBrowserProcess()); + } } void PrefetchService::Prefetch() { @@ -472,6 +496,14 @@ owned_prefetches_.end()); owned_prefetches_.erase( owned_prefetches_.find(prefetch_container->GetPrefetchContainerKey())); + + auto prefetches_ready_to_serve_iter = + prefetches_ready_to_serve_.find(prefetch_container->GetURL()); + if (prefetches_ready_to_serve_iter != prefetches_ready_to_serve_.end() && + prefetches_ready_to_serve_iter->second->GetPrefetchContainerKey() == + prefetch_container->GetPrefetchContainerKey()) { + prefetches_ready_to_serve_.erase(prefetches_ready_to_serve_iter); + } } void PrefetchService::StartSinglePrefetch( @@ -710,6 +742,100 @@ prefetch_container->SetPrefetchStatus(PrefetchStatus::kPrefetchSuccessful); } +void PrefetchService::PrepareToServe( + base::WeakPtr<PrefetchContainer> prefetch_container) { + // Ensure |this| has this prefetch. + if (all_prefetches_.find(prefetch_container->GetPrefetchContainerKey()) == + all_prefetches_.end()) + return; + + // If the prefetch isn't ready to be served, then stop. + if (prefetch_container->HaveDefaultContextCookiesChanged() || + !prefetch_container->HasValidPrefetchedResponse( + PrefetchCacheableDuration())) + return; + + // If the prefetch has a valid response, then it must be in + // |owned_prefetches_|. + DCHECK( + owned_prefetches_.find(prefetch_container->GetPrefetchContainerKey()) != + owned_prefetches_.end()); + + // If there is already a prefetch with the same URL as |prefetch_container| in + // |prefetches_ready_to_serve_|, then don't do anything. + if (prefetches_ready_to_serve_.find(prefetch_container->GetURL()) != + prefetches_ready_to_serve_.end()) + return; + + // Move prefetch into |prefetches_ready_to_serve_|. + prefetches_ready_to_serve_[prefetch_container->GetURL()] = prefetch_container; + + // Start the process of copying cookies from the isolated network context used + // to make the prefetch to the default network context. + CopyIsolatedCookies(prefetch_container); +} + +void PrefetchService::CopyIsolatedCookies( + base::WeakPtr<PrefetchContainer> prefetch_container) { + DCHECK(prefetch_container); + + if (!prefetch_container->GetNetworkContext()) { + // Not set in unit tests. + return; + } + + // We only need to copy cookies if the prefetch used an isolated network + // context. + if (!prefetch_container->GetPrefetchType() + .IsIsolatedNetworkContextRequired()) { + return; + } + + prefetch_container->OnIsolatedCookieCopyStart(); + net::CookieOptions options = net::CookieOptions::MakeAllInclusive(); + prefetch_container->GetNetworkContext()->GetCookieManager()->GetCookieList( + prefetch_container->GetURL(), options, + net::CookiePartitionKeyCollection::Todo(), + base::BindOnce(&PrefetchService::OnGotIsolatedCookiesForCopy, + weak_method_factory_.GetWeakPtr(), prefetch_container)); +} + +void PrefetchService::OnGotIsolatedCookiesForCopy( + base::WeakPtr<PrefetchContainer> prefetch_container, + const net::CookieAccessResultList& cookie_list, + const net::CookieAccessResultList& excluded_cookies) { + RecordPrefetchProxyPrefetchMainframeCookiesToCopy(cookie_list.size()); + + if (cookie_list.empty()) { + prefetch_container->OnIsolatedCookieCopyComplete(); + return; + } + + base::RepeatingClosure barrier = base::BarrierClosure( + cookie_list.size(), + base::BindOnce(&PrefetchContainer::OnIsolatedCookieCopyComplete, + prefetch_container)); + + net::CookieOptions options = net::CookieOptions::MakeAllInclusive(); + for (const net::CookieWithAccessResult& cookie : cookie_list) { + browser_context_->GetDefaultStoragePartition() + ->GetCookieManagerForBrowserProcess() + ->SetCanonicalCookie(cookie.cookie, prefetch_container->GetURL(), + options, + base::BindOnce(&CookieSetHelper, barrier)); + } +} + +base::WeakPtr<PrefetchContainer> PrefetchService::GetPrefetchToServe( + const GURL& url) const { + auto prefetch_iter = prefetches_ready_to_serve_.find(url); + + if (prefetch_iter == prefetches_ready_to_serve_.end()) + return nullptr; + + return prefetch_iter->second; +} + // static void PrefetchService::SetServiceWorkerContextForTesting( ServiceWorkerContext* context) {
diff --git a/content/browser/speculation_rules/prefetch/prefetch_service.h b/content/browser/speculation_rules/prefetch/prefetch_service.h index b34bbc9..6a241ac 100644 --- a/content/browser/speculation_rules/prefetch/prefetch_service.h +++ b/content/browser/speculation_rules/prefetch/prefetch_service.h
@@ -59,6 +59,15 @@ virtual void PrefetchUrl(base::WeakPtr<PrefetchContainer> prefetch_container); + // Called when a navigation to the URL associated with |prefetch_container| is + // likely to occur in the immediate future. + void PrepareToServe(base::WeakPtr<PrefetchContainer> prefetch_container); + + // Returns the prefetch with |url| that is ready to serve. In order for a + // prefetch to be ready to serve, |PrepareToServe| must have been previously + // called with the prefetch. + base::WeakPtr<PrefetchContainer> GetPrefetchToServe(const GURL& url) const; + // Returns the current prefetches associated with |this|. Used to check the // state of the prefetches. // TODO(https://crbug.com/1299059): Remove this once we can get metrics @@ -158,6 +167,14 @@ network::mojom::URLResponseHeadPtr head, std::unique_ptr<std::string> body); + // Copies any cookies in the isolated network context associated with + // |prefetch_container| to the default network context. + void CopyIsolatedCookies(base::WeakPtr<PrefetchContainer> prefetch_container); + void OnGotIsolatedCookiesForCopy( + base::WeakPtr<PrefetchContainer> prefetch_container, + const net::CookieAccessResultList& cookie_list, + const net::CookieAccessResultList& excluded_cookies); + raw_ptr<BrowserContext> browser_context_; // The custom proxy configurator for Prefetch Proxy. Only used on prefetches @@ -186,6 +203,13 @@ std::unique_ptr<base::OneShotTimer>>> owned_prefetches_; + // The set of prefetches that are ready to serve. In order to be in this map, + // the prefetch must also be in |owned_prefetches_|, have a valid prefetched + // response, and have started the cookie copy process. A prefetch is added to + // this map when |PrepareToServe| is called on it, and once in this map, it + // can be returned by |GetPrefetchToServe|. + std::map<GURL, base::WeakPtr<PrefetchContainer>> prefetches_ready_to_serve_; + SEQUENCE_CHECKER(sequence_checker_); base::WeakPtrFactory<PrefetchService> weak_method_factory_{this};
diff --git a/content/browser/speculation_rules/prefetch/prefetch_service_unittest.cc b/content/browser/speculation_rules/prefetch/prefetch_service_unittest.cc index 577c3528f..3ba40ea 100644 --- a/content/browser/speculation_rules/prefetch/prefetch_service_unittest.cc +++ b/content/browser/speculation_rules/prefetch/prefetch_service_unittest.cc
@@ -15,6 +15,7 @@ #include "content/public/browser/browser_context.h" #include "content/public/browser/storage_partition.h" #include "content/public/test/fake_service_worker_context.h" +#include "content/public/test/mock_navigation_handle.h" #include "content/public/test/test_renderer_host.h" #include "content/public/test/test_utils.h" #include "content/test/test_content_browser_client.h" @@ -26,6 +27,7 @@ #include "services/network/test/test_utils.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/web_preferences/web_preferences.h" +#include "url/gurl.h" namespace content { namespace { @@ -206,6 +208,19 @@ return result; } + void Navigate(const GURL& url, + const GlobalRenderFrameHostId& previous_rfh_id) { + testing::NiceMock<MockNavigationHandle> handle(web_contents()); + handle.set_url(url); + + ON_CALL(handle, GetPreviousRenderFrameHostId) + .WillByDefault(testing::Return(previous_rfh_id)); + + PrefetchDocumentManager* prefetch_document_manager = + PrefetchDocumentManager::GetOrCreateForCurrentDocument(main_rfh()); + prefetch_document_manager->DidStartNavigation(&handle); + } + protected: FakeServiceWorkerContext service_worker_context_; mojo::Remote<network::mojom::CookieManager> cookie_manager_; @@ -253,6 +268,8 @@ /*use_prefetch_proxy=*/true, {{"X-Testing", "Hello World"}}, kHTMLBody); + Navigate(GURL("https://example.com"), main_rfh()->GetGlobalId()); + histogram_tester.ExpectUniqueSample( "PrefetchProxy.Prefetch.Mainframe.RespCode", net::HTTP_OK, 1); histogram_tester.ExpectUniqueSample( @@ -275,7 +292,14 @@ EXPECT_TRUE(prefetch_iter->second->HasPrefetchStatus()); EXPECT_EQ(prefetch_iter->second->GetPrefetchStatus(), PrefetchStatus::kPrefetchSuccessful); - EXPECT_TRUE(prefetch_iter->second->HasPrefetchedResponse()); + EXPECT_TRUE(prefetch_iter->second->HasValidPrefetchedResponse( + base::TimeDelta::Max())); + + base::WeakPtr<PrefetchContainer> serveable_prefetch_container = + prefetch_service_->GetPrefetchToServe(prefetch_iter->second->GetURL()); + ASSERT_TRUE(serveable_prefetch_container); + EXPECT_EQ(serveable_prefetch_container->GetPrefetchContainerKey(), + prefetch_iter->second->GetPrefetchContainerKey()); } TEST_F(PrefetchServiceTest, NotEligibleHostnameNonUnique) { @@ -291,6 +315,8 @@ EXPECT_EQ(RequestCount(), 0); + Navigate(GURL("https://example.com"), main_rfh()->GetGlobalId()); + histogram_tester.ExpectTotalCount("PrefetchProxy.Prefetch.Mainframe.RespCode", 0); histogram_tester.ExpectTotalCount("PrefetchProxy.Prefetch.Mainframe.NetError", @@ -313,7 +339,12 @@ EXPECT_TRUE(prefetch_iter->second->HasPrefetchStatus()); EXPECT_EQ(prefetch_iter->second->GetPrefetchStatus(), PrefetchStatus::kPrefetchNotEligibleHostIsNonUnique); - EXPECT_FALSE(prefetch_iter->second->HasPrefetchedResponse()); + EXPECT_FALSE(prefetch_iter->second->HasValidPrefetchedResponse( + base::TimeDelta::Max())); + + base::WeakPtr<PrefetchContainer> serveable_prefetch_container = + prefetch_service_->GetPrefetchToServe(GURL("https://example.com")); + EXPECT_FALSE(serveable_prefetch_container); } namespace { @@ -371,7 +402,8 @@ EXPECT_TRUE(prefetch_iter->second->HasPrefetchStatus()); EXPECT_EQ(prefetch_iter->second->GetPrefetchStatus(), PrefetchStatus::kPrefetchNotEligibleDataSaverEnabled); - EXPECT_FALSE(prefetch_iter->second->HasPrefetchedResponse()); + EXPECT_FALSE(prefetch_iter->second->HasValidPrefetchedResponse( + base::TimeDelta::Max())); } TEST_F(PrefetchServiceTest, NotEligibleNonHttps) { @@ -384,6 +416,8 @@ EXPECT_EQ(RequestCount(), 0); + Navigate(GURL("http://example.com"), main_rfh()->GetGlobalId()); + histogram_tester.ExpectTotalCount("PrefetchProxy.Prefetch.Mainframe.RespCode", 0); histogram_tester.ExpectTotalCount("PrefetchProxy.Prefetch.Mainframe.NetError", @@ -406,7 +440,12 @@ EXPECT_TRUE(prefetch_iter->second->HasPrefetchStatus()); EXPECT_EQ(prefetch_iter->second->GetPrefetchStatus(), PrefetchStatus::kPrefetchNotEligibleSchemeIsNotHttps); - EXPECT_FALSE(prefetch_iter->second->HasPrefetchedResponse()); + EXPECT_FALSE(prefetch_iter->second->HasValidPrefetchedResponse( + base::TimeDelta::Max())); + + base::WeakPtr<PrefetchContainer> serveable_prefetch_container = + prefetch_service_->GetPrefetchToServe(GURL("http://example.com")); + EXPECT_FALSE(serveable_prefetch_container); } TEST_F(PrefetchServiceTest, EligibleNonHttpsNonProxiedPotentiallyTrustworthy) { @@ -423,6 +462,8 @@ /*use_prefetch_proxy=*/false, {{"X-Testing", "Hello World"}}, kHTMLBody); + Navigate(GURL("http://localhost"), main_rfh()->GetGlobalId()); + histogram_tester.ExpectUniqueSample( "PrefetchProxy.Prefetch.Mainframe.RespCode", net::HTTP_OK, 1); histogram_tester.ExpectUniqueSample( @@ -445,7 +486,14 @@ EXPECT_TRUE(prefetch_iter->second->HasPrefetchStatus()); EXPECT_EQ(prefetch_iter->second->GetPrefetchStatus(), PrefetchStatus::kPrefetchSuccessful); - EXPECT_TRUE(prefetch_iter->second->HasPrefetchedResponse()); + EXPECT_TRUE(prefetch_iter->second->HasValidPrefetchedResponse( + base::TimeDelta::Max())); + + base::WeakPtr<PrefetchContainer> serveable_prefetch_container = + prefetch_service_->GetPrefetchToServe(GURL("http://localhost")); + ASSERT_TRUE(serveable_prefetch_container); + EXPECT_EQ(serveable_prefetch_container->GetPrefetchContainerKey(), + prefetch_iter->second->GetPrefetchContainerKey()); } TEST_F(PrefetchServiceTest, NotEligibleServiceWorkerRegistered) { @@ -461,6 +509,8 @@ EXPECT_EQ(RequestCount(), 0); + Navigate(GURL("https://example.com"), main_rfh()->GetGlobalId()); + histogram_tester.ExpectTotalCount("PrefetchProxy.Prefetch.Mainframe.RespCode", 0); histogram_tester.ExpectTotalCount("PrefetchProxy.Prefetch.Mainframe.NetError", @@ -483,7 +533,12 @@ EXPECT_TRUE(prefetch_iter->second->HasPrefetchStatus()); EXPECT_EQ(prefetch_iter->second->GetPrefetchStatus(), PrefetchStatus::kPrefetchNotEligibleUserHasServiceWorker); - EXPECT_FALSE(prefetch_iter->second->HasPrefetchedResponse()); + EXPECT_FALSE(prefetch_iter->second->HasValidPrefetchedResponse( + base::TimeDelta::Max())); + + base::WeakPtr<PrefetchContainer> serveable_prefetch_container = + prefetch_service_->GetPrefetchToServe(GURL("https://example.com")); + EXPECT_FALSE(serveable_prefetch_container); } TEST_F(PrefetchServiceTest, EligibleServiceWorkerNotRegistered) { @@ -503,6 +558,8 @@ /*use_prefetch_proxy=*/true, {{"X-Testing", "Hello World"}}, kHTMLBody); + Navigate(GURL("https://example.com"), main_rfh()->GetGlobalId()); + histogram_tester.ExpectUniqueSample( "PrefetchProxy.Prefetch.Mainframe.RespCode", net::HTTP_OK, 1); histogram_tester.ExpectUniqueSample( @@ -525,7 +582,14 @@ EXPECT_TRUE(prefetch_iter->second->HasPrefetchStatus()); EXPECT_EQ(prefetch_iter->second->GetPrefetchStatus(), PrefetchStatus::kPrefetchSuccessful); - EXPECT_TRUE(prefetch_iter->second->HasPrefetchedResponse()); + EXPECT_TRUE(prefetch_iter->second->HasValidPrefetchedResponse( + base::TimeDelta::Max())); + + base::WeakPtr<PrefetchContainer> serveable_prefetch_container = + prefetch_service_->GetPrefetchToServe(GURL("https://example.com")); + ASSERT_TRUE(serveable_prefetch_container); + EXPECT_EQ(serveable_prefetch_container->GetPrefetchContainerKey(), + prefetch_iter->second->GetPrefetchContainerKey()); } TEST_F(PrefetchServiceTest, NotEligibleUserHasCookies) { @@ -540,6 +604,8 @@ EXPECT_EQ(RequestCount(), 0); + Navigate(GURL("https://example.com"), main_rfh()->GetGlobalId()); + histogram_tester.ExpectTotalCount("PrefetchProxy.Prefetch.Mainframe.RespCode", 0); histogram_tester.ExpectTotalCount("PrefetchProxy.Prefetch.Mainframe.NetError", @@ -562,7 +628,12 @@ EXPECT_TRUE(prefetch_iter->second->HasPrefetchStatus()); EXPECT_EQ(prefetch_iter->second->GetPrefetchStatus(), PrefetchStatus::kPrefetchNotEligibleUserHasCookies); - EXPECT_FALSE(prefetch_iter->second->HasPrefetchedResponse()); + EXPECT_FALSE(prefetch_iter->second->HasValidPrefetchedResponse( + base::TimeDelta::Max())); + + base::WeakPtr<PrefetchContainer> serveable_prefetch_container = + prefetch_service_->GetPrefetchToServe(GURL("https://example.com")); + EXPECT_FALSE(serveable_prefetch_container); } TEST_F(PrefetchServiceTest, EligibleUserHasCookiesForDifferentUrl) { @@ -581,6 +652,8 @@ /*use_prefetch_proxy=*/true, {{"X-Testing", "Hello World"}}, kHTMLBody); + Navigate(GURL("https://example.com"), main_rfh()->GetGlobalId()); + histogram_tester.ExpectUniqueSample( "PrefetchProxy.Prefetch.Mainframe.RespCode", net::HTTP_OK, 1); histogram_tester.ExpectUniqueSample( @@ -603,7 +676,14 @@ EXPECT_TRUE(prefetch_iter->second->HasPrefetchStatus()); EXPECT_EQ(prefetch_iter->second->GetPrefetchStatus(), PrefetchStatus::kPrefetchSuccessful); - EXPECT_TRUE(prefetch_iter->second->HasPrefetchedResponse()); + EXPECT_TRUE(prefetch_iter->second->HasValidPrefetchedResponse( + base::TimeDelta::Max())); + + base::WeakPtr<PrefetchContainer> serveable_prefetch_container = + prefetch_service_->GetPrefetchToServe(GURL("https://example.com")); + ASSERT_TRUE(serveable_prefetch_container); + EXPECT_EQ(serveable_prefetch_container->GetPrefetchContainerKey(), + prefetch_iter->second->GetPrefetchContainerKey()); } TEST_F(PrefetchServiceTest, EligibleSameOriginPrefetchCanHaveExistingCookies) { @@ -622,6 +702,8 @@ /*use_prefetch_proxy=*/false, {{"X-Testing", "Hello World"}}, kHTMLBody); + Navigate(GURL("https://example.com"), main_rfh()->GetGlobalId()); + histogram_tester.ExpectUniqueSample( "PrefetchProxy.Prefetch.Mainframe.RespCode", net::HTTP_OK, 1); histogram_tester.ExpectUniqueSample( @@ -644,7 +726,14 @@ EXPECT_TRUE(prefetch_iter->second->HasPrefetchStatus()); EXPECT_EQ(prefetch_iter->second->GetPrefetchStatus(), PrefetchStatus::kPrefetchSuccessful); - EXPECT_TRUE(prefetch_iter->second->HasPrefetchedResponse()); + EXPECT_TRUE(prefetch_iter->second->HasValidPrefetchedResponse( + base::TimeDelta::Max())); + + base::WeakPtr<PrefetchContainer> serveable_prefetch_container = + prefetch_service_->GetPrefetchToServe(GURL("https://example.com")); + ASSERT_TRUE(serveable_prefetch_container); + EXPECT_EQ(serveable_prefetch_container->GetPrefetchContainerKey(), + prefetch_iter->second->GetPrefetchContainerKey()); } TEST_F(PrefetchServiceTest, FailedNon2XXResponseCode) { @@ -661,6 +750,8 @@ /*use_prefetch_proxy=*/true, {{"X-Testing", "Hello World"}}, kHTMLBody); + Navigate(GURL("https://example.com"), main_rfh()->GetGlobalId()); + histogram_tester.ExpectUniqueSample( "PrefetchProxy.Prefetch.Mainframe.RespCode", net::HTTP_NOT_FOUND, 1); histogram_tester.ExpectUniqueSample( @@ -683,7 +774,12 @@ EXPECT_TRUE(prefetch_iter->second->HasPrefetchStatus()); EXPECT_EQ(prefetch_iter->second->GetPrefetchStatus(), PrefetchStatus::kPrefetchFailedNon2XX); - EXPECT_FALSE(prefetch_iter->second->HasPrefetchedResponse()); + EXPECT_FALSE(prefetch_iter->second->HasValidPrefetchedResponse( + base::TimeDelta::Max())); + + base::WeakPtr<PrefetchContainer> serveable_prefetch_container = + prefetch_service_->GetPrefetchToServe(GURL("https://example.com")); + EXPECT_FALSE(serveable_prefetch_container); } TEST_F(PrefetchServiceTest, FailedNetError) { @@ -700,6 +796,8 @@ /*use_prefetch_proxy=*/true, {{"X-Testing", "Hello World"}}, kHTMLBody); + Navigate(GURL("https://example.com"), main_rfh()->GetGlobalId()); + histogram_tester.ExpectTotalCount("PrefetchProxy.Prefetch.Mainframe.RespCode", 0); histogram_tester.ExpectUniqueSample( @@ -723,7 +821,12 @@ EXPECT_TRUE(prefetch_iter->second->HasPrefetchStatus()); EXPECT_EQ(prefetch_iter->second->GetPrefetchStatus(), PrefetchStatus::kPrefetchFailedNetError); - EXPECT_FALSE(prefetch_iter->second->HasPrefetchedResponse()); + EXPECT_FALSE(prefetch_iter->second->HasValidPrefetchedResponse( + base::TimeDelta::Max())); + + base::WeakPtr<PrefetchContainer> serveable_prefetch_container = + prefetch_service_->GetPrefetchToServe(GURL("https://example.com")); + EXPECT_FALSE(serveable_prefetch_container); } TEST_F(PrefetchServiceTest, SuccessNonHTML) { @@ -742,6 +845,8 @@ /*use_prefetch_proxy=*/true, {{"X-Testing", "Hello World"}}, body); + Navigate(GURL("https://example.com"), main_rfh()->GetGlobalId()); + histogram_tester.ExpectUniqueSample( "PrefetchProxy.Prefetch.Mainframe.RespCode", net::HTTP_OK, 1); histogram_tester.ExpectUniqueSample( @@ -764,7 +869,66 @@ EXPECT_TRUE(prefetch_iter->second->HasPrefetchStatus()); EXPECT_EQ(prefetch_iter->second->GetPrefetchStatus(), PrefetchStatus::kPrefetchSuccessful); - EXPECT_TRUE(prefetch_iter->second->HasPrefetchedResponse()); + EXPECT_TRUE(prefetch_iter->second->HasValidPrefetchedResponse( + base::TimeDelta::Max())); + + base::WeakPtr<PrefetchContainer> serveable_prefetch_container = + prefetch_service_->GetPrefetchToServe(GURL("https://example.com")); + ASSERT_TRUE(serveable_prefetch_container); + EXPECT_EQ(serveable_prefetch_container->GetPrefetchContainerKey(), + prefetch_iter->second->GetPrefetchContainerKey()); +} + +TEST_F(PrefetchServiceTest, NotServeableNavigationInDifferentRenderFrameHost) { + base::HistogramTester histogram_tester; + + MakePrefetchOnMainFrame(GURL("https://example.com"), + PrefetchType(/*use_isolated_network_context=*/true, + /*use_prefetch_proxy=*/true)); + base::RunLoop().RunUntilIdle(); + + VerifyCommonRequestState(GURL("https://example.com"), + /*use_prefetch_proxy=*/true); + MakeResponseAndWait(net::HTTP_OK, net::OK, kHTMLMimeType, + /*use_prefetch_proxy=*/true, + {{"X-Testing", "Hello World"}}, kHTMLBody); + + // Since the navigation is occurring in a RenderFrameHost other than where the + // prefetch was requested from, we cannot use it. + GlobalRenderFrameHostId other_rfh_id( + main_rfh()->GetGlobalId().child_id + 1, + main_rfh()->GetGlobalId().frame_routing_id + 1); + ASSERT_NE(other_rfh_id, main_rfh()->GetGlobalId()); + Navigate(GURL("https://example.com"), other_rfh_id); + + histogram_tester.ExpectUniqueSample( + "PrefetchProxy.Prefetch.Mainframe.RespCode", net::HTTP_OK, 1); + histogram_tester.ExpectUniqueSample( + "PrefetchProxy.Prefetch.Mainframe.NetError", net::OK, 1); + histogram_tester.ExpectUniqueSample( + "PrefetchProxy.Prefetch.Mainframe.BodyLength", std::size(kHTMLBody), 1); + histogram_tester.ExpectUniqueSample( + "PrefetchProxy.Prefetch.Mainframe.TotalTime", kTotalTimeDuration, 1); + histogram_tester.ExpectUniqueSample( + "PrefetchProxy.Prefetch.Mainframe.ConnectTime", kConnectTimeDuration, 1); + + auto all_prefetches = prefetch_service_->GetAllPrefetchesForTesting(); + + EXPECT_EQ(all_prefetches.size(), 1U); + + auto prefetch_iter = all_prefetches.find( + std::make_pair(main_rfh()->GetGlobalId(), GURL("https://example.com"))); + ASSERT_TRUE(prefetch_iter != all_prefetches.end()); + + EXPECT_TRUE(prefetch_iter->second->HasPrefetchStatus()); + EXPECT_EQ(prefetch_iter->second->GetPrefetchStatus(), + PrefetchStatus::kPrefetchSuccessful); + EXPECT_TRUE(prefetch_iter->second->HasValidPrefetchedResponse( + base::TimeDelta::Max())); + + base::WeakPtr<PrefetchContainer> serveable_prefetch_container = + prefetch_service_->GetPrefetchToServe(prefetch_iter->second->GetURL()); + EXPECT_FALSE(serveable_prefetch_container); } class PrefetchServiceWithHTMLOnlyTest : public PrefetchServiceTest { @@ -795,6 +959,8 @@ /*use_prefetch_proxy=*/true, {{"X-Testing", "Hello World"}}, body); + Navigate(GURL("https://example.com"), main_rfh()->GetGlobalId()); + histogram_tester.ExpectUniqueSample( "PrefetchProxy.Prefetch.Mainframe.RespCode", net::HTTP_OK, 1); histogram_tester.ExpectUniqueSample( @@ -817,7 +983,12 @@ EXPECT_TRUE(prefetch_iter->second->HasPrefetchStatus()); EXPECT_EQ(prefetch_iter->second->GetPrefetchStatus(), PrefetchStatus::kPrefetchFailedMIMENotSupported); - EXPECT_FALSE(prefetch_iter->second->HasPrefetchedResponse()); + EXPECT_FALSE(prefetch_iter->second->HasValidPrefetchedResponse( + base::TimeDelta::Max())); + + base::WeakPtr<PrefetchContainer> serveable_prefetch_container = + prefetch_service_->GetPrefetchToServe(GURL("https://example.com")); + EXPECT_FALSE(serveable_prefetch_container); } class PrefetchServiceAlwaysMakeDecoyRequestTest : public PrefetchServiceTest { @@ -845,6 +1016,8 @@ /*use_prefetch_proxy=*/true, {{"X-Testing", "Hello World"}}, kHTMLBody); + Navigate(GURL("https://example.com"), main_rfh()->GetGlobalId()); + auto all_prefetches = prefetch_service_->GetAllPrefetchesForTesting(); EXPECT_EQ(all_prefetches.size(), 1U); @@ -856,7 +1029,12 @@ EXPECT_TRUE(prefetch_iter->second->HasPrefetchStatus()); EXPECT_EQ(prefetch_iter->second->GetPrefetchStatus(), PrefetchStatus::kPrefetchIsPrivacyDecoy); - EXPECT_FALSE(prefetch_iter->second->HasPrefetchedResponse()); + EXPECT_FALSE(prefetch_iter->second->HasValidPrefetchedResponse( + base::TimeDelta::Max())); + + base::WeakPtr<PrefetchContainer> serveable_prefetch_container = + prefetch_service_->GetPrefetchToServe(GURL("https://example.com")); + EXPECT_FALSE(serveable_prefetch_container); } // TODO(https://crbug.com/1299059): Add test for incognito mode.
diff --git a/content/browser/speculation_rules/prefetch/prefetch_url_loader_interceptor.cc b/content/browser/speculation_rules/prefetch/prefetch_url_loader_interceptor.cc new file mode 100644 index 0000000..2ce0fa7 --- /dev/null +++ b/content/browser/speculation_rules/prefetch/prefetch_url_loader_interceptor.cc
@@ -0,0 +1,158 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/speculation_rules/prefetch/prefetch_url_loader_interceptor.h" + +#include <memory> + +#include "base/memory/weak_ptr.h" +#include "base/metrics/histogram_macros.h" +#include "base/time/time.h" +#include "content/browser/browser_context_impl.h" +#include "content/browser/loader/navigation_loader_interceptor.h" +#include "content/browser/loader/single_request_url_loader_factory.h" +#include "content/browser/renderer_host/frame_tree_node.h" +#include "content/browser/speculation_rules/prefetch/prefetch_container.h" +#include "content/browser/speculation_rules/prefetch/prefetch_features.h" +#include "content/browser/speculation_rules/prefetch/prefetch_from_string_url_loader.h" +#include "content/browser/speculation_rules/prefetch/prefetch_params.h" +#include "content/browser/speculation_rules/prefetch/prefetch_service.h" +#include "content/browser/speculation_rules/prefetch/prefetched_mainframe_response_container.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/web_contents.h" +#include "services/network/public/cpp/resource_request.h" +#include "url/gurl.h" + +namespace content { +namespace { + +BrowserContext* BrowserContextFromFrameTreeNodeId(int frame_tree_node_id) { + WebContents* web_content = + WebContents::FromFrameTreeNodeId(frame_tree_node_id); + if (!web_content) + return nullptr; + return web_content->GetBrowserContext(); +} + +PrefetchService* PrefetchServiceFromFrameTreeNodeId(int frame_tree_node_id) { + BrowserContext* browser_context = + BrowserContextFromFrameTreeNodeId(frame_tree_node_id); + if (!browser_context) + return nullptr; + return BrowserContextImpl::From(browser_context)->GetPrefetchService(); +} + +void RecordCookieWaitTime(base::TimeDelta wait_time) { + UMA_HISTOGRAM_CUSTOM_TIMES( + "PrefetchProxy.AfterClick.Mainframe.CookieWaitTime", wait_time, + base::TimeDelta(), base::Seconds(5), 50); +} + +} // namespace + +// static +std::unique_ptr<PrefetchURLLoaderInterceptor> +PrefetchURLLoaderInterceptor::MaybeCreateInterceptor(int frame_tree_node_id) { + if (!base::FeatureList::IsEnabled(features::kPrefetchUseContentRefactor)) + return nullptr; + + return std::make_unique<PrefetchURLLoaderInterceptor>(frame_tree_node_id); +} + +PrefetchURLLoaderInterceptor::PrefetchURLLoaderInterceptor( + int frame_tree_node_id) + : frame_tree_node_id_(frame_tree_node_id) {} + +PrefetchURLLoaderInterceptor::~PrefetchURLLoaderInterceptor() = default; + +void PrefetchURLLoaderInterceptor::MaybeCreateLoader( + const network::ResourceRequest& tenative_resource_request, + BrowserContext* browser_context, + NavigationLoaderInterceptor::LoaderCallback callback, + NavigationLoaderInterceptor::FallbackCallback fallback_callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + DCHECK(!loader_callback_); + loader_callback_ = std::move(callback); + url_ = tenative_resource_request.url; + + base::WeakPtr<PrefetchContainer> prefetch_container = GetPrefetch(url_); + if (!prefetch_container || + !prefetch_container->HasValidPrefetchedResponse( + PrefetchCacheableDuration()) || + prefetch_container->HaveDefaultContextCookiesChanged()) { + DoNotInterceptNavigation(); + return; + } + + // TODO(crbug.com/1299059): Check if we need to probe the origin + + EnsureCookiesCopiedAndInterceptPrefetchedNavigation(tenative_resource_request, + prefetch_container); +} + +base::WeakPtr<PrefetchContainer> PrefetchURLLoaderInterceptor::GetPrefetch( + const GURL& url) const { + PrefetchService* prefetch_service = + PrefetchServiceFromFrameTreeNodeId(frame_tree_node_id_); + if (!prefetch_service) + return nullptr; + + return prefetch_service->GetPrefetchToServe(url); +} + +void PrefetchURLLoaderInterceptor:: + EnsureCookiesCopiedAndInterceptPrefetchedNavigation( + const network::ResourceRequest& tenative_resource_request, + base::WeakPtr<PrefetchContainer> prefetch_container) { + if (prefetch_container && + prefetch_container->IsIsolatedCookieCopyInProgress()) { + cookie_copy_start_time_ = base::TimeTicks::Now(); + prefetch_container->SetOnCookieCopyCompleteCallback(base::BindOnce( + &PrefetchURLLoaderInterceptor::InterceptPrefetchedNavigation, + weak_factory_.GetWeakPtr(), tenative_resource_request, + prefetch_container)); + return; + } + + RecordCookieWaitTime(base::TimeDelta()); + + InterceptPrefetchedNavigation(tenative_resource_request, prefetch_container); +} + +void PrefetchURLLoaderInterceptor::InterceptPrefetchedNavigation( + const network::ResourceRequest& tenative_resource_request, + base::WeakPtr<PrefetchContainer> prefetch_container) { + if (cookie_copy_start_time_) { + base::TimeDelta wait_time = + base::TimeTicks::Now() - cookie_copy_start_time_.value(); + DCHECK_GT(wait_time, base::TimeDelta()); + RecordCookieWaitTime(wait_time); + } + + if (!prefetch_container) { + DoNotInterceptNavigation(); + return; + } + + prefetch_container->SetPrefetchStatus(PrefetchStatus::kPrefetchUsedNoProbe); + + std::unique_ptr<PrefetchFromStringURLLoader> url_loader = + std::make_unique<PrefetchFromStringURLLoader>( + prefetch_container->ReleasePrefetchedResponse(), + tenative_resource_request); + + std::move(loader_callback_) + .Run(base::MakeRefCounted<SingleRequestURLLoaderFactory>( + url_loader->ServingResponseHandler())); + + // url_loader manages its own lifetime once bound to the mojo pipes. + url_loader.release(); +} + +void PrefetchURLLoaderInterceptor::DoNotInterceptNavigation() { + std::move(loader_callback_).Run({}); +} + +} // namespace content
diff --git a/content/browser/speculation_rules/prefetch/prefetch_url_loader_interceptor.h b/content/browser/speculation_rules/prefetch/prefetch_url_loader_interceptor.h new file mode 100644 index 0000000..554538bb --- /dev/null +++ b/content/browser/speculation_rules/prefetch/prefetch_url_loader_interceptor.h
@@ -0,0 +1,83 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_SPECULATION_RULES_PREFETCH_PREFETCH_URL_LOADER_INTERCEPTOR_H_ +#define CONTENT_BROWSER_SPECULATION_RULES_PREFETCH_PREFETCH_URL_LOADER_INTERCEPTOR_H_ + +#include <memory> + +#include "base/memory/weak_ptr.h" +#include "base/sequence_checker.h" +#include "base/time/time.h" +#include "content/browser/loader/navigation_loader_interceptor.h" +#include "content/common/content_export.h" +#include "content/public/browser/global_routing_id.h" +#include "services/network/public/cpp/resource_request.h" +#include "url/gurl.h" + +namespace content { + +class BrowserContext; +class PrefetchContainer; + +// Intercepts navigations that can use prefetched resources. +class CONTENT_EXPORT PrefetchURLLoaderInterceptor + : public NavigationLoaderInterceptor { + public: + static std::unique_ptr<PrefetchURLLoaderInterceptor> MaybeCreateInterceptor( + int frame_tree_node_id); + + explicit PrefetchURLLoaderInterceptor(int frame_tree_node_id); + ~PrefetchURLLoaderInterceptor() override; + + PrefetchURLLoaderInterceptor(const PrefetchURLLoaderInterceptor&) = delete; + PrefetchURLLoaderInterceptor& operator=(const PrefetchURLLoaderInterceptor&) = + delete; + + // NavigationLoaderInterceptor + void MaybeCreateLoader( + const network::ResourceRequest& tenative_resource_request, + BrowserContext* browser_context, + NavigationLoaderInterceptor::LoaderCallback callback, + NavigationLoaderInterceptor::FallbackCallback fallback_callback) override; + + private: + // Gets the prefetch associated with |url| form |PrefetchService|. + virtual base::WeakPtr<PrefetchContainer> GetPrefetch(const GURL& url) const; + + // Ensures that the cookies for prefetch are copied from its isolated network + // context to the default network context before calling + // |InterceptPrefetchedNavigation|. + void EnsureCookiesCopiedAndInterceptPrefetchedNavigation( + const network::ResourceRequest& tenative_resource_request, + base::WeakPtr<PrefetchContainer> prefetch_container); + + void InterceptPrefetchedNavigation( + const network::ResourceRequest& tenative_resource_request, + base::WeakPtr<PrefetchContainer> prefetch_container); + void DoNotInterceptNavigation(); + + // The frame tree node |this| is associated with, used to retrieve + // |PrefetchService|. + const int frame_tree_node_id_; + + // The URL being navigated to. + GURL url_; + + // Called once |this| has decided whether to intercept or not intercept the + // navigation. + NavigationLoaderInterceptor::LoaderCallback loader_callback_; + + // The time when we started waiting for cookies to be copied, delaying the + // navigation. Used to calculate total cookie wait time. + absl::optional<base::TimeTicks> cookie_copy_start_time_; + + SEQUENCE_CHECKER(sequence_checker_); + + base::WeakPtrFactory<PrefetchURLLoaderInterceptor> weak_factory_{this}; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_SPECULATION_RULES_PREFETCH_PREFETCH_URL_LOADER_INTERCEPTOR_H_
diff --git a/content/browser/speculation_rules/prefetch/prefetch_url_loader_interceptor_unittest.cc b/content/browser/speculation_rules/prefetch/prefetch_url_loader_interceptor_unittest.cc new file mode 100644 index 0000000..c327ca65 --- /dev/null +++ b/content/browser/speculation_rules/prefetch/prefetch_url_loader_interceptor_unittest.cc
@@ -0,0 +1,446 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/speculation_rules/prefetch/prefetch_url_loader_interceptor.h" + +#include <map> +#include <memory> + +#include "base/callback.h" +#include "base/memory/weak_ptr.h" +#include "base/test/scoped_feature_list.h" +#include "content/browser/speculation_rules/prefetch/prefetch_container.h" +#include "content/browser/speculation_rules/prefetch/prefetch_features.h" +#include "content/browser/speculation_rules/prefetch/prefetch_params.h" +#include "content/browser/speculation_rules/prefetch/prefetch_type.h" +#include "content/browser/speculation_rules/prefetch/prefetched_mainframe_response_container.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/test/test_renderer_host.h" +#include "net/base/isolation_info.h" +#include "services/network/public/mojom/cookie_manager.mojom.h" +#include "services/network/public/mojom/network_context.mojom.h" +#include "services/network/public/mojom/url_response_head.mojom.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h" +#include "url/gurl.h" + +namespace content { +namespace { + +// These tests leak mojo objects (like the PrefetchFromStringURLLoader) because +// they do not have valid mojo channels, which would normally delete the bound +// objects on destruction. This is expected and cannot be easily fixed without +// rewriting these as browsertests. The trade off for the speed and flexibility +// of unittests is an intentional decision. +#if defined(LEAK_SANITIZER) +#define DISABLE_ASAN(x) DISABLED_##x +#else +#define DISABLE_ASAN(x) x +#endif + +class TestPrefetchURLLoaderInterceptor : public PrefetchURLLoaderInterceptor { + public: + explicit TestPrefetchURLLoaderInterceptor(int frame_tree_node_id) + : PrefetchURLLoaderInterceptor(frame_tree_node_id) {} + ~TestPrefetchURLLoaderInterceptor() override = default; + + void AddPrefetch(base::WeakPtr<PrefetchContainer> prefetch_container) { + prefetches_[prefetch_container->GetURL()] = prefetch_container; + } + + private: + base::WeakPtr<PrefetchContainer> GetPrefetch(const GURL& url) const override { + const auto& iter = prefetches_.find(url); + if (iter == prefetches_.end()) + return nullptr; + return iter->second; + } + + std::map<GURL, base::WeakPtr<PrefetchContainer>> prefetches_; +}; + +class PrefetchURLLoaderInterceptorTest : public RenderViewHostTestHarness { + public: + PrefetchURLLoaderInterceptorTest() + : RenderViewHostTestHarness( + base::test::TaskEnvironment::TimeSource::MOCK_TIME) {} + + void SetUp() override { + RenderViewHostTestHarness::SetUp(); + + browser_context() + ->GetDefaultStoragePartition() + ->GetNetworkContext() + ->GetCookieManager(cookie_manager_.BindNewPipeAndPassReceiver()); + + interceptor_ = std::make_unique<TestPrefetchURLLoaderInterceptor>( + web_contents()->GetMainFrame()->GetFrameTreeNodeId()); + } + + void TearDown() override { + interceptor_.release(); + + RenderViewHostTestHarness::TearDown(); + } + + TestPrefetchURLLoaderInterceptor* interceptor() { return interceptor_.get(); } + + void WaitForCallback() { + if (was_intercepted_.has_value()) + return; + + base::RunLoop run_loop; + on_loader_callback_closure_ = run_loop.QuitClosure(); + run_loop.Run(); + } + + void LoaderCallback( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { + was_intercepted_ = url_loader_factory != nullptr; + if (on_loader_callback_closure_) { + std::move(on_loader_callback_closure_).Run(); + } + } + + absl::optional<bool> was_intercepted() { return was_intercepted_; } + + bool SetCookie(const GURL& url, const std::string& value) { + bool result = false; + base::RunLoop run_loop; + + std::unique_ptr<net::CanonicalCookie> cookie(net::CanonicalCookie::Create( + url, value, base::Time::Now(), /*server_time=*/absl::nullopt, + /*cookie_partition_key=*/absl::nullopt)); + EXPECT_TRUE(cookie.get()); + EXPECT_TRUE(cookie->IsHostCookie()); + + net::CookieOptions options; + options.set_include_httponly(); + options.set_same_site_cookie_context( + net::CookieOptions::SameSiteCookieContext::MakeInclusive()); + + cookie_manager_->SetCanonicalCookie( + *cookie.get(), url, options, + base::BindOnce( + [](bool* result, base::RunLoop* run_loop, + net::CookieAccessResult set_cookie_access_result) { + *result = set_cookie_access_result.status.IsInclude(); + run_loop->Quit(); + }, + &result, &run_loop)); + + // This will run until the cookie is set. + run_loop.Run(); + + // This will run until the cookie listener gets the cookie change. + base::RunLoop().RunUntilIdle(); + + return result; + } + + network::mojom::CookieManager* cookie_manager() { + return cookie_manager_.get(); + } + + const base::HistogramTester& histogram_tester() { return histogram_tester_; } + + private: + std::unique_ptr<TestPrefetchURLLoaderInterceptor> interceptor_; + + base::HistogramTester histogram_tester_; + + absl::optional<bool> was_intercepted_; + base::OnceClosure on_loader_callback_closure_; + + mojo::Remote<network::mojom::CookieManager> cookie_manager_; +}; + +TEST_F(PrefetchURLLoaderInterceptorTest, + DISABLE_ASAN(InterceptNavigationCookieCopyCompleted)) { + const GURL kTestUrl("https://example.com"); + + std::unique_ptr<PrefetchContainer> prefetch_container = + std::make_unique<PrefetchContainer>( + main_rfh()->GetGlobalId(), kTestUrl, + PrefetchType(/*use_isolated_network_context=*/true, + /*use_prefetch_proxy=*/true), + nullptr); + + prefetch_container->TakePrefetchedResponse( + std::make_unique<PrefetchedMainframeResponseContainer>( + net::IsolationInfo(), network::mojom::URLResponseHead::New(), + std::make_unique<std::string>("test body"))); + + // Simulate the cookie copy process starting and finishing before + // |MaybeCreateLoader| is called. + prefetch_container->OnIsolatedCookieCopyStart(); + task_environment()->FastForwardBy(base::Milliseconds(10)); + prefetch_container->OnIsolatedCookieCopyComplete(); + + interceptor()->AddPrefetch(prefetch_container->GetWeakPtr()); + + network::ResourceRequest request; + request.url = kTestUrl; + request.resource_type = + static_cast<int>(blink::mojom::ResourceType::kMainFrame); + request.method = "GET"; + + interceptor()->MaybeCreateLoader( + request, browser_context(), + base::BindOnce(&PrefetchURLLoaderInterceptorTest::LoaderCallback, + base::Unretained(this)), + base::BindOnce([](bool) { NOTREACHED(); })); + WaitForCallback(); + + EXPECT_TRUE(was_intercepted().has_value()); + EXPECT_TRUE(was_intercepted().value()); + + histogram_tester().ExpectUniqueTimeSample( + "PrefetchProxy.AfterClick.Mainframe.CookieWaitTime", base::TimeDelta(), + 1); +} + +TEST_F(PrefetchURLLoaderInterceptorTest, + DISABLE_ASAN(InterceptNavigationCookieCopyInProgress)) { + const GURL kTestUrl("https://example.com"); + + std::unique_ptr<PrefetchContainer> prefetch_container = + std::make_unique<PrefetchContainer>( + main_rfh()->GetGlobalId(), kTestUrl, + PrefetchType(/*use_isolated_network_context=*/true, + /*use_prefetch_proxy=*/true), + nullptr); + + prefetch_container->TakePrefetchedResponse( + std::make_unique<PrefetchedMainframeResponseContainer>( + net::IsolationInfo(), network::mojom::URLResponseHead::New(), + std::make_unique<std::string>("test body"))); + + // Simulate the cookie copy process starting, but not finishing until after + // |MaybeCreateLoader| is called. + prefetch_container->OnIsolatedCookieCopyStart(); + task_environment()->FastForwardBy(base::Milliseconds(10)); + + interceptor()->AddPrefetch(prefetch_container->GetWeakPtr()); + + network::ResourceRequest request; + request.url = kTestUrl; + request.resource_type = + static_cast<int>(blink::mojom::ResourceType::kMainFrame); + request.method = "GET"; + + interceptor()->MaybeCreateLoader( + request, browser_context(), + base::BindOnce(&PrefetchURLLoaderInterceptorTest::LoaderCallback, + base::Unretained(this)), + base::BindOnce([](bool) { NOTREACHED(); })); + + // A decision on whether the navigation should be intercepted shouldn't be + // made until after the cookie copy process is completed. + EXPECT_FALSE(was_intercepted().has_value()); + + task_environment()->FastForwardBy(base::Milliseconds(20)); + + prefetch_container->OnIsolatedCookieCopyComplete(); + WaitForCallback(); + + EXPECT_TRUE(was_intercepted().has_value()); + EXPECT_TRUE(was_intercepted().value()); + + histogram_tester().ExpectUniqueTimeSample( + "PrefetchProxy.AfterClick.Mainframe.CookieWaitTime", + base::Milliseconds(20), 1); +} + +TEST_F(PrefetchURLLoaderInterceptorTest, + DISABLE_ASAN(InterceptNavigationNoCookieCopyNeeded)) { + const GURL kTestUrl("https://example.com"); + + // No cookies are copied for prefetches where |use_isolated_network_context| + // is false (i.e. same origin prefetches). + std::unique_ptr<PrefetchContainer> prefetch_container = + std::make_unique<PrefetchContainer>( + main_rfh()->GetGlobalId(), kTestUrl, + PrefetchType(/*use_isolated_network_context=*/false, + /*use_prefetch_proxy=*/false), + nullptr); + + prefetch_container->TakePrefetchedResponse( + std::make_unique<PrefetchedMainframeResponseContainer>( + net::IsolationInfo(), network::mojom::URLResponseHead::New(), + std::make_unique<std::string>("test body"))); + + interceptor()->AddPrefetch(prefetch_container->GetWeakPtr()); + + network::ResourceRequest request; + request.url = kTestUrl; + request.resource_type = + static_cast<int>(blink::mojom::ResourceType::kMainFrame); + request.method = "GET"; + + interceptor()->MaybeCreateLoader( + request, browser_context(), + base::BindOnce(&PrefetchURLLoaderInterceptorTest::LoaderCallback, + base::Unretained(this)), + base::BindOnce([](bool) { NOTREACHED(); })); + WaitForCallback(); + + EXPECT_TRUE(was_intercepted().has_value()); + EXPECT_TRUE(was_intercepted().value()); + + histogram_tester().ExpectUniqueTimeSample( + "PrefetchProxy.AfterClick.Mainframe.CookieWaitTime", base::TimeDelta(), + 1); +} + +TEST_F(PrefetchURLLoaderInterceptorTest, + DISABLE_ASAN(DoNotInterceptNavigationNoPrefetch)) { + const GURL kTestUrl("https://example.com"); + + // With no prefetch set, the navigation shouldn't be intercepted. + + network::ResourceRequest request; + request.url = kTestUrl; + request.resource_type = + static_cast<int>(blink::mojom::ResourceType::kMainFrame); + request.method = "GET"; + + interceptor()->MaybeCreateLoader( + request, browser_context(), + base::BindOnce(&PrefetchURLLoaderInterceptorTest::LoaderCallback, + base::Unretained(this)), + base::BindOnce([](bool) { NOTREACHED(); })); + WaitForCallback(); + + EXPECT_TRUE(was_intercepted().has_value()); + EXPECT_FALSE(was_intercepted().value()); + + histogram_tester().ExpectTotalCount( + "PrefetchProxy.AfterClick.Mainframe.CookieWaitTime", 0); +} + +TEST_F(PrefetchURLLoaderInterceptorTest, + DISABLE_ASAN(DoNotInterceptNavigationNoPrefetchedResponse)) { + const GURL kTestUrl("https://example.com"); + + // Without a prefetched response, the navigation shouldn't be intercepted. + std::unique_ptr<PrefetchContainer> prefetch_container = + std::make_unique<PrefetchContainer>( + main_rfh()->GetGlobalId(), kTestUrl, + PrefetchType(/*use_isolated_network_context=*/true, + /*use_prefetch_proxy=*/true), + nullptr); + + interceptor()->AddPrefetch(prefetch_container->GetWeakPtr()); + + // Set up ResourceRequest + network::ResourceRequest request; + request.url = kTestUrl; + request.resource_type = + static_cast<int>(blink::mojom::ResourceType::kMainFrame); + request.method = "GET"; + + // Try to create loader + interceptor()->MaybeCreateLoader( + request, browser_context(), + base::BindOnce(&PrefetchURLLoaderInterceptorTest::LoaderCallback, + base::Unretained(this)), + base::BindOnce([](bool) { NOTREACHED(); })); + WaitForCallback(); + + EXPECT_TRUE(was_intercepted().has_value()); + EXPECT_FALSE(was_intercepted().value()); + + histogram_tester().ExpectTotalCount( + "PrefetchProxy.AfterClick.Mainframe.CookieWaitTime", 0); +} + +TEST_F(PrefetchURLLoaderInterceptorTest, + DISABLE_ASAN(DoNotInterceptNavigationStalePrefetchedResponse)) { + const GURL kTestUrl("https://example.com"); + + std::unique_ptr<PrefetchContainer> prefetch_container = + std::make_unique<PrefetchContainer>( + main_rfh()->GetGlobalId(), kTestUrl, + PrefetchType(/*use_isolated_network_context=*/true, + /*use_prefetch_proxy=*/true), + nullptr); + + prefetch_container->TakePrefetchedResponse( + std::make_unique<PrefetchedMainframeResponseContainer>( + net::IsolationInfo(), network::mojom::URLResponseHead::New(), + std::make_unique<std::string>("test body"))); + + // Advance time enough so that the response is considered stale. + task_environment()->FastForwardBy(2 * PrefetchCacheableDuration()); + + interceptor()->AddPrefetch(prefetch_container->GetWeakPtr()); + + network::ResourceRequest request; + request.url = kTestUrl; + request.resource_type = + static_cast<int>(blink::mojom::ResourceType::kMainFrame); + request.method = "GET"; + + interceptor()->MaybeCreateLoader( + request, browser_context(), + base::BindOnce(&PrefetchURLLoaderInterceptorTest::LoaderCallback, + base::Unretained(this)), + base::BindOnce([](bool) { NOTREACHED(); })); + WaitForCallback(); + + EXPECT_TRUE(was_intercepted().has_value()); + EXPECT_FALSE(was_intercepted().value()); + + histogram_tester().ExpectTotalCount( + "PrefetchProxy.AfterClick.Mainframe.CookieWaitTime", 0); +} + +TEST_F(PrefetchURLLoaderInterceptorTest, + DISABLE_ASAN(DoNotInterceptNavigationCookiesChanged)) { + const GURL kTestUrl("https://example.com"); + + std::unique_ptr<PrefetchContainer> prefetch_container = + std::make_unique<PrefetchContainer>( + main_rfh()->GetGlobalId(), kTestUrl, + PrefetchType(/*use_isolated_network_context=*/true, + /*use_prefetch_proxy=*/true), + nullptr); + + prefetch_container->TakePrefetchedResponse( + std::make_unique<PrefetchedMainframeResponseContainer>( + net::IsolationInfo(), network::mojom::URLResponseHead::New(), + std::make_unique<std::string>("test body"))); + + // Since the cookies associated with |kTestUrl| have changed, the prefetch can + // no longer be served. + prefetch_container->RegisterCookieListener(cookie_manager()); + ASSERT_TRUE(SetCookie(kTestUrl, "test-cookie")); + + interceptor()->AddPrefetch(prefetch_container->GetWeakPtr()); + + network::ResourceRequest request; + request.url = kTestUrl; + request.resource_type = + static_cast<int>(blink::mojom::ResourceType::kMainFrame); + request.method = "GET"; + + interceptor()->MaybeCreateLoader( + request, browser_context(), + base::BindOnce(&PrefetchURLLoaderInterceptorTest::LoaderCallback, + base::Unretained(this)), + base::BindOnce([](bool) { NOTREACHED(); })); + WaitForCallback(); + + EXPECT_TRUE(was_intercepted().has_value()); + EXPECT_FALSE(was_intercepted().value()); + + histogram_tester().ExpectTotalCount( + "PrefetchProxy.AfterClick.Mainframe.CookieWaitTime", 0); +} + +} // namespace +} // namespace content
diff --git a/content/browser/speculation_rules/prefetch/prefetched_mainframe_response_container.h b/content/browser/speculation_rules/prefetch/prefetched_mainframe_response_container.h index b1b2d84d..2675ce5a 100644 --- a/content/browser/speculation_rules/prefetch/prefetched_mainframe_response_container.h +++ b/content/browser/speculation_rules/prefetch/prefetched_mainframe_response_container.h
@@ -8,12 +8,13 @@ #include <memory> #include <string> +#include "content/common/content_export.h" #include "net/base/isolation_info.h" #include "services/network/public/mojom/url_response_head.mojom.h" namespace content { -class PrefetchedMainframeResponseContainer { +class CONTENT_EXPORT PrefetchedMainframeResponseContainer { public: PrefetchedMainframeResponseContainer(const net::IsolationInfo& info, network::mojom::URLResponseHeadPtr head,
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index f7b4b67..4893e261 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1294,6 +1294,10 @@ } RenderFrameHostImpl* WebContentsImpl::GetMainFrame() { + return GetPrimaryMainFrame(); +} + +RenderFrameHostImpl* WebContentsImpl::GetPrimaryMainFrame() { return primary_frame_tree_.root()->current_frame_host(); }
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 67c3168..4d6a72a 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -334,6 +334,7 @@ const GURL& GetVisibleURL() override; const GURL& GetLastCommittedURL() override; RenderFrameHostImpl* GetMainFrame() override; + RenderFrameHostImpl* GetPrimaryMainFrame() override; PageImpl& GetPrimaryPage() override; RenderFrameHostImpl* GetFocusedFrame() override; bool IsPrerenderedFrame(int frame_tree_node_id) override;
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc index 7e2a83b..05894c4 100644 --- a/content/browser/webid/federated_auth_request_impl.cc +++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -1003,6 +1003,21 @@ void FederatedAuthRequestImpl::OnAccountSelected(const std::string& account_id, bool is_sign_in, bool should_embargo) { + // Check if the user has disabled the FedCM API after the FedCM UI is + // displayed. This ensures that requests are not wrongfully sent to IDPs when + // settings are changed while an existing FedCM UI is displayed. Ideally, we + // should enforce this check before all requests but users typically won't + // have time to disable the FedCM API in other types of requests. + if (GetApiPermissionContext()->GetApiPermissionStatus(origin_) != + FederatedApiPermissionStatus::GRANTED) { + RecordRequestIdTokenStatus(IdTokenStatus::kDisabledInSettings, + render_frame_host_->GetPageUkmSourceId()); + + CompleteRequest(FederatedAuthRequestResult::kErrorDisabledInSettings, "", + /*should_call_callback=*/false); + return; + } + // This could happen if user didn't select any accounts. if (account_id.empty()) { base::TimeTicks dismiss_dialog_time = base::TimeTicks::Now();
diff --git a/content/browser/webid/federated_auth_request_impl_unittest.cc b/content/browser/webid/federated_auth_request_impl_unittest.cc index b9d5418..87ecbea 100644 --- a/content/browser/webid/federated_auth_request_impl_unittest.cc +++ b/content/browser/webid/federated_auth_request_impl_unittest.cc
@@ -1756,4 +1756,60 @@ EXPECT_EQ(RequestIdTokenStatus::kErrorCanceled, auth_helper_.status()); } +// Test that the request fails if user proceeds with the sign in workflow after +// disabling the API while an existing accounts dialog is shown. +TEST_F(BasicFederatedAuthRequestImplTest, ApiDisabledAfterAccountsDialogShown) { + base::HistogramTester histogram_tester_; + + EXPECT_CALL(*mock_dialog_controller(), + ShowAccountsDialog(_, _, _, _, _, _, _)) + .WillOnce(Invoke( + [&](content::WebContents* rp_web_contents, const GURL& idp_signin_url, + base::span<const content::IdentityRequestAccount> accounts, + const IdentityProviderMetadata& idp_metadata, + const ClientIdData& client_id_data, SignInMode sign_in_mode, + IdentityRequestDialogController::AccountSelectionCallback + on_selected) { + // Disable FedCM API + test_api_permission_delegate_->permission_override_ = + std::make_pair(main_test_rfh()->GetLastCommittedOrigin(), + ApiPermissionStatus::BLOCKED_SETTINGS); + + std::move(on_selected) + .Run(/*account_id=*/"", /*is_sign_in=*/false, + /*should_embargo=*/false); + })); + + base::RunLoop ukm_loop; + ukm_recorder()->SetOnAddEntryCallback(Entry::kEntryName, + ukm_loop.QuitClosure()); + + MockConfiguration configuration = kConfigurationValid; + configuration.customized_dialog = true; + RequestExpectations expectations = { + RequestIdTokenStatus::kError, + FederatedAuthRequestResult::kErrorDisabledInSettings, + FETCH_ENDPOINT_ALL_REQUEST_ID_TOKEN & ~FetchedEndpoint::TOKEN}; + + RunAuthTest(kDefaultRequestParameters, expectations, configuration); + + ukm_loop.Run(); + + histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.ShowAccountsDialog", + 1); + histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.ContinueOnDialog", 0); + histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.IdTokenResponse", 0); + histogram_tester_.ExpectTotalCount("Blink.FedCm.Timing.TurnaroundTime", 0); + + histogram_tester_.ExpectUniqueSample("Blink.FedCm.Status.RequestIdToken", + IdTokenStatus::kDisabledInSettings, 1); + + ExpectTimingUKM("Timing.ShowAccountsDialog"); + ExpectNoTimingUKM("Timing.ContinueOnDialog"); + ExpectNoTimingUKM("Timing.IdTokenResponse"); + ExpectNoTimingUKM("Timing.TurnaroundTime"); + + ExpectRequestIdTokenStatusUKM(IdTokenStatus::kDisabledInSettings); +} + } // namespace content
diff --git a/content/browser/webid/idp_network_request_manager.cc b/content/browser/webid/idp_network_request_manager.cc index 71bc4d2..e24c374 100644 --- a/content/browser/webid/idp_network_request_manager.cc +++ b/content/browser/webid/idp_network_request_manager.cc
@@ -136,17 +136,22 @@ std::unique_ptr<network::ResourceRequest> CreateCredentialedResourceRequest( GURL target_url, bool send_referrer, - url::Origin initiator, + url::Origin rp_origin, network::mojom::ClientSecurityStatePtr client_security_state) { auto resource_request = std::make_unique<network::ResourceRequest>(); auto target_origin = url::Origin::Create(target_url); auto site_for_cookies = net::SiteForCookies::FromOrigin(target_origin); AddCsrfHeader(resource_request.get()); - resource_request->request_initiator = initiator; + // We set the initiator to the target origin so that this request is + // considered first-party. We want to send first-party cookies because + // this is not a real third-party request as it is mediated by the browser, + // and third-party cookies will be going away with 3pc deprecation, but we + // still need to send cookies in these requests. + resource_request->request_initiator = target_origin; resource_request->url = target_url; resource_request->site_for_cookies = site_for_cookies; if (send_referrer) { - resource_request->referrer = initiator.GetURL(); + resource_request->referrer = rp_origin.GetURL(); // Since referrer_policy only affects redirects and we disable redirects // below, we don't need to set referrer_policy here. }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/NavigationHandle.java b/content/public/android/java/src/org/chromium/content_public/browser/NavigationHandle.java index 5ad156ab..61929f5 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/NavigationHandle.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/NavigationHandle.java
@@ -30,7 +30,7 @@ private boolean mHasCommitted; private boolean mIsDownload; private boolean mIsErrorPage; - private boolean mIsFragmentNavigation; + private boolean mIsPrimaryMainFrameFragmentNavigation; private boolean mIsValidSearchFormUrl; private @NetError int mErrorCode; private int mHttpStatusCode; @@ -81,12 +81,13 @@ */ @CalledByNative public void didFinish(@NonNull GURL url, boolean isErrorPage, boolean hasCommitted, - boolean isFragmentNavigation, boolean isDownload, boolean isValidSearchFormUrl, - @PageTransition int transition, @NetError int errorCode, int httpStatuscode) { + boolean isPrimaryMainFrameFragmentNavigation, boolean isDownload, + boolean isValidSearchFormUrl, @PageTransition int transition, @NetError int errorCode, + int httpStatuscode) { mUrl = url; mIsErrorPage = isErrorPage; mHasCommitted = hasCommitted; - mIsFragmentNavigation = isFragmentNavigation; + mIsPrimaryMainFrameFragmentNavigation = isPrimaryMainFrameFragmentNavigation; mIsDownload = isDownload; mIsValidSearchFormUrl = isValidSearchFormUrl; mPageTransition = transition; @@ -206,10 +207,10 @@ } /** - * Returns true on same-document navigation with fragment change. + * Returns true on same-document navigation with fragment change in the primary main frame. */ - public boolean isFragmentNavigation() { - return mIsFragmentNavigation; + public boolean isPrimaryMainFrameFragmentNavigation() { + return mIsPrimaryMainFrameFragmentNavigation; } /**
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn index c01888b..f381b6a 100644 --- a/content/public/browser/BUILD.gn +++ b/content/public/browser/BUILD.gn
@@ -181,6 +181,7 @@ "font_list_async.h", "frame_accept_header.cc", "frame_accept_header.h", + "frame_rate_throttling.h", "frame_type.h", "generated_code_cache_settings.h", "global_request_id.cc",
diff --git a/content/public/browser/browsing_data_remover.h b/content/public/browser/browsing_data_remover.h index 541e5bf1..ed436ce 100644 --- a/content/public/browser/browsing_data_remover.h +++ b/content/public/browser/browsing_data_remover.h
@@ -107,11 +107,11 @@ static constexpr DataType DATA_TYPE_TRUST_TOKENS = 1 << 16; // Conversion measurement API - // (https://github.com/WICG/conversion-measurement-api) persistent storage. + // (https://github.com/WICG/attribution-reporting-api) persistent storage. static constexpr DataType DATA_TYPE_CONVERSIONS = 1 << 17; // Aggregation Service - // (https://github.com/WICG/conversion-measurement-api/blob/main/AGGREGATE.md#data-processing-through-the-aggregation-service) + // (https://github.com/WICG/attribution-reporting-api/blob/main/AGGREGATE.md#data-processing-through-a-secure-aggregation-service) // persistent storage. static constexpr DataType DATA_TYPE_AGGREGATION_SERVICE = 1 << 18;
diff --git a/content/public/browser/frame_rate_throttling.h b/content/public/browser/frame_rate_throttling.h new file mode 100644 index 0000000..e9daa6e4 --- /dev/null +++ b/content/public/browser/frame_rate_throttling.h
@@ -0,0 +1,35 @@ +// Copyright 2022 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_PUBLIC_BROWSER_FRAME_RATE_THROTTLING_H_ +#define CONTENT_PUBLIC_BROWSER_FRAME_RATE_THROTTLING_H_ + +#include "base/time/time.h" +#include "content/common/content_export.h" + +namespace content { + +// Signals the frame sink manager that all current and future frame sinks should +// start sending BeginFrames at an interval that is at least as long `interval`. +// Because there is a single viz process, which itself contains a single host +// frame sink manager, calling this function multiple times from anywhere will +// apply the throttling described by the latest call. For instance: +// +// Foo calling StartThrottlingAllFrameSinks(Hertz(15)); +// +// followed by +// +// Bar calling StartThrottlingAllFrameSinks(Hertz(30)); +// +// Will result in framerate being throttled at 30hz +// Should be called from the UI thread. +CONTENT_EXPORT void StartThrottlingAllFrameSinks(base::TimeDelta interval); + +// Stops the BeginFrame throttling enabled by `StartThrottlingAllFrameSinks()`. +// Should be called from the UI thread. +CONTENT_EXPORT void StopThrottlingAllFrameSinks(); + +} // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_FRAME_RATE_THROTTLING_H_
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h index e82a5b7..c98dd2d9 100644 --- a/content/public/browser/web_contents.h +++ b/content/public/browser/web_contents.h
@@ -357,12 +357,14 @@ // WebContents' main frame. virtual const GURL& GetLastCommittedURL() = 0; - // Returns the main frame for the currently active view. Always non-null - // except during WebContents destruction. With MPArch, this returns the - // primary main frame. This WebContents may have additional main frames for - // prerendered pages, bfcached pages, etc. + // Deprecated. Use `GetPrimaryMainFrame` instead. virtual RenderFrameHost* GetMainFrame() = 0; + // Returns the primary main frame for the currently active page. Always + // non-null except during WebContents destruction. This WebContents may + // have additional main frames for prerendered pages, bfcached pages, etc. + virtual RenderFrameHost* GetPrimaryMainFrame() = 0; + // Returns the current page in the primary frame tree of this WebContents. // If this WebContents is associated with an omnibox, usually the URL of the // main document of this page will be displayed in it.
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 7ee5bfd..b282437a 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -801,8 +801,8 @@ const base::Feature kServiceWorkerPaymentApps{"ServiceWorkerPaymentApps", base::FEATURE_ENABLED_BY_DEFAULT}; -// Enable the basic-card payment method from the PaymentRequest API. This flag -// will be used to deprecate basic-card eventually: crbug.com/1209835. +// Enable the basic-card payment method from the PaymentRequest API. This has +// been disabled since M100 and is soon to be removed: crbug.com/1209835. const base::Feature kPaymentRequestBasicCard{"PaymentRequestBasicCard", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 9a54afa..50d49a64 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -2390,11 +2390,13 @@ "../browser/sms/user_consent_handler_unittest.cc", "../browser/sms/webotp_service_unittest.cc", "../browser/speculation_rules/prefetch/prefetch_container_unittest.cc", + "../browser/speculation_rules/prefetch/prefetch_cookie_listener_unittest.cc", "../browser/speculation_rules/prefetch/prefetch_document_manager_unittest.cc", "../browser/speculation_rules/prefetch/prefetch_params_unittest.cc", "../browser/speculation_rules/prefetch/prefetch_proxy_configurator_unittest.cc", "../browser/speculation_rules/prefetch/prefetch_service_unittest.cc", "../browser/speculation_rules/prefetch/prefetch_type_unittest.cc", + "../browser/speculation_rules/prefetch/prefetch_url_loader_interceptor_unittest.cc", "../browser/speculation_rules/speculation_host_impl_unittest.cc", "../browser/speech/tts_controller_unittest.cc", "../browser/startup_task_runner_unittest.cc",
diff --git a/content/test/data/attribution_reporting/interop/README.md b/content/test/data/attribution_reporting/interop/README.md index 695d43b..35836b4 100644 --- a/content/test/data/attribution_reporting/interop/README.md +++ b/content/test/data/attribution_reporting/interop/README.md
@@ -3,7 +3,7 @@ This directory contains a set of tests which ensure the attribution logic as implemented matches the intended behavior of the Attribution Reporting API. -See https://wicg.github.io/conversion-measurement-api/ for the draft specification. +See https://wicg.github.io/attribution-reporting-api/ for the draft specification. See //content/browser/attribution_reporting/attribution_interop_unittest.cc for the tests.
diff --git a/content/test/data/attribution_reporting/register_aggregatable_trigger_data_headers.html.mock-http-headers b/content/test/data/attribution_reporting/register_aggregatable_trigger_data_headers.html.mock-http-headers index 90309f2..144393aa 100644 --- a/content/test/data/attribution_reporting/register_aggregatable_trigger_data_headers.html.mock-http-headers +++ b/content/test/data/attribution_reporting/register_aggregatable_trigger_data_headers.html.mock-http-headers
@@ -1,3 +1,2 @@ HTTP/1.1 200 OK -Attribution-Reporting-Register-Aggregatable-Trigger-Data:[{"key_piece":"0x1","source_keys":["key1"],"filters":{"a":["b"]},"not_filters":{"c":[]}},{"key_piece":"0x0","source_keys":[],"not_filters":{"d":["e","f"],"g":[]}}] -Attribution-Reporting-Register-Aggregatable-Values:{"key1": 123, "key2": 456} +Attribution-Reporting-Register-Trigger:{"aggregatable_trigger_data":[{"key_piece":"0x1","source_keys":["key1"],"filters":{"a":["b"]},"not_filters":{"c":[]}},{"key_piece":"0x0","source_keys":[],"not_filters":{"d":["e","f"],"g":[]}}],"aggregatable_values":{"key1": 123, "key2": 456}}
diff --git a/content/test/data/attribution_reporting/register_trigger_headers.html.mock-http-headers b/content/test/data/attribution_reporting/register_trigger_headers.html.mock-http-headers index 924ce5a..be618df 100644 --- a/content/test/data/attribution_reporting/register_trigger_headers.html.mock-http-headers +++ b/content/test/data/attribution_reporting/register_trigger_headers.html.mock-http-headers
@@ -1,2 +1,2 @@ HTTP/1.1 200 OK -Attribution-Reporting-Register-Event-Trigger:[{"trigger_data": "7"}] \ No newline at end of file +Attribution-Reporting-Register-Trigger:{"event_trigger_data":[{"trigger_data": "7"}]}
diff --git a/content/test/data/attribution_reporting/register_trigger_headers_all_params.html.mock-http-headers b/content/test/data/attribution_reporting/register_trigger_headers_all_params.html.mock-http-headers index 75a2c896..55f2ace9 100644 --- a/content/test/data/attribution_reporting/register_trigger_headers_all_params.html.mock-http-headers +++ b/content/test/data/attribution_reporting/register_trigger_headers_all_params.html.mock-http-headers
@@ -1,6 +1,2 @@ HTTP/1.1 200 OK -Attribution-Reporting-Filters:{"w":[],"x":["y","z"]} -Attribution-Reporting-Register-Event-Trigger:[{"trigger_data": "1","priority":"5","deduplication_key":"1024","filters":{"a":["b"]},"not_filters":{"c":[]}},{"trigger_data":"2","priority":"10","not_filters":{"d":["e","f"],"g":[]}}] -Attribution-Reporting-Register-Aggregatable-Trigger-Data:[{"key_piece":"0x1","source_keys":["key"]}] -Attribution-Reporting-Register-Aggregatable-Values:{"key": 123} -Attribution-Reporting-Trigger-Debug-Key:789 +Attribution-Reporting-Register-Trigger:{"filters":{"w":[],"x":["y","z"]},"event_trigger_data":[{"trigger_data": "1","priority":"5","deduplication_key":"1024","filters":{"a":["b"]},"not_filters":{"c":[]}},{"trigger_data":"2","priority":"10","not_filters":{"d":["e","f"],"g":[]}}],"aggregatable_trigger_data":[{"key_piece":"0x1","source_keys":["key"]}],"aggregatable_values":{"key": 123},"debug_key":"789"}
diff --git a/content/test/data/attribution_reporting/register_trigger_headers_and_redirect.html.mock-http-headers b/content/test/data/attribution_reporting/register_trigger_headers_and_redirect.html.mock-http-headers index f795869..dc7af487 100644 --- a/content/test/data/attribution_reporting/register_trigger_headers_and_redirect.html.mock-http-headers +++ b/content/test/data/attribution_reporting/register_trigger_headers_and_redirect.html.mock-http-headers
@@ -1,3 +1,3 @@ HTTP/1.1 301 Yo -Attribution-Reporting-Register-Event-Trigger:[{"trigger_data": "5"}] +Attribution-Reporting-Register-Trigger:{"event_trigger_data":[{"trigger_data": "5"}]} Location: /register_trigger_headers.html \ No newline at end of file
diff --git a/content/test/data/attribution_reporting/register_trigger_headers_dedup.html.mock-http-headers b/content/test/data/attribution_reporting/register_trigger_headers_dedup.html.mock-http-headers index ec4cd06..38358f8 100644 --- a/content/test/data/attribution_reporting/register_trigger_headers_dedup.html.mock-http-headers +++ b/content/test/data/attribution_reporting/register_trigger_headers_dedup.html.mock-http-headers
@@ -1,2 +1,2 @@ HTTP/1.1 200 OK -Attribution-Reporting-Register-Event-Trigger:[{"trigger_data": "1", "deduplication_key":"123"}] \ No newline at end of file +Attribution-Reporting-Register-Trigger:{"event_trigger_data":[{"trigger_data": "1", "deduplication_key":"123"}]}
diff --git a/content/test/data/attribution_reporting/register_trigger_headers_then_redirect_invalid.html.mock-http-headers b/content/test/data/attribution_reporting/register_trigger_headers_then_redirect_invalid.html.mock-http-headers index 09ca1ff..af8d9bea 100644 --- a/content/test/data/attribution_reporting/register_trigger_headers_then_redirect_invalid.html.mock-http-headers +++ b/content/test/data/attribution_reporting/register_trigger_headers_then_redirect_invalid.html.mock-http-headers
@@ -1,3 +1,3 @@ HTTP/1.1 301 Yo -Attribution-Reporting-Register-Event-Trigger:{[]} +Attribution-Reporting-Register-Trigger:! Location: /register_trigger_headers.html \ No newline at end of file
diff --git a/content/test/data/attribution_reporting/register_trigger_source_trigger.html.mock-http-headers b/content/test/data/attribution_reporting/register_trigger_source_trigger.html.mock-http-headers index 65f4c0ea..10db407 100644 --- a/content/test/data/attribution_reporting/register_trigger_source_trigger.html.mock-http-headers +++ b/content/test/data/attribution_reporting/register_trigger_source_trigger.html.mock-http-headers
@@ -1,3 +1,3 @@ HTTP/1.1 301 Yo -Attribution-Reporting-Register-Event-Trigger:[{"trigger_data": "5"}] +Attribution-Reporting-Register-Trigger:{"event_trigger_data":[{"trigger_data": "5"}]} Location: /register_source_trigger_redirect_chain.html \ No newline at end of file
diff --git a/content/test/data/attribution_reporting/simulator/README.md b/content/test/data/attribution_reporting/simulator/README.md index 1730d289..fb61706 100644 --- a/content/test/data/attribution_reporting/simulator/README.md +++ b/content/test/data/attribution_reporting/simulator/README.md
@@ -206,7 +206,7 @@ }, // The report itself. See - // https://github.com/WICG/conversion-measurement-api/blob/main/EVENT.md#attribution-reports + // https://github.com/WICG/attribution-reporting-api/blob/main/EVENT.md#attribution-reports // for details about its fields. "report": {} }, @@ -238,7 +238,7 @@ ], // The report itself. See - // https://github.com/WICG/conversion-measurement-api/blob/main/AGGREGATE.md#aggregatable-reports + // https://github.com/WICG/attribution-reporting-api/blob/main/AGGREGATE.md#aggregatable-reports // for details about its fields. "report": {} } @@ -291,7 +291,7 @@ }, // The report itself. See - // https://github.com/WICG/conversion-measurement-api/blob/main/EVENT.md#attribution-reports + // https://github.com/WICG/attribution-reporting-api/blob/main/EVENT.md#attribution-reports // for details about its fields. "report": {} }
diff --git a/content/test/data/fuzzer_corpus/attribution_simulator/all_fields.textproto b/content/test/data/fuzzer_corpus/attribution_simulator/all_fields.textproto index 3cb451a..92172b8 100644 --- a/content/test/data/fuzzer_corpus/attribution_simulator/all_fields.textproto +++ b/content/test/data/fuzzer_corpus/attribution_simulator/all_fields.textproto
@@ -127,6 +127,21 @@ } } } + field { + name: "aggregation_keys" + value { + object_value { + field { + name: "a" + value { + string_value { + value: "0x1" + } + } + } + } + } + } } } } @@ -269,6 +284,90 @@ } } } + field { + name: "aggregatable_trigger_data" + value { + array_value { + value { + object_value { + field { + name: "key_piece" + value { + string_value { + value: "0x1" + } + } + } + field { + name: "source_keys" + value { + array_value { + value { + string_value { + value: "a" + } + } + } + } + } + field { + name: "filters" + value { + object_value { + field { + name: "e" + value { + array_value { + value { + string_value { + value: "f" + } + } + } + } + } + } + } + } + field { + name: "not_filters" + value { + object_value { + field { + name: "g" + value { + array_value { + value { + string_value { + value: "h" + } + } + } + } + } + } + } + } + } + } + } + } + } + field { + name: "aggregatable_values" + value { + object_value { + field { + name: "a" + value: { + number_value { + value: 123 + } + } + } + } + } + } } } }
diff --git a/content/web_test/renderer/web_ax_object_proxy.cc b/content/web_test/renderer/web_ax_object_proxy.cc index edf6658..85af3c6 100644 --- a/content/web_test/renderer/web_ax_object_proxy.cc +++ b/content/web_test/renderer/web_ax_object_proxy.cc
@@ -256,11 +256,7 @@ WebAXObjectProxy::Factory* factory) : accessibility_object_(object), factory_(factory) {} -WebAXObjectProxy::~WebAXObjectProxy() { - // v8::Persistent will leak on destroy, due to the default - // NonCopyablePersistentTraits (it claims this may change in the future). - notification_callback_.Reset(); -} +WebAXObjectProxy::~WebAXObjectProxy() = default; void WebAXObjectProxy::UpdateLayout() { blink::WebAXObject::UpdateLayout(accessibility_object_.GetDocument());
diff --git a/content/web_test/renderer/web_ax_object_proxy.h b/content/web_test/renderer/web_ax_object_proxy.h index 963c1f3e..2560ff2 100644 --- a/content/web_test/renderer/web_ax_object_proxy.h +++ b/content/web_test/renderer/web_ax_object_proxy.h
@@ -241,7 +241,7 @@ blink::WebAXObject accessibility_object_; Factory* factory_; - v8::Persistent<v8::Function> notification_callback_; + v8::Global<v8::Function> notification_callback_; }; class RootWebAXObjectProxy : public WebAXObjectProxy { @@ -264,13 +264,7 @@ v8::Local<v8::Object> GetOrCreate(const blink::WebAXObject&) override; private: - // Defines the Persistents as copyable because v8 does not support moving - // in non-copyable (default) traits either. - using CopyablePersistentObject = - v8::Persistent<v8::Object, v8::CopyablePersistentTraits<v8::Object>>; - // Because the v8::Persistent in this container uses CopyablePersistentObject - // traits, it will not leak on destruction. - std::vector<CopyablePersistentObject> elements_; + std::vector<v8::Global<v8::Object>> elements_; }; } // namespace content
diff --git a/device/bluetooth/floss/floss_manager_client.cc b/device/bluetooth/floss/floss_manager_client.cc index 328bce5c..91519c7 100644 --- a/device/bluetooth/floss/floss_manager_client.cc +++ b/device/bluetooth/floss/floss_manager_client.cc
@@ -17,6 +17,7 @@ #include "base/logging.h" #include "base/observer_list.h" #include "base/strings/stringprintf.h" +#include "base/threading/thread_task_runner_handle.h" #include "dbus/bus.h" #include "dbus/exported_object.h" #include "dbus/message.h" @@ -63,6 +64,35 @@ } // namespace +FlossManagerClient::PoweredCallback::PoweredCallback(ResponseCallback<Void> cb, + int timeout_ms) { + cb_ = std::move(cb); + timeout_ms_ = timeout_ms; +} + +FlossManagerClient::PoweredCallback::~PoweredCallback() = default; + +// static +std::unique_ptr<FlossManagerClient::PoweredCallback> +FlossManagerClient::PoweredCallback::CreateWithTimeout( + ResponseCallback<Void> cb, + int timeout_ms) { + std::unique_ptr<FlossManagerClient::PoweredCallback> self = + std::make_unique<FlossManagerClient::PoweredCallback>(std::move(cb), + timeout_ms); + self->PostDelayedError(); + + return self; +} + +void FlossManagerClient::PoweredCallback::PostDelayedError() { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&PoweredCallback::RunError, + weak_ptr_factory_.GetWeakPtr()), + base::Milliseconds(timeout_ms_)); +} + // static const char FlossManagerClient::kExportedCallbacksPath[] = "/org/chromium/bluetooth/managerclient"; @@ -140,6 +170,10 @@ void FlossManagerClient::SetAdapterEnabled(int adapter, bool enabled, ResponseCallback<Void> callback) { + if (adapter != GetDefaultAdapter()) { + return; + } + dbus::ObjectProxy* object_proxy = bus_->GetObjectProxy(service_name_, dbus::ObjectPath(kManagerObject)); if (!object_proxy) { @@ -155,10 +189,22 @@ dbus::MessageWriter writer(&method_call); writer.AppendInt32(adapter); + powered_callback_ = + PoweredCallback::CreateWithTimeout(std::move(callback), kDBusTimeoutMs); + object_proxy->CallMethodWithErrorResponse( &method_call, kDBusTimeoutMs, - base::BindOnce(&FlossManagerClient::DefaultResponseWithCallback<Void>, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + base::BindOnce(&FlossManagerClient::OnSetAdapterEnabled, + weak_ptr_factory_.GetWeakPtr())); +} + +void FlossManagerClient::OnSetAdapterEnabled( + dbus::Response* response, + dbus::ErrorResponse* error_response) { + // Only handle error cases since non-error called in OnHciEnabledChange + if (powered_callback_ && (!response || error_response)) { + powered_callback_.release()->RunError(); + } } // Register manager client against manager. @@ -360,6 +406,10 @@ return; } + if (adapter == GetDefaultAdapter() && powered_callback_) { + powered_callback_.release()->RunNoError(); + } + adapter_to_powered_[adapter] = enabled; for (auto& observer : observers_) {
diff --git a/device/bluetooth/floss/floss_manager_client.h b/device/bluetooth/floss/floss_manager_client.h index 69a00dd..5d695bb 100644 --- a/device/bluetooth/floss/floss_manager_client.h +++ b/device/bluetooth/floss/floss_manager_client.h
@@ -50,6 +50,33 @@ virtual void AdapterEnabledChanged(int adapter, bool enabled) {} }; + class PoweredCallback { + public: + explicit PoweredCallback(ResponseCallback<Void> cb, int timeout_ms); + ~PoweredCallback(); + + static std::unique_ptr<FlossManagerClient::PoweredCallback> + CreateWithTimeout(ResponseCallback<Void> cb, int timeout_ms); + void RunError() { + if (cb_) { + std::move(cb_).Run( + /*ret=*/absl::nullopt, Error(kErrorNoResponse, std::string())); + } + }; + void RunNoError() { + if (cb_) { + std::move(cb_).Run(/*ret=*/absl::nullopt, /*err=*/absl::nullopt); + } + }; + + private: + void PostDelayedError(); + + ResponseCallback<Void> cb_; + int timeout_ms_; + base::WeakPtrFactory<PoweredCallback> weak_ptr_factory_{this}; + }; + // Convert adapter number to object path. static dbus::ObjectPath GenerateAdapterPath(int adapter); @@ -155,12 +182,19 @@ base::ObserverList<Observer> observers_; private: + // Handle response to SetAdapterEnabled + void OnSetAdapterEnabled(dbus::Response* response, + dbus::ErrorResponse* error_response); + // Object path for exported callbacks registered against manager interface. static const char kExportedCallbacksPath[]; // Floss Manager registers ObjectManager at this path. static const char kObjectManagerPath[]; + // Powered callback called only when adapter actually powers on + std::unique_ptr<PoweredCallback> powered_callback_; + base::WeakPtrFactory<FlossManagerClient> weak_ptr_factory_{this}; };
diff --git a/fuchsia/base/BUILD.gn b/fuchsia/base/BUILD.gn index a665f3c..a50ac34 100644 --- a/fuchsia/base/BUILD.gn +++ b/fuchsia/base/BUILD.gn
@@ -14,7 +14,7 @@ "./test/*", "//chromecast/internal/*", "//fuchsia/engine/*", - "//fuchsia/runners/*", + "//fuchsia_web/runners/*", ] sources = [ "fuchsia_dir_scheme.cc", @@ -44,7 +44,7 @@ "./test/*", "//chromecast/internal/*", "//fuchsia/engine/*", - "//fuchsia/runners/*", + "//fuchsia_web/runners/*", ] sources = [ "agent_impl.cc", @@ -84,7 +84,7 @@ testonly = true visibility = [ "//fuchsia/engine/*", - "//fuchsia/runners/*", + "//fuchsia_web/runners/*", ] sources = [ "run_all_integration_tests.cc" ] deps = [ "//base/test:test_support" ]
diff --git a/fuchsia/engine/BUILD.gn b/fuchsia/engine/BUILD.gn index 4fd4f5e..54fcf93 100644 --- a/fuchsia/engine/BUILD.gn +++ b/fuchsia/engine/BUILD.gn
@@ -337,7 +337,7 @@ # TODO(crbug.com/1022542): SwiftShader is used only in tests. It should # not be included in the WebEngine package. # Whenever this list is updated the exclusions in the cast_runner package - # should be updated as well (see fuchsia/runners/BUILD.gn). + # should be updated as well (see fuchsia_web/runners/BUILD.gn). "lib/libvk_swiftshader.so", "vk_swiftshader_icd.json", ] @@ -443,7 +443,7 @@ ] visibility = [ ":*", - "//fuchsia/runners:*", + "//fuchsia_web/runners:*", ] }
diff --git a/fuchsia_web/BUILD.gn b/fuchsia_web/BUILD.gn index b5cb091..81a6767 100644 --- a/fuchsia_web/BUILD.gn +++ b/fuchsia_web/BUILD.gn
@@ -12,8 +12,8 @@ # they are moved. group("gn_all") { deps = [ + "runners:cast_runner", + "runners:web_runner", "//fuchsia/engine:web_engine", - "//fuchsia/runners:cast_runner", - "//fuchsia/runners:web_runner", ] }
diff --git a/fuchsia/runners/BUILD.gn b/fuchsia_web/runners/BUILD.gn similarity index 100% rename from fuchsia/runners/BUILD.gn rename to fuchsia_web/runners/BUILD.gn
diff --git a/fuchsia/runners/DEPS b/fuchsia_web/runners/DEPS similarity index 100% rename from fuchsia/runners/DEPS rename to fuchsia_web/runners/DEPS
diff --git a/fuchsia/runners/cast/DEPS b/fuchsia_web/runners/cast/DEPS similarity index 100% rename from fuchsia/runners/cast/DEPS rename to fuchsia_web/runners/cast/DEPS
diff --git a/fuchsia/runners/cast/OWNERS b/fuchsia_web/runners/cast/OWNERS similarity index 100% rename from fuchsia/runners/cast/OWNERS rename to fuchsia_web/runners/cast/OWNERS
diff --git a/fuchsia/runners/cast/api_bindings_client.cc b/fuchsia_web/runners/cast/api_bindings_client.cc similarity index 98% rename from fuchsia/runners/cast/api_bindings_client.cc rename to fuchsia_web/runners/cast/api_bindings_client.cc index 2a436a46..699d36147 100644 --- a/fuchsia/runners/cast/api_bindings_client.cc +++ b/fuchsia_web/runners/cast/api_bindings_client.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 "fuchsia/runners/cast/api_bindings_client.h" +#include "fuchsia_web/runners/cast/api_bindings_client.h" #include <utility>
diff --git a/fuchsia/runners/cast/api_bindings_client.h b/fuchsia_web/runners/cast/api_bindings_client.h similarity index 91% rename from fuchsia/runners/cast/api_bindings_client.h rename to fuchsia_web/runners/cast/api_bindings_client.h index 249b899..1a1d48b 100644 --- a/fuchsia/runners/cast/api_bindings_client.h +++ b/fuchsia_web/runners/cast/api_bindings_client.h
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_RUNNERS_CAST_API_BINDINGS_CLIENT_H_ -#define FUCHSIA_RUNNERS_CAST_API_BINDINGS_CLIENT_H_ +#ifndef FUCHSIA_WEB_RUNNERS_CAST_API_BINDINGS_CLIENT_H_ +#define FUCHSIA_WEB_RUNNERS_CAST_API_BINDINGS_CLIENT_H_ #include <fuchsia/web/cpp/fidl.h> #include <vector> #include "components/cast/message_port/message_port.h" #include "components/cast/named_message_port_connector/named_message_port_connector.h" -#include "fuchsia/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" +#include "fuchsia_web/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" #include "third_party/abseil-cpp/absl/types/optional.h" // Injects scripts received from the ApiBindings service, and provides connected @@ -63,4 +63,4 @@ base::OnceClosure on_initialization_complete_; }; -#endif // FUCHSIA_RUNNERS_CAST_API_BINDINGS_CLIENT_H_ +#endif // FUCHSIA_WEB_RUNNERS_CAST_API_BINDINGS_CLIENT_H_
diff --git a/fuchsia/runners/cast/api_bindings_client_browsertest.cc b/fuchsia_web/runners/cast/api_bindings_client_browsertest.cc similarity index 94% rename from fuchsia/runners/cast/api_bindings_client_browsertest.cc rename to fuchsia_web/runners/cast/api_bindings_client_browsertest.cc index b14f1f41..c43511c 100644 --- a/fuchsia/runners/cast/api_bindings_client_browsertest.cc +++ b/fuchsia_web/runners/cast/api_bindings_client_browsertest.cc
@@ -18,10 +18,10 @@ #include "fuchsia/base/test/test_navigation_listener.h" #include "fuchsia/engine/test/frame_for_test.h" #include "fuchsia/engine/test/web_engine_browser_test.h" -#include "fuchsia/runners/cast/api_bindings_client.h" -#include "fuchsia/runners/cast/create_web_message.h" -#include "fuchsia/runners/cast/fake_api_bindings.h" -#include "fuchsia/runners/cast/named_message_port_connector_fuchsia.h" +#include "fuchsia_web/runners/cast/api_bindings_client.h" +#include "fuchsia_web/runners/cast/create_web_message.h" +#include "fuchsia_web/runners/cast/fake_api_bindings.h" +#include "fuchsia_web/runners/cast/named_message_port_connector_fuchsia.h" #include "testing/gtest/include/gtest/gtest.h" namespace { @@ -29,7 +29,7 @@ class ApiBindingsClientTest : public cr_fuchsia::WebEngineBrowserTest { public: ApiBindingsClientTest() : api_service_binding_(&api_service_) { - set_test_server_root(base::FilePath("fuchsia/runners/cast/testdata")); + set_test_server_root(base::FilePath("fuchsia_web/runners/cast/testdata")); } ~ApiBindingsClientTest() override = default;
diff --git a/fuchsia/runners/cast/application_controller_impl.cc b/fuchsia_web/runners/cast/application_controller_impl.cc similarity index 95% rename from fuchsia/runners/cast/application_controller_impl.cc rename to fuchsia_web/runners/cast/application_controller_impl.cc index 414e2ff..f38dcc5 100644 --- a/fuchsia/runners/cast/application_controller_impl.cc +++ b/fuchsia_web/runners/cast/application_controller_impl.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/runners/cast/application_controller_impl.h" +#include "fuchsia_web/runners/cast/application_controller_impl.h" #include <fuchsia/diagnostics/cpp/fidl.h>
diff --git a/fuchsia/runners/cast/application_controller_impl.h b/fuchsia_web/runners/cast/application_controller_impl.h similarity index 82% rename from fuchsia/runners/cast/application_controller_impl.h rename to fuchsia_web/runners/cast/application_controller_impl.h index d4d5de98..2ddd4bbc 100644 --- a/fuchsia/runners/cast/application_controller_impl.h +++ b/fuchsia_web/runners/cast/application_controller_impl.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_RUNNERS_CAST_APPLICATION_CONTROLLER_IMPL_H_ -#define FUCHSIA_RUNNERS_CAST_APPLICATION_CONTROLLER_IMPL_H_ +#ifndef FUCHSIA_WEB_RUNNERS_CAST_APPLICATION_CONTROLLER_IMPL_H_ +#define FUCHSIA_WEB_RUNNERS_CAST_APPLICATION_CONTROLLER_IMPL_H_ #include <fuchsia/diagnostics/cpp/fidl.h> #include <fuchsia/media/sessions2/cpp/fidl.h> @@ -11,7 +11,7 @@ #include <lib/fidl/cpp/binding.h> #include <lib/fidl/cpp/interface_request.h> -#include "fuchsia/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" +#include "fuchsia_web/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" class ApplicationControllerImpl final : public chromium::cast::ApplicationController { @@ -39,4 +39,4 @@ fuchsia::web::Frame* const frame_; }; -#endif // FUCHSIA_RUNNERS_CAST_APPLICATION_CONTROLLER_IMPL_H_ +#endif // FUCHSIA_WEB_RUNNERS_CAST_APPLICATION_CONTROLLER_IMPL_H_
diff --git a/fuchsia/runners/cast/application_controller_impl_unittest.cc b/fuchsia_web/runners/cast/application_controller_impl_unittest.cc similarity index 96% rename from fuchsia/runners/cast/application_controller_impl_unittest.cc rename to fuchsia_web/runners/cast/application_controller_impl_unittest.cc index c40d473..06280026 100644 --- a/fuchsia/runners/cast/application_controller_impl_unittest.cc +++ b/fuchsia_web/runners/cast/application_controller_impl_unittest.cc
@@ -12,8 +12,8 @@ #include "base/test/task_environment.h" #include "base/test/test_future.h" #include "fuchsia/base/test/fit_adapter.h" -#include "fuchsia/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" -#include "fuchsia/runners/cast/application_controller_impl.h" +#include "fuchsia_web/runners/cast/application_controller_impl.h" +#include "fuchsia_web/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/fuchsia/runners/cast/cast_component.cc b/fuchsia_web/runners/cast/cast_component.cc similarity index 96% rename from fuchsia/runners/cast/cast_component.cc rename to fuchsia_web/runners/cast/cast_component.cc index d79c10c..985cb75e 100644 --- a/fuchsia/runners/cast/cast_component.cc +++ b/fuchsia_web/runners/cast/cast_component.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 "fuchsia/runners/cast/cast_component.h" +#include "fuchsia_web/runners/cast/cast_component.h" #include <lib/fidl/cpp/binding.h> #include <lib/ui/scenic/cpp/view_ref_pair.h> @@ -19,11 +19,11 @@ #include "components/cast/message_port/fuchsia/message_port_fuchsia.h" #include "components/cast/message_port/platform_message_port.h" #include "fuchsia/base/agent_manager.h" -#include "fuchsia/runners/cast/cast_runner.h" -#include "fuchsia/runners/cast/cast_streaming.h" -#include "fuchsia/runners/cast/create_web_message.h" -#include "fuchsia/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" -#include "fuchsia/runners/common/web_component.h" +#include "fuchsia_web/runners/cast/cast_runner.h" +#include "fuchsia_web/runners/cast/cast_streaming.h" +#include "fuchsia_web/runners/cast/create_web_message.h" +#include "fuchsia_web/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" +#include "fuchsia_web/runners/common/web_component.h" namespace {
diff --git a/fuchsia/runners/cast/cast_component.h b/fuchsia_web/runners/cast/cast_component.h similarity index 91% rename from fuchsia/runners/cast/cast_component.h rename to fuchsia_web/runners/cast/cast_component.h index 53056c1..cffb3a89 100644 --- a/fuchsia/runners/cast/cast_component.h +++ b/fuchsia_web/runners/cast/cast_component.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_RUNNERS_CAST_CAST_COMPONENT_H_ -#define FUCHSIA_RUNNERS_CAST_CAST_COMPONENT_H_ +#ifndef FUCHSIA_WEB_RUNNERS_CAST_CAST_COMPONENT_H_ +#define FUCHSIA_WEB_RUNNERS_CAST_CAST_COMPONENT_H_ #include <fuchsia/camera3/cpp/fidl.h> #include <fuchsia/legacymetrics/cpp/fidl.h> @@ -20,11 +20,11 @@ #include "base/gtest_prod_util.h" #include "base/message_loop/message_pump_for_io.h" #include "base/message_loop/message_pump_fuchsia.h" -#include "fuchsia/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" -#include "fuchsia/runners/cast/api_bindings_client.h" -#include "fuchsia/runners/cast/application_controller_impl.h" -#include "fuchsia/runners/cast/named_message_port_connector_fuchsia.h" -#include "fuchsia/runners/common/web_component.h" +#include "fuchsia_web/runners/cast/api_bindings_client.h" +#include "fuchsia_web/runners/cast/application_controller_impl.h" +#include "fuchsia_web/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" +#include "fuchsia_web/runners/cast/named_message_port_connector_fuchsia.h" +#include "fuchsia_web/runners/common/web_component.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace cr_fuchsia { @@ -143,4 +143,4 @@ base::MessagePumpForIO::ZxHandleWatchController headless_disconnect_watch_; }; -#endif // FUCHSIA_RUNNERS_CAST_CAST_COMPONENT_H_ +#endif // FUCHSIA_WEB_RUNNERS_CAST_CAST_COMPONENT_H_
diff --git a/fuchsia/runners/cast/cast_runner.cc b/fuchsia_web/runners/cast/cast_runner.cc similarity index 99% rename from fuchsia/runners/cast/cast_runner.cc rename to fuchsia_web/runners/cast/cast_runner.cc index 4edfedc..836d0b6 100644 --- a/fuchsia/runners/cast/cast_runner.cc +++ b/fuchsia_web/runners/cast/cast_runner.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 "fuchsia/runners/cast/cast_runner.h" +#include "fuchsia_web/runners/cast/cast_runner.h" #include <fuchsia/sys/cpp/fidl.h> #include <fuchsia/web/cpp/fidl.h> @@ -28,9 +28,9 @@ #include "components/cast/common/constants.h" #include "components/fuchsia_component_support/config_reader.h" #include "fuchsia/base/agent_manager.h" -#include "fuchsia/runners/cast/cast_streaming.h" -#include "fuchsia/runners/cast/pending_cast_component.h" -#include "fuchsia/runners/common/web_content_runner.h" +#include "fuchsia_web/runners/cast/cast_streaming.h" +#include "fuchsia_web/runners/cast/pending_cast_component.h" +#include "fuchsia_web/runners/common/web_content_runner.h" #include "media/base/media_switches.h" #include "url/gurl.h"
diff --git a/fuchsia/runners/cast/cast_runner.cml b/fuchsia_web/runners/cast/cast_runner.cml similarity index 100% rename from fuchsia/runners/cast/cast_runner.cml rename to fuchsia_web/runners/cast/cast_runner.cml
diff --git a/fuchsia/runners/cast/cast_runner.cmx b/fuchsia_web/runners/cast/cast_runner.cmx similarity index 100% rename from fuchsia/runners/cast/cast_runner.cmx rename to fuchsia_web/runners/cast/cast_runner.cmx
diff --git a/fuchsia/runners/cast/cast_runner.h b/fuchsia_web/runners/cast/cast_runner.h similarity index 95% rename from fuchsia/runners/cast/cast_runner.h rename to fuchsia_web/runners/cast/cast_runner.h index 49db9e0..d6946c41 100644 --- a/fuchsia/runners/cast/cast_runner.h +++ b/fuchsia_web/runners/cast/cast_runner.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_RUNNERS_CAST_CAST_RUNNER_H_ -#define FUCHSIA_RUNNERS_CAST_CAST_RUNNER_H_ +#ifndef FUCHSIA_WEB_RUNNERS_CAST_CAST_RUNNER_H_ +#define FUCHSIA_WEB_RUNNERS_CAST_CAST_RUNNER_H_ #include <fuchsia/camera3/cpp/fidl.h> #include <fuchsia/legacymetrics/cpp/fidl.h> @@ -18,10 +18,10 @@ #include "base/containers/flat_set.h" #include "base/containers/unique_ptr_adapters.h" #include "base/fuchsia/startup_context.h" -#include "fuchsia/runners/cast/cast_component.h" -#include "fuchsia/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" -#include "fuchsia/runners/cast/pending_cast_component.h" -#include "fuchsia/runners/common/web_content_runner.h" +#include "fuchsia_web/runners/cast/cast_component.h" +#include "fuchsia_web/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" +#include "fuchsia_web/runners/cast/pending_cast_component.h" +#include "fuchsia_web/runners/common/web_content_runner.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace base { @@ -193,4 +193,4 @@ bool was_cache_sentinel_created_ = false; }; -#endif // FUCHSIA_RUNNERS_CAST_CAST_RUNNER_H_ +#endif // FUCHSIA_WEB_RUNNERS_CAST_CAST_RUNNER_H_
diff --git a/fuchsia/runners/cast/cast_runner_integration_test.cc b/fuchsia_web/runners/cast/cast_runner_integration_test.cc similarity index 98% rename from fuchsia/runners/cast/cast_runner_integration_test.cc rename to fuchsia_web/runners/cast/cast_runner_integration_test.cc index 6b7fa8b..9fbd02a 100644 --- a/fuchsia/runners/cast/cast_runner_integration_test.cc +++ b/fuchsia_web/runners/cast/cast_runner_integration_test.cc
@@ -49,11 +49,11 @@ #include "fuchsia/base/test/frame_test_util.h" #include "fuchsia/base/test/test_devtools_list_fetcher.h" #include "fuchsia/base/test/url_request_rewrite_test_util.h" -#include "fuchsia/runners/cast/cast_runner.h" -#include "fuchsia/runners/cast/cast_runner_switches.h" -#include "fuchsia/runners/cast/fake_api_bindings.h" -#include "fuchsia/runners/cast/fake_application_config_manager.h" -#include "fuchsia/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" +#include "fuchsia_web/runners/cast/cast_runner.h" +#include "fuchsia_web/runners/cast/cast_runner_switches.h" +#include "fuchsia_web/runners/cast/fake_api_bindings.h" +#include "fuchsia_web/runners/cast/fake_application_config_manager.h" +#include "fuchsia_web/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" #include "media/fuchsia/audio/fake_audio_device_enumerator.h" #include "net/test/embedded_test_server/default_handlers.h" #include "net/test/embedded_test_server/http_request.h" @@ -67,7 +67,7 @@ constexpr char kBlankAppUrl[] = "/defaultresponse"; constexpr char kEchoHeaderPath[] = "/echoheader?Test"; -constexpr char kTestServerRoot[] = "fuchsia/runners/cast/testdata"; +constexpr char kTestServerRoot[] = "fuchsia_web/runners/cast/testdata"; constexpr char kDummyAgentUrl[] = "fuchsia-pkg://fuchsia.com/dummy_agent#meta/dummy_agent.cmx"; @@ -334,7 +334,7 @@ ASSERT_TRUE( base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &pkg_path)); provider.set_directory(base::OpenDirectoryHandle( - pkg_path.AppendASCII("fuchsia/runners/cast/testdata"))); + pkg_path.AppendASCII("fuchsia_web/runners/cast/testdata"))); std::vector<fuchsia::web::ContentDirectoryProvider> providers; providers.emplace_back(std::move(provider));
diff --git a/fuchsia/runners/cast/cast_runner_switches.cc b/fuchsia_web/runners/cast/cast_runner_switches.cc similarity index 85% rename from fuchsia/runners/cast/cast_runner_switches.cc rename to fuchsia_web/runners/cast/cast_runner_switches.cc index f207f2f..1224604 100644 --- a/fuchsia/runners/cast/cast_runner_switches.cc +++ b/fuchsia_web/runners/cast/cast_runner_switches.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 "fuchsia/runners/cast/cast_runner_switches.h" +#include "fuchsia_web/runners/cast/cast_runner_switches.h" const char kDisableVulkanForTestsSwitch[] = "disable-vulkan-for-tests";
diff --git a/fuchsia/runners/cast/cast_runner_switches.h b/fuchsia_web/runners/cast/cast_runner_switches.h similarity index 73% rename from fuchsia/runners/cast/cast_runner_switches.h rename to fuchsia_web/runners/cast/cast_runner_switches.h index b7d9a63..3662a0e 100644 --- a/fuchsia/runners/cast/cast_runner_switches.h +++ b/fuchsia_web/runners/cast/cast_runner_switches.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_RUNNERS_CAST_CAST_RUNNER_SWITCHES_H_ -#define FUCHSIA_RUNNERS_CAST_CAST_RUNNER_SWITCHES_H_ +#ifndef FUCHSIA_WEB_RUNNERS_CAST_CAST_RUNNER_SWITCHES_H_ +#define FUCHSIA_WEB_RUNNERS_CAST_CAST_RUNNER_SWITCHES_H_ // Disable Vulkan flag for the cast runner. Used for tests. extern const char kDisableVulkanForTestsSwitch[]; @@ -15,4 +15,4 @@ // Force headless mode. extern const char kForceHeadlessForTestsSwitch[]; -#endif // FUCHSIA_RUNNERS_CAST_CAST_RUNNER_SWITCHES_H_ +#endif // FUCHSIA_WEB_RUNNERS_CAST_CAST_RUNNER_SWITCHES_H_
diff --git a/fuchsia/runners/cast/cast_streaming.cc b/fuchsia_web/runners/cast/cast_streaming.cc similarity index 95% rename from fuchsia/runners/cast/cast_streaming.cc rename to fuchsia_web/runners/cast/cast_streaming.cc index 765e995..d2af03bd 100644 --- a/fuchsia/runners/cast/cast_streaming.cc +++ b/fuchsia_web/runners/cast/cast_streaming.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 "fuchsia/runners/cast/cast_streaming.h" +#include "fuchsia_web/runners/cast/cast_streaming.h" #include <string> @@ -14,7 +14,7 @@ namespace { constexpr char kCastStreamingAppUrl[] = "cast-streaming:receiver"; -constexpr char kCastDataDirectory[] = "fuchsia/runners/cast/data"; +constexpr char kCastDataDirectory[] = "fuchsia_web/runners/cast/data"; constexpr char kCastStreamingContentDirectoryName[] = "cast-streaming"; constexpr char kCastStreamingMessagePortOrigin[] = "cast-streaming:receiver"; constexpr char kCastStreamingVideoOnlyMessagePortOrigin[] =
diff --git a/fuchsia/runners/cast/cast_streaming.h b/fuchsia_web/runners/cast/cast_streaming.h similarity index 81% rename from fuchsia/runners/cast/cast_streaming.h rename to fuchsia_web/runners/cast/cast_streaming.h index d55dbc9f..fbad9b8 100644 --- a/fuchsia/runners/cast/cast_streaming.h +++ b/fuchsia_web/runners/cast/cast_streaming.h
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_RUNNERS_CAST_CAST_STREAMING_H_ -#define FUCHSIA_RUNNERS_CAST_CAST_STREAMING_H_ +#ifndef FUCHSIA_WEB_RUNNERS_CAST_CAST_STREAMING_H_ +#define FUCHSIA_WEB_RUNNERS_CAST_CAST_STREAMING_H_ #include <fuchsia/web/cpp/fidl.h> #include "base/callback.h" #include "base/strings/string_piece.h" -#include "fuchsia/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" +#include "fuchsia_web/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" // TODO(crbug.com/1082821): Remove unused methods here once the // Cast Streaming Receiver component has been implemented. @@ -30,4 +30,4 @@ // Returns the proper origin value for the MessagePort for |app_id|. std::string GetMessagePortOriginForAppId(const std::string& app_id); -#endif // FUCHSIA_RUNNERS_CAST_CAST_STREAMING_H_ +#endif // FUCHSIA_WEB_RUNNERS_CAST_CAST_STREAMING_H_
diff --git a/fuchsia/runners/cast/create_web_message.cc b/fuchsia_web/runners/cast/create_web_message.cc similarity index 94% rename from fuchsia/runners/cast/create_web_message.cc rename to fuchsia_web/runners/cast/create_web_message.cc index c850bbfc..c1457f5 100644 --- a/fuchsia/runners/cast/create_web_message.cc +++ b/fuchsia_web/runners/cast/create_web_message.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 "fuchsia/runners/cast/create_web_message.h" +#include "fuchsia_web/runners/cast/create_web_message.h" #include "base/fuchsia/mem_buffer_util.h" #include "components/cast/message_port/fuchsia/message_port_fuchsia.h"
diff --git a/fuchsia/runners/cast/create_web_message.h b/fuchsia_web/runners/cast/create_web_message.h similarity index 77% rename from fuchsia/runners/cast/create_web_message.h rename to fuchsia_web/runners/cast/create_web_message.h index 0be842d..3c63e24 100644 --- a/fuchsia/runners/cast/create_web_message.h +++ b/fuchsia_web/runners/cast/create_web_message.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_RUNNERS_CAST_CREATE_WEB_MESSAGE_H_ -#define FUCHSIA_RUNNERS_CAST_CREATE_WEB_MESSAGE_H_ +#ifndef FUCHSIA_WEB_RUNNERS_CAST_CREATE_WEB_MESSAGE_H_ +#define FUCHSIA_WEB_RUNNERS_CAST_CREATE_WEB_MESSAGE_H_ #include <fuchsia/web/cpp/fidl.h> #include <memory> @@ -17,4 +17,4 @@ base::StringPiece message, std::unique_ptr<cast_api_bindings::MessagePort> port); -#endif // FUCHSIA_RUNNERS_CAST_CREATE_WEB_MESSAGE_H_ +#endif // FUCHSIA_WEB_RUNNERS_CAST_CREATE_WEB_MESSAGE_H_
diff --git a/fuchsia/runners/cast/data/receiver.html b/fuchsia_web/runners/cast/data/receiver.html similarity index 100% rename from fuchsia/runners/cast/data/receiver.html rename to fuchsia_web/runners/cast/data/receiver.html
diff --git a/fuchsia/runners/cast/fake_api_bindings.cc b/fuchsia_web/runners/cast/fake_api_bindings.cc similarity index 96% rename from fuchsia/runners/cast/fake_api_bindings.cc rename to fuchsia_web/runners/cast/fake_api_bindings.cc index c7c17695..2940321 100644 --- a/fuchsia/runners/cast/fake_api_bindings.cc +++ b/fuchsia_web/runners/cast/fake_api_bindings.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 "fuchsia/runners/cast/fake_api_bindings.h" +#include "fuchsia_web/runners/cast/fake_api_bindings.h" #include "base/auto_reset.h" #include "base/fuchsia/fuchsia_logging.h"
diff --git a/fuchsia/runners/cast/fake_api_bindings.h b/fuchsia_web/runners/cast/fake_api_bindings.h similarity index 89% rename from fuchsia/runners/cast/fake_api_bindings.h rename to fuchsia_web/runners/cast/fake_api_bindings.h index 5f8a183..a1d571b 100644 --- a/fuchsia/runners/cast/fake_api_bindings.h +++ b/fuchsia_web/runners/cast/fake_api_bindings.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_RUNNERS_CAST_FAKE_API_BINDINGS_H_ -#define FUCHSIA_RUNNERS_CAST_FAKE_API_BINDINGS_H_ +#ifndef FUCHSIA_WEB_RUNNERS_CAST_FAKE_API_BINDINGS_H_ +#define FUCHSIA_WEB_RUNNERS_CAST_FAKE_API_BINDINGS_H_ #include <string> #include <utility> @@ -12,7 +12,7 @@ #include "base/callback.h" #include "base/containers/flat_map.h" #include "base/strings/string_piece.h" -#include "fuchsia/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" +#include "fuchsia_web/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" // Simple implementation of the ApiBindings service, for use by tests. class FakeApiBindingsImpl : public chromium::cast::ApiBindings { @@ -55,4 +55,4 @@ base::OnceClosure on_expected_port_received_; }; -#endif // FUCHSIA_RUNNERS_CAST_FAKE_API_BINDINGS_H_ +#endif // FUCHSIA_WEB_RUNNERS_CAST_FAKE_API_BINDINGS_H_
diff --git a/fuchsia/runners/cast/fake_application_config_manager.cc b/fuchsia_web/runners/cast/fake_application_config_manager.cc similarity index 93% rename from fuchsia/runners/cast/fake_application_config_manager.cc rename to fuchsia_web/runners/cast/fake_application_config_manager.cc index b56c5bb..eb05824 100644 --- a/fuchsia/runners/cast/fake_application_config_manager.cc +++ b/fuchsia_web/runners/cast/fake_application_config_manager.cc
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fuchsia/runners/cast/fake_application_config_manager.h" +#include "fuchsia_web/runners/cast/fake_application_config_manager.h" #include <string> #include <utility> #include "base/logging.h" -#include "fuchsia/runners/cast/cast_component.h" +#include "fuchsia_web/runners/cast/cast_component.h" constexpr char FakeApplicationConfigManager::kFakeAgentUrl[] = "fuchsia-pkg://fuchsia.com/fake_agent#meta/fake_agent.cmx";
diff --git a/fuchsia/runners/cast/fake_application_config_manager.h b/fuchsia_web/runners/cast/fake_application_config_manager.h similarity index 84% rename from fuchsia/runners/cast/fake_application_config_manager.h rename to fuchsia_web/runners/cast/fake_application_config_manager.h index 1b85fc90..a3a5b9c 100644 --- a/fuchsia/runners/cast/fake_application_config_manager.h +++ b/fuchsia_web/runners/cast/fake_application_config_manager.h
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_RUNNERS_CAST_FAKE_APPLICATION_CONFIG_MANAGER_H_ -#define FUCHSIA_RUNNERS_CAST_FAKE_APPLICATION_CONFIG_MANAGER_H_ +#ifndef FUCHSIA_WEB_RUNNERS_CAST_FAKE_APPLICATION_CONFIG_MANAGER_H_ +#define FUCHSIA_WEB_RUNNERS_CAST_FAKE_APPLICATION_CONFIG_MANAGER_H_ #include <map> #include <string> #include <vector> -#include "fuchsia/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" +#include "fuchsia_web/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" #include "url/gurl.h" // Test cast.ApplicationConfigManager implementation which maps a test Cast @@ -47,4 +47,4 @@ std::map<std::string, chromium::cast::ApplicationConfig> id_to_config_; }; -#endif // FUCHSIA_RUNNERS_CAST_FAKE_APPLICATION_CONFIG_MANAGER_H_ +#endif // FUCHSIA_WEB_RUNNERS_CAST_FAKE_APPLICATION_CONFIG_MANAGER_H_
diff --git a/fuchsia/runners/cast/fidl/BUILD.gn b/fuchsia_web/runners/cast/fidl/BUILD.gn similarity index 88% rename from fuchsia/runners/cast/fidl/BUILD.gn rename to fuchsia_web/runners/cast/fidl/BUILD.gn index ff07b77..63edb42 100644 --- a/fuchsia/runners/cast/fidl/BUILD.gn +++ b/fuchsia_web/runners/cast/fidl/BUILD.gn
@@ -26,7 +26,7 @@ visibility = [ "//chromecast/bindings:*", "//chromecast/internal/*", - "//fuchsia/runners:cast_runner_core", - "//fuchsia/runners:cast_runner_test_core", + "//fuchsia_web/runners:cast_runner_core", + "//fuchsia_web/runners:cast_runner_test_core", ] }
diff --git a/fuchsia/runners/cast/fidl/OWNERS b/fuchsia_web/runners/cast/fidl/OWNERS similarity index 100% rename from fuchsia/runners/cast/fidl/OWNERS rename to fuchsia_web/runners/cast/fidl/OWNERS
diff --git a/fuchsia/runners/cast/fidl/api_bindings.fidl b/fuchsia_web/runners/cast/fidl/api_bindings.fidl similarity index 100% rename from fuchsia/runners/cast/fidl/api_bindings.fidl rename to fuchsia_web/runners/cast/fidl/api_bindings.fidl
diff --git a/fuchsia/runners/cast/fidl/application_config.fidl b/fuchsia_web/runners/cast/fidl/application_config.fidl similarity index 100% rename from fuchsia/runners/cast/fidl/application_config.fidl rename to fuchsia_web/runners/cast/fidl/application_config.fidl
diff --git a/fuchsia/runners/cast/fidl/application_context.fidl b/fuchsia_web/runners/cast/fidl/application_context.fidl similarity index 100% rename from fuchsia/runners/cast/fidl/application_context.fidl rename to fuchsia_web/runners/cast/fidl/application_context.fidl
diff --git a/fuchsia/runners/cast/fidl/application_controller.fidl b/fuchsia_web/runners/cast/fidl/application_controller.fidl similarity index 100% rename from fuchsia/runners/cast/fidl/application_controller.fidl rename to fuchsia_web/runners/cast/fidl/application_controller.fidl
diff --git a/fuchsia/runners/cast/fidl/cors_exempt_headers.fidl b/fuchsia_web/runners/cast/fidl/cors_exempt_headers.fidl similarity index 100% rename from fuchsia/runners/cast/fidl/cors_exempt_headers.fidl rename to fuchsia_web/runners/cast/fidl/cors_exempt_headers.fidl
diff --git a/fuchsia/runners/cast/fidl/data_reset.fidl b/fuchsia_web/runners/cast/fidl/data_reset.fidl similarity index 100% rename from fuchsia/runners/cast/fidl/data_reset.fidl rename to fuchsia_web/runners/cast/fidl/data_reset.fidl
diff --git a/fuchsia/runners/cast/fidl/url_request_rewriter.fidl b/fuchsia_web/runners/cast/fidl/url_request_rewriter.fidl similarity index 100% rename from fuchsia/runners/cast/fidl/url_request_rewriter.fidl rename to fuchsia_web/runners/cast/fidl/url_request_rewriter.fidl
diff --git a/fuchsia/runners/cast/main.cc b/fuchsia_web/runners/cast/main.cc similarity index 97% rename from fuchsia/runners/cast/main.cc rename to fuchsia_web/runners/cast/main.cc index c84ece3..aadaaac 100644 --- a/fuchsia/runners/cast/main.cc +++ b/fuchsia_web/runners/cast/main.cc
@@ -26,8 +26,8 @@ #include "fuchsia/base/fuchsia_dir_scheme.h" #include "fuchsia/base/init_logging.h" #include "fuchsia/engine/web_instance_host/web_instance_host.h" -#include "fuchsia/runners/cast/cast_runner.h" -#include "fuchsia/runners/cast/cast_runner_switches.h" +#include "fuchsia_web/runners/cast/cast_runner.h" +#include "fuchsia_web/runners/cast/cast_runner_switches.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace {
diff --git a/fuchsia/runners/cast/named_message_port_connector_fuchsia.cc b/fuchsia_web/runners/cast/named_message_port_connector_fuchsia.cc similarity index 96% rename from fuchsia/runners/cast/named_message_port_connector_fuchsia.cc rename to fuchsia_web/runners/cast/named_message_port_connector_fuchsia.cc index fdcfa74f..2d4bb718 100644 --- a/fuchsia/runners/cast/named_message_port_connector_fuchsia.cc +++ b/fuchsia_web/runners/cast/named_message_port_connector_fuchsia.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 "fuchsia/runners/cast/named_message_port_connector_fuchsia.h" +#include "fuchsia_web/runners/cast/named_message_port_connector_fuchsia.h" #include <fuchsia/mem/cpp/fidl.h> #include <fuchsia/web/cpp/fidl.h>
diff --git a/fuchsia/runners/cast/named_message_port_connector_fuchsia.h b/fuchsia_web/runners/cast/named_message_port_connector_fuchsia.h similarity index 82% rename from fuchsia/runners/cast/named_message_port_connector_fuchsia.h rename to fuchsia_web/runners/cast/named_message_port_connector_fuchsia.h index 75742a5..edba48d 100644 --- a/fuchsia/runners/cast/named_message_port_connector_fuchsia.h +++ b/fuchsia_web/runners/cast/named_message_port_connector_fuchsia.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_RUNNERS_CAST_NAMED_MESSAGE_PORT_CONNECTOR_FUCHSIA_H_ -#define FUCHSIA_RUNNERS_CAST_NAMED_MESSAGE_PORT_CONNECTOR_FUCHSIA_H_ +#ifndef FUCHSIA_WEB_RUNNERS_CAST_NAMED_MESSAGE_PORT_CONNECTOR_FUCHSIA_H_ +#define FUCHSIA_WEB_RUNNERS_CAST_NAMED_MESSAGE_PORT_CONNECTOR_FUCHSIA_H_ #include "components/cast/named_message_port_connector/named_message_port_connector.h" @@ -33,4 +33,4 @@ fuchsia::web::Frame* frame_ = nullptr; }; -#endif // FUCHSIA_RUNNERS_CAST_NAMED_MESSAGE_PORT_CONNECTOR_FUCHSIA_H_ +#endif // FUCHSIA_WEB_RUNNERS_CAST_NAMED_MESSAGE_PORT_CONNECTOR_FUCHSIA_H_
diff --git a/fuchsia/runners/cast/named_message_port_connector_fuchsia_browsertest.cc b/fuchsia_web/runners/cast/named_message_port_connector_fuchsia_browsertest.cc similarity index 96% rename from fuchsia/runners/cast/named_message_port_connector_fuchsia_browsertest.cc rename to fuchsia_web/runners/cast/named_message_port_connector_fuchsia_browsertest.cc index 250624c8..ddbc6e8 100644 --- a/fuchsia/runners/cast/named_message_port_connector_fuchsia_browsertest.cc +++ b/fuchsia_web/runners/cast/named_message_port_connector_fuchsia_browsertest.cc
@@ -15,8 +15,8 @@ #include "fuchsia/base/test/test_navigation_listener.h" #include "fuchsia/engine/test/frame_for_test.h" #include "fuchsia/engine/test/web_engine_browser_test.h" -#include "fuchsia/runners/cast/create_web_message.h" -#include "fuchsia/runners/cast/named_message_port_connector_fuchsia.h" +#include "fuchsia_web/runners/cast/create_web_message.h" +#include "fuchsia_web/runners/cast/named_message_port_connector_fuchsia.h" #include "testing/gmock/include/gmock/gmock-matchers.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -30,7 +30,7 @@ : public cr_fuchsia::WebEngineBrowserTest { public: NamedMessagePortConnectorFuchsiaTest() { - set_test_server_root(base::FilePath("fuchsia/runners/cast/testdata")); + set_test_server_root(base::FilePath("fuchsia_web/runners/cast/testdata")); } ~NamedMessagePortConnectorFuchsiaTest() override = default;
diff --git a/fuchsia/runners/cast/pending_cast_component.cc b/fuchsia_web/runners/cast/pending_cast_component.cc similarity index 98% rename from fuchsia/runners/cast/pending_cast_component.cc rename to fuchsia_web/runners/cast/pending_cast_component.cc index bf5e60f8..ae97e50 100644 --- a/fuchsia/runners/cast/pending_cast_component.cc +++ b/fuchsia_web/runners/cast/pending_cast_component.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 "fuchsia/runners/cast/pending_cast_component.h" +#include "fuchsia_web/runners/cast/pending_cast_component.h" #include "base/bind.h" #include "base/check.h"
diff --git a/fuchsia/runners/cast/pending_cast_component.h b/fuchsia_web/runners/cast/pending_cast_component.h similarity index 89% rename from fuchsia/runners/cast/pending_cast_component.h rename to fuchsia_web/runners/cast/pending_cast_component.h index 86c61b5..b124b74d 100644 --- a/fuchsia/runners/cast/pending_cast_component.h +++ b/fuchsia_web/runners/cast/pending_cast_component.h
@@ -2,16 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_RUNNERS_CAST_PENDING_CAST_COMPONENT_H_ -#define FUCHSIA_RUNNERS_CAST_PENDING_CAST_COMPONENT_H_ +#ifndef FUCHSIA_WEB_RUNNERS_CAST_PENDING_CAST_COMPONENT_H_ +#define FUCHSIA_WEB_RUNNERS_CAST_PENDING_CAST_COMPONENT_H_ #include <fuchsia/sys/cpp/fidl.h> #include <lib/fidl/cpp/interface_request.h> #include <memory> #include "base/strings/string_piece.h" -#include "fuchsia/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" -#include "fuchsia/runners/cast/cast_component.h" +#include "fuchsia_web/runners/cast/cast_component.h" +#include "fuchsia_web/runners/cast/fidl/fidl/chromium/cast/cpp/fidl.h" namespace base { class StartupContext; @@ -76,4 +76,4 @@ chromium::cast::ApplicationConfigManagerPtr application_config_manager_; }; -#endif // FUCHSIA_RUNNERS_CAST_PENDING_CAST_COMPONENT_H_ +#endif // FUCHSIA_WEB_RUNNERS_CAST_PENDING_CAST_COMPONENT_H_
diff --git a/fuchsia/runners/cast/testdata/camera.html b/fuchsia_web/runners/cast/testdata/camera.html similarity index 100% rename from fuchsia/runners/cast/testdata/camera.html rename to fuchsia_web/runners/cast/testdata/camera.html
diff --git a/fuchsia/runners/cast/testdata/connector.html b/fuchsia_web/runners/cast/testdata/connector.html similarity index 100% rename from fuchsia/runners/cast/testdata/connector.html rename to fuchsia_web/runners/cast/testdata/connector.html
diff --git a/fuchsia/runners/cast/testdata/connector_multiple_ports.html b/fuchsia_web/runners/cast/testdata/connector_multiple_ports.html similarity index 100% rename from fuchsia/runners/cast/testdata/connector_multiple_ports.html rename to fuchsia_web/runners/cast/testdata/connector_multiple_ports.html
diff --git a/fuchsia/runners/cast/testdata/css_animation.html b/fuchsia_web/runners/cast/testdata/css_animation.html similarity index 100% rename from fuchsia/runners/cast/testdata/css_animation.html rename to fuchsia_web/runners/cast/testdata/css_animation.html
diff --git a/fuchsia/runners/cast/testdata/echo.html b/fuchsia_web/runners/cast/testdata/echo.html similarity index 100% rename from fuchsia/runners/cast/testdata/echo.html rename to fuchsia_web/runners/cast/testdata/echo.html
diff --git a/fuchsia/runners/cast/testdata/empty.html b/fuchsia_web/runners/cast/testdata/empty.html similarity index 100% rename from fuchsia/runners/cast/testdata/empty.html rename to fuchsia_web/runners/cast/testdata/empty.html
diff --git a/fuchsia/runners/cast/testdata/microphone.html b/fuchsia_web/runners/cast/testdata/microphone.html similarity index 100% rename from fuchsia/runners/cast/testdata/microphone.html rename to fuchsia_web/runners/cast/testdata/microphone.html
diff --git a/fuchsia/runners/cast/testdata/webgl_presence.html b/fuchsia_web/runners/cast/testdata/webgl_presence.html similarity index 100% rename from fuchsia/runners/cast/testdata/webgl_presence.html rename to fuchsia_web/runners/cast/testdata/webgl_presence.html
diff --git a/fuchsia/runners/common/web_component.cc b/fuchsia_web/runners/common/web_component.cc similarity index 98% rename from fuchsia/runners/common/web_component.cc rename to fuchsia_web/runners/common/web_component.cc index c8e9aaf..a417909 100644 --- a/fuchsia/runners/common/web_component.cc +++ b/fuchsia_web/runners/common/web_component.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 "fuchsia/runners/common/web_component.h" +#include "fuchsia_web/runners/common/web_component.h" #include <fuchsia/ui/views/cpp/fidl.h> #include <lib/fit/function.h> @@ -13,7 +13,7 @@ #include "base/fuchsia/fuchsia_logging.h" #include "base/logging.h" #include "base/strings/string_piece.h" -#include "fuchsia/runners/common/web_content_runner.h" +#include "fuchsia_web/runners/common/web_content_runner.h" WebComponent::WebComponent( base::StringPiece debug_name,
diff --git a/fuchsia/runners/common/web_component.h b/fuchsia_web/runners/common/web_component.h similarity index 97% rename from fuchsia/runners/common/web_component.h rename to fuchsia_web/runners/common/web_component.h index 45c828c..f1968dd 100644 --- a/fuchsia/runners/common/web_component.h +++ b/fuchsia_web/runners/common/web_component.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_RUNNERS_COMMON_WEB_COMPONENT_H_ -#define FUCHSIA_RUNNERS_COMMON_WEB_COMPONENT_H_ +#ifndef FUCHSIA_WEB_RUNNERS_COMMON_WEB_COMPONENT_H_ +#define FUCHSIA_WEB_RUNNERS_COMMON_WEB_COMPONENT_H_ #include <fuchsia/modular/cpp/fidl.h> #include <fuchsia/sys/cpp/fidl.h> @@ -143,4 +143,4 @@ navigation_listener_binding_; }; -#endif // FUCHSIA_RUNNERS_COMMON_WEB_COMPONENT_H_ +#endif // FUCHSIA_WEB_RUNNERS_COMMON_WEB_COMPONENT_H_
diff --git a/fuchsia/runners/common/web_content_runner.cc b/fuchsia_web/runners/common/web_content_runner.cc similarity index 97% rename from fuchsia/runners/common/web_content_runner.cc rename to fuchsia_web/runners/common/web_content_runner.cc index b07f2de..8384bdc 100644 --- a/fuchsia/runners/common/web_content_runner.cc +++ b/fuchsia_web/runners/common/web_content_runner.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 "fuchsia/runners/common/web_content_runner.h" +#include "fuchsia_web/runners/common/web_content_runner.h" #include <fuchsia/sys/cpp/fidl.h> #include <lib/fdio/directory.h> @@ -23,8 +23,8 @@ #include "base/logging.h" #include "base/strings/stringprintf.h" #include "fuchsia/engine/web_instance_host/web_instance_host.h" -#include "fuchsia/runners/buildflags.h" -#include "fuchsia/runners/common/web_component.h" +#include "fuchsia_web/runners/buildflags.h" +#include "fuchsia_web/runners/common/web_component.h" #include "url/gurl.h" namespace {
diff --git a/fuchsia/runners/common/web_content_runner.h b/fuchsia_web/runners/common/web_content_runner.h similarity index 96% rename from fuchsia/runners/common/web_content_runner.h rename to fuchsia_web/runners/common/web_content_runner.h index e13865f..cf9e3ea9 100644 --- a/fuchsia/runners/common/web_content_runner.h +++ b/fuchsia_web/runners/common/web_content_runner.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FUCHSIA_RUNNERS_COMMON_WEB_CONTENT_RUNNER_H_ -#define FUCHSIA_RUNNERS_COMMON_WEB_CONTENT_RUNNER_H_ +#ifndef FUCHSIA_WEB_RUNNERS_COMMON_WEB_CONTENT_RUNNER_H_ +#define FUCHSIA_WEB_RUNNERS_COMMON_WEB_CONTENT_RUNNER_H_ #include <fuchsia/io/cpp/fidl.h> #include <fuchsia/sys/cpp/fidl.h> @@ -124,4 +124,4 @@ base::OnceClosure on_empty_callback_; }; -#endif // FUCHSIA_RUNNERS_COMMON_WEB_CONTENT_RUNNER_H_ +#endif // FUCHSIA_WEB_RUNNERS_COMMON_WEB_CONTENT_RUNNER_H_
diff --git a/fuchsia/runners/web/DEPS b/fuchsia_web/runners/web/DEPS similarity index 100% rename from fuchsia/runners/web/DEPS rename to fuchsia_web/runners/web/DEPS
diff --git a/fuchsia/runners/web/OWNERS b/fuchsia_web/runners/web/OWNERS similarity index 100% rename from fuchsia/runners/web/OWNERS rename to fuchsia_web/runners/web/OWNERS
diff --git a/fuchsia/runners/web/main.cc b/fuchsia_web/runners/web/main.cc similarity index 96% rename from fuchsia/runners/web/main.cc rename to fuchsia_web/runners/web/main.cc index c473c29..3ce02a0 100644 --- a/fuchsia/runners/web/main.cc +++ b/fuchsia_web/runners/web/main.cc
@@ -17,8 +17,8 @@ #include "fuchsia/base/fuchsia_dir_scheme.h" #include "fuchsia/base/init_logging.h" #include "fuchsia/engine/web_instance_host/web_instance_host.h" -#include "fuchsia/runners/buildflags.h" -#include "fuchsia/runners/common/web_content_runner.h" +#include "fuchsia_web/runners/buildflags.h" +#include "fuchsia_web/runners/common/web_content_runner.h" namespace {
diff --git a/fuchsia/runners/web/web_runner.cmx b/fuchsia_web/runners/web/web_runner.cmx similarity index 100% rename from fuchsia/runners/web/web_runner.cmx rename to fuchsia_web/runners/web/web_runner.cmx
diff --git a/fuchsia/runners/web/web_runner_smoke_test.cc b/fuchsia_web/runners/web/web_runner_smoke_test.cc similarity index 100% rename from fuchsia/runners/web/web_runner_smoke_test.cc rename to fuchsia_web/runners/web/web_runner_smoke_test.cc
diff --git a/headless/BUILD.gn b/headless/BUILD.gn index f0291b82..a6e8bfd7 100644 --- a/headless/BUILD.gn +++ b/headless/BUILD.gn
@@ -239,24 +239,6 @@ ] } -if (headless_fontconfig_utils && !is_fuchsia) { - static_library("headless_fontconfig_utils") { - sources = [ - "public/headless_export.h", - "public/util/fontconfig.cc", - "public/util/fontconfig.h", - ] - - deps = [ - "//base", - "//build/config/freetype", - "//third_party/fontconfig", - ] - - configs += [ ":inside_headless_component" ] - } -} - inspector_protocol_generate("protocol_sources") { visibility = [ ":backend_cdp_bindings", @@ -624,10 +606,6 @@ deps += [ "//device/bluetooth" ] } - if (headless_fontconfig_utils && !is_fuchsia) { - deps += [ ":headless_fontconfig_utils" ] - } - configs += [ ":inside_headless_component" ] configs += [ ":headless_defines_config" ] }
diff --git a/headless/headless.gni b/headless/headless.gni index 11b102d..11aed66a 100644 --- a/headless/headless.gni +++ b/headless/headless.gni
@@ -6,9 +6,6 @@ # Embed resource.pak file into the binary for easier distribution. headless_use_embedded_resources = false - # Provide bindings for font loading for headless embedders. - headless_fontconfig_utils = false - # Use Prefs component to access Local State and other preferences. headless_use_prefs = true
diff --git a/headless/public/util/fontconfig.cc b/headless/public/util/fontconfig.cc deleted file mode 100644 index ef0f2ba..0000000 --- a/headless/public/util/fontconfig.cc +++ /dev/null
@@ -1,121 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "headless/public/util/fontconfig.h" - -// Should be included before freetype.h. -#include <ft2build.h> - -#include <dirent.h> -#include <fontconfig/fontconfig.h> -#include <freetype/freetype.h> -#include <set> -#include <string> - -#include "base/check.h" -#include "base/check_op.h" -#include "base/logging.h" - -namespace headless { -namespace { -void GetFontFileNames(const FcFontSet* font_set, - std::set<std::string>* file_names) { - if (font_set == NULL) - return; - for (int i = 0; i < font_set->nfont; ++i) { - FcPattern* pattern = font_set->fonts[i]; - FcValue font_file; - if (FcPatternGet(pattern, "file", 0, &font_file) == FcResultMatch) { - file_names->insert(reinterpret_cast<const char*>(font_file.u.s)); - } else { - VLOG(1) << "Failed to find filename."; - FcPatternPrint(pattern); - } - } -} -FcConfig* g_config = nullptr; -} // namespace - -void InitFonts(const char* fontconfig_path) { - // The following is roughly equivalent to calling FcInit(). We jump through - // a bunch of hoops here to avoid using fontconfig's directory scanning - // logic. The problem with fontconfig is that it follows symlinks when doing - // recursive directory scans. - // - // The approach below ignores any <dir>...</dir> entries in fonts.conf. This - // is deliberate. Specifying dirs is problematic because they're either - // absolute or relative to our process's current working directory which - // could be anything. Instead we assume that all font files will be in the - // same directory as fonts.conf. We'll scan + load them here. - FcConfig* config = FcConfigCreate(); - g_config = config; - CHECK(config); - - // FcConfigParseAndLoad is a seriously goofy function. Depending on whether - // name passed in begins with a slash, it will treat it either as a file name - // to be found in the directory where it expects to find the font - // configuration OR it will will treat it as a directory where it expects to - // find fonts.conf. The latter behavior is the one we want. Passing - // fontconfig_path via the environment is a quick and dirty way to get - // uniform behavior regardless whether it's a relative path or not. - setenv("FONTCONFIG_PATH", fontconfig_path, 1); - CHECK(FcConfigParseAndLoad(config, nullptr, FcTrue)) - << "Failed to load font configuration. FONTCONFIG_PATH=" - << fontconfig_path; - - DIR* fc_dir = opendir(fontconfig_path); - CHECK(fc_dir) << "Failed to open font directory " << fontconfig_path << ": " - << strerror(errno); - - // The fonts must be loaded in a consistent order. This makes rendered results - // stable across runs, otherwise replacement font picks are random - // and cause flakiness. - std::set<std::string> fonts; - struct dirent *result; - while ((result = readdir(fc_dir))) { - fonts.insert(result->d_name); - } - for (const std::string& font : fonts) { - const std::string full_path = fontconfig_path + ("/" + font); - struct stat statbuf; - CHECK_EQ(0, stat(full_path.c_str(), &statbuf)) - << "Failed to stat " << full_path << ": " << strerror(errno); - if (S_ISREG(statbuf.st_mode)) { - // FcConfigAppFontAddFile will silently ignore non-fonts. - FcConfigAppFontAddFile( - config, reinterpret_cast<const FcChar8*>(full_path.c_str())); - } - } - closedir(fc_dir); - CHECK(FcConfigSetCurrent(config)); - - // Retrieve font from both of fontconfig's font sets for pre-loading. - std::set<std::string> font_files; - GetFontFileNames(FcConfigGetFonts(NULL, FcSetSystem), &font_files); - GetFontFileNames(FcConfigGetFonts(NULL, FcSetApplication), &font_files); - CHECK_GT(font_files.size(), 0u) - << "Font configuration doesn't contain any fonts!"; - - // Get freetype to load every font file we know about. This will cause the - // font files to get cached in memory. Once that's done we shouldn't have to - // access the file system for fonts at all. - FT_Library library; - FT_Init_FreeType(&library); - for (std::set<std::string>::const_iterator iter = font_files.begin(); - iter != font_files.end(); ++iter) { - FT_Face face; - CHECK_EQ(0, FT_New_Face(library, iter->c_str(), 0, &face)) - << "Failed to load font face: " << *iter; - FT_Done_Face(face); - } - FT_Done_FreeType(library); // Cached stuff will stick around... ? -} - -void ReleaseFonts() { - CHECK(g_config); - FcConfigDestroy(g_config); - FcFini(); -} - -} // namespace headless
diff --git a/headless/public/util/fontconfig.h b/headless/public/util/fontconfig.h deleted file mode 100644 index b3e1ec1e..0000000 --- a/headless/public/util/fontconfig.h +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef HEADLESS_PUBLIC_UTIL_FONTCONFIG_H_ -#define HEADLESS_PUBLIC_UTIL_FONTCONFIG_H_ - -#include "headless/public/headless_export.h" - -namespace headless { - -// Initialize fontconfig by loading fonts from given path without following -// symlinks. This is a wrapper around FcInit from libfreetype bundled with -// Chromium modified to enable headless embedders to deploy in custom -// environments. -HEADLESS_EXPORT void InitFonts(const char* font_config_path); - -HEADLESS_EXPORT void ReleaseFonts(); - -} // namespace headless - -#endif // HEADLESS_PUBLIC_UTIL_FONTCONFIG_H_
diff --git a/infra/orchestrator/BUILD.gn b/infra/orchestrator/BUILD.gn index 2ba1f5d..d26c636 100644 --- a/infra/orchestrator/BUILD.gn +++ b/infra/orchestrator/BUILD.gn
@@ -26,6 +26,13 @@ if (use_clang_coverage) { data += [ "//tools/clang/scripts/update.py" ] } + + if (use_jacoco_coverage) { + data += [ + "//third_party/jdk/current/bin/java", + "//third_party/jacoco/lib/jacococli.jar", + ] + } write_runtime_deps = "$root_out_dir/orchestrator_all.runtime_deps" }
diff --git a/ios/chrome/app/application_delegate/metrics_mediator.mm b/ios/chrome/app/application_delegate/metrics_mediator.mm index 08f502f3..0701885 100644 --- a/ios/chrome/app/application_delegate/metrics_mediator.mm +++ b/ios/chrome/app/application_delegate/metrics_mediator.mm
@@ -563,6 +563,8 @@ GetApplicationContext()->GetLocalState()->ClearPref( metrics::prefs::kMetricsClientID); GetApplicationContext()->GetLocalState()->ClearPref( + metrics::prefs::kMetricsProvisionalClientID); + GetApplicationContext()->GetLocalState()->ClearPref( metrics::prefs::kMetricsReportingEnabledTimestamp); crash_keys::ClearMetricsClientId(); }
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 463ebe5..ae50c94 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -969,6 +969,9 @@ <message name="IDS_IOS_FOLLOW_MANAGEMENT_UNFOLLOW_ACTION" desc="The 'Unfollow' action for a channel in the following feed management UI"> Unfollow </message> + <message name="IDS_IOS_FOLLOW_MANAGEMENT_VISIT_SITE_ACTION" desc="The 'Visit Site' action for a followed item in the following feed management UI"> + Visit Site + </message> <message name="IDS_IOS_FOLLOWING_FEED_TITLE" desc="The title in the Following feed header label."> Following </message>
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_FOLLOW_MANAGEMENT_VISIT_SITE_ACTION.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_FOLLOW_MANAGEMENT_VISIT_SITE_ACTION.png.sha1 new file mode 100644 index 0000000..3407cb2 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_FOLLOW_MANAGEMENT_VISIT_SITE_ACTION.png.sha1
@@ -0,0 +1 @@ +cd6496ca58d1b2e6bc86bf29e4bfc09dca771d9c \ No newline at end of file
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 1561718..fc2ca15d 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -664,11 +664,6 @@ flags_ui::kOsIos, FEATURE_VALUE_TYPE( autofill::features::kAutofillFillMerchantPromoCodeFields)}, - {"context-menu-phase2", - flag_descriptions::kWebViewNativeContextMenuPhase2Name, - flag_descriptions::kWebViewNativeContextMenuPhase2Description, - flags_ui::kOsIos, - FEATURE_VALUE_TYPE(web::features::kWebViewNativeContextMenuPhase2)}, {"default-wkwebview-context-menu", flag_descriptions::kDefaultWebViewContextMenuName, flag_descriptions::kDefaultWebViewContextMenuDescription, flags_ui::kOsIos, @@ -836,12 +831,6 @@ flag_descriptions::kEnhancedProtectionPhase2Name, flag_descriptions::kEnhancedProtectionPhase2Description, flags_ui::kOsIos, FEATURE_VALUE_TYPE(safe_browsing::kEnhancedProtectionPhase2IOS)}, - {"context-menu-phase2-screenshot", - flag_descriptions::kWebViewNativeContextMenuPhase2ScreenshotName, - flag_descriptions::kWebViewNativeContextMenuPhase2ScreenshotDescription, - flags_ui::kOsIos, - FEATURE_VALUE_TYPE( - web::features::kWebViewNativeContextMenuPhase2Screenshot)}, {"autofill-enable-unmask-card-request-set-instrument-id", flag_descriptions::kAutofillEnableUnmaskCardRequestSetInstrumentIdName, flag_descriptions::
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index a3d60031..62fe7df 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -696,19 +696,6 @@ const char kWebPageAlternativeTextZoomDescription[] = "When enabled, switches the method used to zoom web pages."; -const char kWebViewNativeContextMenuPhase2Name[] = - "Context Menu with non-live preview"; -const char kWebViewNativeContextMenuPhase2Description[] = - "When enabled, the context menu displayed when long pressing on a link or " - "an image has a non-live preview."; - -const char kWebViewNativeContextMenuPhase2ScreenshotName[] = - "Screenshot preview animation for Context Menu"; - -const char kWebViewNativeContextMenuPhase2ScreenshotDescription[] = - "When enabled with phase2, uses a screenshot as transition animation to " - "the context menu."; - // Please insert your name/description above in alphabetical order. } // namespace flag_descriptions
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index ce3b91b..cb7be79 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -627,16 +627,6 @@ extern const char kWebPageAlternativeTextZoomName[]; extern const char kWebPageAlternativeTextZoomDescription[]; -// Title and description for the flag to enable the phase 2 of context menus in -// the WebView. -extern const char kWebViewNativeContextMenuPhase2Name[]; -extern const char kWebViewNativeContextMenuPhase2Description[]; - -// Title and description for the flag to enable screenshot preview in the phase -// 2 of context menus in the WebView. -extern const char kWebViewNativeContextMenuPhase2ScreenshotName[]; -extern const char kWebViewNativeContextMenuPhase2ScreenshotDescription[]; - // Please add names and descriptions above in alphabetical order. } // namespace flag_descriptions
diff --git a/ios/chrome/browser/pref_names.cc b/ios/chrome/browser/pref_names.cc index c7585a3..ae4fc986 100644 --- a/ios/chrome/browser/pref_names.cc +++ b/ios/chrome/browser/pref_names.cc
@@ -98,6 +98,16 @@ const char kIosSettingsSigninPromoDisplayedCount[] = "ios.settings.signin_promo_displayed_count"; +// Preference that hold a boolean indicating if the user has already dismissed +// the sign-in promo in the ntp feed top section. +const char kIosNtpFeedTopPromoAlreadySeen[] = + "ios.ntp_feed_top.promo_already_seen"; + +// Integer to represent the number of time the sign-in promo has been displayed +// in the ntp feed top section. +const char kIosNtpFeedTopSigninPromoDisplayedCount[] = + "ios.ntp_feed_top.signin_promo_displayed_count"; + // Preference that holds a boolean indicating whether the link previews are // enabled. Link previews display a live preview of the selected link after a // long press.
diff --git a/ios/chrome/browser/pref_names.h b/ios/chrome/browser/pref_names.h index acdbdaa..1f3ec8a36 100644 --- a/ios/chrome/browser/pref_names.h +++ b/ios/chrome/browser/pref_names.h
@@ -30,6 +30,8 @@ extern const char kIosDiscoverFeedLastRefreshTime[]; extern const char kIosSettingsPromoAlreadySeen[]; extern const char kIosSettingsSigninPromoDisplayedCount[]; +extern const char kIosNtpFeedTopPromoAlreadySeen[]; +extern const char kIosNtpFeedTopSigninPromoDisplayedCount[]; extern const char kLinkPreviewEnabled[]; extern const char kNTPContentSuggestionsEnabled[]; extern const char kNTPFollowingFeedSortType[];
diff --git a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm index da6cbb4c..250d4d2 100644 --- a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm +++ b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm
@@ -6,6 +6,7 @@ #include <memory> +#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" @@ -43,6 +44,7 @@ case signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER: case signin_metrics::AccessPoint::ACCESS_POINT_RECENT_TABS: case signin_metrics::AccessPoint::ACCESS_POINT_TAB_SWITCHER: + case signin_metrics::AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO: return true; case signin_metrics::AccessPoint::ACCESS_POINT_START_PAGE: case signin_metrics::AccessPoint::ACCESS_POINT_NTP_LINK: @@ -87,15 +89,20 @@ int displayed_count) { switch (access_point) { case signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER: - UMA_HISTOGRAM_COUNTS_100( + base::UmaHistogramCounts100( "MobileSignInPromo.BookmarkManager.ImpressionsTilSigninButtons", displayed_count); break; case signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS: - UMA_HISTOGRAM_COUNTS_100( + base::UmaHistogramCounts100( "MobileSignInPromo.SettingsManager.ImpressionsTilSigninButtons", displayed_count); break; + case signin_metrics::AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO: + base::UmaHistogramCounts100( + "MobileSignInPromo.NTPFeedTop.ImpressionsTilSigninButtons", + displayed_count); + break; case signin_metrics::AccessPoint:: ACCESS_POINT_ENTERPRISE_SIGNOUT_COORDINATOR: case signin_metrics::AccessPoint::ACCESS_POINT_RECENT_TABS: @@ -143,15 +150,20 @@ int displayed_count) { switch (access_point) { case signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER: - UMA_HISTOGRAM_COUNTS_100( + base::UmaHistogramCounts100( "MobileSignInPromo.BookmarkManager.ImpressionsTilDismiss", displayed_count); break; case signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS: - UMA_HISTOGRAM_COUNTS_100( + base::UmaHistogramCounts100( "MobileSignInPromo.SettingsManager.ImpressionsTilDismiss", displayed_count); break; + case signin_metrics::AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO: + base::UmaHistogramCounts100( + "MobileSignInPromo.NTPFeedTop.ImpressionsTilDismiss", + displayed_count); + break; case signin_metrics::AccessPoint:: ACCESS_POINT_ENTERPRISE_SIGNOUT_COORDINATOR: case signin_metrics::AccessPoint::ACCESS_POINT_RECENT_TABS: @@ -199,15 +211,20 @@ int displayed_count) { switch (access_point) { case signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER: - UMA_HISTOGRAM_COUNTS_100( + base::UmaHistogramCounts100( "MobileSignInPromo.BookmarkManager.ImpressionsTilXButton", displayed_count); break; case signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS: - UMA_HISTOGRAM_COUNTS_100( + base::UmaHistogramCounts100( "MobileSignInPromo.SettingsManager.ImpressionsTilXButton", displayed_count); break; + case signin_metrics::AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO: + base::UmaHistogramCounts100( + "MobileSignInPromo.NTPFeedTop.ImpressionsTilXButton", + displayed_count); + break; case signin_metrics::AccessPoint:: ACCESS_POINT_ENTERPRISE_SIGNOUT_COORDINATOR: case signin_metrics::AccessPoint::ACCESS_POINT_RECENT_TABS: @@ -256,6 +273,8 @@ return prefs::kIosBookmarkSigninPromoDisplayedCount; case signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS: return prefs::kIosSettingsSigninPromoDisplayedCount; + case signin_metrics::AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO: + return prefs::kIosNtpFeedTopSigninPromoDisplayedCount; case signin_metrics::AccessPoint::ACCESS_POINT_RECENT_TABS: case signin_metrics::AccessPoint::ACCESS_POINT_TAB_SWITCHER: case signin_metrics::AccessPoint::ACCESS_POINT_START_PAGE: @@ -302,6 +321,8 @@ return prefs::kIosBookmarkPromoAlreadySeen; case signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS: return prefs::kIosSettingsPromoAlreadySeen; + case signin_metrics::AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO: + return prefs::kIosNtpFeedTopPromoAlreadySeen; case signin_metrics::AccessPoint::ACCESS_POINT_RECENT_TABS: case signin_metrics::AccessPoint::ACCESS_POINT_TAB_SWITCHER: case signin_metrics::AccessPoint::ACCESS_POINT_START_PAGE: @@ -391,6 +412,10 @@ registry->RegisterBooleanPref(prefs::kIosSettingsPromoAlreadySeen, false); registry->RegisterIntegerPref(prefs::kIosSettingsSigninPromoDisplayedCount, 0); + // NTP Feed + registry->RegisterBooleanPref(prefs::kIosNtpFeedTopPromoAlreadySeen, false); + registry->RegisterIntegerPref(prefs::kIosNtpFeedTopSigninPromoDisplayedCount, + 0); } + (BOOL)shouldDisplaySigninPromoViewWithAccessPoint:
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.h b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.h index e226f03..e836077 100644 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.h +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.h
@@ -26,6 +26,7 @@ @class ContentSuggestionsCollectionViewController; @protocol FeedControlDelegate; @class FeedMetricsRecorder; +class GURL; @protocol LogoVendor; @class NewTabPageViewController; @protocol NTPHomeConsumer; @@ -112,6 +113,10 @@ // feed menu. - (void)handleFeedLearnMoreTapped; +// Handles the actions following a tap on the "Visit Site" item in the followed +// item edit menu of the follow management page. +- (void)handleVisitSiteFromFollowManagementList:(const GURL&)url; + @end #endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_NTP_HOME_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm index c3cf3f70..aff9877e 100644 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm
@@ -260,6 +260,11 @@ [self.feedMetricsRecorder recordHeaderMenuLearnMoreTapped]; } +- (void)handleVisitSiteFromFollowManagementList:(const GURL&)url { + // TODO(crbug.com/1331102): Add metrics. + [self openMenuItemWebPage:url]; +} + #pragma mark - Properties. - (void)setWebState:(web::WebState*)webState {
diff --git a/ios/chrome/browser/ui/context_menu/BUILD.gn b/ios/chrome/browser/ui/context_menu/BUILD.gn index 9237cdd5..f1b8ccaf 100644 --- a/ios/chrome/browser/ui/context_menu/BUILD.gn +++ b/ios/chrome/browser/ui/context_menu/BUILD.gn
@@ -48,12 +48,6 @@ sources = [ "context_menu_utils.h", "context_menu_utils.mm", - "image_preview_view_controller.h", - "image_preview_view_controller.mm", - "link_no_preview_view.h", - "link_no_preview_view.mm", - "link_no_preview_view_controller.h", - "link_no_preview_view_controller.mm", ] deps = [ "//base",
diff --git a/ios/chrome/browser/ui/context_menu/context_menu_configuration_provider.mm b/ios/chrome/browser/ui/context_menu/context_menu_configuration_provider.mm index 63561300..ee99ccce 100644 --- a/ios/chrome/browser/ui/context_menu/context_menu_configuration_provider.mm +++ b/ios/chrome/browser/ui/context_menu/context_menu_configuration_provider.mm
@@ -24,8 +24,6 @@ #import "ios/chrome/browser/ui/commands/reading_list_add_command.h" #import "ios/chrome/browser/ui/commands/search_image_with_lens_command.h" #import "ios/chrome/browser/ui/context_menu/context_menu_utils.h" -#import "ios/chrome/browser/ui/context_menu/image_preview_view_controller.h" -#import "ios/chrome/browser/ui/context_menu/link_no_preview_view_controller.h" #import "ios/chrome/browser/ui/image_util/image_copier.h" #import "ios/chrome/browser/ui/image_util/image_saver.h" #import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_commands.h" @@ -299,19 +297,14 @@ NSString* menuTitle = nil; if (isLink || isImage) { - if (!base::FeatureList::IsEnabled( - web::features::kWebViewNativeContextMenuPhase2)) { - menuTitle = GetContextMenuTitle(params); + menuTitle = GetContextMenuTitle(params); - // Truncate context meny titles that originate from URLs, leaving text - // titles untruncated. - if (!IsImageTitle(params) && - menuTitle.length > kContextMenuMaxURLTitleLength + 1) { - menuTitle = [[menuTitle substringToIndex:kContextMenuMaxURLTitleLength] - stringByAppendingString:kContextMenuEllipsis]; - } - } else if (!isLink) { - menuTitle = GetContextMenuTitle(params); + // Truncate context meny titles that originate from URLs, leaving text + // titles untruncated. + if (!IsImageTitle(params) && + menuTitle.length > kContextMenuMaxURLTitleLength + 1) { + menuTitle = [[menuTitle substringToIndex:kContextMenuMaxURLTitleLength] + stringByAppendingString:kContextMenuEllipsis]; } } @@ -323,55 +316,9 @@ return menu; }; - UIContextMenuContentPreviewProvider previewProvider = nil; - if (isLink || isImage) { - previewProvider = ^UIViewController* { - if (!weakSelf || !base::FeatureList::IsEnabled( - web::features::kWebViewNativeContextMenuPhase2)) { - return nil; - } - if (isLink) { - NSString* title = GetContextMenuTitle(params); - NSString* subtitle = GetContextMenuSubtitle(params); - LinkNoPreviewViewController* previewViewController = - [[LinkNoPreviewViewController alloc] initWithTitle:title - subtitle:subtitle]; - - __weak LinkNoPreviewViewController* weakPreview = previewViewController; - FaviconLoader* faviconLoader = - IOSChromeFaviconLoaderFactory::GetForBrowserState( - weakSelf.browser->GetBrowserState()); - faviconLoader->FaviconForPageUrl( - linkURL, kDesiredSmallFaviconSizePt, kDesiredSmallFaviconSizePt, - /*fallback_to_google_server=*/false, - ^(FaviconAttributes* attributes) { - [weakPreview configureFaviconWithAttributes:attributes]; - }); - return previewViewController; - } - DCHECK(isImage); - ImagePreviewViewController* preview = [[ImagePreviewViewController alloc] - initWithPreferredContentSize:CGSizeMake(params.natural_width, - params.natural_height)]; - if (params.screenshot) { - [preview updateImage:params.screenshot]; - } - __weak ImagePreviewViewController* weakPreview = preview; - - ImageFetchTabHelper* imageFetcher = - ImageFetchTabHelper::FromWebState(weakSelf.currentWebState); - DCHECK(imageFetcher); - imageFetcher->GetImageData(imageURL, referrer, ^(NSData* data) { - [weakPreview updateImageData:data]; - }); - - return preview; - }; - } - return [UIContextMenuConfiguration configurationWithIdentifier:nil - previewProvider:previewProvider + previewProvider:nil actionProvider:actionProvider]; }
diff --git a/ios/chrome/browser/ui/context_menu/context_menu_egtest.mm b/ios/chrome/browser/ui/context_menu/context_menu_egtest.mm index 9d35c2d..a213802 100644 --- a/ios/chrome/browser/ui/context_menu/context_menu_egtest.mm +++ b/ios/chrome/browser/ui/context_menu/context_menu_egtest.mm
@@ -361,100 +361,8 @@ assertWithMatcher:grey_notNil()]; } -// Tests context menu for image that are also links. -- (void)testContextMenuImageLink { - if (![ChromeEarlGrey isContextMenuInWebViewEnabled]) { - EARL_GREY_TEST_SKIPPED(@"Test for the new implementation of context menu"); - } - - const GURL shortTileURL = self.testServer->GetURL(kLinkImagePageUrl); - [ChromeEarlGrey loadURL:shortTileURL]; - [ChromeEarlGrey waitForPageToFinishLoading]; - [ChromeEarlGrey waitForWebStateZoomScale:1.0]; - - LongPressElement(kLogoPageChromiumImageId); - // Check that the title is shown. - std::string displayedHost = shortTileURL.host() + ":" + shortTileURL.port(); - [[EarlGrey selectElementWithMatcher: - grey_allOf(chrome_test_util::StaticTextWithAccessibilityLabel( - base::SysUTF8ToNSString(displayedHost)), - grey_not(grey_ancestor(grey_kindOfClassName( - @"LocationBarSteadyView"))), - nil)] assertWithMatcher:grey_notNil()]; - // Check the subtitle is shown. - const GURL shortLinkHrefURL = - self.testServer->GetURL(base::SysNSStringToUTF8(kShortLinkHref)); - [[EarlGrey selectElementWithMatcher:chrome_test_util::ContainsPartialText( - base::SysUTF8ToNSString( - shortLinkHrefURL.spec()))] - assertWithMatcher:grey_notNil()]; - - ClearContextMenu(); -} - // Tests context menu title truncation cases. - (void)testContextMenuTitleTruncation { - if (![ChromeEarlGrey isContextMenuInWebViewEnabled]) { - EARL_GREY_TEST_SKIPPED(@"Test for the new implementation of context menu"); - } - - const GURL shortTileURL = self.testServer->GetURL(kShortTruncationPageUrl); - [ChromeEarlGrey loadURL:shortTileURL]; - [ChromeEarlGrey waitForPageToFinishLoading]; - [ChromeEarlGrey waitForWebStateZoomScale:1.0]; - - LongPressElement(kLogoPageChromiumImageId); - [[EarlGrey selectElementWithMatcher:grey_text(kShortImgTitle)] - assertWithMatcher:grey_notNil()]; - ClearContextMenu(); - - LongPressElement(kInitialPageDestinationLinkId); - // Check that the title is shown. - std::string displayedHost = shortTileURL.host() + ":" + shortTileURL.port(); - [[EarlGrey selectElementWithMatcher: - grey_allOf(chrome_test_util::StaticTextWithAccessibilityLabel( - base::SysUTF8ToNSString(displayedHost)), - grey_not(grey_ancestor(grey_kindOfClassName( - @"LocationBarSteadyView"))), - nil)] assertWithMatcher:grey_notNil()]; - - // Check the subtitle is shown. - const GURL shortLinkHrefURL = - self.testServer->GetURL(base::SysNSStringToUTF8(kShortLinkHref)); - [[EarlGrey selectElementWithMatcher:chrome_test_util::ContainsPartialText( - base::SysUTF8ToNSString( - shortLinkHrefURL.spec()))] - assertWithMatcher:grey_notNil()]; - ClearContextMenu(); - - // Check the long title. - const GURL longTitleURL = self.testServer->GetURL(kLongTruncationPageUrl); - [ChromeEarlGrey loadURL:longTitleURL]; - [ChromeEarlGrey waitForPageToFinishLoading]; - [ChromeEarlGrey waitForWebStateZoomScale:1.0]; - - LongPressElement(kLogoPageChromiumImageId); - [[EarlGrey selectElementWithMatcher:grey_text(kLongImgTitle)] - assertWithMatcher:grey_notNil()]; - ClearContextMenu(); - - LongPressElement(kInitialPageDestinationLinkId); - // The menu will be fully displayed (the truncation is done by UILabel). - const GURL longLinkHrefURL = - self.testServer->GetURL(base::SysNSStringToUTF8(kLongLinkHref)); - [[EarlGrey selectElementWithMatcher:chrome_test_util::ContainsPartialText( - base::SysUTF8ToNSString( - longLinkHrefURL.spec()))] - assertWithMatcher:grey_notNil()]; - ClearContextMenu(); -} - -// Tests context menu title truncation cases. -- (void)testLegacyContextMenuTitleTruncation { - if ([ChromeEarlGrey isContextMenuInWebViewEnabled]) { - EARL_GREY_TEST_SKIPPED(@"Test for the old implementation of context menu"); - } - const GURL shortTtileURL = self.testServer->GetURL(kShortTruncationPageUrl); [ChromeEarlGrey loadURL:shortTtileURL]; [ChromeEarlGrey waitForPageToFinishLoading]; @@ -679,38 +587,6 @@ [ChromeEarlGrey waitForMainTabCount:0 inWindowWithNumber:1]; } -// Tests that tapping on the preview loads the page pointed by the destination -// URL. -- (void)testTappingOnPreview { - if (![ChromeEarlGrey isContextMenuInWebViewEnabled]) { - EARL_GREY_TEST_SKIPPED(@"Test for the new implementation of context menu"); - } - - const GURL initialURL = self.testServer->GetURL(kInitialPageUrl); - [ChromeEarlGrey loadURL:initialURL]; - [ChromeEarlGrey - waitForWebStateContainingText:kInitialPageDestinationLinkText]; - [ChromeEarlGrey waitForWebStateZoomScale:1.0]; - - LongPressElement(kInitialPageDestinationLinkId); - - const GURL destinationURL = self.testServer->GetURL(kDestinationPageUrl); - - [[EarlGrey - selectElementWithMatcher:grey_allOf(grey_accessibilityLabel( - base::SysUTF8ToNSString( - destinationURL.spec())), - grey_sufficientlyVisible(), nil)] - performAction:grey_tap()]; - - [ChromeEarlGrey waitForWebStateContainingText:kDestinationPageText]; - [ChromeEarlGrey waitForMainTabCount:1]; - - // Verify url. - [[EarlGrey selectElementWithMatcher:OmniboxText(destinationURL.GetContent())] - assertWithMatcher:grey_notNil()]; -} - // Checks that JavaScript links only have the "copy" option. - (void)testJavaScriptLinks { const GURL initialURL = self.testServer->GetURL(kJavaScriptPageUrl);
diff --git a/ios/chrome/browser/ui/context_menu/context_menu_utils.h b/ios/chrome/browser/ui/context_menu/context_menu_utils.h index a2c9190..685060b 100644 --- a/ios/chrome/browser/ui/context_menu/context_menu_utils.h +++ b/ios/chrome/browser/ui/context_menu/context_menu_utils.h
@@ -17,7 +17,6 @@ // Returns the subtitle for the context menu |params|. NSString* GetContextMenuSubtitle(web::ContextMenuParams params); -// DEPRECATED. // Returns whether the title for context menu |params| is an image title. bool IsImageTitle(web::ContextMenuParams params);
diff --git a/ios/chrome/browser/ui/context_menu/context_menu_utils.mm b/ios/chrome/browser/ui/context_menu/context_menu_utils.mm index 97109e5a..a70b6e97 100644 --- a/ios/chrome/browser/ui/context_menu/context_menu_utils.mm +++ b/ios/chrome/browser/ui/context_menu/context_menu_utils.mm
@@ -27,11 +27,8 @@ typedef std::pair<NSString*, ContextMenuTitleOrigin> TitleAndOrigin; -// DEPRECATED // Returns the title and origin for |params|. TitleAndOrigin GetContextMenuTitleAndOrigin(web::ContextMenuParams params) { - DCHECK(!base::FeatureList::IsEnabled( - web::features::kWebViewNativeContextMenuPhase2)); NSString* title = nil; ContextMenuTitleOrigin origin = ContextMenuTitleOrigin::kUnknown; @@ -78,36 +75,7 @@ } // namespace NSString* GetContextMenuTitle(web::ContextMenuParams params) { - if (!base::FeatureList::IsEnabled( - web::features::kWebViewNativeContextMenuPhase2)) { - return GetContextMenuTitleAndOrigin(params).first; - } - if (params.link_url.is_valid()) { - if (params.link_url.SchemeIsHTTPOrHTTPS()) { - url_formatter::FormatUrlTypes format_types = - url_formatter::kFormatUrlOmitDefaults | - url_formatter::kFormatUrlTrimAfterHost | - url_formatter::kFormatUrlOmitHTTPS | - url_formatter::kFormatUrlOmitTrivialSubdomains; - - std::u16string formatted_url = url_formatter::FormatUrl( - params.link_url, format_types, base::UnescapeRule::NORMAL, - /*new_parsed=*/nullptr, - /*prefix_end=*/nullptr, /*offset_for_adjustment=*/nullptr); - return base::SysUTF16ToNSString(formatted_url); - } else { - return base::SysUTF8ToNSString(params.link_url.scheme()); - } - } - NSString* title = params.title_attribute; - if (params.alt_text && params.src_url.is_valid()) { - if (title) { - title = [NSString stringWithFormat:@"%@ – %@", params.alt_text, title]; - } else { - title = params.alt_text; - } - } - return title; + return GetContextMenuTitleAndOrigin(params).first; } NSString* GetContextMenuSubtitle(web::ContextMenuParams params) { @@ -115,8 +83,6 @@ } bool IsImageTitle(web::ContextMenuParams params) { - DCHECK(!base::FeatureList::IsEnabled( - web::features::kWebViewNativeContextMenuPhase2)); return GetContextMenuTitleAndOrigin(params).second == ContextMenuTitleOrigin::kImageTitle; }
diff --git a/ios/chrome/browser/ui/context_menu/context_menu_utils_unittest.mm b/ios/chrome/browser/ui/context_menu/context_menu_utils_unittest.mm index 2a9b670c6..03dd0fc8 100644 --- a/ios/chrome/browser/ui/context_menu/context_menu_utils_unittest.mm +++ b/ios/chrome/browser/ui/context_menu/context_menu_utils_unittest.mm
@@ -95,83 +95,3 @@ EXPECT_TRUE([GetContextMenuTitle(params) hasSuffix:@(kTitle)]); EXPECT_TRUE(IsImageTitle(params)); } - -// Tests that a link with HTTP scheme returns the simplified domain as title. -TEST_F(ContextMenuUtilsTest, TitleForHTTPLink) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - web::features::kWebViewNativeContextMenuPhase2); - - web::ContextMenuParams params; - params.link_url = GURL(kLinkUrl); - params.title_attribute = @(kTitle); - - EXPECT_NSEQ(@"link.url", GetContextMenuTitle(params)); -} - -// Tests that a link with a JavaScript scheme returns the scheme. -TEST_F(ContextMenuUtilsTest, TitleForJavaScript) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - web::features::kWebViewNativeContextMenuPhase2); - - web::ContextMenuParams params; - params.link_url = GURL(kJavaScriptLinkUrl); - params.title_attribute = @(kTitle); - - EXPECT_NSEQ(@"javascript", GetContextMenuTitle(params)); -} - -// Tests that a link with a data scheme returns the scheme. -TEST_F(ContextMenuUtilsTest, TitleForData) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - web::features::kWebViewNativeContextMenuPhase2); - - web::ContextMenuParams params; - params.link_url = GURL(kDataUrl); - params.title_attribute = @(kTitle); - - EXPECT_NSEQ(@"data", GetContextMenuTitle(params)); -} - -// Tests that the title is returned when there is no alt text. -TEST_F(ContextMenuUtilsTest, TitleForTitle) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - web::features::kWebViewNativeContextMenuPhase2); - - web::ContextMenuParams params; - params.src_url = GURL(kSrcUrl); - params.title_attribute = @(kTitle); - - EXPECT_NSEQ(@(kTitle), GetContextMenuTitle(params)); -} - -// Tests that the alt text is returned when there is no title. -TEST_F(ContextMenuUtilsTest, TitleForAlt) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - web::features::kWebViewNativeContextMenuPhase2); - - web::ContextMenuParams params; - params.src_url = GURL(kSrcUrl); - params.alt_text = @(kAltText); - - EXPECT_NSEQ(@(kAltText), GetContextMenuTitle(params)); -} - -// Tests that the title and the alt text are returned. -TEST_F(ContextMenuUtilsTest, TitleForTitleAndAlt) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature( - web::features::kWebViewNativeContextMenuPhase2); - - web::ContextMenuParams params; - params.src_url = GURL(kSrcUrl); - params.title_attribute = @(kTitle); - params.alt_text = @(kAltText); - - NSString* expected = [NSString stringWithFormat:@"%s – %s", kAltText, kTitle]; - EXPECT_NSEQ(expected, GetContextMenuTitle(params)); -}
diff --git a/ios/chrome/browser/ui/context_menu/image_preview_view_controller.h b/ios/chrome/browser/ui/context_menu/image_preview_view_controller.h deleted file mode 100644 index aaa9b8d..0000000 --- a/ios/chrome/browser/ui/context_menu/image_preview_view_controller.h +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_CONTEXT_MENU_IMAGE_PREVIEW_VIEW_CONTROLLER_H_ -#define IOS_CHROME_BROWSER_UI_CONTEXT_MENU_IMAGE_PREVIEW_VIEW_CONTROLLER_H_ - -#import <UIKit/UIKit.h> - -// View Controller showing a preview of an image. -@interface ImagePreviewViewController : UIViewController - -// Initializes with |preferredContentSize|. -- (instancetype)initWithPreferredContentSize:(CGSize)preferredContentSize - NS_DESIGNATED_INITIALIZER; - -- (instancetype)init NS_UNAVAILABLE; -- (instancetype)initWithCoder:(NSCoder*)coder NS_UNAVAILABLE; - -- (instancetype)initWithNibName:(NSString*)nibNameOrNil - bundle:(NSBundle*)nibBundleOrNil NS_UNAVAILABLE; - -// Sets the displayed image to |image|. -- (void)updateImage:(UIImage*)image; - -// Sets the displayed image to |data|. -- (void)updateImageData:(NSData*)data; - -@end - -#endif // IOS_CHROME_BROWSER_UI_CONTEXT_MENU_IMAGE_PREVIEW_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/context_menu/image_preview_view_controller.mm b/ios/chrome/browser/ui/context_menu/image_preview_view_controller.mm deleted file mode 100644 index ccaa16ce..0000000 --- a/ios/chrome/browser/ui/context_menu/image_preview_view_controller.mm +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/context_menu/image_preview_view_controller.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { -const CGFloat kDefaultSize = 50; -} // namespace - -@interface ImagePreviewViewController () - -// The image view containing the image. -@property(nonatomic, strong) UIImageView* view; - -@end - -@implementation ImagePreviewViewController - -@dynamic view; - -#pragma mark - Public - -- (instancetype)initWithPreferredContentSize:(CGSize)preferredContentSize { - self = [super initWithNibName:nil bundle:nil]; - if (self) { - if (preferredContentSize.width <= 0.0 || - preferredContentSize.height <= 0.0) { - self.preferredContentSize = CGSizeMake(kDefaultSize, kDefaultSize); - } else { - self.preferredContentSize = preferredContentSize; - } - } - return self; -} - -- (void)loadView { - self.view = [[UIImageView alloc] init]; -} - -- (void)updateImage:(UIImage*)image { - self.view.image = image; -} - -- (void)updateImageData:(NSData*)data { - UIImage* image = [UIImage imageWithData:data]; - self.view.image = image; - - // UIPreviewProvider cannot animate |preferredContentSize| changes. - // Changing |preferredContentSize| during animation will make it glitch. - // See crbug.com/1288017. - // Here we set |preferredContentSize| as a last resort, if - // the |preferredContentSize| provided during initialization is invalid. - if (self.preferredContentSize.width == kDefaultSize && - self.preferredContentSize.height == kDefaultSize) { - self.preferredContentSize = image.size; - } -} - -@end
diff --git a/ios/chrome/browser/ui/context_menu/link_no_preview_view.h b/ios/chrome/browser/ui/context_menu/link_no_preview_view.h deleted file mode 100644 index 0a022a5..0000000 --- a/ios/chrome/browser/ui/context_menu/link_no_preview_view.h +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_CONTEXT_MENU_LINK_NO_PREVIEW_VIEW_H_ -#define IOS_CHROME_BROWSER_UI_CONTEXT_MENU_LINK_NO_PREVIEW_VIEW_H_ - -#import <UIKit/UIKit.h> - -@class FaviconAttributes; - -// View showing the information for a link when a preview of the destination is -// not displayed. -@interface LinkNoPreviewView : UIView - -// Initializes the view with its |title| and |subtitle|. -- (instancetype)initWithTitle:(NSString*)title subtitle:(NSString*)subtitle; - -// Sets the favicon for the preview. -- (void)configureWithAttributes:(FaviconAttributes*)attributes; - -@end - -#endif // IOS_CHROME_BROWSER_UI_CONTEXT_MENU_LINK_NO_PREVIEW_VIEW_H_
diff --git a/ios/chrome/browser/ui/context_menu/link_no_preview_view.mm b/ios/chrome/browser/ui/context_menu/link_no_preview_view.mm deleted file mode 100644 index a4b0826..0000000 --- a/ios/chrome/browser/ui/context_menu/link_no_preview_view.mm +++ /dev/null
@@ -1,95 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/context_menu/link_no_preview_view.h" - -#import "ios/chrome/common/ui/colors/semantic_color_names.h" -#import "ios/chrome/common/ui/favicon/favicon_container_view.h" -#import "ios/chrome/common/ui/favicon/favicon_view.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -namespace { - -// Padding for top. -const CGFloat kPaddingTopMargin = 14; -// Padding for leading/trailing/bottom. -const CGFloat kPaddingMargin = 16; -// Margin between the favicon and the text. -const CGFloat kFaviconToTextMargin = 12; -// Number of lines for the subtitle. -const CGFloat kNumberOfSubtitleLines = 3; - -} // namespace - -@interface LinkNoPreviewView () - -@property(nonatomic, strong) UILabel* title; - -@property(nonatomic, strong) UILabel* subtitle; - -@property(nonatomic, strong) FaviconContainerView* faviconContainer; - -@end - -@implementation LinkNoPreviewView - -- (instancetype)initWithTitle:(NSString*)title subtitle:(NSString*)subtitle { - self = [super init]; - if (self) { - _title = [[UILabel alloc] init]; - _title.translatesAutoresizingMaskIntoConstraints = NO; - _title.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; - _title.adjustsFontForContentSizeCategory = YES; - _title.textColor = [UIColor colorNamed:kTextPrimaryColor]; - _title.text = title; - [self addSubview:_title]; - - _subtitle = [[UILabel alloc] init]; - _subtitle.translatesAutoresizingMaskIntoConstraints = NO; - _subtitle.font = [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]; - _subtitle.adjustsFontForContentSizeCategory = YES; - _subtitle.numberOfLines = kNumberOfSubtitleLines; - _subtitle.textColor = [UIColor colorNamed:kTextSecondaryColor]; - _subtitle.lineBreakMode = NSLineBreakByCharWrapping; - _subtitle.text = subtitle; - [self addSubview:_subtitle]; - - _faviconContainer = [[FaviconContainerView alloc] init]; - _faviconContainer.translatesAutoresizingMaskIntoConstraints = NO; - [self addSubview:_faviconContainer]; - - [NSLayoutConstraint activateConstraints:@[ - [_title.topAnchor constraintEqualToAnchor:self.topAnchor - constant:kPaddingTopMargin], - [_title.trailingAnchor constraintEqualToAnchor:self.trailingAnchor - constant:-kPaddingMargin], - - [_subtitle.topAnchor constraintEqualToAnchor:_title.bottomAnchor], - - [_subtitle.leadingAnchor constraintEqualToAnchor:_title.leadingAnchor], - [_subtitle.trailingAnchor constraintEqualToAnchor:_title.trailingAnchor], - [_subtitle.bottomAnchor constraintEqualToAnchor:self.bottomAnchor - constant:-kPaddingMargin], - - [_faviconContainer.leadingAnchor - constraintEqualToAnchor:self.leadingAnchor - constant:kPaddingMargin], - [_faviconContainer.trailingAnchor - constraintEqualToAnchor:_title.leadingAnchor - constant:-kFaviconToTextMargin], - [_faviconContainer.centerYAnchor - constraintEqualToAnchor:self.centerYAnchor], - ]]; - } - return self; -} - -- (void)configureWithAttributes:(FaviconAttributes*)attributes { - [self.faviconContainer.faviconView configureWithAttributes:attributes]; -} - -@end
diff --git a/ios/chrome/browser/ui/context_menu/link_no_preview_view_controller.h b/ios/chrome/browser/ui/context_menu/link_no_preview_view_controller.h deleted file mode 100644 index ef452b4..0000000 --- a/ios/chrome/browser/ui/context_menu/link_no_preview_view_controller.h +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_UI_CONTEXT_MENU_LINK_NO_PREVIEW_VIEW_CONTROLLER_H_ -#define IOS_CHROME_BROWSER_UI_CONTEXT_MENU_LINK_NO_PREVIEW_VIEW_CONTROLLER_H_ - -#import <UIKit/UIKit.h> - -@class FaviconAttributes; - -// View Controller showing the information for a link when a preview of the -// destination is not displayed. -@interface LinkNoPreviewViewController : UIViewController - -// Initializes with the |title| and |subtitle| to be displayed. -- (instancetype)initWithTitle:(NSString*)title - subtitle:(NSString*)subtitle NS_DESIGNATED_INITIALIZER; - -- (instancetype)init NS_UNAVAILABLE; -- (instancetype)initWithCoder:(NSCoder*)coder NS_UNAVAILABLE; - -- (instancetype)initWithNibName:(NSString*)nibNameOrNil - bundle:(NSBundle*)nibBundleOrNil NS_UNAVAILABLE; - -// Configures the Favicon with |attributes|. -- (void)configureFaviconWithAttributes:(FaviconAttributes*)attributes; - -@end - -#endif // IOS_CHROME_BROWSER_UI_CONTEXT_MENU_LINK_NO_PREVIEW_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/context_menu/link_no_preview_view_controller.mm b/ios/chrome/browser/ui/context_menu/link_no_preview_view_controller.mm deleted file mode 100644 index d6c9be4..0000000 --- a/ios/chrome/browser/ui/context_menu/link_no_preview_view_controller.mm +++ /dev/null
@@ -1,55 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "ios/chrome/browser/ui/context_menu/link_no_preview_view_controller.h" - -#import "ios/chrome/browser/ui/context_menu/link_no_preview_view.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@interface LinkNoPreviewViewController () - -@property(nonatomic, copy) NSString* contextMenuTitle; -@property(nonatomic, copy) NSString* subtitle; -@property(nonatomic, strong) LinkNoPreviewView* view; - -@end - -@implementation LinkNoPreviewViewController - -@dynamic view; - -- (instancetype)initWithTitle:(NSString*)title subtitle:(NSString*)subtitle { - self = [super initWithNibName:nil bundle:nil]; - if (self) { - _contextMenuTitle = title; - _subtitle = subtitle; - } - return self; -} - -- (void)configureFaviconWithAttributes:(FaviconAttributes*)attributes { - [self.view configureWithAttributes:attributes]; -} - -- (void)loadView { - self.view = [[LinkNoPreviewView alloc] initWithTitle:self.contextMenuTitle - subtitle:self.subtitle]; - self.view.backgroundColor = UIColor.systemBackgroundColor; -} - -- (void)viewDidLayoutSubviews { - self.preferredContentSize = [self computePreferredContentSize]; -} - -- (CGSize)computePreferredContentSize { - CGFloat width = self.view.bounds.size.width; - CGSize minimalSize = - [self.view systemLayoutSizeFittingSize:CGSizeMake(width, 0)]; - return CGSizeMake(width, minimalSize.height); -} - -@end
diff --git a/ios/chrome/browser/ui/fullscreen/animated_scoped_fullscreen_disabler.h b/ios/chrome/browser/ui/fullscreen/animated_scoped_fullscreen_disabler.h index 06cce69a..3f11106 100644 --- a/ios/chrome/browser/ui/fullscreen/animated_scoped_fullscreen_disabler.h +++ b/ios/chrome/browser/ui/fullscreen/animated_scoped_fullscreen_disabler.h
@@ -45,7 +45,7 @@ // A container object for the list of observers. __strong AnimatedScopedFullscreenDisablerObserverListContainer* observer_list_container_ = nil; - // Whether this disabler is contributing to |controller_|'s disabled counter. + // Whether this disabler is contributing to `controller_`'s disabled counter. bool disabling_ = false; // Used to implement animation blocks safely. base::WeakPtrFactory<AnimatedScopedFullscreenDisabler> weak_factory_{this};
diff --git a/ios/chrome/browser/ui/fullscreen/animated_scoped_fullscreen_disabler.mm b/ios/chrome/browser/ui/fullscreen/animated_scoped_fullscreen_disabler.mm index 5879515..e3e1f45 100644 --- a/ios/chrome/browser/ui/fullscreen/animated_scoped_fullscreen_disabler.mm +++ b/ios/chrome/browser/ui/fullscreen/animated_scoped_fullscreen_disabler.mm
@@ -26,7 +26,7 @@ // The disabler passed on initialization. @property(nonatomic, readonly) AnimatedScopedFullscreenDisabler* disabler; -// Designated initializer for a container containing |disabler|'s observer list. +// Designated initializer for a container containing `disabler`'s observer list. - (instancetype)initWithDisabler:(AnimatedScopedFullscreenDisabler*)disabler NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE; @@ -149,7 +149,7 @@ animation_completed.Run(); }]; } else { - // If |controller_| is already disabled, no animation is necessary. + // If `controller_` is already disabled, no animation is necessary. controller_->IncrementDisabledCounter(); } }
diff --git a/ios/chrome/browser/ui/fullscreen/chrome_coordinator+fullscreen_disabling.mm b/ios/chrome/browser/ui/fullscreen/chrome_coordinator+fullscreen_disabling.mm index e0f8fef..7c29155 100644 --- a/ios/chrome/browser/ui/fullscreen/chrome_coordinator+fullscreen_disabling.mm +++ b/ios/chrome/browser/ui/fullscreen/chrome_coordinator+fullscreen_disabling.mm
@@ -37,10 +37,10 @@ @property(nonatomic, readonly) FullscreenController* controller; // Factory method that returns the disabler wrapper associated with -// |coordinator|, lazily instantiating it if necessary. +// `coordinator`, lazily instantiating it if necessary. + (instancetype)wrapperForCoordinator:(ChromeCoordinator*)coordinator; -// Initializer for a wrapper that disables |controller|. +// Initializer for a wrapper that disables `controller`. - (instancetype)initWithFullscreenController:(FullscreenController*)controller NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE;
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_animator.h b/ios/chrome/browser/ui/fullscreen/fullscreen_animator.h index 40b5c2f..de6ddfae 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_animator.h +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_animator.h
@@ -13,7 +13,7 @@ EXIT_FULLSCREEN }; -// Returns the final fullscreen progress for an animation with |style|. +// Returns the final fullscreen progress for an animation with `style`. CGFloat GetFinalFullscreenProgressForAnimation(FullscreenAnimatorStyle style); // Helper object for animating changes to fullscreen progress. Subclasses of @@ -28,7 +28,7 @@ // The final calculated fullscreen value. @property(nonatomic, readonly) CGFloat finalProgress; // The current progress value. This is the fullscreen progress value -// interpolated between |startProgress| and |finalProgress| using the timing +// interpolated between `startProgress` and `finalProgress` using the timing // curve and the fraction complete of the animation. @property(nonatomic, readonly) CGFloat currentProgress; @@ -41,7 +41,7 @@ NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE; -// Returns the progress value corresponding with |position|. +// Returns the progress value corresponding with `position`. - (CGFloat)progressForAnimatingPosition:(UIViewAnimatingPosition)position; @end
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_animator.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_animator.mm index 8f9dda7..dfd806b 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_animator.mm +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_animator.mm
@@ -83,8 +83,8 @@ - (void)stopAnimation:(BOOL)withoutFinishing { // Record the progress value when transitioning from the active to stopped - // state. This allows |currentProgress| to return the correct value after - // stopping, as |fractionComplete| is reset to 0.0 for stopped animators. + // state. This allows `currentProgress` to return the correct value after + // stopping, as `fractionComplete` is reset to 0.0 for stopped animators. if (self.state == UIViewAnimatingStateActive) _progressUponStopping = self.currentProgress; if (_progressUponStopping == _startProgress)
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_browser_observer.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_browser_observer.mm index 7b5f9de..a2e2f31 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_browser_observer.mm +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_browser_observer.mm
@@ -15,7 +15,7 @@ Browser* browser) : web_state_list_observer_(web_state_list_observer) { DCHECK(web_state_list_observer_); - // TODO(crbug.com/790886): DCHECK |browser| once FullscreenController is fully + // TODO(crbug.com/790886): DCHECK `browser` once FullscreenController is fully // scoped to a Browser. if (browser) { web_state_list_observer_->SetWebStateList(browser->GetWebStateList());
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_content_adjustment_util.h b/ios/chrome/browser/ui/fullscreen/fullscreen_content_adjustment_util.h index 64de38f..a1610be 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_content_adjustment_util.h +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_content_adjustment_util.h
@@ -10,7 +10,7 @@ @protocol CRWWebViewProxy; class FullscreenModel; -// Updates |proxy|'s content offset and top padding to ensure that the content +// Updates `proxy`'s content offset and top padding to ensure that the content // is fully visible under the hdeader. void MoveContentBelowHeader(id<CRWWebViewProxy> proxy, FullscreenModel* model);
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_controller.h b/ios/chrome/browser/ui/fullscreen/fullscreen_controller.h index 5d7d3f7..ba3dc792 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_controller.h +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_controller.h
@@ -22,7 +22,7 @@ public: explicit FullscreenController() = default; - // Retrieves the FullscreenController for |browser|. This should only be + // Retrieves the FullscreenController for `browser`. This should only be // called with the kFullscreenControllerBrowserScoped turned on. static FullscreenController* FromBrowser(Browser* browser);
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_controller_impl.h b/ios/chrome/browser/ui/fullscreen/fullscreen_controller_impl.h index 495bf30..8175f68 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_controller_impl.h +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_controller_impl.h
@@ -58,12 +58,12 @@ FullscreenModel model_; // Object that manages sending signals to FullscreenControllerImplObservers. FullscreenMediator mediator_; - // A WebStateListObserver that updates |model_| for WebStateList changes. + // A WebStateListObserver that updates `model_` for WebStateList changes. FullscreenWebStateListObserver web_state_list_observer_; - // A FullscreenBrowserObserver that resets |web_state_list_| when the Browser + // A FullscreenBrowserObserver that resets `web_state_list_` when the Browser // is destroyed. FullscreenBrowserObserver fullscreen_browser_observer_; - // The bridge used to forward brodcasted UI to |model_|. + // The bridge used to forward brodcasted UI to `model_`. __strong ChromeBroadcastOberverBridge* bridge_ = nil; // A helper object that listens for system notifications. __strong FullscreenSystemNotificationObserver* notification_observer_ = nil;
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_controller_observer.h b/ios/chrome/browser/ui/fullscreen/fullscreen_controller_observer.h index d401375c..9fc87c0 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_controller_observer.h +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_controller_observer.h
@@ -21,26 +21,26 @@ virtual ~FullscreenControllerObserver() = default; - // Invoked when the maximum or minimum viewport insets for |controller| have + // Invoked when the maximum or minimum viewport insets for `controller` have // been updated. virtual void FullscreenViewportInsetRangeChanged( FullscreenController* controller, UIEdgeInsets min_viewport_insets, UIEdgeInsets max_viewport_insets) {} - // Invoked after a scrolling event has caused |controller| to calculate - // |progress|. A |progress| value of 1.0 denotes that the toolbar should be - // completely visible, while a |progress| value of 0.0 denotes that the + // Invoked after a scrolling event has caused `controller` to calculate + // `progress`. A `progress` value of 1.0 denotes that the toolbar should be + // completely visible, while a `progress` value of 0.0 denotes that the // toolbar should be competely hidden. virtual void FullscreenProgressUpdated(FullscreenController* controller, CGFloat progress) {} - // Invoked with |controller| is enabled or disabled. + // Invoked with `controller` is enabled or disabled. virtual void FullscreenEnabledStateChanged(FullscreenController* controller, bool enabled) {} - // Invoked when |controller| is about to start an animation with |animator|. - // Observers are expected to add animations to update UI for |animator|'s + // Invoked when `controller` is about to start an animation with `animator`. + // Observers are expected to add animations to update UI for `animator`'s // final progress. virtual void FullscreenWillAnimate(FullscreenController* controller, FullscreenAnimator* animator) {} @@ -50,7 +50,7 @@ virtual void FullscreenControllerWillShutDown( FullscreenController* controller) {} - // Invoked when |controller| needs to resize its horizontal insets. + // Invoked when `controller` needs to resize its horizontal insets. // TODO(crbug.com/1114054) remove after fixing multiwindow resizing issue. virtual void ResizeHorizontalInsets(FullscreenController* controller) {} };
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_egtest.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_egtest.mm index 6db5a25..c78482c 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_egtest.mm +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_egtest.mm
@@ -44,7 +44,7 @@ performAction:grey_swipeFastInDirection(kGREYDirectionUp)]; } -// Asserts that the current URL is the |expectedURL| one. +// Asserts that the current URL is the `expectedURL` one. void AssertURLIs(const GURL& expectedURL) { NSString* description = [NSString stringWithFormat:@"Timeout waiting for the url to be %@", @@ -120,7 +120,7 @@ // Test that the toolbar is still visible after a user swipes down. // Use a slow swipe here because in this combination of conditions (one // page PDF, overscroll actions enabled, fast swipe), the - // |UIScrollViewDelegate scrollViewDidEndDecelerating:| is not called leading + // `UIScrollViewDelegate scrollViewDidEndDecelerating:` is not called leading // to an EarlGrey infinite wait. [[EarlGrey selectElementWithMatcher:WebStateScrollViewMatcher()] performAction:grey_swipeSlowInDirection(kGREYDirectionDown)];
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_mediator.h b/ios/chrome/browser/ui/fullscreen/fullscreen_mediator.h index bb980a1..82f7f8d9 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_mediator.h +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_mediator.h
@@ -72,12 +72,12 @@ void FullscreenModelScrollEventEnded(FullscreenModel* model) override; void FullscreenModelWasReset(FullscreenModel* model) override; - // Sets up |animator_| with |style|, notifies FullscreenControllerObservers, + // Sets up `animator_` with `style`, notifies FullscreenControllerObservers, // and starts the animation. void AnimateWithStyle(FullscreenAnimatorStyle style); // Stops the current scroll end animation if one is in progress. If - // |update_model| is true, the FullscreenModel will be updated with the active + // `update_model` is true, the FullscreenModel will be updated with the active // animator's current progress value. void StopAnimating(bool update_model);
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_model.h b/ios/chrome/browser/ui/fullscreen/fullscreen_model.h index 5dca44c..4dcbe8d 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_model.h +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_model.h
@@ -79,7 +79,7 @@ return GetToolbarInsetsAtProgress(progress_); } - // Returns the toolbar insets at |progress|. + // Returns the toolbar insets at `progress`. UIEdgeInsets GetToolbarInsetsAtProgress(CGFloat progress) const { return UIEdgeInsetsMake( GetCollapsedToolbarHeight() + progress * (GetExpandedToolbarHeight() - @@ -87,7 +87,7 @@ 0, progress * bottom_toolbar_height_, 0); } - // Increments and decrements |disabled_counter_| for features that require the + // Increments and decrements `disabled_counter_` for features that require the // toolbar be completely visible. void IncrementDisabledCounter(); void DecrementDisabledCounter(); @@ -98,10 +98,10 @@ // Instructs the model to ignore broadcasted scroll updates for the remainder // of the current scroll. Has no effect if not called while a scroll is // occurring. The model will resume listening for scroll events when - // |scrolling_| is reset to false. + // `scrolling_` is reset to false. void IgnoreRemainderOfCurrentScroll(); - // Called when a scroll end animation finishes. |progress| is the fullscreen + // Called when a scroll end animation finishes. `progress` is the fullscreen // progress corresponding to the final state of the aniamtion. void AnimationEndedWithProgress(CGFloat progress); @@ -164,13 +164,13 @@ bool GetFreezeToolbarHeight() const; private: - // Returns how a scroll to the current |y_content_offset_| from |from_offset| + // Returns how a scroll to the current `y_content_offset_` from `from_offset` // should be handled. enum class ScrollAction : short { kIgnore, // Ignore the scroll. - kUpdateBaseOffset, // Update |base_offset_| only. - kUpdateProgress, // Update |progress_| only. - kUpdateBaseOffsetAndProgress, // Update |bse_offset_| and |progress_|. + kUpdateBaseOffset, // Update `base_offset_` only. + kUpdateProgress, // Update `progress_` only. + kUpdateBaseOffsetAndProgress, // Update `bse_offset_` and `progress_`. }; ScrollAction ActionForScrollFromOffset(CGFloat from_offset) const; @@ -183,11 +183,11 @@ void UpdateProgress(); // Updates the disabled counter depending on the current values of - // |scroll_view_height_| and |content_height_|. + // `scroll_view_height_` and `content_height_`. void UpdateDisabledCounterForContentHeight(); - // Setter for |progress_|. Notifies observers of the new value if - // |notify_observers| is true. + // Setter for `progress_`. Notifies observers of the new value if + // `notify_observers` is true. void SetProgress(CGFloat progress); // ChromeBroadcastObserverInterface: @@ -207,7 +207,7 @@ // The percentage of the toolbar that should be visible, where 1.0 denotes a // fully visible toolbar and 0.0 denotes a completely hidden one. CGFloat progress_ = 0.0; - // The base offset from which to calculate fullscreen state. When |locked_| + // The base offset from which to calculate fullscreen state. When `locked_` // is false, it is reset to the current offset after each scroll event. CGFloat base_offset_ = NAN; // The height of the toolbars being shown or hidden by this model.
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_model.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_model.mm index 74f4bb3..965a3cb53 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_model.mm +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_model.mm
@@ -15,7 +15,7 @@ #endif namespace { -// Object that increments |counter| by 1 for its lifetime. +// Object that increments `counter` by 1 for its lifetime. class ScopedIncrementer { public: explicit ScopedIncrementer(size_t* counter) : counter_(counter) {
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_model_observer.h b/ios/chrome/browser/ui/fullscreen/fullscreen_model_observer.h index 3b9597ad..2d43900 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_model_observer.h +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_model_observer.h
@@ -19,19 +19,19 @@ virtual ~FullscreenModelObserver() = default; - // Invoked when |model|'s toolbar heights have been updated. + // Invoked when `model`'s toolbar heights have been updated. virtual void FullscreenModelToolbarHeightsUpdated(FullscreenModel* model) {} - // Invoked when |model|'s calculated progress() value is updated. + // Invoked when `model`'s calculated progress() value is updated. virtual void FullscreenModelProgressUpdated(FullscreenModel* model) {} - // Invoked when |model| is enabled or disabled. + // Invoked when `model` is enabled or disabled. virtual void FullscreenModelEnabledStateChanged(FullscreenModel* model) {} - // Invoked when a scroll event being tracked by |model| has started. + // Invoked when a scroll event being tracked by `model` has started. virtual void FullscreenModelScrollEventStarted(FullscreenModel* model) {} - // Invoked when a scroll event being tracked by |model| has ended. + // Invoked when a scroll event being tracked by `model` has ended. virtual void FullscreenModelScrollEventEnded(FullscreenModel* model) {} // Invoked when the model is reset.
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_model_unittest.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_model_unittest.mm index f066e91..a3442ad 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_model_unittest.mm +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_model_unittest.mm
@@ -21,7 +21,7 @@ const CGFloat kScrollViewHeight = 400.0; // The content height used for tests. const CGFloat kContentHeight = 5000.0; -// Converts |insets| to a string for debugging. +// Converts `insets` to a string for debugging. std::string GetStringFromInsets(UIEdgeInsets insets) { return base::SysNSStringToUTF8(NSStringFromUIEdgeInsets(insets)); } @@ -227,7 +227,7 @@ // Tests that toolbar_insets() returns the correct values. TEST_F(FullscreenModelTest, ToolbarInsets) { - // Checks whether |insets| are equal to the expected insets at |progress|. + // Checks whether `insets` are equal to the expected insets at `progress`. void (^check_insets)(UIEdgeInsets insets, CGFloat progress) = ^void(UIEdgeInsets insets, CGFloat progress) { UIEdgeInsets expected_insets = UIEdgeInsetsMake(
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_system_notification_observer.h b/ios/chrome/browser/ui/fullscreen/fullscreen_system_notification_observer.h index 3919328c..39ae864 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_system_notification_observer.h +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_system_notification_observer.h
@@ -17,7 +17,7 @@ // Additionally, this object notifies the mediator of foreground events. @interface FullscreenSystemNotificationObserver : NSObject -// Designated initializer that updates |controller| and |mediator| for system +// Designated initializer that updates `controller` and `mediator` for system // notifications. - (nullable instancetype) initWithController:(nonnull FullscreenController*)controller
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_system_notification_observer.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_system_notification_observer.mm index eaff423..30da5b4 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_system_notification_observer.mm +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_system_notification_observer.mm
@@ -26,10 +26,10 @@ // The FullscreenMediator through which foreground events are propagated to // FullscreenControllerObservers. @property(nonatomic, readonly, nonnull) FullscreenMediator* mediator; -// Creates or destroys |_voiceOverDisabler| depending on whether VoiceOver is +// Creates or destroys `_voiceOverDisabler` depending on whether VoiceOver is // enabled. - (void)voiceOverStatusChanged; -// Called when the keyboard is shown/hidden to reset |_keyboardDisabler|. +// Called when the keyboard is shown/hidden to reset `_keyboardDisabler`. - (void)keyboardWillShow; - (void)keyboardDidHide; // Called when the application is foregrounded. @@ -80,7 +80,7 @@ } - (void)dealloc { - // |-disconnect| should be called before deallocation. + // `-disconnect` should be called before deallocation. DCHECK(!_controller); }
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_ui_element.h b/ios/chrome/browser/ui/fullscreen/fullscreen_ui_element.h index bffdbb0..3ed8e67 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_ui_element.h +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_ui_element.h
@@ -13,28 +13,28 @@ // protocol to react to changes in Fullscreen state. @protocol FullscreenUIElement<NSObject> -// Tells the UI to update its state for |progress|. A fullscreen |progress| -// value denotes that the toolbar should be completely visible, and a |progress| +// Tells the UI to update its state for `progress`. A fullscreen `progress` +// value denotes that the toolbar should be completely visible, and a `progress` // value of 0.0 denotes that the toolbar should be completely hidden. // // This selector is called for every scroll offset, it's not optional, as -// checking |-respondsToSelector:| for every FullscreenUIElement at every scroll +// checking `-respondsToSelector:` for every FullscreenUIElement at every scroll // offset can introduce performance issues. // // If the implementation of this selector uses batched layout updates (e.g. -// updating the UI in |-layoutSubviews| or by updating constraints), then a -// layout pass should be forced using |-setNeedsLayout| and |-layoutIfNeeded|. +// updating the UI in `-layoutSubviews` or by updating constraints), then a +// layout pass should be forced using `-setNeedsLayout` and `-layoutIfNeeded`. // This will ensure that the layout is updated for each scroll position rather // than batching multiple fullscreen progress updates together. This is // especially important for FullscreenUIElements that do not implement -// |-animateFullscreenWithAnimator:|, as this selctor is called by +// `-animateFullscreenWithAnimator:`, as this selctor is called by // FullscreenUIUpdater in an animation block. - (void)updateForFullscreenProgress:(CGFloat)progress; @optional // Tells the UI to update its state after the max and min viewport insets have -// been updated to new values. |progress| is the current progress value, and +// been updated to new values. `progress` is the current progress value, and // can be used to update the UI at the current progress with the new viewport // inset range. - (void)updateForFullscreenMinViewportInsets:(UIEdgeInsets)minViewportInsets @@ -42,13 +42,13 @@ // Tells the UI that fullscreen is enabled or disabled. FullscreenUIUpdater's // default behavior if this selector is not implemented is to call -// |-updateForFullscreenProgress:| with a progress value of 1.0. +// `-updateForFullscreenProgress:` with a progress value of 1.0. - (void)updateForFullscreenEnabled:(BOOL)enabled; // Called when fullscreen is about to initate an animation. // FullscreenUIUpdater's default behavior if this selector is not implemented is -// to add an animation block calling |-updateForFullscreenProgress:| with a -// progress value of |animator.finalProgress|. +// to add an animation block calling `-updateForFullscreenProgress:` with a +// progress value of `animator.finalProgress`. - (void)animateFullscreenWithAnimator:(FullscreenAnimator*)animator; @end
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_ui_updater.h b/ios/chrome/browser/ui/fullscreen/fullscreen_ui_updater.h index 12440e9..cb90dd4 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_ui_updater.h +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_ui_updater.h
@@ -15,16 +15,16 @@ // FullscreenUIElements. class FullscreenUIUpdater { public: - // Constructor for an updater that updates |ui_element| for observed events - // from |controller|. Both arguments must be non-null. |ui_element| is not - // retained. The updater will observe |controller| until the controller is + // Constructor for an updater that updates `ui_element` for observed events + // from `controller`. Both arguments must be non-null. `ui_element` is not + // retained. The updater will observe `controller` until the controller is // shut down or the updater is destroyed. FullscreenUIUpdater(FullscreenController* controller, id<FullscreenUIElement> ui_element); ~FullscreenUIUpdater(); private: - // Stops observing |controller_|. + // Stops observing `controller_`. void Disconnect(); // Helper object that forwards FullscreenControllerObserver callbacks to their @@ -32,7 +32,7 @@ class FullscreenControllerObserverForwarder : public FullscreenControllerObserver { public: - // Constructor for a forwarder that updates |ui_element| for |updater|. + // Constructor for a forwarder that updates `ui_element` for `updater`. FullscreenControllerObserverForwarder(FullscreenUIUpdater* updater, id<FullscreenUIElement> ui_element); @@ -59,7 +59,7 @@ FullscreenController* controller_ = nullptr; // The observer forwarder. FullscreenControllerObserverForwarder forwarder_; - // Scoped observer for |forwarder_|. + // Scoped observer for `forwarder_`. base::ScopedObservation<FullscreenController, FullscreenControllerObserver> observation_{&forwarder_}; };
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_list_observer.h b/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_list_observer.h index 0d4dee5..a1259104 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_list_observer.h +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_list_observer.h
@@ -19,8 +19,8 @@ // FullscreenModel for navigation events. class FullscreenWebStateListObserver : public WebStateListObserver { public: - // Constructor for an observer for |web_state_list| that updates |model|. - // |controller| is used to create ScopedFullscreenDisablers for WebState + // Constructor for an observer for `web_state_list` that updates `model`. + // `controller` is used to create ScopedFullscreenDisablers for WebState // navigation events that require the toolbar to be visible. FullscreenWebStateListObserver(FullscreenController* controller, FullscreenModel* model, @@ -58,13 +58,13 @@ int index, bool user_action) override; - // Called when |web_state| is activated in |web_state_list_|. + // Called when `web_state` is activated in `web_state_list_`. void WebStateWasActivated(web::WebState* web_state); - // Called when |web_state| is removed from |web_state_list_|. + // Called when `web_state` is removed from `web_state_list_`. void WebStateWasRemoved(web::WebState* web_state); - // Whether |web_state| has been activated during the lifetime of this object. + // Whether `web_state` has been activated during the lifetime of this object. bool HasWebStateBeenActivated(web::WebState* web_state); // The controller passed on construction. @@ -75,7 +75,7 @@ WebStateList* web_state_list_ = nullptr; // The observer for the active WebState. FullscreenWebStateObserver web_state_observer_; - // The WebStates that have been activated in |web_state_list_|. + // The WebStates that have been activated in `web_state_list_`. std::set<web::WebState*> activated_web_states_; };
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.h b/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.h index 3d00f62..26894a8e 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.h +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.h
@@ -16,13 +16,13 @@ // A WebStateObserver that updates a FullscreenModel for navigation events. class FullscreenWebStateObserver : public web::WebStateObserver { public: - // Constructor for an observer that updates |controller| and |model|. + // Constructor for an observer that updates `controller` and `model`. FullscreenWebStateObserver(FullscreenController* controller, FullscreenModel* model, FullscreenMediator* mediator); ~FullscreenWebStateObserver() override; - // Tells the observer to start observing |web_state|. + // Tells the observer to start observing `web_state`. void SetWebState(web::WebState* web_state); private: @@ -41,7 +41,7 @@ FullscreenModel* model_; // The mediator passed on construction. FullscreenMediator* mediator_ = nullptr; - // Observer for |web_state_|'s scroll view proxy. + // Observer for `web_state_`'s scroll view proxy. __strong FullscreenWebViewProxyObserver* web_view_proxy_observer_; // The URL received in the NavigationContext of the last finished navigation. GURL last_navigation_url_;
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.mm index 71d0d0f..f35105a 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.mm +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.mm
@@ -74,9 +74,9 @@ // Due to limitations in WKWebView's rendering, different MIME types must be // inset using different techniques: - // - PDFs need to be inset using the scroll view's |contentInset| property or + // - PDFs need to be inset using the scroll view's `contentInset` property or // the floating page indicator is laid out incorrectly. - // - For normal pages, using |contentInset| breaks the layout of fixed- + // - For normal pages, using `contentInset` breaks the layout of fixed- // position DOM elements, so top padding must be accomplished by updating // the WKWebView's frame. bool is_pdf = web_state->GetContentsMimeType() == "application/pdf";
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_proxy_observer.h b/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_proxy_observer.h index c69e7af..e7f3ad0 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_proxy_observer.h +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_proxy_observer.h
@@ -17,7 +17,7 @@ // The proxy being observed. @property(nonatomic, weak, nullable) id<CRWWebViewProxy> proxy; -// Designated initializer for an observer that uses |model| to update its proxy. +// Designated initializer for an observer that uses `model` to update its proxy. - (nullable instancetype)initWithModel:(nonnull FullscreenModel*)model mediator:(nonnull FullscreenMediator*)mediator NS_DESIGNATED_INITIALIZER;
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_resizer.h b/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_resizer.h index dbeadde..9bca1c3 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_resizer.h +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_resizer.h
@@ -18,7 +18,7 @@ // feature. @interface FullscreenWebViewResizer : NSObject -// Initializes the object with the fullscreen |model|, used to get the +// Initializes the object with the fullscreen `model`, used to get the // information about the state of fullscreen. - (instancetype)initWithModel:(FullscreenModel*)model NS_DESIGNATED_INITIALIZER; @@ -35,7 +35,7 @@ // model. - (void)updateForCurrentState; -// Force the updates of the WebView to |progress|. |progress| should be between +// Force the updates of the WebView to `progress`. `progress` should be between // 0 and 1, 0 meaning that the application is in fullscreen, 1 that it is out of // fullscreen. - (void)forceToUpdateToProgress:(CGFloat)progress;
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_resizer.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_resizer.mm index 830ef5c..0c462cf8 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_resizer.mm +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_web_view_resizer.mm
@@ -82,7 +82,7 @@ #pragma mark - Private // Updates the WebView of the current webState to adjust it to the current -// fullscreen |progress|. |progress| should be between 0 and 1, 0 meaning that +// fullscreen `progress`. `progress` should be between 0 and 1, 0 meaning that // the application is in fullscreen, 1 that it is out of fullscreen. - (void)updateForFullscreenProgress:(CGFloat)progress { if (!self.webState || !self.webState->GetView().superview) @@ -92,7 +92,7 @@ self.model->SetWebViewSafeAreaInsets(self.webState->GetView().safeAreaInsets); } -// Updates the WebState view, resizing it such as |insets| is the insets between +// Updates the WebState view, resizing it such as `insets` is the insets between // the WebState view and its superview. - (void)updateForInsets:(UIEdgeInsets)insets { UIView* webView = self.webState->GetView(); @@ -139,7 +139,7 @@ } } -// Observes the frame property of the view of the |webState| using KVO. +// Observes the frame property of the view of the `webState` using KVO. - (void)observeWebStateViewFrame:(web::WebState*)webState { if (!webState->GetView()) return;
diff --git a/ios/chrome/browser/ui/fullscreen/test/fullscreen_model_test_util.h b/ios/chrome/browser/ui/fullscreen/test/fullscreen_model_test_util.h index e487201..c8c8dc94 100644 --- a/ios/chrome/browser/ui/fullscreen/test/fullscreen_model_test_util.h +++ b/ios/chrome/browser/ui/fullscreen/test/fullscreen_model_test_util.h
@@ -14,22 +14,22 @@ void SetUpFullscreenModelForTesting(FullscreenModel* model, CGFloat toolbar_height); -// Simulates a user scroll event in |model| for a scroll of |offset_delta| +// Simulates a user scroll event in `model` for a scroll of `offset_delta` // points. void SimulateFullscreenUserScrollWithDelta(FullscreenModel* model, CGFloat offset_delta); -// Simulates a user scroll event in |model| that will result in a progress value -// of |progress|. +// Simulates a user scroll event in `model` that will result in a progress value +// of `progress`. void SimulateFullscreenUserScrollForProgress(FullscreenModel* model, CGFloat progress); -// Returns the delta from |model|'s current Y offset that would result in -// |progress|. +// Returns the delta from `model`'s current Y offset that would result in +// `progress`. CGFloat GetFullscreenOffsetDeltaForProgress(FullscreenModel* model, CGFloat progress); -// Returns the base offset against which |model| would calculate |progress|, +// Returns the base offset against which `model` would calculate `progress`, // given its toolbar height and content offset. CGFloat GetFullscreenBaseOffsetForProgress(FullscreenModel* model, CGFloat progress);
diff --git a/ios/chrome/browser/ui/ntp/feed_management/BUILD.gn b/ios/chrome/browser/ui/ntp/feed_management/BUILD.gn index bb4613b8..0e34717f 100644 --- a/ios/chrome/browser/ui/ntp/feed_management/BUILD.gn +++ b/ios/chrome/browser/ui/ntp/feed_management/BUILD.gn
@@ -79,6 +79,7 @@ "//ios/chrome/browser/net:crurl", "//ios/chrome/browser/ui/follow", "//ios/chrome/browser/ui/ntp:metrics", + "//ios/chrome/browser/ui/ntp/feed_management:navigation_delegate", "//ios/chrome/browser/ui/table_view", "//ios/chrome/common/ui/favicon", "//ui/base",
diff --git a/ios/chrome/browser/ui/ntp/feed_management/feed_management_coordinator.mm b/ios/chrome/browser/ui/ntp/feed_management/feed_management_coordinator.mm index 4e2c33b..b73dec0 100644 --- a/ios/chrome/browser/ui/ntp/feed_management/feed_management_coordinator.mm +++ b/ios/chrome/browser/ui/ntp/feed_management/feed_management_coordinator.mm
@@ -79,6 +79,7 @@ initWithBrowserState:self.browser->GetBrowserState()]; followManagementViewController.followedWebChannelsDataSource = mediator; followManagementViewController.faviconDataSource = mediator; + followManagementViewController.navigationDelegate = self.navigationDelegate; self.followManagementMediator = mediator; followManagementViewController.feedMetricsRecorder = self.feedMetricsRecorder;
diff --git a/ios/chrome/browser/ui/ntp/feed_management/feed_management_navigation_delegate.h b/ios/chrome/browser/ui/ntp/feed_management/feed_management_navigation_delegate.h index 3c75bd5..2f7e613 100644 --- a/ios/chrome/browser/ui/ntp/feed_management/feed_management_navigation_delegate.h +++ b/ios/chrome/browser/ui/ntp/feed_management/feed_management_navigation_delegate.h
@@ -5,6 +5,8 @@ #ifndef IOS_CHROME_BROWSER_UI_NTP_FEED_MANAGEMENT_FEED_MANAGEMENT_NAVIGATION_DELEGATE_H_ #define IOS_CHROME_BROWSER_UI_NTP_FEED_MANAGEMENT_FEED_MANAGEMENT_NAVIGATION_DELEGATE_H_ +class GURL; + // Delegate for handling navigation actions. @protocol FeedManagementNavigationDelegate @@ -17,6 +19,9 @@ // Navigate to hidden. - (void)handleNavigateToHidden; +// Navigate to |url| of a followed site. +- (void)handleNavigateToFollowedURL:(const GURL&)url; + @end #endif // IOS_CHROME_BROWSER_UI_NTP_FEED_MANAGEMENT_FEED_MANAGEMENT_NAVIGATION_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/ntp/feed_management/feed_management_view_controller.mm b/ios/chrome/browser/ui/ntp/feed_management/feed_management_view_controller.mm index 52c2053a..dab0ca0 100644 --- a/ios/chrome/browser/ui/ntp/feed_management/feed_management_view_controller.mm +++ b/ios/chrome/browser/ui/ntp/feed_management/feed_management_view_controller.mm
@@ -37,6 +37,8 @@ - (void)viewDidLoad { [super viewDidLoad]; + self.tableView.separatorInset = + UIEdgeInsetsMake(0, kTableViewSeparatorInset, 0, 0); self.title = l10n_util::GetNSString(IDS_IOS_FEED_MANAGEMENT_TITLE); self.navigationController.navigationBar.prefersLargeTitles = YES;
diff --git a/ios/chrome/browser/ui/ntp/feed_management/follow_management_view_controller.h b/ios/chrome/browser/ui/ntp/feed_management/follow_management_view_controller.h index 410ba10..4e0e41ce 100644 --- a/ios/chrome/browser/ui/ntp/feed_management/follow_management_view_controller.h +++ b/ios/chrome/browser/ui/ntp/feed_management/follow_management_view_controller.h
@@ -8,10 +8,11 @@ #import "ios/chrome/browser/ui/ntp/feed_management/follow_management_ui_updater.h" #import "ios/chrome/browser/ui/table_view/chrome_table_view_controller.h" +@protocol FeedManagementNavigationDelegate; @class FeedMetricsRecorder; @protocol FollowedWebChannelsDataSource; -@protocol TableViewFaviconDataSource; @protocol FollowManagementViewDelegate; +@protocol TableViewFaviconDataSource; // The UI that displays the web channels that the user is following. @interface FollowManagementViewController @@ -30,6 +31,10 @@ // Feed metrics recorder. @property(nonatomic, weak) FeedMetricsRecorder* feedMetricsRecorder; +// Delegate to execute user actions related to navigation. +@property(nonatomic, weak) id<FeedManagementNavigationDelegate> + navigationDelegate; + @end #endif // IOS_CHROME_BROWSER_UI_NTP_FEED_MANAGEMENT_FOLLOW_MANAGEMENT_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/ntp/feed_management/follow_management_view_controller.mm b/ios/chrome/browser/ui/ntp/feed_management/follow_management_view_controller.mm index 9869fa3c..b3dba85 100644 --- a/ios/chrome/browser/ui/ntp/feed_management/follow_management_view_controller.mm +++ b/ios/chrome/browser/ui/ntp/feed_management/follow_management_view_controller.mm
@@ -8,6 +8,7 @@ #import "ios/chrome/browser/net/crurl.h" #import "ios/chrome/browser/ui/follow/follow_block_types.h" #import "ios/chrome/browser/ui/follow/followed_web_channel.h" +#import "ios/chrome/browser/ui/ntp/feed_management/feed_management_navigation_delegate.h" #import "ios/chrome/browser/ui/ntp/feed_management/follow_management_view_delegate.h" #import "ios/chrome/browser/ui/ntp/feed_management/followed_web_channel_item.h" #import "ios/chrome/browser/ui/ntp/feed_management/followed_web_channels_data_source.h" @@ -41,6 +42,9 @@ // Saved placement of the item that was last attempted to unfollow. @property(nonatomic, strong) NSIndexPath* indexPathOfLastUnfollowAttempt; +// Saved indexPath of the item that is being selected. +@property(nonatomic, strong) NSIndexPath* indexPathOfSelectedRow; + // Saved item that was attempted to unfollow. @property(nonatomic, strong) FollowedWebChannelItem* lastUnfollowedWebChannelItem; @@ -111,7 +115,27 @@ - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath { - [tableView deselectRowAtIndexPath:indexPath animated:YES]; + self.indexPathOfSelectedRow = indexPath; + + UIMenuController* menu = [UIMenuController sharedMenuController]; + UIMenuItem* visitSiteOption = [[UIMenuItem alloc] + initWithTitle:l10n_util::GetNSString( + IDS_IOS_FOLLOW_MANAGEMENT_VISIT_SITE_ACTION) + action:@selector(visitSiteTapped)]; + UIMenuItem* unfollowOption = [[UIMenuItem alloc] + initWithTitle:l10n_util::GetNSString( + IDS_IOS_FOLLOW_MANAGEMENT_UNFOLLOW_ACTION) + action:@selector(unfollowTapped)]; + menu.menuItems = @[ visitSiteOption, unfollowOption ]; + [self becomeFirstResponder]; + [menu showMenuFromView:tableView + rect:[tableView rectForRowAtIndexPath:indexPath]]; + + // When the menu is manually presented, it doesn't get focused by + // Voiceover. This notification forces voiceover to select the + // presented menu. + UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, + menu); } - (UISwipeActionsConfiguration*)tableView:(UITableView*)tableView @@ -163,6 +187,60 @@ actionProvider:actionProvider]; } +#pragma mark - UIResponder + +- (BOOL)canBecomeFirstResponder { + return YES; +} + +- (BOOL)becomeFirstResponder { + // starts listening for UIMenuControllerDidHideMenuNotification and triggers + // resignFirstResponder if received. + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(resignFirstResponder) + name:UIMenuControllerDidHideMenuNotification + object:nil]; + return [super becomeFirstResponder]; +} + +- (BOOL)resignFirstResponder { + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:UIMenuControllerDidHideMenuNotification + object:nil]; + self.indexPathOfSelectedRow = nil; + return [super resignFirstResponder]; +} + +- (BOOL)canPerformAction:(SEL)action withSender:(id)sender { + if (action == @selector(visitSiteTapped) || action == @selector + (unfollowTapped)) { + return YES; + } + return NO; +} + +#pragma mark - Edit Menu Actions + +- (void)visitSiteTapped { + FollowedWebChannelItem* followedWebChannelItem = + base::mac::ObjCCastStrict<FollowedWebChannelItem>( + [self.tableViewModel itemAtIndexPath:self.indexPathOfSelectedRow]); + const GURL& webPageURL = + followedWebChannelItem.followedWebChannel.webPageURL.gurl; + __weak FollowManagementViewController* weakSelf = self; + [self dismissViewControllerAnimated:YES + completion:^{ + [weakSelf.navigationDelegate + handleNavigateToFollowedURL:webPageURL]; + }]; +} + +- (void)unfollowTapped { + [self requestUnfollowWebChannelAtIndexPath:self.indexPathOfSelectedRow]; +} + #pragma mark - FollowManagementUIUpdater - (void)removeFollowedWebChannel:(FollowedWebChannel*)channel {
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm index 17dd7deab..c27cd52c 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
@@ -995,6 +995,10 @@ [self.ntpMediator handleFeedManageHiddenTapped]; } +- (void)handleNavigateToFollowedURL:(const GURL&)url { + [self.ntpMediator handleVisitSiteFromFollowManagementList:url]; +} + #pragma mark - Private // Updates the NTP to take into account a new feed, or a change in feed
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm index e263d3f..d344572 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_view_controller.mm
@@ -342,6 +342,7 @@ : self.discoverFeedWrapperViewController; // Configures the feed header in the view hierarchy if it is visible. if (self.feedHeaderViewController) { + self.feedHeaderViewController.view.layer.zPosition = FLT_MAX; [self addViewController:self.feedHeaderViewController toParentViewController:parentViewController]; } @@ -880,6 +881,8 @@ self.fakeOmniboxPinnedToTop) { [self resetFakeOmniboxConstraints]; } + } else if (self.fakeOmniboxPinnedToTop) { + [self resetFakeOmniboxConstraints]; } // Handles the sticky feed header.
diff --git a/ios/chrome/browser/ui/screen_time/screen_time_consumer.h b/ios/chrome/browser/ui/screen_time/screen_time_consumer.h index 1db7c37..017fc9a 100644 --- a/ios/chrome/browser/ui/screen_time/screen_time_consumer.h +++ b/ios/chrome/browser/ui/screen_time/screen_time_consumer.h
@@ -9,7 +9,7 @@ // A protocol to update information reported to the ScreenTime system. @protocol ScreenTimeConsumer -// Sets |URL| as the active URL reported to the ScreenTime system when the +// Sets `URL` as the active URL reported to the ScreenTime system when the // underlying web view is visible. - (void)setURL:(NSURL*)URL;
diff --git a/ios/chrome/browser/ui/screen_time/screen_time_mediator.h b/ios/chrome/browser/ui/screen_time/screen_time_mediator.h index f821b8c..9a08319 100644 --- a/ios/chrome/browser/ui/screen_time/screen_time_mediator.h +++ b/ios/chrome/browser/ui/screen_time/screen_time_mediator.h
@@ -15,8 +15,8 @@ @interface ScreenTimeMediator : NSObject @property(nonatomic, weak) id<ScreenTimeConsumer> consumer; -// This mediator reports information from |webStateList| to the ScreenTime -// system. Recording is disabled if |suppressUsageRecording| is YES. +// This mediator reports information from `webStateList` to the ScreenTime +// system. Recording is disabled if `suppressUsageRecording` is YES. - (instancetype)initWithWebStateList:(WebStateList*)webStateList suppressUsageRecording:(BOOL)suppressUsageRecording NS_DESIGNATED_INITIALIZER;
diff --git a/ios/chrome/browser/ui/screen_time/screen_time_mediator.mm b/ios/chrome/browser/ui/screen_time/screen_time_mediator.mm index a778d48..3b025a0f 100644 --- a/ios/chrome/browser/ui/screen_time/screen_time_mediator.mm +++ b/ios/chrome/browser/ui/screen_time/screen_time_mediator.mm
@@ -49,7 +49,7 @@ } - (void)dealloc { - // |-disconnect| must be called before deallocation. + // `-disconnect` must be called before deallocation. DCHECK(!_webStateList); }
diff --git a/ios/chrome/browser/ui/settings/content_settings/content_settings_table_view_controller.mm b/ios/chrome/browser/ui/settings/content_settings/content_settings_table_view_controller.mm index de57098d..7d42f26 100644 --- a/ios/chrome/browser/ui/settings/content_settings/content_settings_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/content_settings/content_settings_table_view_controller.mm
@@ -186,9 +186,7 @@ } } - if (IsDiscoverFeedPreviewEnabled() || - base::FeatureList::IsEnabled( - web::features::kWebViewNativeContextMenuPhase2)) { + if (IsDiscoverFeedPreviewEnabled()) { [model addItem:[self linkPreviewItem] toSectionWithIdentifier:SectionIdentifierSettings]; }
diff --git a/ios/chrome/browser/ui/settings/safety_check/safety_check_consumer.h b/ios/chrome/browser/ui/settings/safety_check/safety_check_consumer.h index 40f13e0..3968ce3c 100644 --- a/ios/chrome/browser/ui/settings/safety_check/safety_check_consumer.h +++ b/ios/chrome/browser/ui/settings/safety_check/safety_check_consumer.h
@@ -14,13 +14,13 @@ // Consumer protocol for safety check. @protocol SafetyCheckConsumer <ChromeTableViewConsumer> -// Initializes the check types section with |items|. +// Initializes the check types section with `items`. - (void)setCheckItems:(NSArray<TableViewItem*>*)items; -// Initializes the safety check header with |item|. +// Initializes the safety check header with `item`. - (void)setSafetyCheckHeaderItem:(TableViewLinkHeaderFooterItem*)item; -// Initializes the check start section with |item|. +// Initializes the check start section with `item`. - (void)setCheckStartItem:(TableViewItem*)item; // Initializes the footer with timestamp of last completed run.
diff --git a/ios/chrome/browser/ui/settings/safety_check/safety_check_coordinator.h b/ios/chrome/browser/ui/settings/safety_check/safety_check_coordinator.h index c39f899..16d1734 100644 --- a/ios/chrome/browser/ui/settings/safety_check/safety_check_coordinator.h +++ b/ios/chrome/browser/ui/settings/safety_check/safety_check_coordinator.h
@@ -27,8 +27,8 @@ - (instancetype)initWithBaseViewController:(UIViewController*)viewController browser:(Browser*)browser NS_UNAVAILABLE; -// |navigationController|: Handles user movement to check subpages. -// |browser|: browser state for preferences and password check. +// `navigationController`: Handles user movement to check subpages. +// `browser`: browser state for preferences and password check. - (instancetype)initWithBaseNavigationController: (UINavigationController*)navigationController browser:(Browser*)browser
diff --git a/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.h b/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.h index 42a7b9a..ee5431d 100644 --- a/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.h +++ b/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.h
@@ -27,11 +27,11 @@ @interface SafetyCheckMediator : NSObject <SafetyCheckServiceDelegate> // Designated initializer. All the parameters should not be null. -// |userPrefService|: Preference service to access safe browsing state. -// |passwordCheckManager|: Password check manager to enable use of the password +// `userPrefService`: Preference service to access safe browsing state. +// `passwordCheckManager`: Password check manager to enable use of the password // check service. -// |authService|: Authentication service to check users authentication status. -// |syncService|: Sync service to check sync and sync encryption status. +// `authService`: Authentication service to check users authentication status. +// `syncService`: Sync service to check sync and sync encryption status. - (instancetype)initWithUserPrefService:(PrefService*)userPrefService passwordCheckManager: (scoped_refptr<IOSChromePasswordCheckManager>)
diff --git a/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.mm b/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.mm index 487ee651..53c1bf6 100644 --- a/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.mm +++ b/ios/chrome/browser/ui/settings/safety_check/safety_check_mediator.mm
@@ -501,7 +501,7 @@ // If not managed compute error info to show in popover, if available. NSAttributedString* info = [self popoverInfoForType:itemType]; - // If |info| is empty there is no popover to display. + // If `info` is empty there is no popover to display. if (!info) return; @@ -517,7 +517,7 @@ #pragma mark - Private methods -// Computes the text needed for a popover on |itemType| if available. +// Computes the text needed for a popover on `itemType` if available. - (NSAttributedString*)popoverInfoForType:(NSInteger)itemType { SafteyCheckItemType type = static_cast<SafteyCheckItemType>(itemType); switch (type) { @@ -541,7 +541,7 @@ } // Computes the appropriate display state of the password check row based on -// |currentPasswordCheckState|. +// `currentPasswordCheckState`. - (PasswordCheckRowStates)computePasswordCheckRowState: (PasswordCheckState)newState { BOOL wasRunning = @@ -781,7 +781,7 @@ __weak __typeof__(self) weakSelf = self; // This handles a discrepancy between password check and safety check. In // password check a user cannot start a check if they have no passwords, but - // in safety check they can, but the |passwordCheckManager| won't even start + // in safety check they can, but the `passwordCheckManager` won't even start // a check. This if block below allows safety check to push the disabled // state after check now is pressed. if (self.currentPasswordCheckState == PasswordCheckState::kNoPasswords) { @@ -817,7 +817,7 @@ } } -// Checks if any of the safety checks are still running, resets |checkStartItem| +// Checks if any of the safety checks are still running, resets `checkStartItem` // if all checks have finished. - (void)resetsCheckStartItemIfNeeded { if (self.checksRemaining) { @@ -838,7 +838,7 @@ forKey:kTimestampOfLastIssueFoundKey]; self.checkDidRun = NO; } - // If no checks are still running, reset |checkStartItem|. + // If no checks are still running, reset `checkStartItem`. self.checkStartState = CheckStartStateDefault; [self reconfigureCheckStartSection]; @@ -857,7 +857,7 @@ return updateCheckRunning || passwordCheckRunning || safeBrowsingCheckRunning; } -// Updates |updateCheckItem| to reflect the device being offline if the check +// Updates `updateCheckItem` to reflect the device being offline if the check // was running. - (void)handleUpdateCheckOffline { if (self.updateCheckRowState == UpdateCheckRowStateRunning) { @@ -870,7 +870,7 @@ } // Verifies if the Omaha service returned an answer, if not sets -// |updateCheckItem| to an Omaha error state. +// `updateCheckItem` to an Omaha error state. - (void)verifyUpdateCheckComplete { // If still in running state assume Omaha error. if (self.updateCheckRowState == UpdateCheckRowStateRunning) { @@ -883,7 +883,7 @@ } // If the update check would have completed too quickly, making the UI appear -// jittery, delay the reconfigure call, using |newRowState|. +// jittery, delay the reconfigure call, using `newRowState`. - (void)possiblyDelayReconfigureUpdateCheckItemWithState: (UpdateCheckRowStates)newRowState { double secondsSinceStart = @@ -965,7 +965,7 @@ } // Performs the update check and triggers the display update to -// |updateCheckItem|. +// `updateCheckItem`. - (void)performUpdateCheck { __weak __typeof__(self) weakSelf = self; @@ -1005,8 +1005,8 @@ [self reconfigureSafeBrowsingCheckItem]; } -// Reconfigures the display of the |updateCheckItem| based on current state of -// |updateCheckRowState|. +// Reconfigures the display of the `updateCheckItem` based on current state of +// `updateCheckRowState`. - (void)reconfigureUpdateCheckItem { // Reset state to prevent conflicts. self.updateCheckItem.enabled = YES; @@ -1016,7 +1016,7 @@ self.updateCheckItem.trailingImageTintColor = nil; self.updateCheckItem.accessoryType = UITableViewCellAccessoryNone; - // On any item update, see if |checkStartItem| should be updated. + // On any item update, see if `checkStartItem` should be updated. [self resetsCheckStartItemIfNeeded]; switch (self.updateCheckRowState) { @@ -1100,8 +1100,8 @@ [self.consumer reconfigureCellsForItems:@[ self.updateCheckItem ]]; } -// Reconfigures the display of the |passwordCheckItem| based on current state of -// |passwordCheckRowState|. +// Reconfigures the display of the `passwordCheckItem` based on current state of +// `passwordCheckRowState`. - (void)reconfigurePasswordCheckItem { // Reset state to prevent conflicts. self.passwordCheckItem.enabled = YES; @@ -1111,7 +1111,7 @@ self.passwordCheckItem.trailingImageTintColor = nil; self.passwordCheckItem.accessoryType = UITableViewCellAccessoryNone; - // On any item update, see if |checkStartItem| should be updated. + // On any item update, see if `checkStartItem` should be updated. [self resetsCheckStartItemIfNeeded]; switch (self.passwordCheckRowState) { @@ -1172,8 +1172,8 @@ [self.consumer reconfigureCellsForItems:@[ self.passwordCheckItem ]]; } -// Reconfigures the display of the |safeBrowsingCheckItem| based on current -// state of |safeBrowsingCheckRowState|. +// Reconfigures the display of the `safeBrowsingCheckItem` based on current +// state of `safeBrowsingCheckRowState`. - (void)reconfigureSafeBrowsingCheckItem { // Reset state to prevent conflicts. self.safeBrowsingCheckItem.enabled = YES; @@ -1183,7 +1183,7 @@ self.safeBrowsingCheckItem.trailingImageTintColor = nil; self.safeBrowsingCheckItem.accessoryType = UITableViewCellAccessoryNone; - // On any item update, see if |checkStartItem| should be updated. + // On any item update, see if `checkStartItem` should be updated. [self resetsCheckStartItemIfNeeded]; switch (self.safeBrowsingCheckRowState) {
diff --git a/ios/chrome/browser/ui/settings/safety_check/safety_check_navigation_commands.h b/ios/chrome/browser/ui/settings/safety_check/safety_check_navigation_commands.h index afb9b55c..5c87e09 100644 --- a/ios/chrome/browser/ui/settings/safety_check/safety_check_navigation_commands.h +++ b/ios/chrome/browser/ui/settings/safety_check/safety_check_navigation_commands.h
@@ -12,13 +12,13 @@ // Shows password issues page. - (void)showPasswordIssuesPage; -// Opens update page at |location|. +// Opens update page at `location`. - (void)showUpdateAtLocation:(NSString*)location; // Shows page with Safe Browsing preference toggle. - (void)showSafeBrowsingPreferencePage; -// Shows the error popover with the corresponding |text|. +// Shows the error popover with the corresponding `text`. - (void)showErrorInfoFrom:(UIButton*)buttonView withText:(NSAttributedString*)text;
diff --git a/ios/chrome/browser/ui/settings/safety_check/safety_check_service_delegate.h b/ios/chrome/browser/ui/settings/safety_check/safety_check_service_delegate.h index bd72ee4..c3d57bea 100644 --- a/ios/chrome/browser/ui/settings/safety_check/safety_check_service_delegate.h +++ b/ios/chrome/browser/ui/settings/safety_check/safety_check_service_delegate.h
@@ -15,13 +15,13 @@ // Called when item is tapped. - (void)didSelectItem:(TableViewItem*)item; -// Determines if selection animation should be shown for |item|. +// Determines if selection animation should be shown for `item`. - (BOOL)isItemClickable:(TableViewItem*)item; -// Checks if |item| should have an error popover. +// Checks if `item` should have an error popover. - (BOOL)isItemWithErrorInfo:(TableViewItem*)item; -// Notifies the mediator that an info button was tapped for |itemType|. +// Notifies the mediator that an info button was tapped for `itemType`. - (void)infoButtonWasTapped:(UIButton*)buttonView usingItemType:(NSInteger)itemType;
diff --git a/ios/chrome/browser/ui/sharing/sharing_coordinator.h b/ios/chrome/browser/ui/sharing/sharing_coordinator.h index f8f6d5a22..b10ee59e 100644 --- a/ios/chrome/browser/ui/sharing/sharing_coordinator.h +++ b/ios/chrome/browser/ui/sharing/sharing_coordinator.h
@@ -18,17 +18,17 @@ @interface SharingCoordinator : ChromeCoordinator // Creates a coordinator configured to share the current tab's URL using the -// base |viewController|, a |browser|, |params| with all the necessary values -// to drive the scenario, and an |originView| from which the scenario was -// triggered. This initializer also uses the |originView|'s bounds to position +// base `viewController`, a `browser`, `params` with all the necessary values +// to drive the scenario, and an `originView` from which the scenario was +// triggered. This initializer also uses the `originView`'s bounds to position // the activity view popover on iPad. - (instancetype)initWithBaseViewController:(UIViewController*)viewController browser:(Browser*)browser params:(ActivityParams*)params originView:(UIView*)originView; -// Creates a coordinator configured to share the URLs specified in |params|. -// This initializer uses |barButtonItem| to position the activity view popover +// Creates a coordinator configured to share the URLs specified in `params`. +// This initializer uses `barButtonItem` to position the activity view popover // on iPad. - (instancetype)initWithBaseViewController:(UIViewController*)viewController browser:(Browser*)browser @@ -36,10 +36,10 @@ anchor:(UIBarButtonItem*)barButtonItem; // Creates a coordinator configured to share the current tab's URL using the -// base |viewController|, a |browser|, |params| with all the necessary values -// to drive the scenario. If |barButtonItem| is non-null, it will be used -// to present the activity view popover on iPad. Otherwise, |originView| and -// |originRect| will be used to position the activity view popover on iPad. +// base `viewController`, a `browser`, `params` with all the necessary values +// to drive the scenario. If `barButtonItem` is non-null, it will be used +// to present the activity view popover on iPad. Otherwise, `originView` and +// `originRect` will be used to position the activity view popover on iPad. - (instancetype)initWithBaseViewController:(UIViewController*)viewController browser:(Browser*)browser params:(ActivityParams*)params
diff --git a/ios/chrome/browser/ui/side_swipe/card_side_swipe_view.mm b/ios/chrome/browser/ui/side_swipe/card_side_swipe_view.mm index 467b3e64..6eac1a9 100644 --- a/ios/chrome/browser/ui/side_swipe/card_side_swipe_view.mm +++ b/ios/chrome/browser/ui/side_swipe/card_side_swipe_view.mm
@@ -54,7 +54,7 @@ - (BOOL)isEdgeSwipe; // Initialize card based on model_'s webstatelist index. - (void)setupCard:(SwipeView*)card withIndex:(int)index; -// Build a |kResizeFactor| sized greyscaled version of |image|. +// Build a `kResizeFactor` sized greyscaled version of `image`. - (UIImage*)smallGreyImage:(UIImage*)image; @property(nonatomic, strong) NSLayoutConstraint* backgroundTopConstraint; @@ -164,7 +164,7 @@ return greyImage; } -// Create card view based on |_webStateList|'s index. +// Create card view based on `_webStateList`'s index. - (void)setupCard:(SwipeView*)card withIndex:(int)index { if (index < 0 || index >= _webStateList->count()) { [card setHidden:YES]; @@ -189,9 +189,9 @@ } // Helper method that is invoked once the color snapshot has been fetched -// for the WebState returned by |weakWebState|. As the fetching is done +// for the WebState returned by `weakWebState`. As the fetching is done // asynchronously, it is possible for the WebState to have been destroyed -// and thus for |webStateGetter| to return nullptr. +// and thus for `webStateGetter` to return nullptr. - (void)colorSnapshotRetrieved:(UIImage*)image card:(SwipeView*)card weakWebState:(base::WeakPtr<web::WebState>)weakWebState { @@ -227,14 +227,14 @@ }); } -// Move cards according to |currentPoint_.x|. Edge cards only drag -// |kEdgeCardDragPercentage| of |bounds|. +// Move cards according to `currentPoint_.x`. Edge cards only drag +// `kEdgeCardDragPercentage` of `bounds`. - (void)updateCardPositions { CGFloat width = [self cardWidth]; if ([self isEdgeSwipe]) { // If an edge card, don't allow the card to be dragged across the screen. - // Instead, drag across |kEdgeCardDragPercentage| of the screen. + // Instead, drag across `kEdgeCardDragPercentage` of the screen. _rightCard.transform = CGAffineTransformMakeTranslation( (_currentPoint.x) * kEdgeCardDragPercentage, 0); _leftCard.transform = CGAffineTransformMakeTranslation( @@ -290,7 +290,7 @@ } // Update the current WebState and animate the proper card view if the -// |currentPoint_| is past the center of |bounds|. +// `currentPoint_` is past the center of `bounds`. - (void)finishPan { int currentIndex = _webStateList->active_index(); // Something happened and now there is not active WebState. End card side let @@ -304,7 +304,7 @@ int destinationWebStateIndex = currentIndex; CGFloat offset = UseRTLLayout() ? -1 : 1; if (_direction == UISwipeGestureRecognizerDirectionRight) { - // If swipe is right and |currentPoint_.x| is over the first 1/3, move left. + // If swipe is right and `currentPoint_.x` is over the first 1/3, move left. if (_currentPoint.x > width / 3.0 && ![self isEdgeSwipe]) { rightTransform = CGAffineTransformMakeTranslation(width + kCardHorizontalSpacing, 0); @@ -320,7 +320,7 @@ base::RecordAction(UserMetricsAction("MobileStackSwipeCancelled")); } } else { - // If swipe is left and |currentPoint_.x| is over the first 1/3, move right. + // If swipe is left and `currentPoint_.x` is over the first 1/3, move right. if (_currentPoint.x < (width / 3.0) * 2.0 && ![self isEdgeSwipe]) { leftTransform = CGAffineTransformMakeTranslation(-width - kCardHorizontalSpacing, 0);
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_controller.h b/ios/chrome/browser/ui/side_swipe/side_swipe_controller.h index c10561ea..944cfbb 100644 --- a/ios/chrome/browser/ui/side_swipe/side_swipe_controller.h +++ b/ios/chrome/browser/ui/side_swipe/side_swipe_controller.h
@@ -33,14 +33,14 @@ - (void)sideSwipeViewDismissAnimationDidEnd:(UIView*)sideSwipeView; // Returns the main content view. - (UIView*)sideSwipeContentView; -// Makes |tab| the currently visible tab, displaying its view. +// Makes `tab` the currently visible tab, displaying its view. - (void)sideSwipeRedisplayWebState:(web::WebState*)webState; // Controls the visibility of views such as the findbar, infobar and voice // search bar. - (void)updateAccessoryViewsForSideSwipeWithVisibility:(BOOL)visible; // Returns the height of the header view for the current tab. - (CGFloat)headerHeightForSideSwipe; -// Returns |YES| if side swipe should be blocked from initiating, such as when +// Returns `YES` if side swipe should be blocked from initiating, such as when // voice search is up, or if the tools menu is enabled. - (BOOL)preventSideSwipe; // Returns whether a swipe on the toolbar can start. @@ -53,7 +53,7 @@ // Controls how an edge gesture is processed, either as tab change or a page // change. For tab changes two full screen CardSideSwipeView views are dragged // across the screen. For page changes the SideSwipeControllerDelegate -// |contentView| is moved across the screen and a SideSwipeNavigationView is +// `contentView` is moved across the screen and a SideSwipeNavigationView is // shown in the remaining space. @interface SideSwipeController : NSObject<CRWSwipeRecognizerProvider, UIGestureRecognizerDelegate> @@ -87,7 +87,7 @@ // Enable or disable the side swipe gesture recognizer. - (void)setEnabled:(BOOL)enabled; -// Returns |NO| if the device should not rotate. +// Returns `NO` if the device should not rotate. - (BOOL)shouldAutorotate; // Resets the swipeDelegate's contentView frame origin x position to zero.
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm b/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm index 65ca0f6..2258ba8 100644 --- a/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm +++ b/ios/chrome/browser/ui/side_swipe/side_swipe_controller.mm
@@ -64,7 +64,7 @@ WebStateListObserving> { @private - // Zeroes out |_browser| when it is destroyed. + // Zeroes out `_browser` when it is destroyed. std::unique_ptr<SideSwipeControllerBrowserRemover> _browserRemover; // Side swipe view for tab navigation. @@ -122,8 +122,8 @@ // The webStateList owned by the current browser. @property(nonatomic, readonly) WebStateList* webStateList; -// Load grey snapshots for the next |kIpadGreySwipeTabCount| tabs in -// |direction|. +// Load grey snapshots for the next `kIpadGreySwipeTabCount` tabs in +// `direction`. - (void)createGreyCache:(UISwipeGestureRecognizerDirection)direction; // Tell snapshot cache to clear grey cache. - (void)deleteGreyCache; @@ -132,15 +132,15 @@ // Handle tab side swipe for iPhone. Introduces a CardSideSwipeView to convey // the tab change. - (void)handleiPhoneTabSwipe:(SideSwipeGestureRecognizer*)gesture; -// Overlays |curtain_| as a white view to hide the web view while it updates. -// Calls |completionHandler| when the curtain is removed. +// Overlays `curtain_` as a white view to hide the web view while it updates. +// Calls `completionHandler` when the curtain is removed. - (void)addCurtainWithCompletionHandler:(ProceduralBlock)completionHandler; -// Removes the |curtain_| and calls |completionHandler| when the curtain is +// Removes the `curtain_` and calls `completionHandler` when the curtain is // removed. - (void)dismissCurtainWithCompletionHandler:(ProceduralBlock)completionHandler; -// Removes the |curtain_| if there was an active swipe, and resets -// |inSwipe_| value. +// Removes the `curtain_` if there was an active swipe, and resets +// `inSwipe_` value. - (void)dismissCurtain; // Cleans up Browser, WebStateList, and WebState references in the instance of a // BrowserDestroyed BrowserObserver call. @@ -293,7 +293,7 @@ return NO; } -// Gestures should only be recognized within |contentArea_| or the toolbar. +// Gestures should only be recognized within `contentArea_` or the toolbar. - (BOOL)gestureRecognizerShouldBegin:(SideSwipeGestureRecognizer*)gesture { if (_inSwipe) { return NO; @@ -315,7 +315,7 @@ return [_swipeDelegate canBeginToolbarSwipe]; } - // Otherwise, only allow contentView touches with |swipeGestureRecognizer_|. + // Otherwise, only allow contentView touches with `swipeGestureRecognizer_`. // The content view frame is inset by -1 because CGRectContainsPoint does // include points on the max X and Y edges, which will happen frequently with // edge swipes from the right side. @@ -420,7 +420,7 @@ } else if (gesture.state == UIGestureRecognizerStateChanged) { // Side swipe for iPad involves changing the selected tab as the swipe moves // across the width of the view. The screen is broken up into - // |kIpadTabSwipeDistance| / |width| segments, with the current tab in the + // `kIpadTabSwipeDistance` / `width` segments, with the current tab in the // first section. The swipe does not wrap edges. CGFloat distance = [gesture locationInView:gesture.view].x; if (gesture.direction == UISwipeGestureRecognizerDirectionLeft) {
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_egtest.mm b/ios/chrome/browser/ui/side_swipe/side_swipe_egtest.mm index bc17f47..6446f19 100644 --- a/ios/chrome/browser/ui/side_swipe/side_swipe_egtest.mm +++ b/ios/chrome/browser/ui/side_swipe/side_swipe_egtest.mm
@@ -39,7 +39,7 @@ #pragma mark - Helpers -// Checks that side swipe on an element of class |klass| is working to change +// Checks that side swipe on an element of class `klass` is working to change // tab. - (void)checkSideSwipeOnToolbarClassName:(NSString*)className { // Setup the server.
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_gesture_recognizer.mm b/ios/chrome/browser/ui/side_swipe/side_swipe_gesture_recognizer.mm index c3f4fabd..7c897491 100644 --- a/ios/chrome/browser/ui/side_swipe/side_swipe_gesture_recognizer.mm +++ b/ios/chrome/browser/ui/side_swipe/side_swipe_gesture_recognizer.mm
@@ -14,7 +14,7 @@ namespace { -// The absolute maximum swipe angle from |x = y| for a swipe to begin. +// The absolute maximum swipe angle from `x = y` for a swipe to begin. const CGFloat kMaxSwipeYAngle = 65; // The minimum distance between touches for a swipe to begin. const CGFloat kDefaultMinSwipeXThreshold = 4; @@ -84,16 +84,16 @@ } // In iOS10, sometimes a PanGestureRecognizer will fire a touchesMoved even - // after touchesBegan sets its state to |UIGestureRecognizerStateFailed|. + // after touchesBegan sets its state to `UIGestureRecognizerStateFailed`. // Somehow the state is re-set to UIGestureRecognizerStatePossible, and ends - // up in moved. Checking if |_startPoint| has been set is a secondary way to + // up in moved. Checking if `_startPoint` has been set is a secondary way to // catch for failed gestures. if (CGPointEqualToPoint(_startPoint, CGPointZero)) { self.state = UIGestureRecognizerStateFailed; return; } - // Don't swipe at an angle greater than |kMaxSwipeYAngle|. + // Don't swipe at an angle greater than `kMaxSwipeYAngle`. UITouch* touch = [[event allTouches] anyObject]; CGPoint currentPoint = [touch locationInView:self.view]; CGFloat dy = currentPoint.y - _startPoint.y; @@ -104,7 +104,7 @@ return; } - // On devices that support force presses a -touchesMoved fires when |force| + // On devices that support force presses a -touchesMoved fires when `force` // changes and not the location of the touch. Ignore these events. if (currentPoint.x == _startPoint.x) { self.state = UIGestureRecognizerStatePossible; @@ -128,7 +128,7 @@ } } - // Begin recognizer after |self.swipeThreshold| distance swiped. + // Begin recognizer after `self.swipeThreshold` distance swiped. if (std::abs(currentPoint.x - _startPoint.x) > self.swipeThreshold) { if (_direction == UISwipeGestureRecognizerDirectionRight) { _swipeOffset = currentPoint.x;
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_navigation_view.h b/ios/chrome/browser/ui/side_swipe/side_swipe_navigation_view.h index 0994865c..c0dc3f9 100644 --- a/ios/chrome/browser/ui/side_swipe/side_swipe_navigation_view.h +++ b/ios/chrome/browser/ui/side_swipe/side_swipe_navigation_view.h
@@ -22,7 +22,7 @@ image:(UIImage*)image; // Update views for latest gesture, and call completion blocks whether -// |threshold| is met. +// `threshold` is met. - (void)handleHorizontalPan:(SideSwipeGestureRecognizer*)gesture onOverThresholdCompletion:(void (^)(void))onOverThresholdCompletion onUnderThresholdCompletion:(void (^)(void))onUnderThresholdCompletion;
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_navigation_view.mm b/ios/chrome/browser/ui/side_swipe/side_swipe_navigation_view.mm index 138db21..b3f891f2 100644 --- a/ios/chrome/browser/ui/side_swipe/side_swipe_navigation_view.mm +++ b/ios/chrome/browser/ui/side_swipe/side_swipe_navigation_view.mm
@@ -47,7 +47,7 @@ const CGFloat kSwipeThreshold = 0.53; // Convert the velocity (which is measured in points per second) to points per -// |kSwipeVelocityFraction| of a second. +// `kSwipeVelocityFraction` of a second. const CGFloat kSwipeVelocityFraction = 0.1; // Distance after which the arrow should animate in. @@ -85,7 +85,7 @@ // The selection bubble. CAShapeLayer* _selectionCircleLayer; - // If |NO| this is an edge gesture and navigation isn't possible. Don't show + // If `NO` this is an edge gesture and navigation isn't possible. Don't show // arrows and bubbles and don't allow navigate. BOOL _canNavigate; } @@ -184,7 +184,7 @@ } [self setFrame:frame]; - // Move |selectionCircleLayer_| without animations. + // Move `selectionCircleLayer_` without animations. CGRect bounds = self.bounds; CGPoint center = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds)); [_arrowView setCenter:AlignPointToPixel(center)]; @@ -322,7 +322,7 @@ CGFloat distance = currentPoint.x; // The snap back animation is 0.1 seconds, so convert the velocity distance - // to where the |x| position would in .1 seconds. + // to where the `x` position would in .1 seconds. CGFloat velocityOffset = velocityPoint.x * kSwipeVelocityFraction; CGFloat width = CGRectGetWidth(self.targetView.bounds); if (gesture.direction == UISwipeGestureRecognizerDirectionLeft) { @@ -351,7 +351,7 @@ CGFloat threshold = width * kSwipeThreshold; CGFloat finalDistance = distance + velocityOffset; // Ensure the actual distance traveled has met the minimum arrow threshold - // and that the distance including expected velocity is over |threshold|. + // and that the distance including expected velocity is over `threshold`. if (distance > kArrowThreshold && finalDistance > threshold && _canNavigate && gesture.state == UIGestureRecognizerStateEnded) { TriggerHapticFeedbackForImpact(UIImpactFeedbackStyleMedium);
diff --git a/ios/chrome/browser/ui/side_swipe/side_swipe_util.h b/ios/chrome/browser/ui/side_swipe/side_swipe_util.h index 715c145..b6bb911 100644 --- a/ios/chrome/browser/ui/side_swipe/side_swipe_util.h +++ b/ios/chrome/browser/ui/side_swipe/side_swipe_util.h
@@ -17,7 +17,7 @@ // If swiping to the left (or right in RTL). BOOL IsSwipingForward(UISwipeGestureRecognizerDirection direction); -// Returns |YES| if the item should use Chromium native swipe. This is true for +// Returns `YES` if the item should use Chromium native swipe. This is true for // the NTP and chrome://crash. BOOL UseNativeSwipe(web::NavigationItem* item);
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm index 1f772d1..dd15a5cb 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_cell.mm
@@ -305,16 +305,17 @@ return; } // Do not fade in if there is no previous snapshot - if (_snapshot == nil) { - return; + if (_snapshot != nil) { + [UIView transitionWithView:self.snapshotView + duration:0.2f + options:UIViewAnimationOptionTransitionCrossDissolve + animations:^{ + self.snapshotView.image = snapshot; + } + completion:nil]; + } else { + self.snapshotView.image = snapshot; } - [UIView transitionWithView:self.snapshotView - duration:0.2f - options:UIViewAnimationOptionTransitionCrossDissolve - animations:^{ - self.snapshotView.image = snapshot; - } - completion:nil]; _snapshot = snapshot; }
diff --git a/ios/chrome/test/app/signin_test_util.mm b/ios/chrome/test/app/signin_test_util.mm index 30c6117..15404af9 100644 --- a/ios/chrome/test/app/signin_test_util.mm +++ b/ios/chrome/test/app/signin_test_util.mm
@@ -117,6 +117,8 @@ prefs->SetBoolean(prefs::kIosBookmarkPromoAlreadySeen, false); prefs->SetInteger(prefs::kIosSettingsSigninPromoDisplayedCount, 0); prefs->SetBoolean(prefs::kIosSettingsPromoAlreadySeen, false); + prefs->SetInteger(prefs::kIosNtpFeedTopSigninPromoDisplayedCount, 0); + prefs->SetBoolean(prefs::kIosNtpFeedTopPromoAlreadySeen, false); prefs->SetBoolean(prefs::kSigninShouldPromptForSigninAgain, false); }
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.h b/ios/chrome/test/earl_grey/chrome_earl_grey.h index 40abb5a1..88b66a7 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey.h +++ b/ios/chrome/test/earl_grey/chrome_earl_grey.h
@@ -654,9 +654,6 @@ // can, open multiple windows. - (BOOL)areMultipleWindowsSupported; -// Returns whether the new ContextMenu for web content feature is enabled. -- (BOOL)isContextMenuInWebViewEnabled; - // Returns whether the NewOverflowMenu feature is enabled. - (BOOL)isNewOverflowMenuEnabled;
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.mm b/ios/chrome/test/earl_grey/chrome_earl_grey.mm index 541a3c2..0881908 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey.mm +++ b/ios/chrome/test/earl_grey/chrome_earl_grey.mm
@@ -1241,10 +1241,6 @@ return [ChromeEarlGreyAppInterface areMultipleWindowsSupported]; } -- (BOOL)isContextMenuInWebViewEnabled { - return [ChromeEarlGreyAppInterface isContextMenuInWebViewEnabled]; -} - - (BOOL)isNewOverflowMenuEnabled { return [ChromeEarlGreyAppInterface isNewOverflowMenuEnabled]; }
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h index caa1190..c19574b 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h +++ b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.h
@@ -533,9 +533,6 @@ // can, open multiple windows. + (BOOL)areMultipleWindowsSupported; -// Returns whether the new ContextMenu for web content feature is enabled. -+ (BOOL)isContextMenuInWebViewEnabled; - // Returns whether the NewOverflowMenu feature is enabled. + (BOOL)isNewOverflowMenuEnabled;
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm index c5116a56..6f8bea4 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm +++ b/ios/chrome/test/earl_grey/chrome_earl_grey_app_interface.mm
@@ -1119,11 +1119,6 @@ return base::ios::IsMultipleScenesSupported(); } -+ (BOOL)isContextMenuInWebViewEnabled { - return base::FeatureList::IsEnabled( - web::features::kWebViewNativeContextMenuPhase2); -} - + (BOOL)isNewOverflowMenuEnabled { return IsNewOverflowMenuEnabled(); }
diff --git a/ios/web/common/features.h b/ios/web/common/features.h index e03a553..c9ae8564 100644 --- a/ios/web/common/features.h +++ b/ios/web/common/features.h
@@ -43,13 +43,6 @@ // WKWebView is set as NSURLRequestAttributionUser on iOS 15. extern const base::Feature kSetRequestAttribution; -// When enabled, display non-live preview for context menus in web content. -extern const base::Feature kWebViewNativeContextMenuPhase2; - -// When enabled, uses a screenshot transition to display context menus in web -// content. -extern const base::Feature kWebViewNativeContextMenuPhase2Screenshot; - // When enabled, the default context menu from WKWebView is used. extern const base::Feature kDefaultWebViewContextMenu;
diff --git a/ios/web/common/features.mm b/ios/web/common/features.mm index 37cc9e7..2e262e3c 100644 --- a/ios/web/common/features.mm +++ b/ios/web/common/features.mm
@@ -37,13 +37,6 @@ const base::Feature kSetRequestAttribution{"SetRequestAttribution", base::FEATURE_ENABLED_BY_DEFAULT}; -const base::Feature kWebViewNativeContextMenuPhase2{ - "WebViewNativeContextMenuPhase2", base::FEATURE_DISABLED_BY_DEFAULT}; - -const base::Feature kWebViewNativeContextMenuPhase2Screenshot{ - "WebViewNativeContextMenuPhase2Screenshot", - base::FEATURE_DISABLED_BY_DEFAULT}; - const base::Feature kDefaultWebViewContextMenu{ "DefaultWebViewContextMenu", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ios/web/js_features/context_menu/context_menu_constants.h b/ios/web/js_features/context_menu/context_menu_constants.h index 302b9af..84f8cf2 100644 --- a/ios/web/js_features/context_menu/context_menu_constants.h +++ b/ios/web/js_features/context_menu/context_menu_constants.h
@@ -47,21 +47,6 @@ // only). extern const char kContextMenuElementAlt[]; -// Optional key. Represents element's naturalWidth attribute if present (<img> -// element only). -extern const char kContextMenuElementNaturalWidth[]; - -// Optional key. Represents element's naturalHeight attribute if present (<img> -// element only). -extern const char kContextMenuElementNaturalHeight[]; - -// Optional key. Represents element's client bounding box if present. -extern const char kContextMenuElementBoundingBox[]; -extern const char kContextMenuElementBoundingBoxX[]; -extern const char kContextMenuElementBoundingBoxY[]; -extern const char kContextMenuElementBoundingBoxWidth[]; -extern const char kContextMenuElementBoundingBoxHeight[]; - } // namespace web #endif // IOS_WEB_JS_FEATURES_CONTEXT_MENU_CONTEXT_MENU_CONSTANTS_H_
diff --git a/ios/web/js_features/context_menu/context_menu_constants.mm b/ios/web/js_features/context_menu/context_menu_constants.mm index 06fbd44..0cf961e 100644 --- a/ios/web/js_features/context_menu/context_menu_constants.mm +++ b/ios/web/js_features/context_menu/context_menu_constants.mm
@@ -19,12 +19,5 @@ const char kContextMenuElementInnerText[] = "innerText"; const char kContextMenuElementTextOffset[] = "textOffset"; const char kContextMenuElementAlt[] = "alt"; -const char kContextMenuElementNaturalWidth[] = "naturalWidth"; -const char kContextMenuElementNaturalHeight[] = "naturalHeight"; -const char kContextMenuElementBoundingBox[] = "boundingBox"; -const char kContextMenuElementBoundingBoxX[] = "x"; -const char kContextMenuElementBoundingBoxY[] = "y"; -const char kContextMenuElementBoundingBoxWidth[] = "width"; -const char kContextMenuElementBoundingBoxHeight[] = "height"; } // namespace web
diff --git a/ios/web/js_features/context_menu/context_menu_js_unittest.mm b/ios/web/js_features/context_menu/context_menu_js_unittest.mm index 67d08db..2acb568a 100644 --- a/ios/web/js_features/context_menu/context_menu_js_unittest.mm +++ b/ios/web/js_features/context_menu/context_menu_js_unittest.mm
@@ -82,21 +82,13 @@ "CjxyZWN0IHdpZHRoPSI" "2MDAiIGhlaWdodD0iNjAwIiBmaWxsPSIjMDA2NmZmIi8+Cjwvc3ZnPg=="; -// Natural width of kImageSource after styling -const double kImageNaturalWidth = 84.0; - -// Natural height of kImageSource after styling -const double kImageNaturalHeight = 25.0; - // Alt text on image element for accessibility. const char kImageAlt[] = "Some alt text for an image"; // Style used to size the image returned by |GetHtmlForImage()|. const char kImageSizeStyle[] = "width:100%;height:25%;"; -// Style used to size a div with the background image set. The div should be -// the same size as the image's natural size as specified in kImageNaturalWidth -// andkImageNaturalHeight. +// Style used to size a div with the background image set. const char kBackgroundDivStyle[] = "width:100%;height:25px;"; // Style used to create an overlay div. @@ -304,20 +296,6 @@ // Returns the test page URL. NSURL* GetTestURL() { return net::NSURLWithGURL(GURL(kTestUrl)); } - // Returns the expected bounding box values for the test Image. - base::Value GetExpectedBoundingBoxForTestImage() { - base::Value bounding_box_expected_value(base::Value::Type::DICTIONARY); - bounding_box_expected_value.SetDoubleKey(kContextMenuElementBoundingBoxX, - 8.0); - bounding_box_expected_value.SetDoubleKey(kContextMenuElementBoundingBoxY, - 8.0); - bounding_box_expected_value.SetDoubleKey( - kContextMenuElementBoundingBoxWidth, 84.0); - bounding_box_expected_value.SetDoubleKey( - kContextMenuElementBoundingBoxHeight, 25.0); - return bounding_box_expected_value; - } - // Executes __gCrWeb.findElementAtPoint script with the given |point| in the // web view viewport's coordinate space. id ExecuteFindElementFromPointJavaScript(CGPoint point) { @@ -347,12 +325,6 @@ expected_value.SetStringKey(kContextMenuElementSource, kImageSource); expected_value.SetStringKey(kContextMenuElementAlt, kImageAlt); expected_value.SetStringKey(kContextMenuElementReferrerPolicy, "default"); - expected_value.SetDoubleKey(kContextMenuElementNaturalWidth, - kImageNaturalWidth); - expected_value.SetDoubleKey(kContextMenuElementNaturalHeight, - kImageNaturalHeight); - expected_value.SetKey(kContextMenuElementBoundingBox, - GetExpectedBoundingBoxForTestImage()); expected_value.SetStringKey(kContextMenuElementTagName, "img"); CheckElementResult(kPointOnImage, expected_value); @@ -375,12 +347,6 @@ expected_value.SetStringKey(kContextMenuElementSource, kImageSource); expected_value.SetStringKey(kContextMenuElementAlt, kImageAlt); expected_value.SetStringKey(kContextMenuElementReferrerPolicy, "default"); - expected_value.SetKey(kContextMenuElementBoundingBox, - GetExpectedBoundingBoxForTestImage()); - expected_value.SetDoubleKey(kContextMenuElementNaturalWidth, - kImageNaturalWidth); - expected_value.SetDoubleKey(kContextMenuElementNaturalHeight, - kImageNaturalHeight); expected_value.SetStringKey(kContextMenuElementTagName, "img"); CheckElementResult(kPointOnImage, expected_value); @@ -399,8 +365,6 @@ expected_value.SetStringKey(kContextMenuElementRequestId, kRequestId); expected_value.SetStringKey(kContextMenuElementSource, kImageSource); expected_value.SetStringKey(kContextMenuElementReferrerPolicy, "default"); - expected_value.SetKey(kContextMenuElementBoundingBox, - GetExpectedBoundingBoxForTestImage()); expected_value.SetStringKey(kContextMenuElementTagName, "img"); CheckElementResult(kPointOnImage, expected_value); @@ -422,12 +386,6 @@ expected_value.SetStringKey(kContextMenuElementSource, kImageSource); expected_value.SetStringKey(kContextMenuElementAlt, kImageAlt); expected_value.SetStringKey(kContextMenuElementReferrerPolicy, "default"); - expected_value.SetDoubleKey(kContextMenuElementNaturalWidth, - kImageNaturalWidth); - expected_value.SetDoubleKey(kContextMenuElementNaturalHeight, - kImageNaturalHeight); - expected_value.SetKey(kContextMenuElementBoundingBox, - GetExpectedBoundingBoxForTestImage()); expected_value.SetStringKey(kContextMenuElementTagName, "img"); CheckElementResult(kPointOnImage, expected_value); @@ -450,7 +408,6 @@ expected_value.SetStringKey(kContextMenuElementTagName, "DIV"); std::vector<const char*> ignored_keys; - ignored_keys.push_back(kContextMenuElementBoundingBox); ignored_keys.push_back(kContextMenuElementTextOffset); CheckElementResult(kPointOnImage, expected_value, ignored_keys); @@ -470,12 +427,6 @@ expected_value.SetStringKey(kContextMenuElementSource, kImageSource); expected_value.SetStringKey(kContextMenuElementAlt, kImageAlt); expected_value.SetStringKey(kContextMenuElementReferrerPolicy, "default"); - expected_value.SetDoubleKey(kContextMenuElementNaturalWidth, - kImageNaturalWidth); - expected_value.SetDoubleKey(kContextMenuElementNaturalHeight, - kImageNaturalHeight); - expected_value.SetKey(kContextMenuElementBoundingBox, - GetExpectedBoundingBoxForTestImage()); expected_value.SetStringKey(kContextMenuElementTitle, image_title); expected_value.SetStringKey(kContextMenuElementTagName, "img"); @@ -493,12 +444,6 @@ expected_value.SetStringKey(kContextMenuElementSource, kImageSource); expected_value.SetStringKey(kContextMenuElementAlt, kImageAlt); expected_value.SetStringKey(kContextMenuElementReferrerPolicy, "default"); - expected_value.SetKey(kContextMenuElementBoundingBox, - GetExpectedBoundingBoxForTestImage()); - expected_value.SetDoubleKey(kContextMenuElementNaturalWidth, - kImageNaturalWidth); - expected_value.SetDoubleKey(kContextMenuElementNaturalHeight, - kImageNaturalHeight); expected_value.SetStringKey(kContextMenuElementTagName, "img"); CheckElementResult(kPointOnImage, expected_value); @@ -544,12 +489,6 @@ expected_value.SetStringKey(kContextMenuElementSource, kImageSource); expected_value.SetStringKey(kContextMenuElementAlt, kImageAlt); expected_value.SetStringKey(kContextMenuElementReferrerPolicy, "default"); - expected_value.SetDoubleKey(kContextMenuElementNaturalWidth, - kImageNaturalWidth); - expected_value.SetDoubleKey(kContextMenuElementNaturalHeight, - kImageNaturalHeight); - expected_value.SetKey(kContextMenuElementBoundingBox, - GetExpectedBoundingBoxForTestImage()); expected_value.SetStringKey(kContextMenuElementHyperlink, image_link); expected_value.SetStringKey(kContextMenuElementTagName, "img"); @@ -605,8 +544,6 @@ expected_value.SetStringKey(kContextMenuElementSource, image_source); expected_value.SetStringKey(kContextMenuElementAlt, kImageAlt); expected_value.SetStringKey(kContextMenuElementReferrerPolicy, "default"); - expected_value.SetKey(kContextMenuElementBoundingBox, - GetExpectedBoundingBoxForTestImage()); expected_value.SetStringKey(kContextMenuElementHyperlink, image_link); expected_value.SetStringKey(kContextMenuElementTagName, "img"); @@ -633,8 +570,6 @@ expected_value.SetStringKey(kContextMenuElementSource, image_source); expected_value.SetStringKey(kContextMenuElementAlt, kImageAlt); expected_value.SetStringKey(kContextMenuElementReferrerPolicy, "default"); - expected_value.SetKey(kContextMenuElementBoundingBox, - GetExpectedBoundingBoxForTestImage()); expected_value.SetStringKey(kContextMenuElementHyperlink, image_link); expected_value.SetStringKey(kContextMenuElementTagName, "img"); @@ -661,8 +596,6 @@ expected_value.SetStringKey(kContextMenuElementSource, image_source); expected_value.SetStringKey(kContextMenuElementAlt, kImageAlt); expected_value.SetStringKey(kContextMenuElementReferrerPolicy, "default"); - expected_value.SetKey(kContextMenuElementBoundingBox, - GetExpectedBoundingBoxForTestImage()); expected_value.SetStringKey(kContextMenuElementTagName, "img"); // Make sure the returned JSON does not have an 'href' key. @@ -688,8 +621,6 @@ expected_value.SetStringKey(kContextMenuElementSource, image_source); expected_value.SetStringKey(kContextMenuElementAlt, kImageAlt); expected_value.SetStringKey(kContextMenuElementReferrerPolicy, "default"); - expected_value.SetKey(kContextMenuElementBoundingBox, - GetExpectedBoundingBoxForTestImage()); expected_value.SetStringKey(kContextMenuElementTagName, "img"); // Make sure the returned JSON does not have an 'href' key. @@ -710,12 +641,6 @@ expected_value.SetStringKey(kContextMenuElementSource, kImageSource); expected_value.SetStringKey(kContextMenuElementAlt, kImageAlt); expected_value.SetStringKey(kContextMenuElementReferrerPolicy, "default"); - expected_value.SetDoubleKey(kContextMenuElementNaturalWidth, - kImageNaturalWidth); - expected_value.SetDoubleKey(kContextMenuElementNaturalHeight, - kImageNaturalHeight); - expected_value.SetKey(kContextMenuElementBoundingBox, - GetExpectedBoundingBoxForTestImage()); expected_value.SetStringKey(kContextMenuElementTagName, "img"); // Make sure the returned JSON does not have an 'href' key. @@ -742,10 +667,7 @@ expected_value.SetStringKey(kContextMenuElementHyperlink, image_link); expected_value.SetStringKey(kContextMenuElementTagName, "a"); - std::vector<const char*> ignored_keys; - ignored_keys.push_back(kContextMenuElementBoundingBox); - - CheckElementResult(kPointOnImage, expected_value, ignored_keys); + CheckElementResult(kPointOnImage, expected_value); } #pragma mark - SVG shape links @@ -762,10 +684,7 @@ expected_value.SetStringKey(kContextMenuElementHyperlink, link); expected_value.SetStringKey(kContextMenuElementTagName, "a"); - std::vector<const char*> ignored_keys; - ignored_keys.push_back(kContextMenuElementBoundingBox); - - CheckElementResult(kPointOnSvgLink, expected_value, ignored_keys); + CheckElementResult(kPointOnSvgLink, expected_value); } // Tests that an SVG shape xlink returns details for the link. @@ -780,10 +699,7 @@ expected_value.SetStringKey(kContextMenuElementHyperlink, link); expected_value.SetStringKey(kContextMenuElementTagName, "a"); - std::vector<const char*> ignored_keys; - ignored_keys.push_back(kContextMenuElementBoundingBox); - - CheckElementResult(kPointOnSvgLink, expected_value, ignored_keys); + CheckElementResult(kPointOnSvgLink, expected_value); } // Tests that a point within an SVG element but outside a linked shape does not @@ -799,7 +715,6 @@ expected_value.SetStringKey(kContextMenuElementTagName, "P"); std::vector<const char*> ignored_keys; - ignored_keys.push_back(kContextMenuElementBoundingBox); ignored_keys.push_back(kContextMenuElementTextOffset); CheckElementResult(kPointOutsideSvgLink, expected_value, ignored_keys); @@ -881,12 +796,8 @@ expected_value.SetStringKey(kContextMenuElementHyperlink, link); expected_value.SetStringKey(kContextMenuElementTagName, "a"); - std::vector<const char*> ignored_keys; - ignored_keys.push_back(kContextMenuElementBoundingBox); - // Link is at bottom of the page content. - CheckElementResult(CGPointMake(50.0, content_height - 100), expected_value, - ignored_keys); + CheckElementResult(CGPointMake(50.0, content_height - 100), expected_value); } // Tests that __gCrWeb.findElementAtPoint finds a link inside shadow DOM @@ -905,10 +816,7 @@ expected_value.SetStringKey(kContextMenuElementHyperlink, link); expected_value.SetStringKey(kContextMenuElementTagName, "a"); - std::vector<const char*> ignored_keys; - ignored_keys.push_back(kContextMenuElementBoundingBox); - - CheckElementResult(kPointOnShadowDomLink, expected_value, ignored_keys); + CheckElementResult(kPointOnShadowDomLink, expected_value); } // Tests that a point within shadow DOM content but not on a link does not @@ -926,7 +834,6 @@ expected_value.SetStringKey(kContextMenuElementTagName, "DIV"); std::vector<const char*> ignored_keys; - ignored_keys.push_back(kContextMenuElementBoundingBox); ignored_keys.push_back(kContextMenuElementTextOffset); CheckElementResult(kPointOutsideShadowDomLink, expected_value, ignored_keys); @@ -948,10 +855,7 @@ expected_value.SetStringKey(kContextMenuElementHyperlink, link); expected_value.SetStringKey(kContextMenuElementTagName, "a"); - std::vector<const char*> ignored_keys; - ignored_keys.push_back(kContextMenuElementBoundingBox); - - CheckElementResult(kPointOnLink, expected_value, ignored_keys); + CheckElementResult(kPointOnLink, expected_value); } // Tests that a callout information about a link is displayed when @@ -972,10 +876,7 @@ expected_value.SetStringKey(kContextMenuElementHyperlink, link); expected_value.SetStringKey(kContextMenuElementTagName, "a"); - std::vector<const char*> ignored_keys; - ignored_keys.push_back(kContextMenuElementBoundingBox); - - CheckElementResult(kPointOnLink, expected_value, ignored_keys); + CheckElementResult(kPointOnLink, expected_value); } // Tests that no callout information about a link is displayed when @@ -996,7 +897,6 @@ expected_value.SetStringKey(kContextMenuElementTagName, "P"); std::vector<const char*> ignored_keys; - ignored_keys.push_back(kContextMenuElementBoundingBox); ignored_keys.push_back(kContextMenuElementTextOffset); CheckElementResult(kPointOnLink, expected_value, ignored_keys); @@ -1019,7 +919,6 @@ expected_value.SetStringKey(kContextMenuElementTagName, "P"); std::vector<const char*> ignored_keys; - ignored_keys.push_back(kContextMenuElementBoundingBox); ignored_keys.push_back(kContextMenuElementTextOffset); CheckElementResult(kPointOnLink, expected_value, ignored_keys); @@ -1044,10 +943,7 @@ expected_value.SetStringKey(kContextMenuElementHyperlink, link); expected_value.SetStringKey(kContextMenuElementTagName, "a"); - std::vector<const char*> ignored_keys; - ignored_keys.push_back(kContextMenuElementBoundingBox); - - CheckElementResult(kPointOnLink, expected_value, ignored_keys); + CheckElementResult(kPointOnLink, expected_value); } } // namespace web
diff --git a/ios/web/js_features/context_menu/context_menu_params.mm b/ios/web/js_features/context_menu/context_menu_params.mm index 2b53a9e..9f3ef91 100644 --- a/ios/web/js_features/context_menu/context_menu_params.mm +++ b/ios/web/js_features/context_menu/context_menu_params.mm
@@ -15,9 +15,6 @@ tag_name(nil), referrer_policy(ReferrerPolicyDefault), location(CGPointZero), - natural_width(0.0), - natural_height(0.0), - bounding_box(CGRectZero), text_offset(0) {} ContextMenuParams::ContextMenuParams(const ContextMenuParams& other) = default;
diff --git a/ios/web/js_features/context_menu/context_menu_params_utils.mm b/ios/web/js_features/context_menu/context_menu_params_utils.mm index 45784b4..36ee250 100644 --- a/ios/web/js_features/context_menu/context_menu_params_utils.mm +++ b/ios/web/js_features/context_menu/context_menu_params_utils.mm
@@ -17,25 +17,6 @@ namespace web { -CGRect BoundingBoxFromBoundingBoxDictionary(const base::Value* boundingBox) { - absl::optional<double> x = - boundingBox->FindDoubleKey(kContextMenuElementBoundingBoxX); - absl::optional<double> y = - boundingBox->FindDoubleKey(kContextMenuElementBoundingBoxY); - absl::optional<double> width = - boundingBox->FindDoubleKey(kContextMenuElementBoundingBoxWidth); - absl::optional<double> height = - boundingBox->FindDoubleKey(kContextMenuElementBoundingBoxHeight); - - if (x && y && width && height && width > 0.0 && height > 0.0) { - const double elementSize = *height * *width; - if (elementSize < kContextMenuMaxScreenshotSize) { - return CGRectMake(*x, *y, *width, *height); - } - } - return CGRectZero; -} - ContextMenuParams ContextMenuParamsFromElementDictionary(base::Value* element) { ContextMenuParams params; if (!element || !element->is_dict()) { @@ -87,24 +68,6 @@ params.text_offset = *text_offset; } - absl::optional<double> natural_width = - element->FindDoubleKey(web::kContextMenuElementNaturalWidth); - if (natural_width.has_value()) { - params.natural_width = *natural_width; - } - - absl::optional<double> natural_height = - element->FindDoubleKey(web::kContextMenuElementNaturalHeight); - if (natural_height.has_value()) { - params.natural_height = *natural_height; - } - - base::Value* bounding_box = - element->FindDictKey(web::kContextMenuElementBoundingBox); - if (bounding_box) { - params.bounding_box = BoundingBoxFromBoundingBoxDictionary(bounding_box); - } - return params; }
diff --git a/ios/web/js_features/context_menu/context_menu_params_utils_unittest.mm b/ios/web/js_features/context_menu/context_menu_params_utils_unittest.mm index 5b77c104..07ccca42 100644 --- a/ios/web/js_features/context_menu/context_menu_params_utils_unittest.mm +++ b/ios/web/js_features/context_menu/context_menu_params_utils_unittest.mm
@@ -27,12 +27,6 @@ const char kReferrerPolicy[] = "always"; const char kLinkText[] = "link text"; const char kAlt[] = "alt text"; -const double kNaturalWidth = 200.0; -const double kNaturalHeight = 300.0; -const double kBoundingBoxX = 10.0; -const double kBoundingBoxY = 20.0; -const double kBoundingBoxWidth = 50.0; -const double kBoundingBoxHeight = 200.0; // Returns true if the |params| contain enough information to present a context // menu. (A valid url for either link_url or src_url must exist in the params.) @@ -64,10 +58,6 @@ EXPECT_NSEQ(params.text, nil); EXPECT_NSEQ(params.title_attribute, nil); EXPECT_NSEQ(params.alt_text, nil); - EXPECT_NEAR(params.natural_width, 0.0, DBL_EPSILON); - EXPECT_NEAR(params.natural_height, 0.0, DBL_EPSILON); - EXPECT_TRUE(CGRectIsEmpty(params.bounding_box)); - EXPECT_EQ(params.screenshot, nil); } // Tests the parsing of the element NSDictionary. @@ -79,19 +69,6 @@ element_dict.SetStringKey(kContextMenuElementReferrerPolicy, kReferrerPolicy); element_dict.SetStringKey(kContextMenuElementInnerText, kLinkText); element_dict.SetStringKey(kContextMenuElementAlt, kAlt); - element_dict.SetDoubleKey(kContextMenuElementNaturalWidth, kNaturalWidth); - element_dict.SetDoubleKey(kContextMenuElementNaturalHeight, kNaturalHeight); - base::Value bounding_box_element_dict(base::Value::Type::DICTIONARY); - bounding_box_element_dict.SetDoubleKey(kContextMenuElementBoundingBoxX, - kBoundingBoxX); - bounding_box_element_dict.SetDoubleKey(kContextMenuElementBoundingBoxY, - kBoundingBoxY); - bounding_box_element_dict.SetDoubleKey(kContextMenuElementBoundingBoxWidth, - kBoundingBoxWidth); - bounding_box_element_dict.SetDoubleKey(kContextMenuElementBoundingBoxHeight, - kBoundingBoxHeight); - element_dict.SetKey(kContextMenuElementBoundingBox, - std::move(bounding_box_element_dict)); ContextMenuParams params = ContextMenuParamsFromElementDictionary(&element_dict); @@ -106,14 +83,6 @@ EXPECT_NSEQ(params.title_attribute, @(kTitle)); EXPECT_NSEQ(params.alt_text, @(kAlt)); - - EXPECT_NEAR(params.natural_width, kNaturalWidth, DBL_EPSILON); - EXPECT_NEAR(params.natural_height, kNaturalHeight, DBL_EPSILON); - - EXPECT_NEAR(params.bounding_box.origin.x, kBoundingBoxX, DBL_EPSILON); - EXPECT_NEAR(params.bounding_box.origin.y, kBoundingBoxY, DBL_EPSILON); - EXPECT_NEAR(params.bounding_box.size.width, kBoundingBoxWidth, DBL_EPSILON); - EXPECT_NEAR(params.bounding_box.size.height, kBoundingBoxHeight, DBL_EPSILON); }
diff --git a/ios/web/js_features/context_menu/resources/all_frames_context_menu.js b/ios/web/js_features/context_menu/resources/all_frames_context_menu.js index 33b1893..c9044834 100644 --- a/ios/web/js_features/context_menu/resources/all_frames_context_menu.js +++ b/ios/web/js_features/context_menu/resources/all_frames_context_menu.js
@@ -28,7 +28,6 @@ * {@code referrerPolicy} The referrer policy to use for * navigations away from the current page. * {@code innerText} The inner text of the link. - * {@code boundingBox} The bounding box of the element. * }. */ var getResponseForLinkElement = function(element) { @@ -37,7 +36,6 @@ href: getElementHref_(element), referrerPolicy: getReferrerPolicy_(element), innerText: element.innerText, - boundingBox: getElementBoundingBox_(element) }; }; @@ -50,15 +48,10 @@ * {@code src} The src of the image. * {@code referrerPolicy} The referrer policy to use for * navigations away from the current page. - * {@code boundingBox} The bounding box of the element. * {@code title} (optional) The title of the image, if one * exists. * {@code href} (optional) The URL of the link, if one * exists. - * {@code naturalWidth} (optional) The natural width of - * the image, if one exists. - * {@code naturalHeight} (optional) The natural height of - * the image, if one exists. * }. */ var getResponseForImageElement = function(element, src) { @@ -66,7 +59,6 @@ tagName: 'img', src: src, referrerPolicy: getReferrerPolicy_(), - boundingBox: getElementBoundingBox_(element) }; var parent = element.parentNode; // Copy the title, if any. @@ -95,14 +87,6 @@ } parent = parent.parentNode; } - // Copy the image natural width, if any. - if (element.naturalWidth) { - result.naturalWidth = element.naturalWidth; - } - // Copy the image natural height, if any. - if (element.naturalHeight) { - result.naturalHeight = element.naturalHeight; - } return result; }; @@ -123,7 +107,6 @@ var getResponseForTextElement = function(element, x, y) { var result = { tagName: element.tagName, - boundingBox: getElementBoundingBox_(element), }; // caretRangeFromPoint is custom WebKit method. if (document.caretRangeFromPoint) { @@ -476,30 +459,6 @@ return href; }; -/** - * Returns the client bounding box of the given element. - * @param {HTMLElement} element to retrieve the bounding box - * @return {!Object} An object of the form { - * {@code x} The x coordinate of the bounding box origin. - * {@code y} The y coordinate of the bounding box origin. - * {@code width} The width of the bounding box size. - * {@code height} The height of the bounding box size. - * }. - */ -var getElementBoundingBox_ = function(element) { - var boundingBox = element.getBoundingClientRect(); - if (boundingBox) { - return { - x: boundingBox.x, - y: boundingBox.y, - width: boundingBox.width, - height: boundingBox.height - }; - } - else { - return null; - } -}; /** * Checks if the element is effectively transparent and should be skipped when
diff --git a/ios/web/public/ui/context_menu_params.h b/ios/web/public/ui/context_menu_params.h index 1be10a5..ea07f667 100644 --- a/ios/web/public/ui/context_menu_params.h +++ b/ios/web/public/ui/context_menu_params.h
@@ -57,18 +57,6 @@ // The text for the "alt" attribute of an HTML img element. Can be null. NSString* alt_text; - // The natural width of the HTML img element. Can be null = 0. - double natural_width; - - // The natural height of the HTML img element. Can be null = 0. - double natural_height; - - // The client bounding box of the HTML element. Can be null = CGRectZero. - CGRect bounding_box; - - // The screenshot of the HTML element. Can be null = nil. - UIImage* screenshot; - // The offset in text where the tap occurs. Can be null = 0. double text_offset; };
diff --git a/ios/web/web_state/ui/crw_context_menu_controller.mm b/ios/web/web_state/ui/crw_context_menu_controller.mm index e2fdf26..2e22e42 100644 --- a/ios/web/web_state/ui/crw_context_menu_controller.mm +++ b/ios/web/web_state/ui/crw_context_menu_controller.mm
@@ -23,11 +23,6 @@ namespace { const CGFloat kJavaScriptTimeout = 1; -// The animation still looks good without the screenshot so the timeout is -// smaller. -const CGFloat kScreenshotTimeout = 0.3; -const CGFloat kScreenshotInset = 2; -const CGFloat kScreenshotCornerRadius = 10; // Wrapper around CFRunLoop() to help crash server put all crashes happening // while the loop is executed in the same bucket. Marked as `noinline` to @@ -111,29 +106,7 @@ } web::ContextMenuParams params = optionalParams.value(); - // Converts javascript bounding box to webView bounding box. - CGRect screenshotBoundingBox = params.bounding_box; - if (!CGRectIsEmpty(screenshotBoundingBox)) { - screenshotBoundingBox = - [self webViewBoundingBoxFromElementBoundingBox:screenshotBoundingBox]; - } - - // Adding the screenshot view here, so it can be used in the delegate's - // methods. - if (base::FeatureList::IsEnabled( - web::features::kWebViewNativeContextMenuPhase2Screenshot) && - base::FeatureList::IsEnabled( - web::features::kWebViewNativeContextMenuPhase2) && - !CGRectIsEmpty(screenshotBoundingBox)) { - self.screenshotView = - [self fetchScreenshotViewAtBoundingBox:screenshotBoundingBox]; - params.screenshot = self.screenshotView.image; - self.screenshotView.center = - CGPointMake(CGRectGetMidX(screenshotBoundingBox), - CGRectGetMidY(screenshotBoundingBox)); - } else { - self.screenshotView.center = location; - } + self.screenshotView.center = location; // Adding the screenshotView here so they can be used in the // delegate's methods. Will be removed if no menu is presented. @@ -163,20 +136,26 @@ (UIContextMenuInteraction*)interaction previewForHighlightingMenuWithConfiguration: (UIContextMenuConfiguration*)configuration { + UIPreviewParameters* previewParameters = [[UIPreviewParameters alloc] init]; + previewParameters.backgroundColor = UIColor.clearColor; + return [[UITargetedPreview alloc] initWithView:self.screenshotView - parameters:[self previewParameters]]; + parameters:previewParameters]; } - (UITargetedPreview*)contextMenuInteraction: (UIContextMenuInteraction*)interaction previewForDismissingMenuWithConfiguration: (UIContextMenuConfiguration*)configuration { + UIPreviewParameters* previewParameters = [[UIPreviewParameters alloc] init]; + previewParameters.backgroundColor = UIColor.clearColor; + // If the dismiss view is not attached to the view hierarchy, fallback to nil // to prevent app crashing. See crbug.com/1231888. UITargetedPreview* targetPreview = self.screenshotView.window ? [[UITargetedPreview alloc] initWithView:self.screenshotView - parameters:[self previewParameters]] + parameters:previewParameters] : nil; self.screenshotView = nil; return targetPreview; @@ -205,21 +184,6 @@ #pragma mark - Private -// Returns preview parameters for highlight/dismiss previews. -- (UIPreviewParameters*)previewParameters { - UIPreviewParameters* previewParameters = [[UIPreviewParameters alloc] init]; - previewParameters.backgroundColor = UIColor.clearColor; - if (kScreenshotInset < self.screenshotView.frame.size.width && - kScreenshotInset < self.screenshotView.frame.size.height) { - previewParameters.visiblePath = [UIBezierPath - bezierPathWithRoundedRect:CGRectInset(self.screenshotView.bounds, - kScreenshotInset, - kScreenshotInset) - cornerRadius:kScreenshotCornerRadius]; - } - return previewParameters; -} - // Prevents the web view gesture recognizer to get the touch events. - (void)cancelAllTouches { // All user gestures are handled by a subview of web view scroll view @@ -289,89 +253,4 @@ return resultParams; } -// Converts HTMLElement bounding box to webView coordinates. -// Returns CGRectZero if the converted bounding box exeeds the maximum allowed -// size. -- (CGRect)webViewBoundingBoxFromElementBoundingBox:(CGRect)elementBoundingBox { - CGRect boundingBox = elementBoundingBox; - - // Viewport gives the correct top inset. - id<CRWViewportAdjustmentContainer> viewportAdjustmentContainer = - static_cast<id<CRWViewportAdjustmentContainer>>(self.webState->GetView()); - UIView<CRWViewportAdjustment>* viewportAdjustmentView = - [viewportAdjustmentContainer fullscreenViewportAdjuster]; - UIEdgeInsets viewportInsets = [viewportAdjustmentView viewportInsets]; - - // Bounding box is scaled to handle page zooming. - // ScrollView gives the correct left inset. - CGFloat zoomScale = self.webView.scrollView.zoomScale; - boundingBox.size.width *= zoomScale; - boundingBox.size.height *= zoomScale; - boundingBox.origin.x = boundingBox.origin.x * zoomScale + - self.webView.scrollView.adjustedContentInset.left; - boundingBox.origin.y = boundingBox.origin.y * zoomScale + viewportInsets.top; - - const double size = boundingBox.size.height * boundingBox.size.width; - if (size >= web::kContextMenuMaxScreenshotSize) { - return CGRectZero; - } - - return boundingBox; -} - -// Fetches a UIImageView containing a screenshot of webState at location of -// |screenshotBoundingBox|. The screenshot image can be empty. -- (UIImageView*)fetchScreenshotViewAtBoundingBox:(CGRect)screenshotBoundingBox { - // While traditionally using dispatch_async would be used here, we have to - // instead use CFRunLoop because dispatch_async blocks the thread. As this - // function is called by iOS when it detects the user's force touch, it is on - // the main thread and we cannot block that. CFRunLoop instead just loops on - // the main thread until the completion block is fired. - __block BOOL isRunLoopNested = NO; - __block BOOL screenshotCompleted = NO; - __block BOOL isRunLoopComplete = NO; - - __block UIImageView* screenshotView = [[UIImageView alloc] - initWithFrame:CGRectMake(0, 0, screenshotBoundingBox.size.width, - screenshotBoundingBox.size.height)]; - screenshotView.backgroundColor = UIColor.clearColor; - self.webState->TakeSnapshot( - gfx::RectF(screenshotBoundingBox), - base::BindRepeating(^(const gfx::Image& image) { - screenshotCompleted = YES; - if (image.HasRepresentation( - gfx::Image::RepresentationType::kImageRepCocoaTouch)) { - screenshotView.image = image.ToUIImage(); - } - if (isRunLoopNested) { - CFRunLoopStop(CFRunLoopGetCurrent()); - } - })); - - // Make sure to timeout in case the screenshot doesn't return in a timely - // manner. While this is executing, the scrolling on the page is frozen. - // Interacting with the page will force this method to return even before any - // of this code is called. - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, - (int64_t)(kScreenshotTimeout * NSEC_PER_SEC)), - dispatch_get_main_queue(), ^{ - if (!isRunLoopComplete) { - CFRunLoopStop(CFRunLoopGetCurrent()); - screenshotCompleted = YES; - } - }); - - // CFRunLoopRun isn't necessary if javascript evaluation is completed by the - // time we reach this line. - if (!screenshotCompleted) { - isRunLoopNested = YES; - ContextMenuNestedCFRunLoop(); - isRunLoopNested = NO; - } - - isRunLoopComplete = YES; - - return screenshotView; -} - @end
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 7bca356..f3a15a8a 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -206,19 +206,12 @@ const char kEnableLiveCaptionPrefForTesting[] = "enable-live-caption-pref-for-testing"; -#if BUILDFLAG(ENABLE_PLATFORM_HEVC) -// Enables playback of clear (unencrypted) HEVC content for testing purposes. -const char kEnableClearHevcForTesting[] = "enable-clear-hevc-for-testing"; -#endif - #if BUILDFLAG(IS_CHROMEOS) // These are flags passed from ash-chrome to lacros-chrome that correspond to // buildflags for the platform we are running on. lacros-chrome only builds for // x86/arm differences, so we unconditionally build in the below features into // the relevant parts of lacros-chrome and then filter the functionality based // on these command line flags. -MEDIA_EXPORT extern const char kLacrosEnablePlatformEncryptedHevc[] = - "lacros-enable-platform-encrypted-hevc"; MEDIA_EXPORT extern const char kLacrosEnablePlatformHevc[] = "lacros-enable-platform-hevc"; MEDIA_EXPORT extern const char kLacrosUseChromeosProtectedMedia[] =
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index ef7f048..247bdae9 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -88,17 +88,7 @@ MEDIA_EXPORT extern const char kOverrideHardwareSecureCodecsForTesting[]; MEDIA_EXPORT extern const char kEnableLiveCaptionPrefForTesting[]; -#if BUILDFLAG(ENABLE_PLATFORM_HEVC) -// TODO(crbug/1311348): Remove this after Chrome clear HEVC lands and Chrome OS -// is uprev'd to use that version and we then also land changes to tast-tests -// that drop usage of this flag. -MEDIA_EXPORT extern const char kEnableClearHevcForTesting[]; -#endif - #if BUILDFLAG(IS_CHROMEOS) -// TODO(crbug/1311348): Remove kLacrosEnablePlatformEncryptedHevc after Chrome -// clear HEVC lands and Chrome OS is uprev'd to use that version for ash-chrome. -MEDIA_EXPORT extern const char kLacrosEnablePlatformEncryptedHevc[]; MEDIA_EXPORT extern const char kLacrosEnablePlatformHevc[]; MEDIA_EXPORT extern const char kLacrosUseChromeosProtectedMedia[]; MEDIA_EXPORT extern const char kLacrosUseChromeosProtectedAv1[];
diff --git a/net/base/address_list.cc b/net/base/address_list.cc index b3c91d8..121bdc4c 100644 --- a/net/base/address_list.cc +++ b/net/base/address_list.cc
@@ -116,19 +116,19 @@ } base::Value AddressList::NetLogParams() const { - base::Value dict(base::Value::Type::DICTIONARY); + base::Value::Dict dict; - base::Value address_list(base::Value::Type::LIST); + base::Value::List address_list; for (const auto& ip_endpoint : *this) address_list.Append(ip_endpoint.ToString()); - dict.SetKey("address_list", std::move(address_list)); + dict.Set("address_list", std::move(address_list)); - base::Value alias_list(base::Value::Type::LIST); + base::Value::List alias_list; for (const std::string& alias : dns_aliases_) alias_list.Append(alias); - dict.SetKey("aliases", std::move(alias_list)); + dict.Set("aliases", std::move(alias_list)); - return dict; + return base::Value(std::move(dict)); } void AddressList::Deduplicate() {
diff --git a/net/base/backoff_entry_serializer_unittest.cc b/net/base/backoff_entry_serializer_unittest.cc index 856c640..02e515a4 100644 --- a/net/base/backoff_entry_serializer_unittest.cc +++ b/net/base/backoff_entry_serializer_unittest.cc
@@ -141,7 +141,7 @@ // Check that the serialized backoff duration matches our expectation. const std::string& serialized_backoff_duration_string = - serialized.GetListDeprecated()[2].GetString(); + serialized.GetList()[2].GetString(); int64_t serialized_backoff_duration_us; EXPECT_TRUE(base::StringToInt64(serialized_backoff_duration_string, &serialized_backoff_duration_us)); @@ -174,7 +174,7 @@ // Reach into the serialization and check the string-formatted release time. const std::string& serialized_release_time = - serialized.GetListDeprecated()[3].GetString(); + serialized.GetList()[3].GetString(); EXPECT_EQ(serialized_release_time, "0"); // Test that |DeserializeFromValue| notices this zero-valued release time and @@ -331,74 +331,74 @@ } TEST(BackoffEntrySerializerTest, DeserializeUnknownVersion) { - base::Value serialized(base::Value::Type::LIST); + base::Value::List serialized; serialized.Append(0); // Format version that never existed serialized.Append(0); // Failure count serialized.Append(2.0); // Backoff duration serialized.Append("1234"); // Absolute release time auto deserialized = BackoffEntrySerializer::DeserializeFromValue( - serialized, &base_policy, nullptr, kParseTime); + base::Value(std::move(serialized)), &base_policy, nullptr, kParseTime); ASSERT_FALSE(deserialized); } TEST(BackoffEntrySerializerTest, DeserializeVersion1) { - base::Value serialized(base::Value::Type::LIST); + base::Value::List serialized; serialized.Append(SerializationFormatVersion::kVersion1); serialized.Append(0); // Failure count serialized.Append(2.0); // Backoff duration in seconds as double serialized.Append("1234"); // Absolute release time auto deserialized = BackoffEntrySerializer::DeserializeFromValue( - serialized, &base_policy, nullptr, kParseTime); + base::Value(std::move(serialized)), &base_policy, nullptr, kParseTime); ASSERT_TRUE(deserialized); } TEST(BackoffEntrySerializerTest, DeserializeVersion2) { - base::Value serialized(base::Value::Type::LIST); + base::Value::List serialized; serialized.Append(SerializationFormatVersion::kVersion2); serialized.Append(0); // Failure count serialized.Append("2000"); // Backoff duration serialized.Append("1234"); // Absolute release time auto deserialized = BackoffEntrySerializer::DeserializeFromValue( - serialized, &base_policy, nullptr, kParseTime); + base::Value(std::move(serialized)), &base_policy, nullptr, kParseTime); ASSERT_TRUE(deserialized); } TEST(BackoffEntrySerializerTest, DeserializeVersion2NegativeDuration) { - base::Value serialized(base::Value::Type::LIST); + base::Value::List serialized; serialized.Append(SerializationFormatVersion::kVersion2); serialized.Append(0); // Failure count serialized.Append("-2000"); // Backoff duration serialized.Append("1234"); // Absolute release time auto deserialized = BackoffEntrySerializer::DeserializeFromValue( - serialized, &base_policy, nullptr, kParseTime); + base::Value(std::move(serialized)), &base_policy, nullptr, kParseTime); ASSERT_TRUE(deserialized); } TEST(BackoffEntrySerializerTest, DeserializeVersion1WrongDurationType) { - base::Value serialized(base::Value::Type::LIST); + base::Value::List serialized; serialized.Append(SerializationFormatVersion::kVersion1); serialized.Append(0); // Failure count serialized.Append("2000"); // Backoff duration in seconds as double serialized.Append("1234"); // Absolute release time auto deserialized = BackoffEntrySerializer::DeserializeFromValue( - serialized, &base_policy, nullptr, kParseTime); + base::Value(std::move(serialized)), &base_policy, nullptr, kParseTime); ASSERT_FALSE(deserialized); } TEST(BackoffEntrySerializerTest, DeserializeVersion2WrongDurationType) { - base::Value serialized(base::Value::Type::LIST); + base::Value::List serialized; serialized.Append(SerializationFormatVersion::kVersion2); serialized.Append(0); // Failure count serialized.Append(2.0); // Backoff duration serialized.Append("1234"); // Absolute release time auto deserialized = BackoffEntrySerializer::DeserializeFromValue( - serialized, &base_policy, nullptr, kParseTime); + base::Value(std::move(serialized)), &base_policy, nullptr, kParseTime); ASSERT_FALSE(deserialized); }
diff --git a/net/base/connection_endpoint_metadata.cc b/net/base/connection_endpoint_metadata.cc index 7930fa8..842c0e53 100644 --- a/net/base/connection_endpoint_metadata.cc +++ b/net/base/connection_endpoint_metadata.cc
@@ -27,15 +27,15 @@ ConnectionEndpointMetadata&&) = default; base::Value ConnectionEndpointMetadata::ToValue() const { - base::Value::DictStorage dict; + base::Value::Dict dict; - base::Value::ListStorage alpns_list; + base::Value::List alpns_list; for (const std::string& alpn : supported_protocol_alpns) { - alpns_list.emplace_back(alpn); + alpns_list.Append(alpn); } - dict.emplace(kSupportedProtocolAlpnsKey, std::move(alpns_list)); + dict.Set(kSupportedProtocolAlpnsKey, std::move(alpns_list)); - dict.emplace(kEchConfigListKey, base::Base64Encode(ech_config_list)); + dict.Set(kEchConfigListKey, base::Base64Encode(ech_config_list)); return base::Value(std::move(dict)); } @@ -43,21 +43,22 @@ // static absl::optional<ConnectionEndpointMetadata> ConnectionEndpointMetadata::FromValue(const base::Value& value) { - if (!value.is_dict()) + const base::Value::Dict* dict = value.GetIfDict(); + if (!dict) return absl::nullopt; - const base::Value* alpns_value = - value.FindListKey(kSupportedProtocolAlpnsKey); + const base::Value::List* alpns_list = + dict->FindList(kSupportedProtocolAlpnsKey); const std::string* ech_config_list_value = - value.FindStringKey(kEchConfigListKey); + dict->FindString(kEchConfigListKey); - if (!alpns_value || !ech_config_list_value) + if (!alpns_list || !ech_config_list_value) return absl::nullopt; ConnectionEndpointMetadata metadata; std::vector<std::string> alpns; - for (const base::Value& value : alpns_value->GetListDeprecated()) { + for (const base::Value& value : *alpns_list) { if (!value.is_string()) return absl::nullopt; metadata.supported_protocol_alpns.push_back(value.GetString());
diff --git a/net/base/logging_network_change_observer.cc b/net/base/logging_network_change_observer.cc index 0a221b7ea..11beacd 100644 --- a/net/base/logging_network_change_observer.cc +++ b/net/base/logging_network_change_observer.cc
@@ -41,25 +41,24 @@ // like the default network, and the types of active networks. base::Value NetworkSpecificNetLogParams( NetworkChangeNotifier::NetworkHandle network) { - base::Value dict(base::Value::Type::DICTIONARY); - dict.SetIntKey("changed_network_handle", HumanReadableNetworkHandle(network)); - dict.SetStringKey( - "changed_network_type", - NetworkChangeNotifier::ConnectionTypeToString( - NetworkChangeNotifier::GetNetworkConnectionType(network))); - dict.SetIntKey( + base::Value::Dict dict; + dict.Set("changed_network_handle", HumanReadableNetworkHandle(network)); + dict.Set("changed_network_type", + NetworkChangeNotifier::ConnectionTypeToString( + NetworkChangeNotifier::GetNetworkConnectionType(network))); + dict.Set( "default_active_network_handle", HumanReadableNetworkHandle(NetworkChangeNotifier::GetDefaultNetwork())); NetworkChangeNotifier::NetworkList networks; NetworkChangeNotifier::GetConnectedNetworks(&networks); for (NetworkChangeNotifier::NetworkHandle active_network : networks) { - dict.SetStringKey( + dict.Set( "current_active_networks." + base::NumberToString(HumanReadableNetworkHandle(active_network)), NetworkChangeNotifier::ConnectionTypeToString( NetworkChangeNotifier::GetNetworkConnectionType(active_network))); } - return dict; + return base::Value(std::move(dict)); } void NetLogNetworkSpecific(NetLog* net_log,
diff --git a/net/base/network_isolation_key.cc b/net/base/network_isolation_key.cc index e6fc03ba..4ee3e9e 100644 --- a/net/base/network_isolation_key.cc +++ b/net/base/network_isolation_key.cc
@@ -126,15 +126,16 @@ SerializeSiteWithNonce(*top_frame_site_); if (!top_frame_value) return false; - *out_value = base::Value(base::Value::Type::LIST); - out_value->Append(std::move(*top_frame_value)); + base::Value::List list; + list.Append(std::move(top_frame_value).value()); absl::optional<std::string> frame_value = SerializeSiteWithNonce(*frame_site_); if (!frame_value) return false; - out_value->Append(std::move(*frame_value)); + list.Append(std::move(frame_value).value()); + *out_value = base::Value(std::move(list)); return true; } @@ -144,7 +145,7 @@ if (!value.is_list()) return false; - base::Value::ConstListView list = value.GetListDeprecated(); + const base::Value::List& list = value.GetList(); if (list.empty()) { *network_isolation_key = NetworkIsolationKey(); return true;
diff --git a/net/base/network_isolation_key_unittest.cc b/net/base/network_isolation_key_unittest.cc index 6f05b842..a2320dd 100644 --- a/net/base/network_isolation_key_unittest.cc +++ b/net/base/network_isolation_key_unittest.cc
@@ -258,22 +258,20 @@ } TEST_P(NetworkIsolationKeyTest, FromValueBadData) { - // Can't create these inline, since vector initialization lists require a - // copy, and base::Value has no copy operator, only move. - base::Value::ListStorage not_a_url_list; - not_a_url_list.emplace_back(base::Value("not-a-url")); + base::Value::List not_a_url_list; + not_a_url_list.Append("not-a-url"); - base::Value::ListStorage transient_origin_list; - transient_origin_list.emplace_back(base::Value("data:text/html,transient")); + base::Value::List transient_origin_list; + transient_origin_list.Append("data:text/html,transient"); - base::Value::ListStorage too_many_origins_list; - too_many_origins_list.emplace_back(base::Value("https://too/")); - too_many_origins_list.emplace_back(base::Value("https://many/")); - too_many_origins_list.emplace_back(base::Value("https://origins/")); + base::Value::List too_many_origins_list; + too_many_origins_list.Append("https://too/"); + too_many_origins_list.Append("https://many/"); + too_many_origins_list.Append("https://origins/"); const base::Value kTestCases[] = { - base::Value(base::Value::Type::STRING), - base::Value(base::Value::Type::DICTIONARY), + base::Value(std::string()), + base::Value(base::Value::Dict()), base::Value(std::move(not_a_url_list)), base::Value(std::move(transient_origin_list)), base::Value(std::move(too_many_origins_list)), @@ -285,11 +283,11 @@ EXPECT_FALSE(NetworkIsolationKey::FromValue(test_case, &key)) << test_case; } - base::Value::ListStorage triple_key_list; - triple_key_list.emplace_back(base::Value("http://www.triple.com")); - triple_key_list.emplace_back(base::Value("http://www.key.com")); + base::Value::List triple_key_list; + triple_key_list.Append("http://www.triple.com"); + triple_key_list.Append("http://www.key.com"); NetworkIsolationKey key; - const auto triple_key_case = base::Value(std::move(triple_key_list)); + base::Value triple_key_case(std::move(triple_key_list)); // When double key is enabled top_level_site must equal frame_site. bool expect_fail_on_different_sites =
diff --git a/net/base/upload_data_stream.cc b/net/base/upload_data_stream.cc index bd5aea1..cccaedb0 100644 --- a/net/base/upload_data_stream.cc +++ b/net/base/upload_data_stream.cc
@@ -17,19 +17,19 @@ base::Value NetLogInitEndInfoParams(int result, int total_size, bool is_chunked) { - base::Value dict(base::Value::Type::DICTIONARY); + base::Value::Dict dict; - dict.SetIntKey("net_error", result); - dict.SetIntKey("total_size", total_size); - dict.SetBoolKey("is_chunked", is_chunked); - return dict; + dict.Set("net_error", result); + dict.Set("total_size", total_size); + dict.Set("is_chunked", is_chunked); + return base::Value(std::move(dict)); } base::Value CreateReadInfoParams(int current_position) { - base::Value dict(base::Value::Type::DICTIONARY); + base::Value::Dict dict; - dict.SetIntKey("current_position", current_position); - return dict; + dict.Set("current_position", current_position); + return base::Value(std::move(dict)); } } // namespace
diff --git a/net/cookies/cookie_monster_change_dispatcher.cc b/net/cookies/cookie_monster_change_dispatcher.cc index d9e41f2..cf92836 100644 --- a/net/cookies/cookie_monster_change_dispatcher.cc +++ b/net/cookies/cookie_monster_change_dispatcher.cc
@@ -183,7 +183,7 @@ std::unique_ptr<Subscription> subscription = std::make_unique<Subscription>( weak_ptr_factory_.GetWeakPtr(), std::string(kGlobalDomainKey), - std::string(kGlobalNameKey), GURL(""), CookiePartitionKey::Todo(), + std::string(kGlobalNameKey), GURL(""), absl::nullopt, first_party_sets_enabled_, std::move(callback)); LinkSubscription(subscription.get());
diff --git a/net/cookies/cookie_partition_key.h b/net/cookies/cookie_partition_key.h index 60ff48b..4b920323 100644 --- a/net/cookies/cookie_partition_key.h +++ b/net/cookies/cookie_partition_key.h
@@ -92,10 +92,6 @@ return absl::make_optional(CookiePartitionKey(true)); } - // Temporary method, used to mark the places where we need to supply the - // cookie partition key to CanonicalCookie::Create. - static absl::optional<CookiePartitionKey> Todo() { return absl::nullopt; } - const SchemefulSite& site() const { return site_; } bool from_script() const { return from_script_; }
diff --git a/net/ssl/openssl_ssl_util.cc b/net/ssl/openssl_ssl_util.cc index ca3987f..c5b7bfb 100644 --- a/net/ssl/openssl_ssl_util.cc +++ b/net/ssl/openssl_ssl_util.cc
@@ -132,18 +132,18 @@ base::Value NetLogOpenSSLErrorParams(int net_error, int ssl_error, const OpenSSLErrorInfo& error_info) { - base::DictionaryValue dict; - dict.SetInteger("net_error", net_error); - dict.SetInteger("ssl_error", ssl_error); + base::Value::Dict dict; + dict.Set("net_error", net_error); + dict.Set("ssl_error", ssl_error); if (error_info.error_code != 0) { - dict.SetInteger("error_lib", ERR_GET_LIB(error_info.error_code)); - dict.SetInteger("error_reason", ERR_GET_REASON(error_info.error_code)); + dict.Set("error_lib", ERR_GET_LIB(error_info.error_code)); + dict.Set("error_reason", ERR_GET_REASON(error_info.error_code)); } if (error_info.file != nullptr) - dict.SetString("file", error_info.file); + dict.Set("file", error_info.file); if (error_info.line != 0) - dict.SetInteger("line", error_info.line); - return std::move(dict); + dict.Set("line", error_info.line); + return base::Value(std::move(dict)); } } // namespace
diff --git a/services/network/cookie_manager.cc b/services/network/cookie_manager.cc index 07c1fb8..a9113d9 100644 --- a/services/network/cookie_manager.cc +++ b/services/network/cookie_manager.cc
@@ -284,15 +284,17 @@ base::Unretained(listener_registration.get())); if (name) { + // TODO(https://crbug.com/1225444): Include the correct cookie partition + // key when attaching cookie change listeners to service workers. listener_registration->subscription = cookie_store_->GetChangeDispatcher().AddCallbackForCookie( - url, *name, net::CookiePartitionKey::Todo(), - std::move(cookie_change_callback)); + url, *name, absl::nullopt, std::move(cookie_change_callback)); } else { + // TODO(https://crbug.com/1225444): Include the correct cookie partition + // key when attaching cookie change listeners to service workers. listener_registration->subscription = cookie_store_->GetChangeDispatcher().AddCallbackForUrl( - url, net::CookiePartitionKey::Todo(), - std::move(cookie_change_callback)); + url, absl::nullopt, std::move(cookie_change_callback)); } listener_registration->listener.set_disconnect_handler(
diff --git a/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom b/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom index a9a0e5a..3c495df 100644 --- a/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom +++ b/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom
@@ -147,6 +147,17 @@ Throttle(array<FrameSinkId> frame_sink_ids, mojo_base.mojom.TimeDelta interval); + // Throttles all current and future frame sinks to send BeginFrames at an + // interval at least as long as |interval|. Because there is a single viz + // process, which itself contains a single host frame sink manager, calling + // this multiple times from anywhere will apply the throttling described by + // the latest call. + StartThrottlingAllFrameSinks(mojo_base.mojom.TimeDelta interval); + + // Disables the global throttling triggered by StartThrottlingAllFrameSinks(). + // If throttling is already disabled, this has no effect. + StopThrottlingAllFrameSinks(); + // Takes a snapshot of |surface_id| or a newer surface with the same // FrameSinkId. The request will be queued up until such surface exists and is // reachable from the root surface.
diff --git a/storage/browser/blob/blob_registry_impl.cc b/storage/browser/blob/blob_registry_impl.cc index 4f73ddcf..5285bab 100644 --- a/storage/browser/blob/blob_registry_impl.cc +++ b/storage/browser/blob/blob_registry_impl.cc
@@ -635,7 +635,6 @@ } if (!context_->registry().HasEntry(uuid)) { LOG(ERROR) << "Invalid UUID: " << uuid; - // TODO(mek): Log histogram, old code logs Storage.Blob.InvalidReference std::move(callback).Run(); return; }
diff --git a/storage/browser/blob/blob_storage_context.cc b/storage/browser/blob/blob_storage_context.cc index 9e2a2416..1a8fecf 100644 --- a/storage/browser/blob/blob_storage_context.cc +++ b/storage/browser/blob/blob_storage_context.cc
@@ -17,7 +17,6 @@ #include "base/location.h" #include "base/logging.h" #include "base/memory/ptr_util.h" -#include "base/metrics/histogram_macros.h" #include "base/numerics/safe_conversions.h" #include "base/numerics/safe_math.h" #include "base/strings/stringprintf.h" @@ -504,14 +503,6 @@ BlobStatus status = entry->status_; DCHECK_NE(BlobStatus::DONE, status); - bool error = BlobStatusIsError(status); - UMA_HISTOGRAM_BOOLEAN("Storage.Blob.Broken", error); - if (error) { - UMA_HISTOGRAM_ENUMERATION("Storage.Blob.BrokenReason", - static_cast<int>(status), - (static_cast<int>(BlobStatus::LAST_ERROR) + 1)); - } - if (BlobStatusIsPending(entry->status_)) { for (const ItemCopyEntry& copy : entry->building_state_->copies) { // Our source item can be a file if it was a slice of an unpopulated file,
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index 689b726..31a7041 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -8155,15 +8155,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", + "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", + "--client-outdir", + "../../weblayer_instrumentation_test_M101/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/SystemWebView.apk", - "--client-outdir", - "../../weblayer_instrumentation_test_M101/out/Release", "--client-version=101", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -8189,7 +8189,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.69" + "revision": "version:101.0.4951.74" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -8665,15 +8665,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", + "--webview-apk-path=apks/AOSP_SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--test-expectations", - "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/AOSP_SystemWebView.apk", "--implementation-outdir", "../../weblayer_instrumentation_test_M101/out/Release", + "--test-expectations", + "../../weblayer/browser/android/javatests/skew/expectations.txt", "--impl-version=101", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -8699,7 +8699,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.69" + "revision": "version:101.0.4951.74" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index bb521f8c..6bef602 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -46129,15 +46129,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", + "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", + "--client-outdir", + "../../weblayer_instrumentation_test_M101/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/SystemWebView.apk", - "--client-outdir", - "../../weblayer_instrumentation_test_M101/out/Release", "--client-version=101", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -46163,7 +46163,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.69" + "revision": "version:101.0.4951.74" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -46639,15 +46639,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", + "--webview-apk-path=apks/AOSP_SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--test-expectations", - "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/AOSP_SystemWebView.apk", "--implementation-outdir", "../../weblayer_instrumentation_test_M101/out/Release", + "--test-expectations", + "../../weblayer/browser/android/javatests/skew/expectations.txt", "--impl-version=101", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -46673,7 +46673,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.69" + "revision": "version:101.0.4951.74" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -47153,15 +47153,15 @@ { "args": [ "--additional-apk=apks/ChromePublic.apk", + "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", + "--client-outdir", + "../../weblayer_instrumentation_test_M101/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/SystemWebView.apk", - "--client-outdir", - "../../weblayer_instrumentation_test_M101/out/Release", "--client-version=101", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -47187,7 +47187,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.69" + "revision": "version:101.0.4951.74" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -47663,15 +47663,15 @@ { "args": [ "--additional-apk=apks/ChromePublic.apk", + "--webview-apk-path=apks/AOSP_SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--test-expectations", - "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/AOSP_SystemWebView.apk", "--implementation-outdir", "../../weblayer_instrumentation_test_M101/out/Release", + "--test-expectations", + "../../weblayer/browser/android/javatests/skew/expectations.txt", "--impl-version=101", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -47697,7 +47697,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.69" + "revision": "version:101.0.4951.74" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -48245,15 +48245,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", + "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", + "--client-outdir", + "../../weblayer_instrumentation_test_M101/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/SystemWebView.apk", - "--client-outdir", - "../../weblayer_instrumentation_test_M101/out/Release", "--client-version=101", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -48279,7 +48279,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.69" + "revision": "version:101.0.4951.74" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -48755,15 +48755,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", + "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--test-expectations", - "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/SystemWebView.apk", "--implementation-outdir", "../../weblayer_instrumentation_test_M101/out/Release", + "--test-expectations", + "../../weblayer/browser/android/javatests/skew/expectations.txt", "--impl-version=101", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -48789,7 +48789,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.69" + "revision": "version:101.0.4951.74" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -49337,15 +49337,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", + "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", + "--client-outdir", + "../../weblayer_instrumentation_test_M101/out/Release", "--implementation-outdir", ".", "--test-expectations", "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/SystemWebView.apk", - "--client-outdir", - "../../weblayer_instrumentation_test_M101/out/Release", "--client-version=101", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -49371,7 +49371,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.69" + "revision": "version:101.0.4951.74" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -49847,15 +49847,15 @@ { "args": [ "--additional-apk=apks/WebLayerShellSystemWebView.apk", + "--webview-apk-path=apks/SystemWebView.apk", "--test-runner-outdir", ".", "--client-outdir", ".", - "--test-expectations", - "../../weblayer/browser/android/javatests/skew/expectations.txt", - "--webview-apk-path=apks/SystemWebView.apk", "--implementation-outdir", "../../weblayer_instrumentation_test_M101/out/Release", + "--test-expectations", + "../../weblayer/browser/android/javatests/skew/expectations.txt", "--impl-version=101", "--gs-results-bucket=chromium-result-details", "--recover-devices", @@ -49881,7 +49881,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M101", - "revision": "version:101.0.4951.69" + "revision": "version:101.0.4951.74" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json index 2d910ce..01dfa8f 100644 --- a/testing/buildbot/chromium.clang.json +++ b/testing/buildbot/chromium.clang.json
@@ -8942,7 +8942,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_browsertests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_browsertests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_browsertests/" }, { "merge": { @@ -8960,7 +8960,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_integration_tests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_integration_tests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/" }, { "merge": { @@ -8978,7 +8978,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_unittests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_unittests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_unittests/" }, { "merge": { @@ -9908,7 +9908,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "web_runner_integration_tests", - "test_id_prefix": "ninja://fuchsia/runners:web_runner_integration_tests/" + "test_id_prefix": "ninja://fuchsia_web/runners:web_runner_integration_tests/" }, { "merge": { @@ -10490,7 +10490,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_browsertests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_browsertests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_browsertests/" }, { "merge": { @@ -10509,7 +10509,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_integration_tests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_integration_tests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/" }, { "merge": { @@ -10528,7 +10528,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_unittests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_unittests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_unittests/" }, { "merge": { @@ -11308,7 +11308,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "web_runner_integration_tests", - "test_id_prefix": "ninja://fuchsia/runners:web_runner_integration_tests/" + "test_id_prefix": "ninja://fuchsia_web/runners:web_runner_integration_tests/" }, { "merge": {
diff --git a/testing/buildbot/chromium.fuchsia.fyi.json b/testing/buildbot/chromium.fuchsia.fyi.json index a15aebbb1..7d218bc00 100644 --- a/testing/buildbot/chromium.fuchsia.fyi.json +++ b/testing/buildbot/chromium.fuchsia.fyi.json
@@ -251,7 +251,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_browsertests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_browsertests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_browsertests/" }, { "merge": { @@ -270,7 +270,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_integration_tests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_integration_tests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/" }, { "merge": { @@ -289,7 +289,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_unittests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_unittests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_unittests/" }, { "merge": { @@ -1078,7 +1078,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "web_runner_integration_tests", - "test_id_prefix": "ninja://fuchsia/runners:web_runner_integration_tests/" + "test_id_prefix": "ninja://fuchsia_web/runners:web_runner_integration_tests/" }, { "merge": { @@ -1405,7 +1405,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_browsertests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_browsertests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_browsertests/" }, { "merge": { @@ -1423,7 +1423,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_integration_tests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_integration_tests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/" }, { "merge": { @@ -1441,7 +1441,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_unittests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_unittests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_unittests/" }, { "merge": { @@ -2380,7 +2380,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "web_runner_integration_tests", - "test_id_prefix": "ninja://fuchsia/runners:web_runner_integration_tests/" + "test_id_prefix": "ninja://fuchsia_web/runners:web_runner_integration_tests/" }, { "merge": { @@ -2701,7 +2701,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_browsertests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_browsertests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_browsertests/" }, { "merge": { @@ -2719,7 +2719,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_integration_tests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_integration_tests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/" }, { "merge": { @@ -2737,7 +2737,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_unittests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_unittests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_unittests/" }, { "merge": { @@ -3667,7 +3667,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "web_runner_integration_tests", - "test_id_prefix": "ninja://fuchsia/runners:web_runner_integration_tests/" + "test_id_prefix": "ninja://fuchsia_web/runners:web_runner_integration_tests/" }, { "merge": {
diff --git a/testing/buildbot/chromium.fuchsia.json b/testing/buildbot/chromium.fuchsia.json index 2ea21e78..aad12baf 100644 --- a/testing/buildbot/chromium.fuchsia.json +++ b/testing/buildbot/chromium.fuchsia.json
@@ -251,7 +251,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_browsertests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_browsertests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_browsertests/" }, { "merge": { @@ -270,7 +270,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_integration_tests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_integration_tests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/" }, { "merge": { @@ -289,7 +289,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_unittests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_unittests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_unittests/" }, { "merge": { @@ -1069,7 +1069,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "web_runner_integration_tests", - "test_id_prefix": "ninja://fuchsia/runners:web_runner_integration_tests/" + "test_id_prefix": "ninja://fuchsia_web/runners:web_runner_integration_tests/" }, { "merge": { @@ -1416,7 +1416,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_browsertests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_browsertests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_browsertests/" }, { "merge": { @@ -1434,7 +1434,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_integration_tests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_integration_tests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/" }, { "merge": { @@ -1452,7 +1452,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_unittests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_unittests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_unittests/" }, { "merge": { @@ -2382,7 +2382,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "web_runner_integration_tests", - "test_id_prefix": "ninja://fuchsia/runners:web_runner_integration_tests/" + "test_id_prefix": "ninja://fuchsia_web/runners:web_runner_integration_tests/" }, { "merge": {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index c66efa71..7c4f096 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -19819,7 +19819,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_browsertests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_browsertests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_browsertests/" }, { "args": [ @@ -19843,7 +19843,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_integration_tests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_integration_tests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/" }, { "args": [ @@ -19867,7 +19867,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_unittests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_unittests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_unittests/" }, { "args": [ @@ -21088,7 +21088,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "web_runner_integration_tests", - "test_id_prefix": "ninja://fuchsia/runners:web_runner_integration_tests/" + "test_id_prefix": "ninja://fuchsia_web/runners:web_runner_integration_tests/" }, { "args": [ @@ -21456,7 +21456,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_browsertests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_browsertests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_browsertests/" }, { "merge": { @@ -21476,7 +21476,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_integration_tests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_integration_tests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/" }, { "merge": { @@ -21496,7 +21496,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "cast_runner_unittests", - "test_id_prefix": "ninja://fuchsia/runners:cast_runner_unittests/" + "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_unittests/" }, { "merge": { @@ -22526,7 +22526,7 @@ "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" }, "test": "web_runner_integration_tests", - "test_id_prefix": "ninja://fuchsia/runners:web_runner_integration_tests/" + "test_id_prefix": "ninja://fuchsia_web/runners:web_runner_integration_tests/" }, { "merge": {
diff --git a/testing/buildbot/filters/fuchsia.browser_tests.filter b/testing/buildbot/filters/fuchsia.browser_tests.filter index 3fb6f52..ac262fa 100644 --- a/testing/buildbot/filters/fuchsia.browser_tests.filter +++ b/testing/buildbot/filters/fuchsia.browser_tests.filter
@@ -108,13 +108,6 @@ # Unexpected infobar hung_plugin -InfoBarUiTest.InvokeUi_multiple_infobars -# TODO(crbug.com/1326968): [loopback_server.cc(887)] Loopback sync cannot read the persistent state -# file (/tmp/.org.chromium.Chromium.JpoHmf/user_data/FakeSyncServer/profile.pb) with error -# FILE_ERROR_NOT_FOUND Possibly broken because profile sign in isn't supported, although it could be -# because /tmp isn't being created --MetricsServiceUserDemographicsBrowserTest.AddSyncedUserBirthYearAndGenderToProtoData/0 --MetricsServiceUserDemographicsBrowserTest.AddSyncedUserBirthYearAndGenderToProtoData/1 - # TODO(crbug.com/1326969): Expects click to deselect text, but click seems like it might not be # hitting the right location -OmniboxPopupContentsViewTest.ClickOmnibox
diff --git a/testing/buildbot/filters/ozone-linux.wayland_browser_tests.filter b/testing/buildbot/filters/ozone-linux.wayland_browser_tests.filter index b7d4d4b..2c76c89f 100644 --- a/testing/buildbot/filters/ozone-linux.wayland_browser_tests.filter +++ b/testing/buildbot/filters/ozone-linux.wayland_browser_tests.filter
@@ -11,6 +11,8 @@ -ChromeSitePerProcessTest.PopupWindowFocus -ExternalProtocolDialogBrowserTest.TestFocus -FolderUploadConfirmationViewTest.InitiallyFocusesCancel +-JavaScriptTabModalDialogViewViewsBrowserTest.AlertDialogAccessibleNameDescriptionAndRole +-JavaScriptTabModalDialogViewViewsBrowserTest.AlertDialogCloseButtonAccessibilityIgnored -PreservedWindowPlacement.Test -ProfileHelperTest.OpenNewWindowForProfile -TabHoverCardBubbleViewBrowserTest.WidgetNotVisibleOnMousePressAfterTabFocus
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 8bf88109..d63b81a 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -327,19 +327,19 @@ "type": "console_test_launcher", }, "cast_runner_browsertests": { - "label": "//fuchsia/runners:cast_runner_browsertests", + "label": "//fuchsia_web/runners:cast_runner_browsertests", "type": "console_test_launcher", }, "cast_runner_integration_tests": { - "label": "//fuchsia/runners:cast_runner_integration_tests", + "label": "//fuchsia_web/runners:cast_runner_integration_tests", "type": "console_test_launcher", }, "cast_runner_pkg":{ - "label": "//fuchsia/runners:cast_runner_pkg", + "label": "//fuchsia_web/runners:cast_runner_pkg", "type": "additonal_compile_target", }, "cast_runner_unittests": { - "label": "//fuchsia/runners:cast_runner_unittests", + "label": "//fuchsia_web/runners:cast_runner_unittests", "type": "console_test_launcher", }, "cast_audio_backend_unittests": { @@ -2015,11 +2015,11 @@ "type": "console_test_launcher", }, "web_runner_integration_tests": { - "label": "//fuchsia/runners:web_runner_integration_tests", + "label": "//fuchsia_web/runners:web_runner_integration_tests", "type": "console_test_launcher", }, "web_runner_pkg": { - "label": "//fuchsia/runners:web_runner_pkg", + "label": "//fuchsia_web/runners:web_runner_pkg", "type": "additonal_compile_target", }, "webapk_client_junit_tests": {
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index cdba141..597f363 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -450,16 +450,16 @@ }, 'WEBLAYER_10_AND_M_IMPL_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': { 'args': [ + '--webview-apk-path=apks/AOSP_SystemWebView.apk', '--test-runner-outdir', '.', '--client-outdir', '.', - '--test-expectations', - '../../weblayer/browser/android/javatests/skew/expectations.txt', - '--webview-apk-path=apks/AOSP_SystemWebView.apk', '--implementation-outdir', '../../weblayer_instrumentation_test_M101/out/Release', - '--impl-version=101' + '--test-expectations', + '../../weblayer/browser/android/javatests/skew/expectations.txt', + '--impl-version=101', ], 'identifier': 'with_impl_from_101', 'swarming': { @@ -467,10 +467,10 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M101', - 'revision': 'version:101.0.4951.69' + 'revision': 'version:101.0.4951.74', } - ] - } + ], + }, }, 'WEBLAYER_10_AND_M_IMPL_SKEW_TESTS_NTH_MINUS_THREE_MILESTONE': { 'args': [ @@ -594,16 +594,16 @@ }, 'WEBLAYER_IMPL_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': { 'args': [ + '--webview-apk-path=apks/SystemWebView.apk', '--test-runner-outdir', '.', '--client-outdir', '.', - '--test-expectations', - '../../weblayer/browser/android/javatests/skew/expectations.txt', - '--webview-apk-path=apks/SystemWebView.apk', '--implementation-outdir', '../../weblayer_instrumentation_test_M101/out/Release', - '--impl-version=101' + '--test-expectations', + '../../weblayer/browser/android/javatests/skew/expectations.txt', + '--impl-version=101', ], 'identifier': 'with_impl_from_101', 'swarming': { @@ -611,10 +611,10 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M101', - 'revision': 'version:101.0.4951.69' + 'revision': 'version:101.0.4951.74', } - ] - } + ], + }, }, 'WEBLAYER_IMPL_SKEW_TESTS_NTH_MINUS_THREE_MILESTONE': { 'args': [ @@ -738,16 +738,16 @@ }, 'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MINUS_TWO_MILESTONE': { 'args': [ + '--webview-apk-path=apks/SystemWebView.apk', '--test-runner-outdir', '.', + '--client-outdir', + '../../weblayer_instrumentation_test_M101/out/Release', '--implementation-outdir', '.', '--test-expectations', '../../weblayer/browser/android/javatests/skew/expectations.txt', - '--webview-apk-path=apks/SystemWebView.apk', - '--client-outdir', - '../../weblayer_instrumentation_test_M101/out/Release', - '--client-version=101' + '--client-version=101', ], 'identifier': 'with_client_from_101', 'swarming': { @@ -755,10 +755,10 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M101', - 'revision': 'version:101.0.4951.69' + 'revision': 'version:101.0.4951.74', } - ] - } + ], + }, }, 'WEBLAYER_CLIENT_SKEW_TESTS_NTH_MINUS_THREE_MILESTONE': { 'args': [
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 5dab1f3..6e86b56 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -543,6 +543,21 @@ ] } ], + "ArcVmBroadcastPreAnrHandling": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ArcVmBroadcastPreAnrHandling" + ] + } + ] + } + ], "ArcVmDalvikMemoryProfile": [ { "platforms": [ @@ -1149,28 +1164,6 @@ ] } ], - "AutofillIgnoreEarlyClicksOnPopup": [ - { - "platforms": [ - "chromeos", - "chromeos_lacros", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled_500ms", - "params": { - "duration": "500ms" - }, - "enable_features": [ - "AutofillIgnoreEarlyClicksOnPopup" - ] - } - ] - } - ], "AutofillKeyboardAccessory": [ { "platforms": [
diff --git a/third_party/blink/common/client_hints/client_hints.cc b/third_party/blink/common/client_hints/client_hints.cc index fb72470..7de1dbd 100644 --- a/third_party/blink/common/client_hints/client_hints.cc +++ b/third_party/blink/common/client_hints/client_hints.cc
@@ -120,10 +120,8 @@ case network::mojom::WebClientHintsType::kSaveData: case network::mojom::WebClientHintsType::kUA: case network::mojom::WebClientHintsType::kUAMobile: - return true; case network::mojom::WebClientHintsType::kUAPlatform: - return base::FeatureList::IsEnabled( - features::kUACHPlatformEnabledByDefault); + return true; default: return false; }
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index b1ed2c9..dd4dcf6 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -1131,11 +1131,6 @@ const base::Feature kUsePageViewportInLCP{"UsePageViewportInLCP", base::FEATURE_ENABLED_BY_DEFAULT}; -// Enable `Sec-CH-UA-Platform` client hint and request header to be sent by -// default -const base::Feature kUACHPlatformEnabledByDefault{ - "UACHPlatformEnabledByDefault", base::FEATURE_ENABLED_BY_DEFAULT}; - // When enabled, allow dropping alpha on media streams for rendering sinks if // other sinks connected do not use alpha. const base::Feature kAllowDropAlphaForMediaStream{
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index be2e45e4..38be643c 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -513,9 +513,6 @@ // heuristic where images occupying the full viewport are ignored. BLINK_COMMON_EXPORT extern const base::Feature kUsePageViewportInLCP; -// Enable "Sec-CH-UA-Platform" client hint and request header for all requests -BLINK_COMMON_EXPORT extern const base::Feature kUACHPlatformEnabledByDefault; - // When enabled, allow dropping alpha on media streams for rendering sinks if // other sinks connected do not use alpha. BLINK_COMMON_EXPORT extern const base::Feature kAllowDropAlphaForMediaStream;
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl index 0230f78..1c633e98 100644 --- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl +++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -702,7 +702,7 @@ InvalidHeader # Details for issues around "Attribution Reporting API" usage. - # Explainer: https://github.com/WICG/conversion-measurement-api + # Explainer: https://github.com/WICG/attribution-reporting-api type AttributionReportingIssueDetails extends object properties AttributionReportingIssueType violationType @@ -767,7 +767,6 @@ NotificationInsecureOrigin NotificationPermissionRequestedIframe ObsoleteWebRtcCipherSuite - PaymentRequestBasicCard PictureSourceSrc PrefixedCancelAnimationFrame PrefixedRequestAnimationFrame
diff --git a/third_party/blink/public/mojom/conversions/attribution_data_host.mojom b/third_party/blink/public/mojom/conversions/attribution_data_host.mojom index 1dd5fc6..f5c0869 100644 --- a/third_party/blink/public/mojom/conversions/attribution_data_host.mojom +++ b/third_party/blink/public/mojom/conversions/attribution_data_host.mojom
@@ -13,7 +13,7 @@ }; // Filter data for selectively matching attribution sources and triggers. -// See https://github.com/WICG/conversion-measurement-api/blob/main/EVENT.md#optional-attribution-filters +// See https://github.com/WICG/attribution-reporting-api/blob/main/EVENT.md#optional-attribution-filters // for details. struct AttributionFilterData { // Map of filter name to a possibly empty set of values. @@ -98,7 +98,7 @@ // Represents a request from a reporting origin to trigger attribution on a // given site. See: -// https://github.com/WICG/conversion-measurement-api/blob/main/EVENT.md#triggering-attribution +// https://github.com/WICG/attribution-reporting-api/blob/main/EVENT.md#triggering-attribution struct AttributionTriggerData { // Origin that registered this trigger, used to determine which source this // trigger is associated with.
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn index d461be9..4a79c311 100644 --- a/third_party/blink/renderer/core/BUILD.gn +++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1908,8 +1908,8 @@ seed_corpus = "//third_party/blink/renderer/core/frame/attribution_src/attribution_source_registration_corpus" } -fuzzer_test("attribution_event_trigger_data_fuzzer") { - sources = [ "frame/attribution_event_trigger_data_fuzzer.cc" ] +fuzzer_test("attribution_trigger_registration_fuzzer") { + sources = [ "frame/attribution_trigger_registration_fuzzer.cc" ] deps = [ ":core", "//testing/libfuzzer/proto:json_proto", @@ -1917,29 +1917,5 @@ "//third_party/blink/renderer/platform:blink_fuzzer_test_support", "//third_party/libprotobuf-mutator", ] - seed_corpus = "//third_party/blink/renderer/core/frame/attribution_src/attribution_event_trigger_data_corpus" -} - -fuzzer_test("attribution_aggregatable_values_fuzzer") { - sources = [ "frame/attribution_aggregatable_values_fuzzer.cc" ] - deps = [ - ":core", - "//testing/libfuzzer/proto:json_proto", - "//testing/libfuzzer/proto:json_proto_converter", - "//third_party/blink/renderer/platform:blink_fuzzer_test_support", - "//third_party/libprotobuf-mutator", - ] - seed_corpus = "//third_party/blink/renderer/core/frame/attribution_src/attribution_aggregatable_values_corpus" -} - -fuzzer_test("attribution_aggregatable_trigger_data_fuzzer") { - sources = [ "frame/attribution_aggregatable_trigger_data_fuzzer.cc" ] - deps = [ - ":core", - "//testing/libfuzzer/proto:json_proto", - "//testing/libfuzzer/proto:json_proto_converter", - "//third_party/blink/renderer/platform:blink_fuzzer_test_support", - "//third_party/libprotobuf-mutator", - ] - seed_corpus = "//third_party/blink/renderer/core/frame/attribution_src/attribution_aggregatable_trigger_data_corpus" + seed_corpus = "//third_party/blink/renderer/core/frame/attribution_src/attribution_trigger_registration_corpus" }
diff --git a/third_party/blink/renderer/core/css/affected_by_pseudo_test.cc b/third_party/blink/renderer/core/css/affected_by_pseudo_test.cc index c167706..4523a33 100644 --- a/third_party/blink/renderer/core/css/affected_by_pseudo_test.cc +++ b/third_party/blink/renderer/core/css/affected_by_pseudo_test.cc
@@ -36,7 +36,8 @@ kSiblingsAffectedByHasForSiblingRelationship, kSiblingsAffectedByHasForSiblingDescendantRelationship, kAffectedByPseudoInHas, - kAncestorsOrSiblingsAffectedByHoverInHas + kAncestorsOrSiblingsAffectedByHoverInHas, + kAffectedByLogicalCombinationsInHas }; void CheckAffectedByFlagsForHas( const char* element_id, @@ -115,6 +116,11 @@ ->AncestorsOrSiblingsAffectedByHoverInHas(); flag_name = "AncestorsOrSiblingsAffectedByHoverInHas"; break; + case kAffectedByLogicalCombinationsInHas: + actual = + GetElementById(element_id)->AffectedByLogicalCombinationsInHas(); + flag_name = "AffectedByLogicalCombinationsInHas"; + break; } DCHECK(flag_name); if (iter.second == actual) @@ -4233,4 +4239,82 @@ GetCSSPropertyColor())); } +TEST_F(AffectedByPseudoTest, AffectedByLogicalCombinationsInHas) { + SetHtmlInnerHTML(R"HTML( + <style> + .a:has(:is(.b .c)) { color: green; } + .d:has(:is(.e)) { color: green; } + </style> + <div id=div1> + <div id=div11 class='a'> + <div id=div111> + <div id=div1111 class='c'></div> + </div> + </div> + <div id=div12 class='d'> + <div id=div121> + <div id=div1211></div> + </div> + </div> + </div> + )HTML"); + + UpdateAllLifecyclePhasesForTest(); + CheckAffectedByFlagsForHas( + "div1", {{kAffectedBySubjectHas, false}, + {kAffectedByLogicalCombinationsInHas, false}, + {kAncestorsOrAncestorSiblingsAffectedByHas, false}, + {kSiblingsAffectedByHas, false}}); + CheckAffectedByFlagsForHas("div11", + {{kAffectedBySubjectHas, true}, + {kAffectedByLogicalCombinationsInHas, true}, + {kAncestorsOrAncestorSiblingsAffectedByHas, true}, + {kSiblingsAffectedByHas, false}}); + CheckAffectedByFlagsForHas("div111", + {{kAffectedBySubjectHas, false}, + {kAffectedByNonSubjectHas, false}, + {kAncestorsOrAncestorSiblingsAffectedByHas, true}, + {kSiblingsAffectedByHas, false}}); + CheckAffectedByFlagsForHas("div1111", + {{kAffectedBySubjectHas, false}, + {kAffectedByNonSubjectHas, false}, + {kAncestorsOrAncestorSiblingsAffectedByHas, true}, + {kSiblingsAffectedByHas, false}}); + CheckAffectedByFlagsForHas("div12", + {{kAffectedBySubjectHas, true}, + {kAffectedByLogicalCombinationsInHas, false}, + {kAncestorsOrAncestorSiblingsAffectedByHas, true}, + {kSiblingsAffectedByHas, false}}); + CheckAffectedByFlagsForHas("div121", + {{kAffectedBySubjectHas, false}, + {kAffectedByNonSubjectHas, false}, + {kAncestorsOrAncestorSiblingsAffectedByHas, true}, + {kSiblingsAffectedByHas, false}}); + CheckAffectedByFlagsForHas("div1211", + {{kAffectedBySubjectHas, false}, + {kAffectedByNonSubjectHas, false}, + {kAncestorsOrAncestorSiblingsAffectedByHas, true}, + {kSiblingsAffectedByHas, false}}); + + unsigned start_count = GetStyleEngine().StyleForElementCount(); + GetElementById("div11")->setAttribute(html_names::kClassAttr, "a b"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_EQ(1U, GetStyleEngine().StyleForElementCount() - start_count); + + start_count = GetStyleEngine().StyleForElementCount(); + GetElementById("div11")->setAttribute(html_names::kClassAttr, "a"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_EQ(1U, GetStyleEngine().StyleForElementCount() - start_count); + + start_count = GetStyleEngine().StyleForElementCount(); + GetElementById("div11")->setAttribute(html_names::kClassAttr, "a invalid"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_EQ(0U, GetStyleEngine().StyleForElementCount() - start_count); + + start_count = GetStyleEngine().StyleForElementCount(); + GetElementById("div12")->setAttribute(html_names::kClassAttr, "d e"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_EQ(0U, GetStyleEngine().StyleForElementCount() - start_count); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_selector.cc b/third_party/blink/renderer/core/css/css_selector.cc index b8125240..5cf4225 100644 --- a/third_party/blink/renderer/core/css/css_selector.cc +++ b/third_party/blink/renderer/core/css/css_selector.cc
@@ -1063,7 +1063,12 @@ void CSSSelector::SetContainsPseudoInsideHasPseudoClass() { CreateRareData(); - data_.rare_data_->bits_.contains_pseudo_inside_has_pseudo_class_ = true; + data_.rare_data_->bits_.has_.contains_pseudo_ = true; +} + +void CSSSelector::SetContainsComplexLogicalCombinationsInsideHasPseudoClass() { + CreateRareData(); + data_.rare_data_->bits_.has_.contains_complex_logical_combinations_ = true; } static bool ValidateSubSelector(const CSSSelector* selector) {
diff --git a/third_party/blink/renderer/core/css/css_selector.h b/third_party/blink/renderer/core/css/css_selector.h index 9d01bb76..90c67d8 100644 --- a/third_party/blink/renderer/core/css/css_selector.h +++ b/third_party/blink/renderer/core/css/css_selector.h
@@ -359,8 +359,12 @@ return has_rare_data_ ? data_.rare_data_->part_names_.get() : nullptr; } bool ContainsPseudoInsideHasPseudoClass() const { - return has_rare_data_ ? data_.rare_data_->bits_ - .contains_pseudo_inside_has_pseudo_class_ + return has_rare_data_ ? data_.rare_data_->bits_.has_.contains_pseudo_ + : false; + } + bool ContainsComplexLogicalCombinationsInsideHasPseudoClass() const { + return has_rare_data_ ? data_.rare_data_->bits_.has_ + .contains_complex_logical_combinations_ : false; } @@ -376,6 +380,7 @@ void SetSelectorList(std::unique_ptr<CSSSelectorList>); void SetPartNames(std::unique_ptr<Vector<AtomicString>>); void SetContainsPseudoInsideHasPseudoClass(); + void SetContainsComplexLogicalCombinationsInsideHasPseudoClass(); void SetNth(int a, int b); bool MatchNth(unsigned count) const; @@ -490,8 +495,14 @@ AttributeMatchType attribute_match_; // used for attribute selector (with value) - // Used for :has() with pseudos in its argument. e.g. :has(:hover) - bool contains_pseudo_inside_has_pseudo_class_; + struct { + // Used for :has() with pseudos in its argument. e.g. :has(:hover) + bool contains_pseudo_; + + // Used for :has() with logical combinations (:is(), :where(), :not()) + // containing complex selector in its argument. e.g. :has(:is(.a .b)) + bool contains_complex_logical_combinations_; + } has_; } bits_; QualifiedName attribute_; // used for attribute selector AtomicString argument_; // Used for :contains, :lang, :nth-*
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_selector.cc b/third_party/blink/renderer/core/css/parser/css_parser_selector.cc index 737a646..451a92f 100644 --- a/third_party/blink/renderer/core/css/parser/css_parser_selector.cc +++ b/third_party/blink/renderer/core/css/parser/css_parser_selector.cc
@@ -62,6 +62,11 @@ selector_->SetContainsPseudoInsideHasPseudoClass(); } +void CSSParserSelector:: + SetContainsComplexLogicalCombinationsInsideHasPseudoClass() { + selector_->SetContainsComplexLogicalCombinationsInsideHasPseudoClass(); +} + void CSSParserSelector::AppendTagHistory( CSSSelector::RelationType relation, std::unique_ptr<CSSParserSelector> selector) {
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_selector.h b/third_party/blink/renderer/core/css/parser/css_parser_selector.h index 2e244c65..00a5929a 100644 --- a/third_party/blink/renderer/core/css/parser/css_parser_selector.h +++ b/third_party/blink/renderer/core/css/parser/css_parser_selector.h
@@ -80,6 +80,7 @@ void SetSelectorList(std::unique_ptr<CSSSelectorList>); void SetAtomics(std::unique_ptr<CSSSelectorList>); void SetContainsPseudoInsideHasPseudoClass(); + void SetContainsComplexLogicalCombinationsInsideHasPseudoClass(); bool IsHostPseudoSelector() const;
diff --git a/third_party/blink/renderer/core/css/parser/css_selector_parser.cc b/third_party/blink/renderer/core/css/parser/css_selector_parser.cc index fe145e2..a2b52140 100644 --- a/third_party/blink/renderer/core/css/parser/css_selector_parser.cc +++ b/third_party/blink/renderer/core/css/parser/css_selector_parser.cc
@@ -342,6 +342,10 @@ previous_compound_flags |= ExtractCompoundFlags(*simple, context_->Mode()); if (CSSSelector::RelationType combinator = ConsumeCombinator(range)) { + if (is_inside_has_argument_ && + is_inside_logical_combination_in_has_argument_) { + found_complex_logical_combinations_in_has_argument_ = true; + } return ConsumePartialComplexSelector(range, combinator, std::move(selector), previous_compound_flags); } @@ -864,6 +868,9 @@ case CSSSelector::kPseudoIs: { DisallowPseudoElementsScope scope(this); base::AutoReset<bool> resist_namespace(&resist_default_namespace_, true); + base::AutoReset<bool> is_inside_logical_combination_in_has_argument( + &is_inside_logical_combination_in_has_argument_, + is_inside_has_argument_); std::unique_ptr<CSSSelectorList> selector_list = std::make_unique<CSSSelectorList>(); @@ -876,6 +883,9 @@ case CSSSelector::kPseudoWhere: { DisallowPseudoElementsScope scope(this); base::AutoReset<bool> resist_namespace(&resist_default_namespace_, true); + base::AutoReset<bool> is_inside_logical_combination_in_has_argument( + &is_inside_logical_combination_in_has_argument_, + is_inside_has_argument_); std::unique_ptr<CSSSelectorList> selector_list = std::make_unique<CSSSelectorList>(); @@ -926,6 +936,8 @@ true); base::AutoReset<bool> found_pseudo_in_has_argument( &found_pseudo_in_has_argument_, false); + base::AutoReset<bool> found_complex_logical_combinations_in_has_argument( + &found_complex_logical_combinations_in_has_argument_, false); std::unique_ptr<CSSSelectorList> selector_list = std::make_unique<CSSSelectorList>(); @@ -936,11 +948,16 @@ selector->SetSelectorList(std::move(selector_list)); if (found_pseudo_in_has_argument_) selector->SetContainsPseudoInsideHasPseudoClass(); + if (found_complex_logical_combinations_in_has_argument_) + selector->SetContainsComplexLogicalCombinationsInsideHasPseudoClass(); return selector; } case CSSSelector::kPseudoNot: { DisallowPseudoElementsScope scope(this); base::AutoReset<bool> resist_namespace(&resist_default_namespace_, true); + base::AutoReset<bool> is_inside_logical_combination_in_has_argument( + &is_inside_logical_combination_in_has_argument_, + is_inside_has_argument_); std::unique_ptr<CSSSelectorList> selector_list = std::make_unique<CSSSelectorList>();
diff --git a/third_party/blink/renderer/core/css/parser/css_selector_parser.h b/third_party/blink/renderer/core/css/parser/css_selector_parser.h index e1ab69fe..f6b6071 100644 --- a/third_party/blink/renderer/core/css/parser/css_selector_parser.h +++ b/third_party/blink/renderer/core/css/parser/css_selector_parser.h
@@ -164,11 +164,17 @@ // the default namespace is '*' while this flag is true. bool ignore_default_namespace_ = false; - // The 'found_pseudo_in_has_argument flag is true when we found any pseudo in - // ':has()' argument while parsing. + // The 'found_pseudo_in_has_argument_' flag is true when we found any pseudo + // in ':has()' argument while parsing. bool found_pseudo_in_has_argument_ = false; bool is_inside_has_argument_ = false; + // The 'found_complex_logical_combinations_in_has_argument_' flag is true when + // we found any logical combinations (:is(), :where(), :not()) containing + // complex selector in ':has()' argument while parsing. + bool found_complex_logical_combinations_in_has_argument_ = false; + bool is_inside_logical_combination_in_has_argument_ = false; + class DisallowPseudoElementsScope { STACK_ALLOCATED();
diff --git a/third_party/blink/renderer/core/css/selector_checker.cc b/third_party/blink/renderer/core/css/selector_checker.cc index 1e5ad9a..6d6b7f2 100644 --- a/third_party/blink/renderer/core/css/selector_checker.cc +++ b/third_party/blink/renderer/core/css/selector_checker.cc
@@ -1521,6 +1521,9 @@ if (selector.ContainsPseudoInsideHasPseudoClass()) element.SetAffectedByPseudoInHas(); + + if (selector.ContainsComplexLogicalCombinationsInsideHasPseudoClass()) + element.SetAffectedByLogicalCombinationsInHas(); } return CheckPseudoHas(context, result); case CSSSelector::kPseudoRelativeLeftmost:
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index 7e37c93..418ccdf 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -984,7 +984,8 @@ bool PossiblyAffectingHasState(Element& element) { return element.AncestorsOrAncestorSiblingsAffectedByHas() || - element.GetSiblingsAffectedByHasFlags(); + element.GetSiblingsAffectedByHasFlags() || + element.AffectedByLogicalCombinationsInHas(); } bool InsertionOrRemovalPossiblyAffectHasStateOfAncestorsOrAncestorSiblings( @@ -1018,12 +1019,37 @@ } // namespace -void StyleEngine::InvalidateAncestorsOrSiblingsAffectedByHasInternal( +void StyleEngine::InvalidateElementAffectedByHas(Element& element, + bool for_pseudo_change) { + if (for_pseudo_change && !element.AffectedByPseudoInHas()) + return; + + const ComputedStyle* style = element.GetComputedStyle(); + + if (style && style->AffectedBySubjectHas()) { + // TODO(blee@igalia.com) Need filtering for irrelevant elements. + // e.g. When we have '.a:has(.b) {}', '.c:has(.d) {}', mutation of class + // value 'd' can invalidate ancestor with class value 'a' because we + // don't have any filtering for this case. + element.SetNeedsStyleRecalc( + StyleChangeType::kLocalStyleChange, + StyleChangeReasonForTracing::Create( + blink::style_change_reason::kStyleInvalidator)); + } + + if (element.AffectedByNonSubjectHas()) { + InvalidationLists invalidation_lists; + GetRuleFeatureSet().CollectInvalidationSetsForPseudoClass( + invalidation_lists, element, CSSSelector::kPseudoHas); + pending_invalidations_.ScheduleInvalidationSetsForNode(invalidation_lists, + element); + } +} + +void StyleEngine::InvalidateAncestorsOrSiblingsAffectedByHas( Element* parent, Element* previous_sibling, bool for_pseudo_change) { - const RuleFeatureSet& features = GetRuleFeatureSet(); - bool traverse_ancestors = false; bool traverse_siblings = false; Element* element = previous_sibling ? previous_sibling : parent; @@ -1034,28 +1060,7 @@ traverse_ancestors |= element->AncestorsOrAncestorSiblingsAffectedByHas(); traverse_siblings = element->GetSiblingsAffectedByHasFlags(); - const ComputedStyle* style = element->GetComputedStyle(); - - if (!for_pseudo_change || element->AffectedByPseudoInHas()) { - if (style && style->AffectedBySubjectHas()) { - // TODO(blee@igalia.com) Need filtering for irrelevant elements. - // e.g. When we have '.a:has(.b) {}', '.c:has(.d) {}', mutation of class - // value 'd' can invalidate ancestor with class value 'a' because we - // don't have any filtering for this case. - element->SetNeedsStyleRecalc( - StyleChangeType::kLocalStyleChange, - StyleChangeReasonForTracing::Create( - blink::style_change_reason::kStyleInvalidator)); - } - - if (element->AffectedByNonSubjectHas()) { - InvalidationLists invalidation_lists; - features.CollectInvalidationSetsForPseudoClass( - invalidation_lists, *element, CSSSelector::kPseudoHas); - pending_invalidations_.ScheduleInvalidationSetsForNode( - invalidation_lists, *element); - } - } + InvalidateElementAffectedByHas(*element, for_pseudo_change); if (traverse_siblings) { previous_sibling = ElementTraversal::PreviousSibling(*element); @@ -1087,8 +1092,8 @@ void StyleEngine::InvalidateAncestorsOrSiblingsAffectedByHasForPseudoChange( Element* parent, Element* previous_sibling) { - InvalidateAncestorsOrSiblingsAffectedByHasInternal( - parent, previous_sibling, true /* for_pseudo_change */); + InvalidateAncestorsOrSiblingsAffectedByHas(parent, previous_sibling, + true /* for_pseudo_change */); } void StyleEngine::InvalidateAncestorsOrSiblingsAffectedByHas( @@ -1105,8 +1110,16 @@ void StyleEngine::InvalidateAncestorsOrSiblingsAffectedByHas( Element* parent, Element* previous_sibling) { - InvalidateAncestorsOrSiblingsAffectedByHasInternal( - parent, previous_sibling, false /* for_pseudo_change */); + InvalidateAncestorsOrSiblingsAffectedByHas(parent, previous_sibling, + false /* for_pseudo_change */); +} + +void StyleEngine::InvalidateChangedElementAffectedByLogicalCombinationsInHas( + Element& changed_element, + bool for_pseudo_change) { + if (!changed_element.AffectedByLogicalCombinationsInHas()) + return; + InvalidateElementAffectedByHas(changed_element, for_pseudo_change); } void StyleEngine::ClassChangedForElement( @@ -1123,6 +1136,8 @@ unsigned changed_size = changed_classes.size(); for (unsigned i = 0; i < changed_size; ++i) { if (features.NeedsHasInvalidationForClass(changed_classes[i])) { + InvalidateChangedElementAffectedByLogicalCombinationsInHas( + element, /* for_pseudo_change */ false); InvalidateAncestorsOrSiblingsAffectedByHas(element); break; } @@ -1216,8 +1231,11 @@ element); } - if (affecting_has_state) + if (affecting_has_state) { + InvalidateChangedElementAffectedByLogicalCombinationsInHas( + element, /* for_pseudo_change */ false); InvalidateAncestorsOrSiblingsAffectedByHas(element); + } } namespace { @@ -1249,8 +1267,11 @@ if (RuntimeEnabledFeatures::CSSPseudoHasEnabled() && features.NeedsHasInvalidationForAttributeChange() && PossiblyAffectingHasState(element)) { - if (features.NeedsHasInvalidationForAttribute(attribute_name)) + if (features.NeedsHasInvalidationForAttribute(attribute_name)) { + InvalidateChangedElementAffectedByLogicalCombinationsInHas( + element, /* for_pseudo_change */ false); InvalidateAncestorsOrSiblingsAffectedByHas(element); + } } if (IsSubtreeAndSiblingsStyleDirty(element)) @@ -1283,6 +1304,8 @@ PossiblyAffectingHasState(element)) { if ((!old_id.IsEmpty() && features.NeedsHasInvalidationForId(old_id)) || (!new_id.IsEmpty() && features.NeedsHasInvalidationForId(new_id))) { + InvalidateChangedElementAffectedByLogicalCombinationsInHas( + element, /* for_pseudo_change */ false); InvalidateAncestorsOrSiblingsAffectedByHas(element); } } @@ -1316,8 +1339,11 @@ RuntimeEnabledFeatures::CSSPseudoHasEnabled() && features.NeedsHasInvalidationForPseudoStateChange() && PossiblyAffectingHasState(element)) { - if (features.NeedsHasInvalidationForPseudoClass(pseudo_type)) + if (features.NeedsHasInvalidationForPseudoClass(pseudo_type)) { + InvalidateChangedElementAffectedByLogicalCombinationsInHas( + element, /* for_pseudo_change */ true); InvalidateAncestorsOrSiblingsAffectedByHasForPseudoChange(element); + } } if (!invalidate_descendants_or_siblings ||
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h index f25bf55..9272fbc 100644 --- a/third_party/blink/renderer/core/css/style_engine.h +++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -722,10 +722,10 @@ void RebuildFieldSetContainer(HTMLFieldSetElement& fieldset); // Invalidate ancestors or siblings affected by :has() state change - void InvalidateAncestorsOrSiblingsAffectedByHasInternal( - Element* parent, - Element* previous_sibling, - bool for_pseudo_change); + inline void InvalidateElementAffectedByHas(Element&, bool for_pseudo_change); + void InvalidateAncestorsOrSiblingsAffectedByHas(Element* parent, + Element* previous_sibling, + bool for_pseudo_change); inline void InvalidateAncestorsOrSiblingsAffectedByHas( Element& changed_element); void InvalidateAncestorsOrSiblingsAffectedByHas(Element* parent, @@ -735,6 +735,10 @@ void InvalidateAncestorsOrSiblingsAffectedByHasForPseudoChange( Element* parent, Element* previous_sibling); + // Invalidate changed element affected by logical combinations in :has() + inline void InvalidateChangedElementAffectedByLogicalCombinationsInHas( + Element& changed_element, + bool for_pseudo_change); Member<Document> document_;
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index e2d00bd..2ecc6ad 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -5566,6 +5566,16 @@ EnsureElementRareData().SetAncestorsOrSiblingsAffectedByFocusVisibleInHas(); } +bool Element::AffectedByLogicalCombinationsInHas() const { + return HasRareData() + ? GetElementRareData()->AffectedByLogicalCombinationsInHas() + : false; +} + +void Element::SetAffectedByLogicalCombinationsInHas() { + EnsureElementRareData().SetAffectedByLogicalCombinationsInHas(); +} + bool Element::UpdateForceLegacyLayout(const ComputedStyle& new_style, const ComputedStyle* old_style) { // ::first-letter may cause structure discrepancies between DOM and layout
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h index b614206..b5e9396 100644 --- a/third_party/blink/renderer/core/dom/element.h +++ b/third_party/blink/renderer/core/dom/element.h
@@ -1111,6 +1111,8 @@ void SetAncestorsOrSiblingsAffectedByFocusInHas(); bool AncestorsOrSiblingsAffectedByFocusVisibleInHas() const; void SetAncestorsOrSiblingsAffectedByFocusVisibleInHas(); + bool AffectedByLogicalCombinationsInHas() const; + void SetAffectedByLogicalCombinationsInHas(); void SaveIntrinsicSize(ResizeObserverSize* size); const ResizeObserverSize* LastIntrinsicSize() const;
diff --git a/third_party/blink/renderer/core/dom/element_rare_data.h b/third_party/blink/renderer/core/dom/element_rare_data.h index 17ee1605..031d21b 100644 --- a/third_party/blink/renderer/core/dom/element_rare_data.h +++ b/third_party/blink/renderer/core/dom/element_rare_data.h
@@ -226,6 +226,12 @@ has_invalidation_flags_ .ancestors_or_siblings_affected_by_focus_visible_in_has = true; } + bool AffectedByLogicalCombinationsInHas() const { + return has_invalidation_flags_.affected_by_logical_combinations_in_has; + } + void SetAffectedByLogicalCombinationsInHas() { + has_invalidation_flags_.affected_by_logical_combinations_in_has = true; + } void Trace(blink::Visitor*) const; @@ -481,6 +487,14 @@ void SetAncestorsOrSiblingsAffectedByFocusVisibleInHas() { EnsureSuperRareData().SetAncestorsOrSiblingsAffectedByFocusVisibleInHas(); } + bool AffectedByLogicalCombinationsInHas() const { + return super_rare_data_ + ? super_rare_data_->AffectedByLogicalCombinationsInHas() + : false; + } + void SetAffectedByLogicalCombinationsInHas() { + EnsureSuperRareData().SetAffectedByLogicalCombinationsInHas(); + } AccessibleNode* GetAccessibleNode() const { if (super_rare_data_)
diff --git a/third_party/blink/renderer/core/dom/has_invalidation_flags.h b/third_party/blink/renderer/core/dom/has_invalidation_flags.h index bdc2262..58d8eba 100644 --- a/third_party/blink/renderer/core/dom/has_invalidation_flags.h +++ b/third_party/blink/renderer/core/dom/has_invalidation_flags.h
@@ -189,6 +189,7 @@ unsigned ancestors_or_siblings_affected_by_active_in_has : 1; unsigned ancestors_or_siblings_affected_by_focus_in_has : 1; unsigned ancestors_or_siblings_affected_by_focus_visible_in_has : 1; + unsigned affected_by_logical_combinations_in_has : 1; HasInvalidationFlags() : affected_by_non_subject_has(false),
diff --git a/third_party/blink/renderer/core/frame/attribution_aggregatable_trigger_data_fuzzer.cc b/third_party/blink/renderer/core/frame/attribution_aggregatable_trigger_data_fuzzer.cc deleted file mode 100644 index cb294ba..0000000 --- a/third_party/blink/renderer/core/frame/attribution_aggregatable_trigger_data_fuzzer.cc +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stdlib.h> -#include <iostream> -#include <string> - -#include "testing/libfuzzer/proto/json.pb.h" -#include "testing/libfuzzer/proto/json_proto_converter.h" -#include "testing/libfuzzer/proto/lpm_interface.h" -#include "third_party/blink/public/mojom/conversions/attribution_data_host.mojom-blink.h" -#include "third_party/blink/renderer/core/frame/attribution_response_parsing.h" -#include "third_party/blink/renderer/platform/testing/blink_fuzzer_test_support.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" - -namespace blink { - -DEFINE_PROTO_FUZZER(const json_proto::JsonValue& json_value) { - static BlinkFuzzerTestSupport test_support = BlinkFuzzerTestSupport(); - - json_proto::JsonProtoConverter converter; - std::string native_input = converter.Convert(json_value); - - if (getenv("LPM_DUMP_NATIVE_INPUT")) - std::cout << native_input << std::endl; - - const String input(native_input.c_str()); - WTF::Vector<mojom::blink::AttributionAggregatableTriggerDataPtr> output; - attribution_response_parsing::ParseAttributionAggregatableTriggerData(input, - output); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/frame/attribution_aggregatable_values_fuzzer.cc b/third_party/blink/renderer/core/frame/attribution_aggregatable_values_fuzzer.cc deleted file mode 100644 index 72fe570..0000000 --- a/third_party/blink/renderer/core/frame/attribution_aggregatable_values_fuzzer.cc +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2022 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <stdint.h> -#include <stdlib.h> -#include <iostream> -#include <string> - -#include "testing/libfuzzer/proto/json.pb.h" -#include "testing/libfuzzer/proto/json_proto_converter.h" -#include "testing/libfuzzer/proto/lpm_interface.h" -#include "third_party/blink/public/mojom/conversions/attribution_data_host.mojom-blink.h" -#include "third_party/blink/renderer/core/frame/attribution_response_parsing.h" -#include "third_party/blink/renderer/platform/testing/blink_fuzzer_test_support.h" -#include "third_party/blink/renderer/platform/wtf/hash_map.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" - -namespace blink { - -DEFINE_PROTO_FUZZER(const json_proto::JsonValue& json_value) { - static BlinkFuzzerTestSupport test_support = BlinkFuzzerTestSupport(); - - json_proto::JsonProtoConverter converter; - std::string native_input = converter.Convert(json_value); - - if (getenv("LPM_DUMP_NATIVE_INPUT")) - std::cout << native_input << std::endl; - - const String input(native_input.c_str()); - WTF::HashMap<String, uint32_t> output; - attribution_response_parsing::ParseAttributionAggregatableValues(input, - output); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/frame/attribution_response_parsing.cc b/third_party/blink/renderer/core/frame/attribution_response_parsing.cc index e391159..9750d79 100644 --- a/third_party/blink/renderer/core/frame/attribution_response_parsing.cc +++ b/third_party/blink/renderer/core/frame/attribution_response_parsing.cc
@@ -76,13 +76,15 @@ return true; } +} // namespace + bool ParseAttributionFilterData( - JSONValue* value, + const JSONValue* value, mojom::blink::AttributionFilterData& filter_data) { if (!value) return true; - JSONObject* object = JSONObject::Cast(value); + const JSONObject* object = JSONObject::Cast(value); if (!object) return false; @@ -105,14 +107,14 @@ UMA_HISTOGRAM_COUNTS_100("Conversions.FiltersPerFilterData", num_filters); for (wtf_size_t i = 0; i < num_filters; ++i) { - JSONObject::Entry entry = object->at(i); + const JSONObject::Entry entry = object->at(i); if (entry.first.CharactersSizeInBytes() > kMaxBytesPerAttributionFilterString) { return false; } - JSONArray* array = JSONArray::Cast(entry.second); + const JSONArray* array = JSONArray::Cast(entry.second); if (!array) return false; @@ -141,8 +143,6 @@ return true; } -} // namespace - bool ParseAggregationKeys( const JSONValue* json, WTF::HashMap<String, absl::uint128>& aggregation_keys) { @@ -272,17 +272,14 @@ } bool ParseEventTriggerData( - const String& json_string, + const JSONValue* json, WTF::Vector<mojom::blink::EventTriggerDataPtr>& event_trigger_data) { - // TODO(apaseltiner): Consider applying a max stack depth to this. - std::unique_ptr<JSONValue> json = ParseJSON(json_string); - - // TODO(johnidel): Log a devtools issues if JSON parsing fails and on - // individual early exits below. if (!json) - return false; + return true; - JSONArray* array_value = JSONArray::Cast(json.get()); + // TODO(apaseltiner): Log a devtools issues on individual early exits below. + + const JSONArray* array_value = JSONArray::Cast(json); if (!array_value) return false; @@ -351,24 +348,12 @@ return true; } -bool ParseFilters(const String& json_string, - mojom::blink::AttributionFilterData& filter_data) { - // TODO(apaseltiner): Consider applying a max stack depth to this. - std::unique_ptr<JSONValue> json = ParseJSON(json_string); - if (!json) - return false; - - return ParseAttributionFilterData(json.get(), filter_data); -} - bool ParseAttributionAggregatableTriggerData( - const String& json_string, + const JSONValue* json, WTF::Vector<mojom::blink::AttributionAggregatableTriggerDataPtr>& trigger_data) { - // TODO(apaseltiner): Consider applying a max stack depth to this. - std::unique_ptr<JSONValue> json = ParseJSON(json_string); if (!json) - return false; + return true; const int kExclusiveMaxHistogramValue = 101; @@ -377,7 +362,7 @@ "Bump the version for histogram " "Conversions.AggregatableTriggerDataLength"); - const auto* array = JSONArray::Cast(json.get()); + const auto* array = JSONArray::Cast(json); if (!array) return false; @@ -444,14 +429,12 @@ } bool ParseAttributionAggregatableValues( - const String& json_string, + const JSONValue* json, WTF::HashMap<String, uint32_t>& values) { - // TODO(apaseltiner): Consider applying a max stack depth to this. - std::unique_ptr<JSONValue> json = ParseJSON(json_string); if (!json) - return false; + return true; - const auto* object = JSONObject::Cast(json.get()); + const auto* object = JSONObject::Cast(json); if (!object || object->size() > kMaxAttributionAggregatableKeysPerSourceOrTrigger) { return false; @@ -483,6 +466,52 @@ return true; } +bool ParseTriggerRegistrationHeader( + const String& json_string, + mojom::blink::AttributionTriggerData& trigger_data) { + std::unique_ptr<JSONValue> json = ParseJSON(json_string); + if (!json) + return false; + + const JSONObject* object = JSONObject::Cast(json.get()); + if (!object) + return false; + + // Populate event triggers. + if (!ParseEventTriggerData(object->Get("event_trigger_data"), + trigger_data.event_triggers)) { + return false; + } + + trigger_data.filters = mojom::blink::AttributionFilterData::New(); + + if (!ParseAttributionFilterData(object->Get("filters"), + *trigger_data.filters)) { + return false; + } + + trigger_data.aggregatable_trigger = + mojom::blink::AttributionAggregatableTrigger::New(); + + if (!ParseAttributionAggregatableTriggerData( + object->Get("aggregatable_trigger_data"), + trigger_data.aggregatable_trigger->trigger_data)) { + return false; + } + + if (!ParseAttributionAggregatableValues( + object->Get("aggregatable_values"), + trigger_data.aggregatable_trigger->values)) { + return false; + } + + String debug_key_string; + if (object->GetString("debug_key", &debug_key_string)) + trigger_data.debug_key = ParseDebugKey(debug_key_string); + + return true; +} + mojom::blink::AttributionTriggerDataPtr ParseAttributionTriggerData( const ResourceResponse& response) { auto trigger_data = mojom::blink::AttributionTriggerData::New(); @@ -494,48 +523,10 @@ return nullptr; trigger_data->reporting_origin = std::move(reporting_origin); - // Populate event triggers. - const AtomicString& event_triggers_json = response.HttpHeaderField( - http_names::kAttributionReportingRegisterEventTrigger); - if (!event_triggers_json.IsNull() && - !attribution_response_parsing::ParseEventTriggerData( - event_triggers_json, trigger_data->event_triggers)) { + const AtomicString& trigger_json = response.HttpHeaderField( + http_names::kAttributionReportingRegisterTrigger); + if (!ParseTriggerRegistrationHeader(trigger_json, *trigger_data)) return nullptr; - } - - trigger_data->filters = mojom::blink::AttributionFilterData::New(); - - const AtomicString& filter_json = - response.HttpHeaderField(http_names::kAttributionReportingFilters); - if (!filter_json.IsNull() && !attribution_response_parsing::ParseFilters( - filter_json, *trigger_data->filters)) { - return nullptr; - } - - trigger_data->aggregatable_trigger = - mojom::blink::AttributionAggregatableTrigger::New(); - - const AtomicString& aggregatable_trigger_json = response.HttpHeaderField( - http_names::kAttributionReportingRegisterAggregatableTriggerData); - if (!aggregatable_trigger_json.IsNull() && - !attribution_response_parsing::ParseAttributionAggregatableTriggerData( - aggregatable_trigger_json, - trigger_data->aggregatable_trigger->trigger_data)) { - return nullptr; - } - - const AtomicString& aggregatable_values_json = response.HttpHeaderField( - http_names::kAttributionReportingRegisterAggregatableValues); - if (!aggregatable_values_json.IsNull() && - !attribution_response_parsing::ParseAttributionAggregatableValues( - aggregatable_values_json, - trigger_data->aggregatable_trigger->values)) { - return nullptr; - } - - trigger_data->debug_key = - attribution_response_parsing::ParseDebugKey(response.HttpHeaderField( - http_names::kAttributionReportingTriggerDebugKey)); return trigger_data; }
diff --git a/third_party/blink/renderer/core/frame/attribution_response_parsing.h b/third_party/blink/renderer/core/frame/attribution_response_parsing.h index 683c99ab1..7a39c08 100644 --- a/third_party/blink/renderer/core/frame/attribution_response_parsing.h +++ b/third_party/blink/renderer/core/frame/attribution_response_parsing.h
@@ -25,8 +25,8 @@ namespace attribution_response_parsing { // Helper functions to parse response headers. See details in the explainer. -// https://github.com/WICG/conversion-measurement-api/blob/main/EVENT.md -// https://github.com/WICG/conversion-measurement-api/blob/main/AGGREGATE.md +// https://github.com/WICG/attribution-reporting-api/blob/main/EVENT.md +// https://github.com/WICG/attribution-reporting-api/blob/main/AGGREGATE.md // Example JSON schema: // [{ @@ -52,6 +52,10 @@ const String& json_string, mojom::blink::AttributionSourceData& source_data); +CORE_EXPORT bool ParseTriggerRegistrationHeader( + const String& json_string, + mojom::blink::AttributionTriggerData& trigger_data); + // Parses event trigger data header of the form: // // [{ @@ -62,7 +66,7 @@ // // Returns whether parsing was successful. CORE_EXPORT bool ParseEventTriggerData( - const String& json_string, + const JSONValue* json, WTF::Vector<mojom::blink::EventTriggerDataPtr>& event_trigger_data); // Parses filter header of the form: @@ -73,8 +77,9 @@ // } // // Returns whether parsing was successful. -CORE_EXPORT bool ParseFilters(const String& json_string, - mojom::blink::AttributionFilterData& filter_data); +CORE_EXPORT bool ParseAttributionFilterData( + const JSONValue* json, + mojom::blink::AttributionFilterData& filter_data); // Example JSON schema: // [{ @@ -88,7 +93,7 @@ // // Returns whether parsing was successful. CORE_EXPORT bool ParseAttributionAggregatableTriggerData( - const String& json_string, + const JSONValue* json, WTF::Vector<mojom::blink::AttributionAggregatableTriggerDataPtr>& trigger_data); @@ -100,7 +105,7 @@ // // Returns whether parsing was successful. CORE_EXPORT bool ParseAttributionAggregatableValues( - const String& json_string, + const JSONValue* json, WTF::HashMap<String, uint32_t>& values); // Returns the attribution trigger data parsed from the response. Returns
diff --git a/third_party/blink/renderer/core/frame/attribution_response_parsing_test.cc b/third_party/blink/renderer/core/frame/attribution_response_parsing_test.cc index 0bd4d77..d8b86700 100644 --- a/third_party/blink/renderer/core/frame/attribution_response_parsing_test.cc +++ b/third_party/blink/renderer/core/frame/attribution_response_parsing_test.cc
@@ -184,22 +184,24 @@ TEST(AttributionResponseParsingTest, ParseAttributionAggregatableTrigger) { const struct { String description; - String header; + std::unique_ptr<JSONValue> json; mojom::blink::AttributionAggregatableTriggerPtr expected; } kTestCases[] = { - {"Empty header", "", nullptr}, - {"Invalid JSON", "{", nullptr}, - {"Not an array", "{}", nullptr}, - {"Element not a dictionary", "[123]", nullptr}, - {"Missing source_keys field", R"([{"key_piece":"0x400"}])", nullptr}, - {"source_keys not an array", - R"([{"key_piece":"0x400","source_keys":"key"}])", nullptr}, - {"source_keys element not a string", - R"([{"key_piece":"0x400","source_keys":[123]}])"}, - {"Missing key_piece field", R"([{"source_keys":["key"]}])", nullptr}, - {"Invalid key", R"([{"key_piece":"0xG00","source_keys":["key"]}])", + {"Null", nullptr, AggregatableTriggerBuilder().Build()}, + {"Not an array", ParseJSON(R"({})"), nullptr}, + {"Element not a dictionary", ParseJSON(R"([123])"), nullptr}, + {"Missing source_keys field", ParseJSON(R"([{"key_piece":"0x400"}])"), nullptr}, - {"Valid trigger", R"([{"key_piece":"0x400","source_keys":["key"]}])", + {"source_keys not an array", + ParseJSON(R"([{"key_piece":"0x400","source_keys":"key"}])"), nullptr}, + {"source_keys element not a string", + ParseJSON(R"([{"key_piece":"0x400","source_keys":[123]}])")}, + {"Missing key_piece field", ParseJSON(R"([{"source_keys":["key"]}])"), + nullptr}, + {"Invalid key", + ParseJSON(R"([{"key_piece":"0xG00","source_keys":["key"]}])"), nullptr}, + {"Valid trigger", + ParseJSON(R"([{"key_piece":"0x400","source_keys":["key"]}])"), AggregatableTriggerBuilder() .AddTriggerData( mojom::blink::AttributionAggregatableTriggerData::New( @@ -208,13 +210,12 @@ /*filters=*/mojom::blink::AttributionFilterData::New(), /*not_filters=*/mojom::blink::AttributionFilterData::New())) .Build()}, - {"Valid trigger with filters", - R"([{ + {"Valid trigger with filters", ParseJSON(R"([{ "key_piece": "0x400", "source_keys": ["key"], "filters": {"filter": ["value1"]}, "not_filters": {"filter": ["value2"]} - }])", + }])"), AggregatableTriggerBuilder() .AddTriggerData( mojom::blink::AttributionAggregatableTriggerData::New( @@ -230,8 +231,8 @@ .Build())) .Build()}, {"Two valid trigger data", - R"([{"key_piece":"0x400","source_keys":["key1"]}, - {"key_piece":"0xA80","source_keys":["key2"]}])", + ParseJSON(R"([{"key_piece":"0x400","source_keys":["key1"]}, + {"key_piece":"0xA80","source_keys":["key2"]}])"), AggregatableTriggerBuilder() .AddTriggerData( mojom::blink::AttributionAggregatableTriggerData::New( @@ -251,8 +252,8 @@ for (const auto& test_case : kTestCases) { WTF::Vector<mojom::blink::AttributionAggregatableTriggerDataPtr> trigger_data; - bool valid = - ParseAttributionAggregatableTriggerData(test_case.header, trigger_data); + bool valid = ParseAttributionAggregatableTriggerData(test_case.json.get(), + trigger_data); EXPECT_EQ(!test_case.expected.is_null(), valid) << test_case.description; if (test_case.expected) { EXPECT_EQ(test_case.expected->trigger_data, trigger_data) @@ -270,10 +271,10 @@ wtf_size_t key_count; wtf_size_t key_size; - String GetHeader() const { + std::unique_ptr<JSONArray> GetHeader() const { String key = GetKey(); - JSONArray array; + auto array = std::make_unique<JSONArray>(); for (wtf_size_t i = 0u; i < trigger_data_count; ++i) { auto object = std::make_unique<JSONObject>(); object->SetString("key_piece", "0x1"); @@ -284,10 +285,10 @@ } object->SetArray("source_keys", std::move(keys)); - array.PushObject(std::move(object)); + array->PushObject(std::move(object)); } - return array.ToJSONString(); + return array; } WTF::Vector<mojom::blink::AttributionAggregatableTriggerDataPtr> @@ -327,10 +328,11 @@ }; for (const auto& test_case : kTestCases) { + std::unique_ptr<JSONArray> json = test_case.GetHeader(); WTF::Vector<mojom::blink::AttributionAggregatableTriggerDataPtr> trigger_data; - bool valid = ParseAttributionAggregatableTriggerData(test_case.GetHeader(), - trigger_data); + bool valid = + ParseAttributionAggregatableTriggerData(json.get(), trigger_data); EXPECT_EQ(test_case.valid, valid) << test_case.description; if (test_case.valid) { @@ -343,26 +345,29 @@ TEST(AttributionResponseParsingTest, ParseAttributionAggregatableValues) { const struct { String description; - String header; + std::unique_ptr<JSONValue> json; bool valid; WTF::HashMap<String, uint32_t> values; } kTestCases[] = { - {"Empty header", "", false, {}}, - {"Invalid JSON", "{", false, {}}, - {"Value not an integer", R"({"key":"1"})", false, {}}, - {"Invalid value", R"({"key":-1})", false, {}}, - {"Valid value", R"({"key":123})", true, {{"key", 123}}}, + {"Null", nullptr, true, {}}, + {"Value not an integer", ParseJSON(R"({"key":"1"})"), false, {}}, + {"Invalid value", ParseJSON(R"({"key":-1})"), false, {}}, + {"Valid value", ParseJSON(R"({"key":123})"), true, {{"key", 123}}}, {"Two valid values", - R"({"key1":123,"key2":456})", + ParseJSON(R"({"key1":123,"key2":456})"), true, {{"key1", 123}, {"key2", 456}}}, - {"Max valid value", R"({"key":65536})", true, {{"key", 65536}}}, - {"Value out of range", R"({"key":65537})", false, {}}, + {"Max valid value", + ParseJSON(R"({"key":65536})"), + true, + {{"key", 65536}}}, + {"Value out of range", ParseJSON(R"({"key":65537})"), false, {}}, }; for (const auto& test_case : kTestCases) { WTF::HashMap<String, uint32_t> values; - bool valid = ParseAttributionAggregatableValues(test_case.header, values); + bool valid = + ParseAttributionAggregatableValues(test_case.json.get(), values); EXPECT_EQ(test_case.valid, valid) << test_case.description; if (test_case.valid) EXPECT_EQ(test_case.values, values) << test_case.description; @@ -377,12 +382,12 @@ wtf_size_t key_count; wtf_size_t key_size; - String GetHeader() const { - JSONObject object; + std::unique_ptr<JSONValue> GetHeader() const { + auto object = std::make_unique<JSONObject>(); for (wtf_size_t i = 0u; i < key_count; ++i) { - object.SetInteger(GetKey(i), i + 1); + object->SetInteger(GetKey(i), i + 1); } - return object.ToJSONString(); + return object; } WTF::HashMap<String, uint32_t> GetValues() const { @@ -419,9 +424,9 @@ }; for (const auto& test_case : kTestCases) { + std::unique_ptr<JSONValue> json = test_case.GetHeader(); WTF::HashMap<String, uint32_t> values; - bool valid = - ParseAttributionAggregatableValues(test_case.GetHeader(), values); + bool valid = ParseAttributionAggregatableValues(json.get(), values); EXPECT_EQ(test_case.valid, valid) << test_case.description; if (test_case.valid) @@ -429,19 +434,19 @@ } } -TEST(AttributionResponseParsingTest, ParseFilters) { +TEST(AttributionResponseParsingTest, ParseFilterData) { const auto make_filter_data_with_keys = [](wtf_size_t n) { - JSONObject root; + auto root = std::make_unique<JSONObject>(); for (wtf_size_t i = 0; i < n; ++i) { - root.SetArray(String::Number(i), std::make_unique<JSONArray>()); + root->SetArray(String::Number(i), std::make_unique<JSONArray>()); } - return root.ToJSONString(); + return root; }; const auto make_filter_data_with_key_length = [](wtf_size_t n) { - JSONObject root; - root.SetArray(String(std::string(n, 'a')), std::make_unique<JSONArray>()); - return root.ToJSONString(); + auto root = std::make_unique<JSONObject>(); + root->SetArray(String(std::string(n, 'a')), std::make_unique<JSONArray>()); + return root; }; const auto make_filter_data_with_values = [](wtf_size_t n) { @@ -450,64 +455,64 @@ array->PushString("x"); } - JSONObject root; - root.SetArray("a", std::move(array)); - return root.ToJSONString(); + auto root = std::make_unique<JSONObject>(); + root->SetArray("a", std::move(array)); + return root; }; const auto make_filter_data_with_value_length = [](wtf_size_t n) { auto array = std::make_unique<JSONArray>(); array->PushString(String(std::string(n, 'a'))); - JSONObject root; - root.SetArray("a", std::move(array)); - return root.ToJSONString(); + auto root = std::make_unique<JSONObject>(); + root->SetArray("a", std::move(array)); + return root; }; const struct { String description; - String json; + std::unique_ptr<JSONValue> json; mojom::blink::AttributionFilterDataPtr expected; } kTestCases[] = { { + "Null", + nullptr, + AttributionFilterDataBuilder().Build(), + }, + { "empty", - R"json({})json", + ParseJSON(R"json({})json"), AttributionFilterDataBuilder().Build(), }, { "source_type", - R"json({"source_type": []})json", + ParseJSON(R"json({"source_type": []})json"), AttributionFilterDataBuilder().AddFilter("source_type", {}).Build(), }, { "multiple", - R"json({ + ParseJSON(R"json({ "a": ["b"], "c": ["e", "d"] - })json", + })json"), AttributionFilterDataBuilder() .AddFilter("a", {"b"}) .AddFilter("c", {"e", "d"}) .Build(), }, { - "invalid_json", - "!", - nullptr, - }, - { "not_dictionary", - R"json(true)json", + ParseJSON(R"json(true)json"), nullptr, }, { "value_not_array", - R"json({"a": true})json", + ParseJSON(R"json({"a": true})json"), nullptr, }, { "array_element_not_string", - R"json({"a": [true]})json", + ParseJSON(R"json({"a": [true]})json"), nullptr, }, { @@ -535,7 +540,7 @@ for (const auto& test_case : kTestCases) { mojom::blink::AttributionFilterData filter_data; - bool valid = ParseFilters(test_case.json, filter_data); + bool valid = ParseAttributionFilterData(test_case.json.get(), filter_data); EXPECT_EQ(valid, !test_case.expected.is_null()) << test_case.description; if (test_case.expected) { @@ -544,25 +549,27 @@ } { + std::unique_ptr<JSONValue> json = make_filter_data_with_keys(50); mojom::blink::AttributionFilterData filter_data; - EXPECT_TRUE(ParseFilters(make_filter_data_with_keys(50), filter_data)); + EXPECT_TRUE(ParseAttributionFilterData(json.get(), filter_data)); } { + std::unique_ptr<JSONValue> json = make_filter_data_with_key_length(25); mojom::blink::AttributionFilterData filter_data; - EXPECT_TRUE( - ParseFilters(make_filter_data_with_key_length(25), filter_data)); + EXPECT_TRUE(ParseAttributionFilterData(json.get(), filter_data)); } { + std::unique_ptr<JSONValue> json = make_filter_data_with_values(50); mojom::blink::AttributionFilterData filter_data; - EXPECT_TRUE(ParseFilters(make_filter_data_with_values(50), filter_data)); + EXPECT_TRUE(ParseAttributionFilterData(json.get(), filter_data)); } { + std::unique_ptr<JSONValue> json = make_filter_data_with_value_length(25); mojom::blink::AttributionFilterData filter_data; - EXPECT_TRUE( - ParseFilters(make_filter_data_with_value_length(25), filter_data)); + EXPECT_TRUE(ParseAttributionFilterData(json.get(), filter_data)); } } @@ -891,55 +898,55 @@ TEST(AttributionResponseParsingTest, ParseEventTriggerData) { const struct { String description; - String json; + std::unique_ptr<JSONValue> json; bool valid; Vector<mojom::blink::EventTriggerDataPtr> expected; } kTestCases[] = { { - "invalid_json", - "!", - false, + "Null", + nullptr, + true, {}, }, { "root_not_array", - R"json({})json", + ParseJSON(R"json({})json"), false, {}, }, { "empty", - R"json([])json", + ParseJSON(R"json([])json"), true, {}, }, { "too_many_values", - R"json([{},{},{},{},{},{},{},{},{},{},{}])json", + ParseJSON(R"json([{},{},{},{},{},{},{},{},{},{},{}])json"), false, {}, }, { "value_not_object", - R"json([123])json", + ParseJSON(R"json([123])json"), false, {}, }, { "missing_trigger_data", - R"json([{}])json", + ParseJSON(R"json([{}])json"), false, {}, }, { "trigger_data_not_string", - R"json([{"trigger_data": 1}])json", + ParseJSON(R"json([{"trigger_data": 1}])json"), false, {}, }, { "invalid_trigger_data", - R"json([{"trigger_data": "-5"}])json", + ParseJSON(R"json([{"trigger_data": "-5"}])json"), true, VectorBuilder<mojom::blink::EventTriggerDataPtr>() .Add(mojom::blink::EventTriggerData::New( @@ -952,7 +959,7 @@ }, { "valid_trigger_data", - R"json([{"trigger_data": "5"}])json", + ParseJSON(R"json([{"trigger_data": "5"}])json"), true, VectorBuilder<mojom::blink::EventTriggerDataPtr>() .Add(mojom::blink::EventTriggerData::New( @@ -965,11 +972,11 @@ }, { "multiple", - R"json([ + ParseJSON(R"json([ {"trigger_data": "5"}, {"trigger_data": "3"}, {"trigger_data": "4"} - ])json", + ])json"), true, VectorBuilder<mojom::blink::EventTriggerDataPtr>() .Add(mojom::blink::EventTriggerData::New( @@ -994,10 +1001,10 @@ }, { "valid_priority", - R"json([{ + ParseJSON(R"json([{ "trigger_data": "5", "priority": "3" - }])json", + }])json"), true, VectorBuilder<mojom::blink::EventTriggerDataPtr>() .Add(mojom::blink::EventTriggerData::New( @@ -1010,10 +1017,10 @@ }, { "priority_not_string", - R"json([{ + ParseJSON(R"json([{ "trigger_data": "5", "priority": 3 - }])json", + }])json"), true, VectorBuilder<mojom::blink::EventTriggerDataPtr>() .Add(mojom::blink::EventTriggerData::New( @@ -1026,10 +1033,10 @@ }, { "invalid_priority", - R"json([{ + ParseJSON(R"json([{ "trigger_data": "5", "priority": "abc" - }])json", + }])json"), true, VectorBuilder<mojom::blink::EventTriggerDataPtr>() .Add(mojom::blink::EventTriggerData::New( @@ -1042,10 +1049,10 @@ }, { "valid_dedup_key", - R"json([{ + ParseJSON(R"json([{ "trigger_data": "5", "deduplication_key": "3" - }])json", + }])json"), true, VectorBuilder<mojom::blink::EventTriggerDataPtr>() .Add(mojom::blink::EventTriggerData::New( @@ -1059,10 +1066,10 @@ }, { "dedup_key_not_string", - R"json([{ + ParseJSON(R"json([{ "trigger_data": "5", "deduplication_key": 3 - }])json", + }])json"), true, VectorBuilder<mojom::blink::EventTriggerDataPtr>() .Add(mojom::blink::EventTriggerData::New( @@ -1075,10 +1082,10 @@ }, { "invalid_dedup_Key", - R"json([{ + ParseJSON(R"json([{ "trigger_data": "5", "deduplication_key": "abc" - }])json", + }])json"), true, VectorBuilder<mojom::blink::EventTriggerDataPtr>() .Add(mojom::blink::EventTriggerData::New( @@ -1091,10 +1098,10 @@ }, { "valid_filters", - R"json([{ + ParseJSON(R"json([{ "trigger_data": "5", "filters": {"source_type": ["navigation"]} - }])json", + }])json"), true, VectorBuilder<mojom::blink::EventTriggerDataPtr>() .Add(mojom::blink::EventTriggerData::New( @@ -1110,19 +1117,19 @@ }, { "invalid_filters", - R"json([{ + ParseJSON(R"json([{ "trigger_data": "5", "filters": 1 - }])json", + }])json"), false, {}, }, { "valid_not_filters", - R"json([{ + ParseJSON(R"json([{ "trigger_data": "5", "not_filters": {"source_type": ["navigation"]} - }])json", + }])json"), true, VectorBuilder<mojom::blink::EventTriggerDataPtr>() .Add(mojom::blink::EventTriggerData::New( @@ -1138,10 +1145,10 @@ }, { "invalid_not_filters", - R"json([{ + ParseJSON(R"json([{ "trigger_data": "5", "not_filters": 1 - }])json", + }])json"), false, {}, }, @@ -1149,7 +1156,7 @@ for (const auto& test_case : kTestCases) { Vector<mojom::blink::EventTriggerDataPtr> actual; - bool valid = ParseEventTriggerData(test_case.json, actual); + bool valid = ParseEventTriggerData(test_case.json.get(), actual); EXPECT_EQ(valid, test_case.valid) << test_case.description; EXPECT_EQ(actual, test_case.expected) << test_case.description; } @@ -1162,9 +1169,9 @@ array->PushString("x"); } - JSONObject object; - object.SetArray("a", std::move(array)); - return object.ToJSONString(); + auto object = std::make_unique<JSONObject>(); + object->SetArray("a", std::move(array)); + return object; }; const struct { @@ -1178,8 +1185,9 @@ for (const auto& test_case : kTestCases) { base::HistogramTester histograms; + std::unique_ptr<JSONValue> json = make_filter_data(test_case.size); mojom::blink::AttributionFilterData filter_data; - ParseFilters(make_filter_data(test_case.size), filter_data); + ParseAttributionFilterData(json.get(), filter_data); histograms.ExpectUniqueSample("Conversions.ValuesPerFilter", test_case.size, test_case.expected); } @@ -1187,11 +1195,11 @@ TEST(AttributionResponseParsingTest, FiltersSizeHistogram) { const auto make_filter_data = [](wtf_size_t n) { - JSONObject object; + auto object = std::make_unique<JSONObject>(); for (wtf_size_t i = 0; i < n; ++i) { - object.SetArray(String::Number(i), std::make_unique<JSONArray>()); + object->SetArray(String::Number(i), std::make_unique<JSONArray>()); } - return object.ToJSONString(); + return object; }; const struct { @@ -1205,8 +1213,9 @@ for (const auto& test_case : kTestCases) { base::HistogramTester histograms; + std::unique_ptr<JSONValue> json = make_filter_data(test_case.size); mojom::blink::AttributionFilterData filter_data; - ParseFilters(make_filter_data(test_case.size), filter_data); + ParseAttributionFilterData(json.get(), filter_data); histograms.ExpectUniqueSample("Conversions.FiltersPerFilterData", test_case.size, test_case.expected); } @@ -1242,14 +1251,14 @@ TEST(AttributionResponseParsingTest, AggregatableTriggerDataHistogram) { const auto make_aggregatable_trigger_with_trigger_data = [](wtf_size_t n) { - JSONArray array; + auto array = std::make_unique<JSONArray>(); for (wtf_size_t i = 0; i < n; ++i) { auto object = std::make_unique<JSONObject>(); object->SetString("key_piece", "0x1"); object->SetArray("source_keys", std::make_unique<JSONArray>()); - array.PushObject(std::move(object)); + array->PushObject(std::move(object)); } - return array.ToJSONString(); + return array; }; const struct { @@ -1263,11 +1272,11 @@ for (const auto& test_case : kTestCases) { base::HistogramTester histograms; + std::unique_ptr<JSONValue> json = + make_aggregatable_trigger_with_trigger_data(test_case.size); WTF::Vector<mojom::blink::AttributionAggregatableTriggerDataPtr> trigger_data; - ParseAttributionAggregatableTriggerData( - make_aggregatable_trigger_with_trigger_data(test_case.size), - trigger_data); + ParseAttributionAggregatableTriggerData(json.get(), trigger_data); histograms.ExpectUniqueSample("Conversions.AggregatableTriggerDataLength", test_case.size, test_case.expected); }
diff --git a/third_party/blink/renderer/core/frame/attribution_src/attribution_aggregatable_trigger_data_corpus/all_params.textproto b/third_party/blink/renderer/core/frame/attribution_src/attribution_aggregatable_trigger_data_corpus/all_params.textproto deleted file mode 100644 index bab1d54..0000000 --- a/third_party/blink/renderer/core/frame/attribution_src/attribution_aggregatable_trigger_data_corpus/all_params.textproto +++ /dev/null
@@ -1,81 +0,0 @@ -array_value { - value { - object_value { - field { - name: "key_piece" - value { - string_value { - value: "0x1" - } - } - } - field { - name: "source_keys" - value { - array_value { - value { - string_value { - value: "a" - } - } - } - } - } - field { - name: "filters" - value { - object_value { - field { - name: "a" - value { - array_value { - value { - string_value { - value: "x" - } - } - } - } - } - field { - name: "b" - value { - array_value { - value { - string_value { - value: "y" - } - } - value { - string_value { - value: "z" - } - } - } - } - } - } - } - } - field { - name: "not_filters" - value { - object_value { - field { - name: "c" - value { - array_value { - value { - string_value { - value: "d" - } - } - } - } - } - } - } - } - } - } -}
diff --git a/third_party/blink/renderer/core/frame/attribution_src/attribution_aggregatable_values_corpus/all_params.textproto b/third_party/blink/renderer/core/frame/attribution_src/attribution_aggregatable_values_corpus/all_params.textproto deleted file mode 100644 index 558cea0b..0000000 --- a/third_party/blink/renderer/core/frame/attribution_src/attribution_aggregatable_values_corpus/all_params.textproto +++ /dev/null
@@ -1,18 +0,0 @@ -object_value { - field { - name: "a" - value { - number_value { - value: 123 - } - } - } - field { - name: "b" - value { - number_value { - value: 456 - } - } - } -}
diff --git a/third_party/blink/renderer/core/frame/attribution_src/attribution_event_trigger_data_corpus/all_params.textproto b/third_party/blink/renderer/core/frame/attribution_src/attribution_event_trigger_data_corpus/all_params.textproto deleted file mode 100644 index 6b184be4..0000000 --- a/third_party/blink/renderer/core/frame/attribution_src/attribution_event_trigger_data_corpus/all_params.textproto +++ /dev/null
@@ -1,97 +0,0 @@ -array_value { - value { - object_value { - field { - name: "trigger_data" - value { - string_value { - value: "1" - } - } - } - field { - name: "priority" - value { - string_value { - value: "2" - } - } - } - field { - name: "deduplication_key" - value { - string_value { - value: "3" - } - } - } - field { - name: "filters" - value { - object_value { - field { - name: "a" - value { - array_value { - value { - string_value { - value: "x" - } - } - } - } - } - field { - name: "b" - value { - array_value { - value { - string_value { - value: "y" - } - } - value { - string_value { - value: "z" - } - } - } - } - } - } - } - } - field { - name: "not_filters" - value { - object_value { - field { - name: "a" - value { - array_value { - value { - string_value { - value: "x" - } - } - } - } - } - field { - name: "c" - value { - array_value { - value { - string_value { - value: "d" - } - } - } - } - } - } - } - } - } - } -}
diff --git a/third_party/blink/renderer/core/frame/attribution_src/attribution_trigger_registration_corpus/all_params.textproto b/third_party/blink/renderer/core/frame/attribution_src/attribution_trigger_registration_corpus/all_params.textproto new file mode 100644 index 0000000..c109a52 --- /dev/null +++ b/third_party/blink/renderer/core/frame/attribution_src/attribution_trigger_registration_corpus/all_params.textproto
@@ -0,0 +1,257 @@ +object_value { + field { + name: "event_trigger_data" + value { + array_value { + value { + object_value { + field { + name: "trigger_data" + value { + string_value { + value: "1" + } + } + } + field { + name: "priority" + value { + string_value { + value: "2" + } + } + } + field { + name: "deduplication_key" + value { + string_value { + value: "3" + } + } + } + field { + name: "filters" + value { + object_value { + field { + name: "a" + value { + array_value { + value { + string_value { + value: "x" + } + } + } + } + } + field { + name: "b" + value { + array_value { + value { + string_value { + value: "y" + } + } + value { + string_value { + value: "z" + } + } + } + } + } + } + } + } + field { + name: "not_filters" + value { + object_value { + field { + name: "a" + value { + array_value { + value { + string_value { + value: "x" + } + } + } + } + } + field { + name: "c" + value { + array_value { + value { + string_value { + value: "d" + } + } + } + } + } + } + } + } + } + } + } + } + } + field { + name: "aggregatable_trigger_data" + value { + array_value { + value { + object_value { + field { + name: "key_piece" + value { + string_value { + value: "0x1" + } + } + } + field { + name: "source_keys" + value { + array_value { + value { + string_value { + value: "a" + } + } + } + } + } + field { + name: "filters" + value { + object_value { + field { + name: "a" + value { + array_value { + value { + string_value { + value: "x" + } + } + } + } + } + field { + name: "b" + value { + array_value { + value { + string_value { + value: "y" + } + } + value { + string_value { + value: "z" + } + } + } + } + } + } + } + } + field { + name: "not_filters" + value { + object_value { + field { + name: "c" + value { + array_value { + value { + string_value { + value: "d" + } + } + } + } + } + } + } + } + } + } + } + } + } + field { + name: "aggregatable_values" + value { + object_value { + field { + name: "a" + value { + number_value { + value: 123 + } + } + } + field { + name: "b" + value { + number_value { + value: 456 + } + } + } + } + } + } + field { + name: "debug_key" + value { + string_value { + value: "789" + } + } + } + field { + name: "filters" + value { + object_value { + field { + name: "a" + value { + array_value { + value { + string_value { + value: "x" + } + } + } + } + } + field { + name: "b" + value { + array_value { + value { + string_value { + value: "y" + } + } + value { + string_value { + value: "z" + } + } + } + } + } + } + } + } +}
diff --git a/third_party/blink/renderer/core/frame/attribution_src_loader.cc b/third_party/blink/renderer/core/frame/attribution_src_loader.cc index 48b2454..28ef1f1a 100644 --- a/third_party/blink/renderer/core/frame/attribution_src_loader.cc +++ b/third_party/blink/renderer/core/frame/attribution_src_loader.cc
@@ -56,16 +56,6 @@ kMaxValue = kFailed, }; -bool ContainsTriggerHeaders(const HTTPHeaderMap& headers) { - return headers.Contains( - http_names::kAttributionReportingRegisterEventTrigger) || - (headers.Contains( - http_names:: - kAttributionReportingRegisterAggregatableTriggerData) && - headers.Contains( - http_names::kAttributionReportingRegisterAggregatableValues)); -} - void RecordAttributionSrcRequestStatus(AttributionSrcRequestStatus status) { base::UmaHistogramEnumeration("Conversions.AttributionSrcRequestStatus", status); @@ -338,8 +328,10 @@ return; } - if (!ContainsTriggerHeaders(response.HttpHeaderFields())) + if (!response.HttpHeaderFields().Contains( + http_names::kAttributionReportingRegisterTrigger)) { return; + } if (!CanRegisterAttribution(RegisterContext::kResourceTrigger, response.CurrentRequestUrl(), @@ -429,7 +421,8 @@ // are present together. bool can_process_trigger = type_ == SrcType::kUndetermined || type_ == SrcType::kTrigger; - if (can_process_trigger && ContainsTriggerHeaders(headers)) { + if (can_process_trigger && + headers.Contains(http_names::kAttributionReportingRegisterTrigger)) { type_ = SrcType::kTrigger; HandleTriggerRegistration(response); }
diff --git a/third_party/blink/renderer/core/frame/attribution_event_trigger_data_fuzzer.cc b/third_party/blink/renderer/core/frame/attribution_trigger_registration_fuzzer.cc similarity index 85% rename from third_party/blink/renderer/core/frame/attribution_event_trigger_data_fuzzer.cc rename to third_party/blink/renderer/core/frame/attribution_trigger_registration_fuzzer.cc index 3b89379..689a4594 100644 --- a/third_party/blink/renderer/core/frame/attribution_event_trigger_data_fuzzer.cc +++ b/third_party/blink/renderer/core/frame/attribution_trigger_registration_fuzzer.cc
@@ -13,7 +13,6 @@ #include "third_party/blink/renderer/core/frame/attribution_response_parsing.h" #include "third_party/blink/renderer/platform/testing/blink_fuzzer_test_support.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" namespace blink { @@ -27,8 +26,8 @@ std::cout << native_input << std::endl; const String input(native_input.c_str()); - WTF::Vector<mojom::blink::EventTriggerDataPtr> output; - attribution_response_parsing::ParseEventTriggerData(input, output); + mojom::blink::AttributionTriggerData output; + attribution_response_parsing::ParseTriggerRegistrationHeader(input, output); } } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/deprecation/deprecation.cc b/third_party/blink/renderer/core/frame/deprecation/deprecation.cc index 5eba69f..9246e0c 100644 --- a/third_party/blink/renderer/core/frame/deprecation/deprecation.cc +++ b/third_party/blink/renderer/core/frame/deprecation/deprecation.cc
@@ -153,9 +153,6 @@ case WebFeature::kObsoleteWebrtcTlsVersion: return DeprecationInfo::WithTranslation( feature, DeprecationIssueType::kObsoleteWebRtcCipherSuite); - case WebFeature::kPaymentRequestBasicCard: - return DeprecationInfo::WithTranslation( - feature, DeprecationIssueType::kPaymentRequestBasicCard); case WebFeature::kPictureSourceSrc: return DeprecationInfo::WithTranslation( feature, DeprecationIssueType::kPictureSourceSrc);
diff --git a/third_party/blink/renderer/core/inspector/inspector_audits_issue.cc b/third_party/blink/renderer/core/inspector/inspector_audits_issue.cc index 9b17250..6152fc9 100644 --- a/third_party/blink/renderer/core/inspector/inspector_audits_issue.cc +++ b/third_party/blink/renderer/core/inspector/inspector_audits_issue.cc
@@ -521,10 +521,6 @@ type = protocol::Audits::DeprecationIssueTypeEnum::ObsoleteWebRtcCipherSuite; break; - case DeprecationIssueType::kPaymentRequestBasicCard: - type = - protocol::Audits::DeprecationIssueTypeEnum::PaymentRequestBasicCard; - break; case DeprecationIssueType::kPictureSourceSrc: type = protocol::Audits::DeprecationIssueTypeEnum::PictureSourceSrc; break;
diff --git a/third_party/blink/renderer/core/inspector/inspector_audits_issue.h b/third_party/blink/renderer/core/inspector/inspector_audits_issue.h index 6d740b1..536da35 100644 --- a/third_party/blink/renderer/core/inspector/inspector_audits_issue.h +++ b/third_party/blink/renderer/core/inspector/inspector_audits_issue.h
@@ -65,7 +65,6 @@ kNotificationInsecureOrigin, kNotificationPermissionRequestedIframe, kObsoleteWebRtcCipherSuite, - kPaymentRequestBasicCard, kPictureSourceSrc, kPrefixedCancelAnimationFrame, kPrefixedRequestAnimationFrame,
diff --git a/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5 b/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5 index ac98ecc..e7bbc21 100644 --- a/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5 +++ b/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5
@@ -137,9 +137,7 @@ { name: "ClientHintUAPlatform", permissions_policy_name: "ch-ua-platform", - default_value_behind_flag: [ - ["UACHPlatformEnabledByDefault", "EnableForAll"], - ], + feature_default: "EnableForAll", }, { name: "ClientHintUAModel",
diff --git a/third_party/blink/renderer/core/style/grid_area.h b/third_party/blink/renderer/core/style/grid_area.h index 0798cd6..169fdc3 100644 --- a/third_party/blink/renderer/core/style/grid_area.h +++ b/third_party/blink/renderer/core/style/grid_area.h
@@ -161,12 +161,12 @@ : kLegacyGridMaxTracks; start_line_ = ClampTo<int>(start_line, -grid_max_tracks, grid_max_tracks - 1); - end_line_ = ClampTo<int>(end_line, -grid_max_tracks + 1, grid_max_tracks); + end_line_ = ClampTo<int>(end_line, start_line_ + 1, grid_max_tracks); #if DCHECK_IS_ON() - DCHECK_LT(start_line, end_line); + DCHECK_LT(start_line_, end_line_); if (type == kTranslatedDefinite) - DCHECK_GE(start_line, static_cast<T>(0)); + DCHECK_GE(start_line_, 0); #endif }
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc b/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc index 8ed28d92..f5898c21 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_request_loader.cc
@@ -6,7 +6,6 @@ #include <algorithm> -#include "base/metrics/histogram_functions.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" @@ -130,10 +129,6 @@ DCHECK(file_reader_loading_); file_reader_loading_ = false; #endif // DCHECK_IS_ON() - - base::UmaHistogramSparse("Storage.Blob.IDBRequestLoader.ReadError", - std::max(0, -loader_->GetNetError())); - ReportError(); }
diff --git a/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.cc index a09eacf..7938b8a 100644 --- a/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.cc +++ b/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.cc
@@ -200,6 +200,15 @@ // Set up an EventPropagator helper to forward any events fired on track so // that they're re-dispatched to anything that's listening on this. event_propagator_ = MakeGarbageCollected<EventPropagator>(track, this); + + // Observers may dispatch events which create and add new Observers. Such + // observers are added directly to the implementation track since track_ is + // now set. + for (auto observer : observers_) { + observer->TrackChangedState(); + track_->AddObserver(observer); + } + observers_.clear(); } void TransferredMediaStreamTrack::SetConstraints( @@ -315,9 +324,9 @@ void TransferredMediaStreamTrack::AddObserver(Observer* observer) { if (track_) { track_->AddObserver(observer); + } else { + observers_.insert(observer); } - // TODO(https://crbug.com/1288839): Save and forward to track_ once it's - // initialized. } TransferredMediaStreamTrack::EventPropagator::EventPropagator( @@ -349,6 +358,7 @@ visitor->Trace(track_); visitor->Trace(execution_context_); visitor->Trace(event_propagator_); + visitor->Trace(observers_); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.h b/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.h index caacde00..7942b0f 100644 --- a/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.h +++ b/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track.h
@@ -127,6 +127,7 @@ WeakMember<ExecutionContext> execution_context_; TransferredValues data_; Member<EventPropagator> event_propagator_; + HeapHashSet<WeakMember<MediaStreamTrack::Observer>> observers_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track_test.cc b/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track_test.cc index 7621323..dd1e3f93f 100644 --- a/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track_test.cc +++ b/third_party/blink/renderer/modules/mediastream/transferred_media_stream_track_test.cc
@@ -17,6 +17,17 @@ namespace { using testing::_; + +class TestObserver : public GarbageCollected<TestObserver>, + public MediaStreamTrack::Observer { + public: + void TrackChangedState() override { observation_count_++; } + int ObservationCount() const { return observation_count_; } + + private: + int observation_count_ = 0; +}; + } // namespace class TransferredMediaStreamTrackTest : public testing::Test { @@ -172,4 +183,25 @@ transferred_track_->applyConstraints(scope.GetScriptState(), MediaTrackConstraints::Create()); } + +TEST_F(TransferredMediaStreamTrackTest, SetImplementationTriggersObservers) { + V8TestingScope scope; + CustomSetUp(scope); + TestObserver* testObserver = MakeGarbageCollected<TestObserver>(); + transferred_track_->AddObserver(testObserver); + transferred_track_->SetImplementation( + MakeGarbageCollected<testing::NiceMock<MockMediaStreamTrack>>()); + EXPECT_EQ(testObserver->ObservationCount(), 1); +} + +TEST_F(TransferredMediaStreamTrackTest, ObserversAddedToImpl) { + V8TestingScope scope; + CustomSetUp(scope); + transferred_track_->AddObserver(MakeGarbageCollected<TestObserver>()); + MockMediaStreamTrack* mock_impl = + MakeGarbageCollected<testing::NiceMock<MockMediaStreamTrack>>(); + EXPECT_CALL(*mock_impl, AddObserver(_)); + transferred_track_->SetImplementation(mock_impl); +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/payments/payment_request.cc b/third_party/blink/renderer/modules/payments/payment_request.cc index e6a69e6..369fb2b 100644 --- a/third_party/blink/renderer/modules/payments/payment_request.cc +++ b/third_party/blink/renderer/modules/payments/payment_request.cc
@@ -437,8 +437,6 @@ if (RuntimeEnabledFeatures::PaymentRequestBasicCardEnabled( &execution_context) && supported_method == "basic-card") { - Deprecation::CountDeprecation(&execution_context, - WebFeature::kPaymentRequestBasicCard); BasicCardHelper::ParseBasiccardData(input, output->supported_networks, exception_state); } else if (supported_method == kSecurePaymentConfirmationMethod &&
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc index e2a9933..24cb42b 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_queue.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_queue.cc
@@ -398,18 +398,24 @@ return; } - WGPUTextureFormat format = destination->texture()->Format(); - size_t required_copy_size = 0; - if (!ComputeAndValidateRequiredBytesInCopy( - data_size, dawn_data_layout, dawn_write_size, format, - dawn_destination.aspect, &required_copy_size, device_)) { - return; - } - - // Only send the data which is really required. + // Handle the data layout offset by offsetting the data pointer instead. This + // helps move less data between then renderer and GPU process (otherwise all + // the data from 0 to offset would be copied over as well). const void* data_ptr = static_cast<const uint8_t*>(data) + dawn_data_layout.offset; dawn_data_layout.offset = 0; + data_size -= dawn_data_layout.offset; + + // Compute a tight upper bound of the number of bytes to send for this + // WriteTexture. This can be 0 for some cases that produce validation errors, + // but we don't create an error in Blink since Dawn can produce better error + // messages (and this is more up-to-spec because the errors must be created on + // the device timeline). + size_t data_size_upper_bound = EstimateWriteTextureBytesUpperBound( + dawn_data_layout, dawn_write_size, destination->texture()->Format(), + dawn_destination.aspect); + size_t required_copy_size = std::min(data_size, data_size_upper_bound); + GetProcs().queueWriteTexture(GetHandle(), &dawn_destination, data_ptr, required_copy_size, &dawn_data_layout, &dawn_write_size);
diff --git a/third_party/blink/renderer/modules/webgpu/texture_utils.cc b/third_party/blink/renderer/modules/webgpu/texture_utils.cc index 87cffc8c..96e7a1e 100644 --- a/third_party/blink/renderer/modules/webgpu/texture_utils.cc +++ b/third_party/blink/renderer/modules/webgpu/texture_utils.cc
@@ -16,266 +16,229 @@ uint32_t height; }; -bool ValidateFormatAndAspectForCopy(WGPUTextureFormat format, - WGPUTextureAspect aspect) { - switch (format) { - // For depth/stencil formats, see the valid format and aspect combinations - // for copy at https://gpuweb.github.io/gpuweb/#depth-formats - case WGPUTextureFormat_Stencil8: - return aspect != WGPUTextureAspect_DepthOnly; - - case WGPUTextureFormat_Depth16Unorm: - return aspect != WGPUTextureAspect_StencilOnly; - - case WGPUTextureFormat_Depth24Plus: - // Depth32Float is not copyable when it is used as copy dst in WriteTexture - case WGPUTextureFormat_Depth32Float: - return false; - - case WGPUTextureFormat_Depth24PlusStencil8: - case WGPUTextureFormat_Depth24UnormStencil8: - // Depth aspect of Depth32FloatStencil8 is not copyable when it is used as - // copy dst in WriteTexture - case WGPUTextureFormat_Depth32FloatStencil8: - return aspect == WGPUTextureAspect_StencilOnly; - - // These formats are not copyable in WriteTexture - case WGPUTextureFormat_R8BG8Biplanar420Unorm: - case WGPUTextureFormat_Force32: - case WGPUTextureFormat_Undefined: - return false; - - default: - return aspect == WGPUTextureAspect_All; - } -} - TexelBlockInfo GetTexelBlockInfoForCopy(WGPUTextureFormat format, WGPUTextureAspect aspect) { - if (!ValidateFormatAndAspectForCopy(format, aspect)) { - return {0u, 0u, 0u}; - } + constexpr TexelBlockInfo kInvalidTexelBlockInfo = {0, 0, 0}; - switch (format) { - case WGPUTextureFormat_R8Unorm: - case WGPUTextureFormat_R8Snorm: - case WGPUTextureFormat_R8Uint: - case WGPUTextureFormat_R8Sint: - return {1u, 1u, 1u}; + switch (aspect) { + case WGPUTextureAspect_All: + switch (format) { + case WGPUTextureFormat_R8Unorm: + case WGPUTextureFormat_R8Snorm: + case WGPUTextureFormat_R8Uint: + case WGPUTextureFormat_R8Sint: + return {1u, 1u, 1u}; - case WGPUTextureFormat_R16Uint: - case WGPUTextureFormat_R16Sint: - case WGPUTextureFormat_R16Float: - case WGPUTextureFormat_RG8Unorm: - case WGPUTextureFormat_RG8Snorm: - case WGPUTextureFormat_RG8Uint: - case WGPUTextureFormat_RG8Sint: - return {2u, 1u, 1u}; + case WGPUTextureFormat_R16Uint: + case WGPUTextureFormat_R16Sint: + case WGPUTextureFormat_R16Float: + case WGPUTextureFormat_RG8Unorm: + case WGPUTextureFormat_RG8Snorm: + case WGPUTextureFormat_RG8Uint: + case WGPUTextureFormat_RG8Sint: + return {2u, 1u, 1u}; - case WGPUTextureFormat_R32Float: - case WGPUTextureFormat_R32Uint: - case WGPUTextureFormat_R32Sint: - case WGPUTextureFormat_RG16Uint: - case WGPUTextureFormat_RG16Sint: - case WGPUTextureFormat_RG16Float: - case WGPUTextureFormat_RGBA8Unorm: - case WGPUTextureFormat_RGBA8UnormSrgb: - case WGPUTextureFormat_RGBA8Snorm: - case WGPUTextureFormat_RGBA8Uint: - case WGPUTextureFormat_RGBA8Sint: - case WGPUTextureFormat_BGRA8Unorm: - case WGPUTextureFormat_BGRA8UnormSrgb: - case WGPUTextureFormat_RGB10A2Unorm: - case WGPUTextureFormat_RG11B10Ufloat: - case WGPUTextureFormat_RGB9E5Ufloat: - return {4u, 1u, 1u}; + case WGPUTextureFormat_R32Float: + case WGPUTextureFormat_R32Uint: + case WGPUTextureFormat_R32Sint: + case WGPUTextureFormat_RG16Uint: + case WGPUTextureFormat_RG16Sint: + case WGPUTextureFormat_RG16Float: + case WGPUTextureFormat_RGBA8Unorm: + case WGPUTextureFormat_RGBA8UnormSrgb: + case WGPUTextureFormat_RGBA8Snorm: + case WGPUTextureFormat_RGBA8Uint: + case WGPUTextureFormat_RGBA8Sint: + case WGPUTextureFormat_BGRA8Unorm: + case WGPUTextureFormat_BGRA8UnormSrgb: + case WGPUTextureFormat_RGB10A2Unorm: + case WGPUTextureFormat_RG11B10Ufloat: + case WGPUTextureFormat_RGB9E5Ufloat: + return {4u, 1u, 1u}; - case WGPUTextureFormat_RG32Float: - case WGPUTextureFormat_RG32Uint: - case WGPUTextureFormat_RG32Sint: - case WGPUTextureFormat_RGBA16Uint: - case WGPUTextureFormat_RGBA16Sint: - case WGPUTextureFormat_RGBA16Float: - return {8u, 1u, 1u}; + case WGPUTextureFormat_RG32Float: + case WGPUTextureFormat_RG32Uint: + case WGPUTextureFormat_RG32Sint: + case WGPUTextureFormat_RGBA16Uint: + case WGPUTextureFormat_RGBA16Sint: + case WGPUTextureFormat_RGBA16Float: + return {8u, 1u, 1u}; - case WGPUTextureFormat_RGBA32Float: - case WGPUTextureFormat_RGBA32Uint: - case WGPUTextureFormat_RGBA32Sint: - return {16u, 1u, 1u}; + case WGPUTextureFormat_RGBA32Float: + case WGPUTextureFormat_RGBA32Uint: + case WGPUTextureFormat_RGBA32Sint: + return {16u, 1u, 1u}; - case WGPUTextureFormat_Stencil8: - return {1u, 1u, 1u}; + case WGPUTextureFormat_Depth16Unorm: + return {2u, 1u, 1u}; + case WGPUTextureFormat_Stencil8: + return {1u, 1u, 1u}; - case WGPUTextureFormat_Depth16Unorm: - return {2u, 1u, 1u}; + case WGPUTextureFormat_BC1RGBAUnorm: + case WGPUTextureFormat_BC1RGBAUnormSrgb: + case WGPUTextureFormat_BC4RUnorm: + case WGPUTextureFormat_BC4RSnorm: + return {8u, 4u, 4u}; - // Only stencil aspect is valid for WriteTexture - case WGPUTextureFormat_Depth24UnormStencil8: - case WGPUTextureFormat_Depth24PlusStencil8: - case WGPUTextureFormat_Depth32FloatStencil8: - return {1u, 1u, 1u}; + case WGPUTextureFormat_BC2RGBAUnorm: + case WGPUTextureFormat_BC2RGBAUnormSrgb: + case WGPUTextureFormat_BC3RGBAUnorm: + case WGPUTextureFormat_BC3RGBAUnormSrgb: + case WGPUTextureFormat_BC5RGUnorm: + case WGPUTextureFormat_BC5RGSnorm: + case WGPUTextureFormat_BC6HRGBUfloat: + case WGPUTextureFormat_BC6HRGBFloat: + case WGPUTextureFormat_BC7RGBAUnorm: + case WGPUTextureFormat_BC7RGBAUnormSrgb: + return {16u, 4u, 4u}; - case WGPUTextureFormat_BC1RGBAUnorm: - case WGPUTextureFormat_BC1RGBAUnormSrgb: - case WGPUTextureFormat_BC4RUnorm: - case WGPUTextureFormat_BC4RSnorm: - return {8u, 4u, 4u}; + case WGPUTextureFormat_ETC2RGB8Unorm: + case WGPUTextureFormat_ETC2RGB8UnormSrgb: + case WGPUTextureFormat_ETC2RGB8A1Unorm: + case WGPUTextureFormat_ETC2RGB8A1UnormSrgb: + case WGPUTextureFormat_EACR11Unorm: + case WGPUTextureFormat_EACR11Snorm: + return {8u, 4u, 4u}; - case WGPUTextureFormat_BC2RGBAUnorm: - case WGPUTextureFormat_BC2RGBAUnormSrgb: - case WGPUTextureFormat_BC3RGBAUnorm: - case WGPUTextureFormat_BC3RGBAUnormSrgb: - case WGPUTextureFormat_BC5RGUnorm: - case WGPUTextureFormat_BC5RGSnorm: - case WGPUTextureFormat_BC6HRGBUfloat: - case WGPUTextureFormat_BC6HRGBFloat: - case WGPUTextureFormat_BC7RGBAUnorm: - case WGPUTextureFormat_BC7RGBAUnormSrgb: - return {16u, 4u, 4u}; + case WGPUTextureFormat_ETC2RGBA8Unorm: + case WGPUTextureFormat_ETC2RGBA8UnormSrgb: + case WGPUTextureFormat_EACRG11Unorm: + case WGPUTextureFormat_EACRG11Snorm: + return {16u, 4u, 4u}; - case WGPUTextureFormat_ETC2RGB8Unorm: - case WGPUTextureFormat_ETC2RGB8UnormSrgb: - case WGPUTextureFormat_ETC2RGB8A1Unorm: - case WGPUTextureFormat_ETC2RGB8A1UnormSrgb: - case WGPUTextureFormat_EACR11Unorm: - case WGPUTextureFormat_EACR11Snorm: - return {8u, 4u, 4u}; + case WGPUTextureFormat_ASTC4x4Unorm: + case WGPUTextureFormat_ASTC4x4UnormSrgb: + return {16u, 4u, 4u}; + case WGPUTextureFormat_ASTC5x4Unorm: + case WGPUTextureFormat_ASTC5x4UnormSrgb: + return {16u, 5u, 4u}; + case WGPUTextureFormat_ASTC5x5Unorm: + case WGPUTextureFormat_ASTC5x5UnormSrgb: + return {16u, 5u, 5u}; + case WGPUTextureFormat_ASTC6x5Unorm: + case WGPUTextureFormat_ASTC6x5UnormSrgb: + return {16u, 6u, 5u}; + case WGPUTextureFormat_ASTC6x6Unorm: + case WGPUTextureFormat_ASTC6x6UnormSrgb: + return {16u, 6u, 6u}; + case WGPUTextureFormat_ASTC8x5Unorm: + case WGPUTextureFormat_ASTC8x5UnormSrgb: + return {16u, 8u, 5u}; + case WGPUTextureFormat_ASTC8x6Unorm: + case WGPUTextureFormat_ASTC8x6UnormSrgb: + return {16u, 8u, 6u}; + case WGPUTextureFormat_ASTC8x8Unorm: + case WGPUTextureFormat_ASTC8x8UnormSrgb: + return {16u, 8u, 8u}; + case WGPUTextureFormat_ASTC10x5Unorm: + case WGPUTextureFormat_ASTC10x5UnormSrgb: + return {16u, 10u, 5u}; + case WGPUTextureFormat_ASTC10x6Unorm: + case WGPUTextureFormat_ASTC10x6UnormSrgb: + return {16u, 10u, 6u}; + case WGPUTextureFormat_ASTC10x8Unorm: + case WGPUTextureFormat_ASTC10x8UnormSrgb: + return {16u, 10u, 8u}; + case WGPUTextureFormat_ASTC10x10Unorm: + case WGPUTextureFormat_ASTC10x10UnormSrgb: + return {16u, 10u, 10u}; + case WGPUTextureFormat_ASTC12x10Unorm: + case WGPUTextureFormat_ASTC12x10UnormSrgb: + return {16u, 12u, 10u}; + case WGPUTextureFormat_ASTC12x12Unorm: + case WGPUTextureFormat_ASTC12x12UnormSrgb: + return {16u, 12u, 12u}; - case WGPUTextureFormat_ETC2RGBA8Unorm: - case WGPUTextureFormat_ETC2RGBA8UnormSrgb: - case WGPUTextureFormat_EACRG11Unorm: - case WGPUTextureFormat_EACRG11Snorm: - return {16u, 4u, 4u}; + default: + return kInvalidTexelBlockInfo; + } - case WGPUTextureFormat_ASTC4x4Unorm: - case WGPUTextureFormat_ASTC4x4UnormSrgb: - return {16u, 4u, 4u}; - case WGPUTextureFormat_ASTC5x4Unorm: - case WGPUTextureFormat_ASTC5x4UnormSrgb: - return {16u, 5u, 4u}; - case WGPUTextureFormat_ASTC5x5Unorm: - case WGPUTextureFormat_ASTC5x5UnormSrgb: - return {16u, 5u, 5u}; - case WGPUTextureFormat_ASTC6x5Unorm: - case WGPUTextureFormat_ASTC6x5UnormSrgb: - return {16u, 6u, 5u}; - case WGPUTextureFormat_ASTC6x6Unorm: - case WGPUTextureFormat_ASTC6x6UnormSrgb: - return {16u, 6u, 6u}; - case WGPUTextureFormat_ASTC8x5Unorm: - case WGPUTextureFormat_ASTC8x5UnormSrgb: - return {16u, 8u, 5u}; - case WGPUTextureFormat_ASTC8x6Unorm: - case WGPUTextureFormat_ASTC8x6UnormSrgb: - return {16u, 8u, 6u}; - case WGPUTextureFormat_ASTC8x8Unorm: - case WGPUTextureFormat_ASTC8x8UnormSrgb: - return {16u, 8u, 8u}; - case WGPUTextureFormat_ASTC10x5Unorm: - case WGPUTextureFormat_ASTC10x5UnormSrgb: - return {16u, 10u, 5u}; - case WGPUTextureFormat_ASTC10x6Unorm: - case WGPUTextureFormat_ASTC10x6UnormSrgb: - return {16u, 10u, 6u}; - case WGPUTextureFormat_ASTC10x8Unorm: - case WGPUTextureFormat_ASTC10x8UnormSrgb: - return {16u, 10u, 8u}; - case WGPUTextureFormat_ASTC10x10Unorm: - case WGPUTextureFormat_ASTC10x10UnormSrgb: - return {16u, 10u, 10u}; - case WGPUTextureFormat_ASTC12x10Unorm: - case WGPUTextureFormat_ASTC12x10UnormSrgb: - return {16u, 12u, 10u}; - case WGPUTextureFormat_ASTC12x12Unorm: - case WGPUTextureFormat_ASTC12x12UnormSrgb: - return {16u, 12u, 12u}; + // Copies to depth/stencil aspects are fairly restricted, see + // https://gpuweb.github.io/gpuweb/#depth-formats so we only list + // combinations of format and aspects that can be copied to with a + // WriteTexture. + case WGPUTextureAspect_DepthOnly: + switch (format) { + case WGPUTextureFormat_Depth16Unorm: + return GetTexelBlockInfoForCopy(format, WGPUTextureAspect_All); + + default: + return kInvalidTexelBlockInfo; + } + + case WGPUTextureAspect_StencilOnly: + switch (format) { + case WGPUTextureFormat_Depth24UnormStencil8: + case WGPUTextureFormat_Depth24PlusStencil8: + case WGPUTextureFormat_Depth32FloatStencil8: + return {1u, 1u, 1u}; + + case WGPUTextureFormat_Stencil8: + return GetTexelBlockInfoForCopy(format, WGPUTextureAspect_All); + + default: + return kInvalidTexelBlockInfo; + } default: NOTREACHED(); - return {0u, 0u, 0u}; + return kInvalidTexelBlockInfo; } } } // anonymous namespace -bool ComputeAndValidateRequiredBytesInCopy(size_t data_size, - WGPUTextureDataLayout layout, +size_t EstimateWriteTextureBytesUpperBound(WGPUTextureDataLayout layout, WGPUExtent3D extent, WGPUTextureFormat format, - WGPUTextureAspect aspect, - size_t* required_copy_size, - GPUDevice* device) { - TexelBlockInfo blockInfo = GetTexelBlockInfoForCopy(format, aspect); - if (!blockInfo.byteSize) { - device->InjectError( - WGPUErrorType_Validation, - "Format, aspect or the combination are not valid for WriteTexture"); - return false; + WGPUTextureAspect aspect) { + // Check for empty copies because of depth first so we can early out. Note + // that we can't early out because of height or width being 0 because padding + // images still need to be accounted for. + if (extent.depthOrArrayLayers == 0) { + return 0; } + TexelBlockInfo blockInfo = GetTexelBlockInfoForCopy(format, aspect); + + // Unknown format/aspect combination will be validated by the GPU process + // again. + if (blockInfo.byteSize == 0) { + return 0; + } + + // If the block size doesn't divide the extent, a validation error will be + // produced on the GPU process side so we don't need to guard against it. uint32_t widthInBlocks = extent.width / blockInfo.width; uint32_t heightInBlocks = extent.height / blockInfo.height; - size_t lastRowBytes = widthInBlocks * blockInfo.byteSize; - if (layout.bytesPerRow == WGPU_STRIDE_UNDEFINED && - (heightInBlocks > 1 || extent.depthOrArrayLayers > 1)) { - device->InjectError(WGPUErrorType_Validation, - "bytesPerRow must be specified"); - return false; - } - - if (layout.rowsPerImage == WGPU_STRIDE_UNDEFINED && - extent.depthOrArrayLayers > 1) { - device->InjectError(WGPUErrorType_Validation, - "rowsPerImage must be specified"); - return false; - } - - if (layout.bytesPerRow < lastRowBytes) { - device->InjectError(WGPUErrorType_Validation, - "bytesPerRow in image data layout is too small"); - return false; - } - - if (layout.rowsPerImage < heightInBlocks) { - device->InjectError(WGPUErrorType_Validation, - "rowsPerImage in image data layout is too small"); - return false; - } - - if (extent.depthOrArrayLayers == 0) { - *required_copy_size = 0; - return true; - } - + // Use checked numerics even though the GPU process will guard against OOB + // because otherwise UBSan will complain about overflows. Note that if + // bytesPerRow or rowsPerImage are WGPU_COPY_STRIDE_UNDEFINED and used, the + // GPU process will also create a validation error because it means that they + // are used when copySize.height/depthOrArrayLayers > 1. base::CheckedNumeric<size_t> requiredBytesInCopy = 0; + + // WebGPU requires that the padding bytes for images are counted, even if the + // copy is empty. if (extent.depthOrArrayLayers > 1) { requiredBytesInCopy = layout.bytesPerRow; requiredBytesInCopy *= layout.rowsPerImage; requiredBytesInCopy *= (extent.depthOrArrayLayers - 1); } + if (heightInBlocks != 0) { - size_t lastImageBytes = - layout.bytesPerRow * (heightInBlocks - 1) + lastRowBytes; + base::CheckedNumeric<size_t> lastRowBytes = widthInBlocks; + lastRowBytes *= blockInfo.byteSize; + + base::CheckedNumeric<size_t> lastImageBytes = layout.bytesPerRow; + lastImageBytes *= (heightInBlocks - 1); + lastImageBytes += lastRowBytes; + requiredBytesInCopy += lastImageBytes; } - if (!requiredBytesInCopy.IsValid()) { - device->InjectError(WGPUErrorType_Validation, - "Required copy size overflows"); - return false; - } - - *required_copy_size = requiredBytesInCopy.ValueOrDie(); - DCHECK(data_size >= layout.offset); - if (*required_copy_size > data_size - layout.offset) { - device->InjectError( - WGPUErrorType_Validation, - "Required copy size for texture layout exceed data size with offset"); - return false; - } - - return true; + return requiredBytesInCopy.ValueOrDefault(0); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/texture_utils.h b/third_party/blink/renderer/modules/webgpu/texture_utils.h index a2a6262..14fcd190 100644 --- a/third_party/blink/renderer/modules/webgpu/texture_utils.h +++ b/third_party/blink/renderer/modules/webgpu/texture_utils.h
@@ -9,13 +9,10 @@ namespace blink { -bool ComputeAndValidateRequiredBytesInCopy(size_t data_size, - WGPUTextureDataLayout layout, +size_t EstimateWriteTextureBytesUpperBound(WGPUTextureDataLayout layout, WGPUExtent3D extent, WGPUTextureFormat format, - WGPUTextureAspect aspect, - size_t* required_copy_size, - GPUDevice* device); + WGPUTextureAspect aspect); } // namespace blink
diff --git a/third_party/blink/renderer/platform/network/http_names.json5 b/third_party/blink/renderer/platform/network/http_names.json5 index 0cc8c46..35e86bfa 100644 --- a/third_party/blink/renderer/platform/network/http_names.json5 +++ b/third_party/blink/renderer/platform/network/http_names.json5
@@ -24,12 +24,8 @@ "Access-Control-Request-Method", "Allow-CSP-From", "Attribution-Reporting-Eligible", - "Attribution-Reporting-Filters", - "Attribution-Reporting-Register-Aggregatable-Trigger-Data", - "Attribution-Reporting-Register-Aggregatable-Values", - "Attribution-Reporting-Register-Event-Trigger", "Attribution-Reporting-Register-Source", - "Attribution-Reporting-Trigger-Debug-Key", + "Attribution-Reporting-Register-Trigger", "Cache-Control", "Content-DPR", "Content-Disposition",
diff --git a/third_party/blink/renderer/platform/widget/compositing/android_webview/synchronous_layer_tree_frame_sink.cc b/third_party/blink/renderer/platform/widget/compositing/android_webview/synchronous_layer_tree_frame_sink.cc index db18ae26..2b2f5b7 100644 --- a/third_party/blink/renderer/platform/widget/compositing/android_webview/synchronous_layer_tree_frame_sink.cc +++ b/third_party/blink/renderer/platform/widget/compositing/android_webview/synchronous_layer_tree_frame_sink.cc
@@ -108,15 +108,9 @@ void BindToClient(viz::OutputSurfaceClient* client) override {} void EnsureBackbuffer() override {} void DiscardBackbuffer() override {} - void BindFramebuffer() override {} void SwapBuffers(viz::OutputSurfaceFrame frame) override {} void Reshape(const ReshapeParams& params) override {} - uint32_t GetFramebufferCopyTextureFormat() override { return 0; } bool IsDisplayedAsOverlayPlane() const override { return false; } - unsigned GetOverlayTextureId() const override { return 0; } - bool HasExternalStencilTest() const override { return false; } - void ApplyExternalStencil() override {} - unsigned UpdateGpuFence() override { return 0; } void SetUpdateVSyncParametersCallback( viz::UpdateVSyncParametersCallback callback) override {} void SetDisplayTransformHint(gfx::OverlayTransform transform) override {}
diff --git a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility index 501c0855..b5f98f8 100644 --- a/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility +++ b/third_party/blink/web_tests/FlagExpectations/force-renderer-accessibility
@@ -33,6 +33,7 @@ external/wpt/html/browsers/browsing-the-web/back-forward-cache/service-worker-clients-matchall.https.html [ Skip ] external/wpt/html/browsers/browsing-the-web/back-forward-cache/service-worker-controlled-after-restore.https.html [ Skip ] external/wpt/html/browsers/browsing-the-web/back-forward-cache/service-worker-unregister.https.html [ Skip ] +external/wpt/html/browsers/browsing-the-web/back-forward-cache/storage-events.html [ Skip ] external/wpt/html/browsers/browsing-the-web/back-forward-cache/timers.html [ Skip ] external/wpt/html/semantics/interactive-elements/the-dialog-element/inert-svg-hittest.html [ Skip ] external/wpt/inert/dynamic-inert-on-focused-element.html [ Skip ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 7555fcf..a1a21254 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -3516,7 +3516,6 @@ crbug.com/626703 [ Mac11-arm64 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-videoDetectorTest.html [ Skip Timeout ] crbug.com/626703 [ Linux ] external/wpt/media-capabilities/encodingInfo.any.worker.html [ Crash ] crbug.com/626703 [ Win10.20h2 ] external/wpt/media-capabilities/encodingInfo.any.worker.html [ Crash ] -crbug.com/626703 [ Mac11-arm64 ] virtual/disable-ua-ch-platform/external/wpt/client-hints/accept-ch-stickiness/same-origin-navigation.https.html [ Crash ] crbug.com/626703 [ Mac11-arm64 ] virtual/forced-high-contrast-colors/external/wpt/forced-colors-mode/backplate/forced-colors-mode-backplate-01.html [ Crash ] crbug.com/626703 external/wpt/workers/interfaces/WorkerUtils/importScripts/blob-url.worker.html [ Failure ] crbug.com/626703 [ Linux ] external/wpt/input-events/input-events-get-target-ranges.html [ Failure Timeout ] @@ -7089,10 +7088,6 @@ crbug.com/1325307 fast/css-grid-layout/grid-auto-repeat-huge-grid-009.html [ Skip ] crbug.com/1325307 fast/css-grid-layout/grid-auto-repeat-huge-grid-010.html [ Skip ] -# suppress geolocation failures -crbug.com/1330988 http/tests/geolocation-api/geolocation-default-feature-policy.https.sub.html [ Failure ] -crbug.com/1330988 http/tests/security/powerfulFeatureRestrictions/geolocation-on-secure-origin-in-secure-origin.html [ Failure ] - # Sheriff 2022-05-30 crbug.com/1330238 [ Mac ] http/tests/devtools/elements/styles-3/styles-computed-trace.js [ Failure Pass Timeout ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 8598d39..ada0d2a 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -1056,12 +1056,6 @@ "args": ["--disable-features=DialogFocusNewSpecBehavior"] }, { - "prefix": "disable-ua-ch-platform", - "platforms": ["Linux", "Mac", "Win"], - "bases": ["external/wpt/client-hints", "wpt_internal/client-hints"], - "args": ["--disable-features=UACHPlatformEnabledByDefault"] - }, - { "prefix": "object-param-url", "platforms": ["Linux", "Mac", "Win"], "bases": ["external/wpt/html/semantics/embedded-content/the-object-element/object-param-url.html"],
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/support/set_cookie.headers b/third_party/blink/web_tests/external/wpt/credential-management/support/set_cookie.headers index ad111fc..8c233d1 100644 --- a/third_party/blink/web_tests/external/wpt/credential-management/support/set_cookie.headers +++ b/third_party/blink/web_tests/external/wpt/credential-management/support/set_cookie.headers
@@ -1 +1 @@ -Set-Cookie: cookie=1; SameSite=None; Secure +Set-Cookie: cookie=1; SameSite=Strict; Secure
diff --git a/third_party/blink/web_tests/fast/css-grid-layout/crash-large-positions.html b/third_party/blink/web_tests/fast/css-grid-layout/crash-large-positions.html index 2c448e4..5ae7d218 100644 --- a/third_party/blink/web_tests/fast/css-grid-layout/crash-large-positions.html +++ b/third_party/blink/web_tests/fast/css-grid-layout/crash-large-positions.html
@@ -5,11 +5,13 @@ <script src="resources/grid-definitions-parsing-utils.js"></script> <div style="display: grid;"> - <div id="item" style="grid-column-start: 5000000000; grid-column-end: -5000000000; grid-row-start: 5000000000; grid-row-end: -5000000000;"></div> + <div id="item1" style="grid-column-start: 5000000000; grid-column-end: -5000000000; grid-row-start: 5000000000; grid-row-end: -5000000000;"></div> + <div id="item2" style="grid-column: 10000000000000000000 / span 5; grid-row: span 5 / 10000000000000000000"></div> </div> <script> test(function() { - testGridPositionDefinitionsValues(document.getElementById("item"), "2.14748e+09", "-2.14748e+09", "2.14748e+09", "-2.14748e+09"); + testGridPositionDefinitionsValues(document.getElementById("item1"), "2.14748e+09", "-2.14748e+09", "2.14748e+09", "-2.14748e+09"); + testGridPositionDefinitionsValues(document.getElementById("item2"), "span 5", "2.14748e+09", "2.14748e+09", "span 5"); }, "Test that setting and getting grid-column|row-start|end to huge values is properly clamped and does not make the renderer crash."); </script>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/attribution-reporting/resources/register-trigger.php b/third_party/blink/web_tests/http/tests/inspector-protocol/attribution-reporting/resources/register-trigger.php index ee0c4ff6..a34c4ff 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/attribution-reporting/resources/register-trigger.php +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/attribution-reporting/resources/register-trigger.php
@@ -1,3 +1,3 @@ <?php -header('Attribution-Reporting-Register-Event-Trigger: []'); +header('Attribution-Reporting-Register-Trigger: {}'); ?>
diff --git a/third_party/blink/web_tests/http/tests/resources/geolocation-mock.js b/third_party/blink/web_tests/http/tests/resources/geolocation-mock.js index 1e9a588..26eaa34f 100644 --- a/third_party/blink/web_tests/http/tests/resources/geolocation-mock.js +++ b/third_party/blink/web_tests/http/tests/resources/geolocation-mock.js
@@ -112,6 +112,7 @@ timestamp: {internalValue: 0n}, errorMessage: "User has not allowed access to system location.", errorCode: Geoposition_ErrorCode.PERMISSION_DENIED, + errorTechnical: "", }; } @@ -139,9 +140,10 @@ const timestamp = {internalValue: BigInt((new Date().getTime() + epochDeltaInMs) * 1000)}; const errorMessage = ''; + const errorTechnical = ''; const valid = true; return {latitude, longitude, accuracy, altitude, altitudeAccuracy, heading, - speed, timestamp, errorMessage, valid}; + speed, timestamp, errorMessage, valid, errorTechnical}; } /** @@ -166,6 +168,7 @@ timestamp: {internalValue: 0n}, errorMessage: message, errorCode: Geoposition_ErrorCode.POSITION_UNAVAILABLE, + errorTechnical: "", }; }
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/invalidation/is-pseudo-containing-complex-in-has-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/invalidation/is-pseudo-containing-complex-in-has-expected.txt index 618cca7..221527e 100644 --- a/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/invalidation/is-pseudo-containing-complex-in-has-expected.txt +++ b/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/invalidation/is-pseudo-containing-complex-in-has-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 476 tests; 408 PASS, 68 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 476 tests; 418 PASS, 58 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #has_scope.classList.add('red') : check matches (false) PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #has_scope.classList.add('red') : check #has_scope color PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #parent.classList.add('a_has_scope') : check matches (true) @@ -7,7 +7,7 @@ PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #parent.classList.remove('a_has_scope') : check matches (false) PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #parent.classList.remove('a_has_scope') : check #has_scope color PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #has_scope.classList.add('a_has_scope') : check matches (true) -FAIL [ .red:has(#descendant:is(.a_has_scope .b)) ] #has_scope.classList.add('a_has_scope') : check #has_scope color assert_equals: expected "rgb(255, 0, 0)" but got "rgb(128, 128, 128)" +PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #has_scope.classList.add('a_has_scope') : check #has_scope color PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #has_scope.classList.remove('a_has_scope') : check matches (false) PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #has_scope.classList.remove('a_has_scope') : check #has_scope color PASS [ .red:has(#descendant:is(.a_has_scope .b)) ] #child.classList.add('a_has_scope') : check matches (true) @@ -23,7 +23,7 @@ PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #parent.classList.remove('a_descendant') : check matches (false) PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #parent.classList.remove('a_descendant') : check #descendant color PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #has_scope.classList.add('a_descendant') : check matches (true) -FAIL [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #has_scope.classList.add('a_descendant') : check #descendant color assert_equals: expected "rgb(255, 69, 0)" but got "rgb(128, 128, 128)" +PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #has_scope.classList.add('a_descendant') : check #descendant color PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #has_scope.classList.remove('a_descendant') : check matches (false) PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #has_scope.classList.remove('a_descendant') : check #descendant color PASS [ .orangered:has(#descendant:is(.a_descendant .b)) #descendant ] #child.classList.add('a_descendant') : check matches (true) @@ -39,7 +39,7 @@ PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #parent.classList.remove('a_indirect_next') : check matches (false) PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #parent.classList.remove('a_indirect_next') : check #indirect_next color PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.add('a_indirect_next') : check matches (true) -FAIL [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.add('a_indirect_next') : check #indirect_next color assert_equals: expected "rgb(139, 0, 0)" but got "rgb(128, 128, 128)" +PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.add('a_indirect_next') : check #indirect_next color PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.remove('a_indirect_next') : check matches (false) PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.remove('a_indirect_next') : check #indirect_next color PASS [ .darkred:has(#descendant:is(.a_indirect_next .b)) ~ #indirect_next ] #child.classList.add('a_indirect_next') : check matches (true) @@ -55,7 +55,7 @@ PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #parent.classList.remove('a_indirect_next_child') : check matches (false) PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #parent.classList.remove('a_indirect_next_child') : check #indirect_next_child color PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('a_indirect_next_child') : check matches (true) -FAIL [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('a_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(255, 192, 203)" but got "rgb(128, 128, 128)" +PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('a_indirect_next_child') : check #indirect_next_child color PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('a_indirect_next_child') : check matches (false) PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('a_indirect_next_child') : check #indirect_next_child color PASS [ .pink:has(#descendant:is(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #child.classList.add('a_indirect_next_child') : check matches (true) @@ -239,7 +239,7 @@ PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #previous) : (removal) check matches (false) PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #previous) : (removal) check #has_scope color PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #has_scope.classList.add('f_has_scope') : check matches (true) -FAIL [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #has_scope.classList.add('f_has_scope') : check #has_scope color assert_equals: expected "rgb(0, 0, 255)" but got "rgb(128, 128, 128)" +PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #has_scope.classList.add('f_has_scope') : check #has_scope color PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #has_scope.classList.remove('f_has_scope') : check matches (false) PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #has_scope.classList.remove('f_has_scope') : check #has_scope color PASS [ .blue:has(~ #indirect_next:is(.p + .f_has_scope ~ .g)) ] #direct_next.classList.add('f_has_scope') : check matches (true) @@ -271,7 +271,7 @@ PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #previous) : (removal) check matches (false) PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #previous) : (removal) check #descendant color PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.add('f_descendant') : check matches (true) -FAIL [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.add('f_descendant') : check #descendant color assert_equals: expected "rgb(135, 206, 235)" but got "rgb(128, 128, 128)" +PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.add('f_descendant') : check #descendant color PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.remove('f_descendant') : check matches (false) PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.remove('f_descendant') : check #descendant color PASS [ .skyblue:has(~ #indirect_next:is(.p + .f_descendant ~ .g)) #descendant ] #direct_next.classList.add('f_descendant') : check matches (true) @@ -303,7 +303,7 @@ PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #previous) : (removal) check matches (false) PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #previous) : (removal) check #indirect_next color PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.add('f_indirect_next') : check matches (true) -FAIL [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.add('f_indirect_next') : check #indirect_next color assert_equals: expected "rgb(173, 216, 230)" but got "rgb(128, 128, 128)" +PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.add('f_indirect_next') : check #indirect_next color PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.remove('f_indirect_next') : check matches (false) PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.remove('f_indirect_next') : check #indirect_next color PASS [ .lightblue:has(~ #indirect_next:is(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #direct_next.classList.add('f_indirect_next') : check matches (true) @@ -335,7 +335,7 @@ PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #previous) : (removal) check matches (false) PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #previous) : (removal) check #indirect_next_child color PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('f_indirect_next_child') : check matches (true) -FAIL [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('f_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(0, 0, 139)" but got "rgb(128, 128, 128)" +PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('f_indirect_next_child') : check #indirect_next_child color PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('f_indirect_next_child') : check matches (false) PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('f_indirect_next_child') : check #indirect_next_child color PASS [ .darkblue:has(~ #indirect_next:is(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #direct_next.classList.add('f_indirect_next_child') : check matches (true) @@ -459,11 +459,11 @@ PASS [ .orange:has(#descendant:is(:is(.m, .n) .o)) ] #parent.classList.remove('n') : check matches (false) PASS [ .orange:has(#descendant:is(:is(.m, .n) .o)) ] #parent.classList.remove('n') : check #has_scope color PASS [ .orange:has(#descendant:is(:is(.m, .n) .o)) ] #has_scope.classList.add('m') : check matches (true) -FAIL [ .orange:has(#descendant:is(:is(.m, .n) .o)) ] #has_scope.classList.add('m') : check #has_scope color assert_equals: expected "rgb(255, 165, 0)" but got "rgb(128, 128, 128)" +PASS [ .orange:has(#descendant:is(:is(.m, .n) .o)) ] #has_scope.classList.add('m') : check #has_scope color PASS [ .orange:has(#descendant:is(:is(.m, .n) .o)) ] #has_scope.classList.remove('m') : check matches (false) PASS [ .orange:has(#descendant:is(:is(.m, .n) .o)) ] #has_scope.classList.remove('m') : check #has_scope color PASS [ .orange:has(#descendant:is(:is(.m, .n) .o)) ] #has_scope.classList.add('n') : check matches (true) -FAIL [ .orange:has(#descendant:is(:is(.m, .n) .o)) ] #has_scope.classList.add('n') : check #has_scope color assert_equals: expected "rgb(255, 165, 0)" but got "rgb(128, 128, 128)" +PASS [ .orange:has(#descendant:is(:is(.m, .n) .o)) ] #has_scope.classList.add('n') : check #has_scope color PASS [ .orange:has(#descendant:is(:is(.m, .n) .o)) ] #has_scope.classList.remove('n') : check matches (false) PASS [ .orange:has(#descendant:is(:is(.m, .n) .o)) ] #has_scope.classList.remove('n') : check #has_scope color PASS [ .orange:has(#descendant:is(:is(.m, .n) .o)) ] #child.classList.add('m') : check matches (true)
diff --git a/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/invalidation/not-pseudo-containing-complex-in-has-expected.txt b/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/invalidation/not-pseudo-containing-complex-in-has-expected.txt index a6665c6..3c63a01 100644 --- a/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/invalidation/not-pseudo-containing-complex-in-has-expected.txt +++ b/third_party/blink/web_tests/platform/generic/external/wpt/css/selectors/invalidation/not-pseudo-containing-complex-in-has-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 460 tests; 394 PASS, 66 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 460 tests; 404 PASS, 56 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #has_scope.classList.add('red') : check matches (true) PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #has_scope.classList.add('red') : check #has_scope color PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #parent.classList.add('a_has_scope') : check matches (false) @@ -7,7 +7,7 @@ PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #parent.classList.remove('a_has_scope') : check matches (true) PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #parent.classList.remove('a_has_scope') : check #has_scope color PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #has_scope.classList.add('a_has_scope') : check matches (false) -FAIL [ .red:has(#descendant:not(.a_has_scope .b)) ] #has_scope.classList.add('a_has_scope') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 0, 0)" +PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #has_scope.classList.add('a_has_scope') : check #has_scope color PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #has_scope.classList.remove('a_has_scope') : check matches (true) PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #has_scope.classList.remove('a_has_scope') : check #has_scope color PASS [ .red:has(#descendant:not(.a_has_scope .b)) ] #child.classList.add('a_has_scope') : check matches (false) @@ -23,7 +23,7 @@ PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #parent.classList.remove('a_descendant') : check matches (true) PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #parent.classList.remove('a_descendant') : check #descendant color PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #has_scope.classList.add('a_descendant') : check matches (false) -FAIL [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #has_scope.classList.add('a_descendant') : check #descendant color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 69, 0)" +PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #has_scope.classList.add('a_descendant') : check #descendant color PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #has_scope.classList.remove('a_descendant') : check matches (true) PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #has_scope.classList.remove('a_descendant') : check #descendant color PASS [ .orangered:has(#descendant:not(.a_descendant .b)) #descendant ] #child.classList.add('a_descendant') : check matches (false) @@ -39,7 +39,7 @@ PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #parent.classList.remove('a_indirect_next') : check matches (true) PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #parent.classList.remove('a_indirect_next') : check #indirect_next color PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.add('a_indirect_next') : check matches (false) -FAIL [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.add('a_indirect_next') : check #indirect_next color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(139, 0, 0)" +PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.add('a_indirect_next') : check #indirect_next color PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.remove('a_indirect_next') : check matches (true) PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #has_scope.classList.remove('a_indirect_next') : check #indirect_next color PASS [ .darkred:has(#descendant:not(.a_indirect_next .b)) ~ #indirect_next ] #child.classList.add('a_indirect_next') : check matches (false) @@ -55,7 +55,7 @@ PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #parent.classList.remove('a_indirect_next_child') : check matches (true) PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #parent.classList.remove('a_indirect_next_child') : check #indirect_next_child color PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('a_indirect_next_child') : check matches (false) -FAIL [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('a_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 192, 203)" +PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('a_indirect_next_child') : check #indirect_next_child color PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('a_indirect_next_child') : check matches (true) PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('a_indirect_next_child') : check #indirect_next_child color PASS [ .pink:has(#descendant:not(.a_indirect_next_child .b)) ~ #indirect_next #indirect_next_child ] #child.classList.add('a_indirect_next_child') : check matches (false) @@ -235,7 +235,7 @@ PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #previous) : (removal) check matches (true) PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] insert/remove .f_has_scope before #previous) : (removal) check #has_scope color PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #has_scope.classList.add('f_has_scope') : check matches (false) -FAIL [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #has_scope.classList.add('f_has_scope') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 0, 255)" +PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #has_scope.classList.add('f_has_scope') : check #has_scope color PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #has_scope.classList.remove('f_has_scope') : check matches (true) PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #has_scope.classList.remove('f_has_scope') : check #has_scope color PASS [ .blue:has(~ #indirect_next:not(.p + .f_has_scope ~ .g)) ] #direct_next.classList.add('f_has_scope') : check matches (false) @@ -259,7 +259,7 @@ PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #previous) : (removal) check matches (true) PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] insert/remove .f_descendant before #previous) : (removal) check #descendant color PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.add('f_descendant') : check matches (false) -FAIL [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.add('f_descendant') : check #descendant color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(135, 206, 235)" +PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.add('f_descendant') : check #descendant color PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.remove('f_descendant') : check matches (true) PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #has_scope.classList.remove('f_descendant') : check #descendant color PASS [ .skyblue:has(~ #indirect_next:not(.p + .f_descendant ~ .g)) #descendant ] #direct_next.classList.add('f_descendant') : check matches (false) @@ -287,7 +287,7 @@ PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #previous) : (removal) check matches (true) PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] insert/remove .f_indirect_next before #previous) : (removal) check #indirect_next color PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.add('f_indirect_next') : check matches (false) -FAIL [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.add('f_indirect_next') : check #indirect_next color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(173, 216, 230)" +PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.add('f_indirect_next') : check #indirect_next color PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.remove('f_indirect_next') : check matches (true) PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #has_scope.classList.remove('f_indirect_next') : check #indirect_next color PASS [ .lightblue:has(~ #indirect_next:not(.p + .f_indirect_next ~ .g)) ~ #indirect_next ] #direct_next.classList.add('f_indirect_next') : check matches (false) @@ -319,7 +319,7 @@ PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #previous) : (removal) check matches (true) PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] insert/remove .f_indirect_next_child before #previous) : (removal) check #indirect_next_child color PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('f_indirect_next_child') : check matches (false) -FAIL [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('f_indirect_next_child') : check #indirect_next_child color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(0, 0, 139)" +PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.add('f_indirect_next_child') : check #indirect_next_child color PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('f_indirect_next_child') : check matches (true) PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #has_scope.classList.remove('f_indirect_next_child') : check #indirect_next_child color PASS [ .darkblue:has(~ #indirect_next:not(.p + .f_indirect_next_child ~ .g)) ~ #indirect_next #indirect_next_child ] #direct_next.classList.add('f_indirect_next_child') : check matches (false) @@ -443,11 +443,11 @@ PASS [ .orange:has(#descendant:not(.m:not(.n) .o)) ] #parent.classList.remove('m') : check matches (true) PASS [ .orange:has(#descendant:not(.m:not(.n) .o)) ] #parent.classList.remove('m') : check #has_scope color PASS [ .orange:has(#descendant:not(.m:not(.n) .o)) ] #has_scope.classList.add('m') : check matches (false) -FAIL [ .orange:has(#descendant:not(.m:not(.n) .o)) ] #has_scope.classList.add('m') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 165, 0)" +PASS [ .orange:has(#descendant:not(.m:not(.n) .o)) ] #has_scope.classList.add('m') : check #has_scope color PASS [ .orange:has(#descendant:not(.m:not(.n) .o)) ] #has_scope.classList.add('n') : check matches (true) PASS [ .orange:has(#descendant:not(.m:not(.n) .o)) ] #has_scope.classList.add('n') : check #has_scope color PASS [ .orange:has(#descendant:not(.m:not(.n) .o)) ] #has_scope.classList.remove('n') : check matches (false) -FAIL [ .orange:has(#descendant:not(.m:not(.n) .o)) ] #has_scope.classList.remove('n') : check #has_scope color assert_equals: expected "rgb(128, 128, 128)" but got "rgb(255, 165, 0)" +PASS [ .orange:has(#descendant:not(.m:not(.n) .o)) ] #has_scope.classList.remove('n') : check #has_scope color PASS [ .orange:has(#descendant:not(.m:not(.n) .o)) ] #has_scope.classList.remove('m') : check matches (true) PASS [ .orange:has(#descendant:not(.m:not(.n) .o)) ] #has_scope.classList.remove('m') : check #has_scope color PASS [ .orange:has(#descendant:not(.m:not(.n) .o)) ] #child.classList.add('m') : check matches (false)
diff --git a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/accept-ch-stickiness/cross-origin-iframe-redirect-with-fp-delegation.https-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/accept-ch-stickiness/cross-origin-iframe-redirect-with-fp-delegation.https-expected.txt deleted file mode 100644 index 54ace634..0000000 --- a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/accept-ch-stickiness/cross-origin-iframe-redirect-with-fp-delegation.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Iframe redirect with Feature Policy delegation got client hints according to expectations. assert_equals: message from opened frame expected "PASS" but got "PLATFORM" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/accept-ch-stickiness/cross-origin-subresource-redirect-with-fp-delegation.https-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/accept-ch-stickiness/cross-origin-subresource-redirect-with-fp-delegation.https-expected.txt deleted file mode 100644 index cea54bbdd..0000000 --- a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/accept-ch-stickiness/cross-origin-subresource-redirect-with-fp-delegation.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL cross-origin subresource redirect with Feature Policy delegation got client hints according to expectations. assert_true: expected true got false -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/accept-ch-stickiness/same-origin-navigation-redirect.https-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/accept-ch-stickiness/same-origin-navigation-redirect.https-expected.txt deleted file mode 100644 index e20ba533..0000000 --- a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/accept-ch-stickiness/same-origin-navigation-redirect.https-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -This is a testharness.js-based test. -PASS redirect on navigation precondition: Test that the browser does not have client hints preferences cached -FAIL redirect on navigation got client hints according to expectations. assert_equals: message from opened page expected "PASS" but got "PLATFORM" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/accept-ch-stickiness/same-origin-subresource-redirect-opted-in.https-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/accept-ch-stickiness/same-origin-subresource-redirect-opted-in.https-expected.txt deleted file mode 100644 index dad4461..0000000 --- a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/accept-ch-stickiness/same-origin-subresource-redirect-opted-in.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL same-origin subresource redirect with opt-in got client hints according to expectations. assert_true: expected true got false -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/accept-ch/feature-policy-navigation/feature-policy.https-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/accept-ch/feature-policy-navigation/feature-policy.https-expected.txt deleted file mode 100644 index 77f8b35..0000000 --- a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/accept-ch/feature-policy-navigation/feature-policy.https-expected.txt +++ /dev/null
@@ -1,6 +0,0 @@ -This is a testharness.js-based test. -FAIL Client hints loaded on cross-origin iframe request with feature policy. promise_test: Unhandled rejection with value: "FAIL sec-ch-ua-platform True None" -PASS Client hints loaded on same-origin iframe request with feature policy. -FAIL Client hints loaded on cross-origin iframe request with feature policy after attempting to set independently. promise_test: Unhandled rejection with value: "FAIL sec-ch-ua-platform True None" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/accept-ch/feature-policy-navigation/no-feature-policy.https-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/accept-ch/feature-policy-navigation/no-feature-policy.https-expected.txt deleted file mode 100644 index e553f8d..0000000 --- a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/accept-ch/feature-policy-navigation/no-feature-policy.https-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -This is a testharness.js-based test. -FAIL Client hints not loaded on cross-origin iframe request with no feature policy. promise_test: Unhandled rejection with value: "FAIL sec-ch-ua-platform True None" -PASS Client hints loaded on same-origin iframe request with no feature policy. -FAIL Client hints loaded on cross-origin iframe request with allow list. promise_test: Unhandled rejection with value: "FAIL sec-ch-ua-platform True None" -PASS Client hints loaded on same-origin iframe request with allow list. -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/http-equiv-accept-ch-iframe.https-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/http-equiv-accept-ch-iframe.https-expected.txt deleted file mode 100644 index d9b3330..0000000 --- a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/http-equiv-accept-ch-iframe.https-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -This is a testharness.js-based test. -FAIL Client hints loaded on same-origin iframe should include hints with a default permissions policy ofself and *, but the http-equiv meta tag has a bug and it doesn't impact iframes. promise_test: Unhandled rejection with value: "FAIL sec-ch-ua-platform True None" -FAIL Client hints loaded on cross-origin iframe only include hints with a default permissions policy of *. promise_test: Unhandled rejection with value: "FAIL sec-ch-ua-platform True None" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/meta-name-accept-ch-iframe.https-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/meta-name-accept-ch-iframe.https-expected.txt deleted file mode 100644 index 76274f94..0000000 --- a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/meta-name-accept-ch-iframe.https-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -This is a testharness.js-based test. -FAIL Client hints loaded on same-origin iframe include hints with a default permissions policy of self and *. promise_test: Unhandled rejection with value: "FAIL sec-ch-ua-platform True None" -FAIL Client hints loaded on cross-origin iframe only include hints with a default permissions policy of *. promise_test: Unhandled rejection with value: "FAIL sec-ch-ua-platform True None" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/sandbox/iframe-csp.https-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/sandbox/iframe-csp.https-expected.txt deleted file mode 100644 index 6786739..0000000 --- a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/sandbox/iframe-csp.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL CSP sandboxed iframe does not send client hint headers assert_equals: message from opened frame expected "PASS" but got "FAIL sec-ch-ua-platform True None" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/sandbox/iframe.https-expected.txt b/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/sandbox/iframe.https-expected.txt deleted file mode 100644 index f11947c..0000000 --- a/third_party/blink/web_tests/platform/generic/virtual/disable-ua-ch-platform/external/wpt/client-hints/sandbox/iframe.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL sandboxed iframe does not send client hint headers assert_equals: message from opened frame expected "PASS" but got "FAIL sec-ch-ua-platform True None" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/virtual/disable-ua-ch-platform/README.md b/third_party/blink/web_tests/virtual/disable-ua-ch-platform/README.md deleted file mode 100644 index 37eafa5..0000000 --- a/third_party/blink/web_tests/virtual/disable-ua-ch-platform/README.md +++ /dev/null
@@ -1,2 +0,0 @@ -This virtual test suite ensures the UACHPlatformEnabledByDefault feature -disables correctly.
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium index 27ad761..e6aee63 100644 --- a/third_party/freetype/README.chromium +++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@ Name: FreeType URL: http://www.freetype.org/ -Version: VER-2-12-1-12-gd68579812 -Revision: d6857981239ea5f6e95cb4eb4402307f3527760a +Version: VER-2-12-1-13-gc26872ed5 +Revision: c26872ed59cba3af2f407b5eefc92fcec92aa52b CPEPrefix: cpe:/a:freetype:freetype:2.11.1 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent JPEG Group) licenses"
diff --git a/tools/attribution_reporting/simulator_main.cc b/tools/attribution_reporting/simulator_main.cc index dc692a1..d852684 100644 --- a/tools/attribution_reporting/simulator_main.cc +++ b/tools/attribution_reporting/simulator_main.cc
@@ -88,10 +88,10 @@ is described below in detail. Learn more about the Attribution Reporting API at -https://github.com/WICG/conversion-measurement-api#attribution-reporting-api. +https://github.com/WICG/attribution-reporting-api#attribution-reporting-api. Learn about the meaning of the input and output fields at -https://github.com/WICG/conversion-measurement-api/blob/main/EVENT.md. +https://github.com/WICG/attribution-reporting-api/blob/main/EVENT.md. Switches: --copy_input_to_output - Optional. If present, the input is copied to the
diff --git a/tools/clang/scripts/build.py b/tools/clang/scripts/build.py index a2ec9e5..9313a100 100755 --- a/tools/clang/scripts/build.py +++ b/tools/clang/scripts/build.py
@@ -1000,7 +1000,6 @@ if args.build_mac_arm: assert platform.machine() != 'arm64', 'build_mac_arm for cross build only' cmake_args += ['-DCMAKE_OSX_ARCHITECTURES=arm64', - '-DLLVM_USE_HOST_TOOLS=ON', '-DCMAKE_SYSTEM_NAME=Darwin'] # The default LLVM_DEFAULT_TARGET_TRIPLE depends on the host machine.
diff --git a/tools/fuchsia/size_tests/BUILD.gn b/tools/fuchsia/size_tests/BUILD.gn index 5b9d723..8a0ffad 100644 --- a/tools/fuchsia/size_tests/BUILD.gn +++ b/tools/fuchsia/size_tests/BUILD.gn
@@ -9,6 +9,6 @@ compute_fuchsia_package_sizes("fuchsia_sizes") { data_deps = [ "//fuchsia/engine:web_engine", - "//fuchsia/runners:cast_runner_pkg", + "//fuchsia_web/runners:cast_runner_pkg", ] }
diff --git a/tools/fuchsia/size_tests/fyi_sizes.json b/tools/fuchsia/size_tests/fyi_sizes.json index c061514..56be7f07 100644 --- a/tools/fuchsia/size_tests/fyi_sizes.json +++ b/tools/fuchsia/size_tests/fyi_sizes.json
@@ -1,7 +1,7 @@ { "far_files" : [ "gen/fuchsia/engine/web_engine/web_engine.far", - "gen/fuchsia/runners/cast_runner/cast_runner.far" + "gen/fuchsia_web/runners/cast_runner/cast_runner.far" ], "far_total_name" : "chrome_fuchsia", "size_limits" : {
diff --git a/tools/fuchsia/size_tests/fyi_sizes_smoketest.json b/tools/fuchsia/size_tests/fyi_sizes_smoketest.json index c061514..56be7f07 100644 --- a/tools/fuchsia/size_tests/fyi_sizes_smoketest.json +++ b/tools/fuchsia/size_tests/fyi_sizes_smoketest.json
@@ -1,7 +1,7 @@ { "far_files" : [ "gen/fuchsia/engine/web_engine/web_engine.far", - "gen/fuchsia/runners/cast_runner/cast_runner.far" + "gen/fuchsia_web/runners/cast_runner/cast_runner.far" ], "far_total_name" : "chrome_fuchsia", "size_limits" : {
diff --git a/tools/fuchsia/size_tests/fyi_sizes_warning.json b/tools/fuchsia/size_tests/fyi_sizes_warning.json index b349273..ee605199 100644 --- a/tools/fuchsia/size_tests/fyi_sizes_warning.json +++ b/tools/fuchsia/size_tests/fyi_sizes_warning.json
@@ -1,7 +1,7 @@ { "far_files" : [ "gen/fuchsia/engine/web_engine/web_engine.far", - "gen/fuchsia/runners/cast_runner/cast_runner.far" + "gen/fuchsia_web/runners/cast_runner/cast_runner.far" ], "far_total_name" : "chrome_fuchsia", "size_limits" : {
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 53f4055..a2c7a18 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -27864,6 +27864,15 @@ </description> </action> +<action name="Signin_Impression_FromNTPFeedTopPromo"> + <owner>mrefaat@google.com</owner> + <owner>sczs@chromium.org</owner> + <owner>feed@chromium.org</owner> + <description> + Recorded when showing sign in entry in the NTP feed top section promo. + </description> +</action> + <action name="Signin_Impression_FromPasswordBubble" not_user_triggered="true"> <owner>gogerald@chromium.org</owner> <description> @@ -28002,6 +28011,18 @@ </description> </action> +<action name="Signin_ImpressionWithAccount_FromNTPFeedTopPromo" + not_user_triggered="true"> + <owner>mrefaat@chromium.org</owner> + <owner>sczs@chromium.org</owner> + <owner>jlebel@chromium.org</owner> + <description> + Recorded when starting sign-in using the promo view, with a default account, + from NTP Feed top section + (signin_metrics::AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO). + </description> +</action> + <action name="Signin_ImpressionWithAccount_FromPasswordBubble" not_user_triggered="true"> <owner>msarda@chromium.org</owner> @@ -28113,6 +28134,18 @@ </description> </action> +<action name="Signin_ImpressionWithNoAccount_FromNTPFeedTopPromo" + not_user_triggered="true"> + <owner>mrefaat@chromium.org</owner> + <owner>jlebel@chromium.org</owner> + <owner>sczs@chromium.org</owner> + <description> + Recorded when starting sign-in using the promo view, with no default + account, from NTP content suggestions + (signin_metrics::AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO). + </description> +</action> + <action name="Signin_ImpressionWithNoAccount_FromPasswordBubble" not_user_triggered="true"> <owner>msarda@chromium.org</owner> @@ -28431,6 +28464,15 @@ </description> </action> +<action name="Signin_Signin_FromNTPFeedTopPromo"> + <owner>jlebel@chromium.org</owner> + <owner>mrefaat@chromium.org</owner> + <description> + Recorded on sign in start from access point + signin_metrics::AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO. + </description> +</action> + <action name="Signin_Signin_FromPasswordBubble"> <owner>gogerald@chromium.org</owner> <description> @@ -28775,6 +28817,16 @@ </description> </action> +<action name="Signin_SigninNewAccountExistingAccount_FromNTPFeedTopPromo"> + <owner>mrefaat@chromium.org</owner> + <owner>jlebel@chromium.org</owner> + <description> + Recorded on sign in start from access point + signin_metrics::AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO, with a new + account, while Chrome already has other accounts. + </description> +</action> + <action name="Signin_SigninNewAccountExistingAccount_FromPasswordBubble"> <owner>bsazonov@chromium.org</owner> <owner>msarda@chromium.org</owner> @@ -28898,6 +28950,17 @@ </description> </action> +<action name="Signin_SigninNewAccountNoExistingAccount_FromNTPFeedTopPromo"> + <owner>mrefaat@chromium.org</owner> + <owner>sczs@chromium.org</owner> + <owner>jlebel@chromium.org</owner> + <description> + Recorded on sign in start from access point + signin_metrics::AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO, with a new + account, while Chrome does not have other accounts. + </description> +</action> + <action name="Signin_SigninNewAccountNoExistingAccount_FromPasswordBubble"> <owner>bsazonov@chromium.org</owner> <owner>msarda@chromium.org</owner> @@ -29146,6 +29209,17 @@ </description> </action> +<action name="Signin_SigninNotDefault_FromNTPFeedTopPromo"> + <owner>mrefaat@chromium.org</owner> + <owner>sczs@chromium.org</owner> + <owner>jlebel@chromium.org</owner> + <description> + Recorded on sign in start from access point + signin_metrics::AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO, using another + account than the default one. + </description> +</action> + <action name="Signin_SigninNotDefault_FromPasswordBubble"> <owner>bsazonov@chromium.org</owner> <owner>msarda@chromium.org</owner> @@ -29274,6 +29348,17 @@ </description> </action> +<action name="Signin_SigninWithDefault_FromNTPFeedTopPromo"> + <owner>mrefaat@chromium.org</owner> + <owner>sczs@chromium.org</owner> + <owner>jlebel@chromium.org</owner> + <description> + Recorded on sign in start from access point + signin_metrics::AccessPoint::ACCESS_POINT_NTP_FEED_TOP_PROMO, using the + default account. + </description> +</action> + <action name="Signin_SigninWithDefault_FromPasswordBubble"> <owner>bsazonov@chromium.org</owner> <owner>msarda@chromium.org</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 0528c3a..cd0306a 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -10790,16 +10790,6 @@ <int value="1" label="Ignored due to multiple pages in the renderer process"/> </enum> -<enum name="BlobBrokenReason"> - <int value="0" label="Unknown"/> - <int value="1" label="There is not enough memory to store this blob"/> - <int value="2" label="File write failed"/> - <int value="3" label="Source died in transit"/> - <int value="4" label="Blob dereferenced while building"/> - <int value="5" label="Referenced blob broken"/> - <int value="6" label="Referenced file unavailable"/> -</enum> - <enum name="BlobBuildFromStreamResult"> <int value="0" label="Success"/> <int value="1" label="Aborted while building"/> @@ -55605,6 +55595,7 @@ label="EnableBluetoothVerboseLogsForGooglers:disabled"/> <int value="-1491417046" label="enable-fullscreen-toolbar-reveal"/> <int value="-1491304576" label="ProgressBarThrottle:disabled"/> + <int value="-1490827023" label="EnableCbdSignOut:disabled"/> <int value="-1490298774" label="enable-captive-portal-bypass-proxy-option"/> <int value="-1490048536" label="PageVisibilityPageContentAnnotations:disabled"/> @@ -57235,6 +57226,7 @@ <int value="-454362199" label="HelpAppV2:disabled"/> <int value="-450976085" label="AutofillSaveCreditCardUsesImprovedMessaging:disabled"/> + <int value="-450917820" label="EnableCbdSignOut:enabled"/> <int value="-450100254" label="OverviewButton:enabled"/> <int value="-449465495" label="disable-browser-task-scheduler"/> <int value="-448929520" label="TranslateMessageUI:enabled"/> @@ -80418,11 +80410,6 @@ <int value="3" label="Last redirect in URL chain"/> </enum> -<enum name="RefcountOperation"> - <int value="0" label="Decrement"/> - <int value="1" label="Increment"/> -</enum> - <enum name="RefineActionUsage"> <int value="0" label="Not used"/> <int value="1" label="Used on Search Suggestion in zero-prefix context"/> @@ -86592,6 +86579,7 @@ <int value="34" label="Enterprise sign-out coordinator"/> <int value="35" label="Signin intercept first run experience"/> <int value="36" label="Send-tab-to-self promo"/> + <int value="37" label="Sign-in promo on NTP feed top section."/> </enum> <enum name="SigninAccountEquality">
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml index d69bc0f..b1caf616 100644 --- a/tools/metrics/histograms/metadata/android/histograms.xml +++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -3532,7 +3532,7 @@ </histogram> <histogram name="Android.WebView.DarkMode.ForceDarkBehavior" - enum="WebViewForceDarkBehavior" expires_after="2022-07-24"> + enum="WebViewForceDarkBehavior" expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -3542,7 +3542,7 @@ </histogram> <histogram name="Android.WebView.DarkMode.ForceDarkMode" - enum="WebViewForceDarkMode2" expires_after="2022-07-24"> + enum="WebViewForceDarkMode2" expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -3552,7 +3552,7 @@ </histogram> <histogram name="Android.WebView.DarkMode.InDarkMode" enum="Boolean" - expires_after="2022-07-24"> + expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -3562,7 +3562,7 @@ </histogram> <histogram name="Android.WebView.DarkMode.InDarkModeVsLightTheme" - enum="WebViewInDarkModeVsLightTheme" expires_after="2022-07-24"> + enum="WebViewInDarkModeVsLightTheme" expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -3572,7 +3572,7 @@ </histogram> <histogram name="Android.WebView.DarkMode.InDarkModeVsNightMode" - enum="WebViewInDarkModeVsNightMode" expires_after="2022-07-24"> + enum="WebViewInDarkModeVsNightMode" expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -3582,7 +3582,7 @@ </histogram> <histogram name="Android.WebView.DarkMode.LightTheme" enum="LightTheme" - expires_after="2022-07-24"> + expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -3592,7 +3592,7 @@ </histogram> <histogram name="Android.WebView.DarkMode.NightMode" enum="NightMode" - expires_after="2022-07-24"> + expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -3603,7 +3603,7 @@ </histogram> <histogram name="Android.WebView.DarkMode.NightModeVsLightTheme" - enum="WebViewNightModeVsLightTheme" expires_after="2022-07-24"> + enum="WebViewNightModeVsLightTheme" expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -3613,7 +3613,7 @@ </histogram> <histogram name="Android.WebView.DarkMode.PageDarkenedAccordingToAppTheme" - enum="Boolean" expires_after="2022-06-24"> + enum="Boolean" expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -3625,7 +3625,7 @@ </histogram> <histogram name="Android.WebView.DarkMode.PrefersDarkFromTheme" - enum="BooleanYesNo" expires_after="2022-07-24"> + enum="BooleanYesNo" expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -3636,7 +3636,7 @@ </histogram> <histogram name="Android.WebView.DarkMode.PrimaryTextLuminanceVsLightTheme" - enum="WebViewPrimaryTextLuminanceVsLightTheme" expires_after="2022-07-24"> + enum="WebViewPrimaryTextLuminanceVsLightTheme" expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -3647,7 +3647,7 @@ </histogram> <histogram name="Android.WebView.DarkMode.PrimaryTextLuminanceVsNightMode" - enum="WebViewPrimaryTextLuminanceVsNightMode" expires_after="2022-07-24"> + enum="WebViewPrimaryTextLuminanceVsNightMode" expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -3844,7 +3844,7 @@ </histogram> <histogram name="Android.WebView.ForceDarkBehavior" - enum="WebViewForceDarkBehavior" expires_after="2022-06-03"> + enum="WebViewForceDarkBehavior" expires_after="2023-06-01"> <owner>peter@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -3854,7 +3854,7 @@ </histogram> <histogram name="Android.WebView.ForceDarkMode" enum="WebViewForceDarkMode" - expires_after="2022-06-03"> + expires_after="2023-06-01"> <owner>peter@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml index d2e8890d..88a1380 100644 --- a/tools/metrics/histograms/metadata/autofill/histograms.xml +++ b/tools/metrics/histograms/metadata/autofill/histograms.xml
@@ -3959,14 +3959,14 @@ </histogram> <histogram name="Autofill.WebView.AutofillSession" enum="AutofillSessionStates" - expires_after="2022-06-08"> + expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary>Records the state of an autofill session.</summary> </histogram> <histogram name="Autofill.WebView.AwGIsCurrentService" enum="BooleanYesNo" - expires_after="2022-06-08"> + expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -3977,14 +3977,14 @@ </histogram> <histogram name="Autofill.WebView.CreatedByActivityContext" - enum="BooleanEnabled" expires_after="2022-06-08"> + enum="BooleanEnabled" expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary>Whether the autofill is created by activity context.</summary> </histogram> <histogram name="Autofill.WebView.Enabled" enum="BooleanEnabled" - expires_after="2022-06-08"> + expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -3993,7 +3993,7 @@ </histogram> <histogram name="Autofill.WebView.ServerPrediction.AwGSuggestionAvailability" - enum="AutofillAwGSuggestionAvailability" expires_after="2022-06-08"> + enum="AutofillAwGSuggestionAvailability" expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -4004,7 +4004,7 @@ </histogram> <histogram name="Autofill.WebView.ServerPredicton.HasValidServerPrediction" - enum="BooleanYesNo" expires_after="2022-06-08"> + enum="BooleanYesNo" expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -4016,7 +4016,7 @@ </histogram> <histogram name="Autofill.WebView.ServerPredicton.PredictionAvailability" - enum="AutofillServerPredictionAvailability" expires_after="2022-06-08"> + enum="AutofillServerPredictionAvailability" expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary> @@ -4029,21 +4029,21 @@ </histogram> <histogram name="Autofill.WebView.SubmissionSource" - enum="AutofillSubmissionSource" expires_after="2022-06-08"> + enum="AutofillSubmissionSource" expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary>Records the source of form submission.</summary> </histogram> <histogram name="Autofill.WebView.SuggestionTime" units="ms" - expires_after="2022-06-08"> + expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary>The time taken to display suggestion.</summary> </histogram> <histogram name="Autofill.WebView.UserChangedAutofilledField" - enum="BooleanEnabled" expires_after="2022-06-08"> + enum="BooleanEnabled" expires_after="2023-06-01"> <owner>michaelbai@chromium.org</owner> <owner>src/android_webview/OWNERS</owner> <summary>Whether the user changed autofilled field.</summary>
diff --git a/tools/metrics/histograms/metadata/mobile/histograms.xml b/tools/metrics/histograms/metadata/mobile/histograms.xml index fc8f58d..79aefca 100644 --- a/tools/metrics/histograms/metadata/mobile/histograms.xml +++ b/tools/metrics/histograms/metadata/mobile/histograms.xml
@@ -1112,6 +1112,41 @@ </summary> </histogram> +<histogram name="MobileSignInPromo.NTPFeedTop.ImpressionsTilDismiss" + units="impressions" expires_after="2023-06-01"> + <owner>mrefaat@chromium.org</owner> + <owner>jlebel@chromium.org</owner> + <owner>chrome-signin-team@google.com</owner> + <summary> + Counts how many times the signin promo is implicitly dismissed (by leaving + the NTP) per impression of the NTP feed top section sign in promo. + </summary> +</histogram> + +<histogram name="MobileSignInPromo.NTPFeedTop.ImpressionsTilSigninButtons" + units="impressions" expires_after="2023-06-01"> + <owner>mrefaat@chromium.org</owner> + <owner>jlebel@chromium.org</owner> + <owner>chrome-signin-team@google.com</owner> + <summary> + Counts how many times one of the "sign in" buttons (any of the + signed-out "Sign in to Chrome" button, the "Continue as + |name|" button, or the "Not |email|?" button) is clicked per + impression of the NTP feed top section sign in promo. + </summary> +</histogram> + +<histogram name="MobileSignInPromo.NTPFeedTop.ImpressionsTilXButton" + units="impressions" expires_after="2023-06-01"> + <owner>mrefaat@chromium.org</owner> + <owner>jlebel@chromium.org</owner> + <owner>chrome-signin-team@google.com</owner> + <summary> + Counts how many times the explicit "X"-to-close button is clicked + per impression of the NTP feed top section sign in promo. + </summary> +</histogram> + <histogram name="MobileSignInPromo.SettingsManager.ImpressionsTilDismiss" units="impressions" expires_after="2023-04-01"> <owner>jlebel@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/net/histograms.xml b/tools/metrics/histograms/metadata/net/histograms.xml index 4ed61f443..a2458af 100644 --- a/tools/metrics/histograms/metadata/net/histograms.xml +++ b/tools/metrics/histograms/metadata/net/histograms.xml
@@ -4672,12 +4672,14 @@ </histogram> <histogram name="Net.SSLKeyLogFileUse" enum="SSLKeyLogFileAction" - expires_after="M92"> + expires_after="M110"> <owner>cthomp@chromium.org</owner> - <owner>security-enamel@chromium.org</owner> + <owner>trusty-transport@chromium.org</owner> <summary> Counts when the SSLKEYLOGFILE environment variable or --ssl-key-log-file command-line flag are set, and when they enable the SSLKeyLogger feature. + + This histogram was temporarily expired from M92 until M104. </summary> </histogram>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index aac2316..e3180a9 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -3640,7 +3640,7 @@ <owner>csharrison@chromium.org</owner> <summary> Records the number of registered conversions - (https://github.com/WICG/conversion-measurement-api) on a given top level + (https://github.com/WICG/attribution-reporting-api) on a given top level page load. Recorded when the page navigates away or is otherwise closed. Only recorded for non-off-the-record profiles (OTR profiles have the feature disabled).
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml index 44c79260..4414220 100644 --- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml +++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -1973,16 +1973,6 @@ </summary> </histogram> -<histogram name="SafeBrowsing.TailoredSecurity.SyncPromptSkippedAlreadyEnabled" - enum="BooleanSkipped" expires_after="2022-10-04"> - <owner>drubery@chromium.org</owner> - <owner>chrome-safebrowsing-alerts@google.com</owner> - <summary> - Records whether a sync prompt was skipped because the user had already - consented to Enhanced Safe Browsing. - </summary> -</histogram> - <histogram name="SafeBrowsing.TailoredSecurityConsented{Status}{PromptType}Outcome" enum="SafeBrowsingTailoredSecurityOutcome" expires_after="2022-11-22">
diff --git a/tools/metrics/histograms/metadata/search/histograms.xml b/tools/metrics/histograms/metadata/search/histograms.xml index 708a242..0c48e49 100644 --- a/tools/metrics/histograms/metadata/search/histograms.xml +++ b/tools/metrics/histograms/metadata/search/histograms.xml
@@ -154,7 +154,10 @@ </histogram> <histogram name="Search.ContextualSearch.Ranker.NotSuppressed.ResultsSeen" - enum="ContextualSearchResultsSeen" expires_after="M77"> + enum="ContextualSearchResultsSeen" expires_after="M104"> + <obsolete> + Removed 06/2022 + </obsolete> <owner>donnd@chromium.org</owner> <owner>twellington@chromium.org</owner> <summary> @@ -164,7 +167,10 @@ </histogram> <histogram name="Search.ContextualSearch.Ranker.Recorded" enum="Boolean" - expires_after="M77"> + expires_after="M104"> + <obsolete> + Removed 06/2022 + </obsolete> <owner>donnd@chromium.org</owner> <owner>twellington@chromium.org</owner> <summary> @@ -185,7 +191,10 @@ </histogram> <histogram name="Search.ContextualSearch.Ranker.Suppressed" enum="Boolean" - expires_after="M85"> + expires_after="M104"> + <obsolete> + Removed 06/2022 + </obsolete> <owner>donnd@chromium.org</owner> <owner>twellington@chromium.org</owner> <summary> @@ -234,7 +243,10 @@ </histogram> <histogram name="Search.ContextualSearch.Ranker.WasAbleToPredict" - enum="Boolean" expires_after="M77"> + enum="Boolean" expires_after="M104"> + <obsolete> + Removed 06/2022 + </obsolete> <owner>donnd@chromium.org</owner> <owner>twellington@chromium.org</owner> <summary> @@ -244,7 +256,10 @@ </histogram> <histogram name="Search.ContextualSearch.Ranker.WouldSuppress.ResultsSeen" - enum="ContextualSearchResultsSeen" expires_after="M77"> + enum="ContextualSearchResultsSeen" expires_after="M104"> + <obsolete> + Removed 06/2022 + </obsolete> <owner>donnd@chromium.org</owner> <owner>twellington@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/storage/histograms.xml b/tools/metrics/histograms/metadata/storage/histograms.xml index cbd62fc..81064b3 100644 --- a/tools/metrics/histograms/metadata/storage/histograms.xml +++ b/tools/metrics/histograms/metadata/storage/histograms.xml
@@ -224,38 +224,6 @@ </summary> </histogram> -<histogram name="Storage.Blob.Broken" enum="BooleanBroken" expires_after="M95"> - <owner>mek@chromium.org</owner> - <owner>dmurph@chromium.org</owner> - <summary> - If a newly constructed blob is broken. See Storage.Blob.BrokenReason for a - the broken reasons. - </summary> -</histogram> - -<histogram name="Storage.Blob.BrokenReason" enum="BlobBrokenReason" - expires_after="M95"> - <owner>mek@chromium.org</owner> - <owner>dmurph@chromium.org</owner> - <summary> - The reason a blob is broken, reported only for broken blobs upon - construction. See Storage.Blob.Broken for the breakdown of blobs broken vs - unbroken. - </summary> -</histogram> - -<histogram name="Storage.Blob.CleanupSuccess" enum="Boolean" - expires_after="M95"> - <owner>mek@chromium.org</owner> - <owner>dmurph@chromium.org</owner> - <summary> - Recorded when the old blob storage directories are cleared. This occurs on - storage partition initialization, and is not recorded if there are no - directories to clear. The value indicates if the file operations were a - success. - </summary> -</histogram> - <histogram name="Storage.Blob.DataURLWorkerRegister" enum="Boolean" expires_after="M106"> <owner>awillia@chromium.org</owner> @@ -309,42 +277,7 @@ <owner>dmurph@chromium.org</owner> <summary> The error code reported by the blob system while trying to read a blob in - the FileReaderLoader. Compare with the - Storage.Blob.IDBRequestLoader.ReadError histogram to eliminate IndexedDB - large-value blobs. - </summary> -</histogram> - -<histogram name="Storage.Blob.IDBRequestLoader.ReadError" enum="NetErrorCodes" - expires_after="M95"> - <owner>mek@chromium.org</owner> - <owner>dmurph@chromium.org</owner> - <summary> - The error code reported by the blob system while trying to read an IndexedDB - large-value blob in the IDBRequestLoader. These blobs are automatically - created in Blink when a website writes a large value to IndexedDB. - </summary> -</histogram> - -<histogram name="Storage.Blob.InvalidReference" enum="RefcountOperation" - expires_after="M95"> - <owner>mek@chromium.org</owner> - <owner>dmurph@chromium.org</owner> - <summary> - Counts the number of times we have an invalid refcount operation. An invalid - increment means the blob didn't exist, and an invalid decrement means we - don't have any record of the blob in our host. - </summary> -</histogram> - -<histogram name="Storage.Blob.InvalidURLRegister" enum="RefcountOperation" - expires_after="M95"> - <owner>mek@chromium.org</owner> - <owner>dmurph@chromium.org</owner> - <summary> - Counts the number of times we have an invalid url registration operation. An - invalid increment means the blob isn't in use by the host yet or the url is - already mapped. An invalid decrement means the url isn't registered. + the FileReaderLoader. </summary> </histogram>
diff --git a/tools/metrics/histograms/metadata/tab/histograms.xml b/tools/metrics/histograms/metadata/tab/histograms.xml index 79a4c31..4097711d 100644 --- a/tools/metrics/histograms/metadata/tab/histograms.xml +++ b/tools/metrics/histograms/metadata/tab/histograms.xml
@@ -2025,7 +2025,7 @@ </histogram> <histogram name="Tabs.SavedTabLoadTime.{SavedTabMethod}.{SavedTabLoadResult}" - units="ms" expires_after="2022-07-11"> + units="ms" expires_after="2023-05-30"> <owner>davidjm@chromium.org</owner> <owner>nyquist@chromium.org</owner> <owner>dtrainor@chromium.org</owner>
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index e1001ca..f1410b1e 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -11,8 +11,8 @@ <item id="accounts_image_fetcher" added_in_milestone="66" content_hash_code="02b53da6" os_list="linux,windows,chromeos,android" file_path="components/signin/internal/identity_manager/account_fetcher_service.cc" /> <item id="adb_client_socket" added_in_milestone="65" content_hash_code="03607bec" os_list="linux,windows,chromeos" file_path="chrome/browser/devtools/device/adb/adb_client_socket.cc" /> <item id="affiliation_lookup_by_hash" added_in_milestone="87" content_hash_code="026afe84" os_list="linux,windows,chromeos,android" file_path="components/password_manager/core/browser/site_affiliation/hash_affiliation_fetcher.cc" /> - <item id="aggregation_service_helper_keys" added_in_milestone="96" content_hash_code="04127781" os_list="linux,windows,chromeos,android" file_path="content/browser/aggregation_service/aggregation_service_network_fetcher_impl.cc" /> - <item id="aggregation_service_report" added_in_milestone="95" content_hash_code="02a9ab82" os_list="linux,windows,chromeos,android" file_path="content/browser/aggregation_service/aggregatable_report_sender.cc" /> + <item id="aggregation_service_helper_keys" added_in_milestone="96" content_hash_code="006e2ea0" os_list="linux,windows,chromeos,android" file_path="content/browser/aggregation_service/aggregation_service_network_fetcher_impl.cc" /> + <item id="aggregation_service_report" added_in_milestone="95" content_hash_code="037768da" os_list="linux,windows,chromeos,android" file_path="content/browser/aggregation_service/aggregatable_report_sender.cc" /> <item id="android_device_manager_socket" added_in_milestone="65" content_hash_code="00623801" os_list="linux,windows,chromeos" file_path="chrome/browser/devtools/device/android_device_manager.cc" /> <item id="android_web_socket" added_in_milestone="65" content_hash_code="00bbd661" os_list="linux,windows,chromeos" file_path="chrome/browser/devtools/device/android_web_socket.cc" /> <item id="auction_downloader" added_in_milestone="92" content_hash_code="0713f212" os_list="linux,windows,chromeos,android" file_path="content/services/auction_worklet/auction_downloader.cc" />
diff --git a/ui/compositor/transform_recorder.cc b/ui/compositor/transform_recorder.cc index faa4a52..a98e7a4 100644 --- a/ui/compositor/transform_recorder.cc +++ b/ui/compositor/transform_recorder.cc
@@ -7,6 +7,7 @@ #include "cc/paint/display_item_list.h" #include "cc/paint/paint_op_buffer.h" #include "ui/compositor/paint_context.h" +#include "ui/gfx/geometry/transform.h" namespace ui {
diff --git a/ui/ozone/platform/x11/x11_window.cc b/ui/ozone/platform/x11/x11_window.cc index 2a56617..7371f85c 100644 --- a/ui/ozone/platform/x11/x11_window.cc +++ b/ui/ozone/platform/x11/x11_window.cc
@@ -34,6 +34,7 @@ #include "ui/events/x/events_x_utils.h" #include "ui/events/x/x11_event_translation.h" #include "ui/gfx/geometry/skia_conversions.h" +#include "ui/gfx/geometry/transform.h" #include "ui/gfx/image/image_skia_rep.h" #include "ui/gfx/x/x11_atom_cache.h" #include "ui/gfx/x/x11_path.h"
diff --git a/weblayer/browser/cookie_manager_impl.cc b/weblayer/browser/cookie_manager_impl.cc index 9a2510f7..5e2352d6 100644 --- a/weblayer/browser/cookie_manager_impl.cc +++ b/weblayer/browser/cookie_manager_impl.cc
@@ -211,9 +211,8 @@ bool CookieManagerImpl::SetCookieInternal(const GURL& url, const std::string& value, SetCookieCallback callback) { - auto cc = - net::CanonicalCookie::Create(url, value, base::Time::Now(), absl::nullopt, - net::CookiePartitionKey::Todo()); + auto cc = net::CanonicalCookie::Create(url, value, base::Time::Now(), + absl::nullopt, absl::nullopt); if (!cc) { return false; }